001 // Copyright 2007, 2008, 2009, 2010 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.internal.services;
016
017 import org.apache.tapestry5.Binding;
018 import org.apache.tapestry5.BindingConstants;
019 import org.apache.tapestry5.ComponentResources;
020 import org.apache.tapestry5.FieldTranslator;
021 import org.apache.tapestry5.FieldValidator;
022 import org.apache.tapestry5.MarkupWriter;
023 import org.apache.tapestry5.ValidationException;
024 import org.apache.tapestry5.ValueEncoder;
025 import org.apache.tapestry5.internal.TapestryInternalUtils;
026 import org.apache.tapestry5.internal.bindings.InvariantBinding;
027 import org.apache.tapestry5.ioc.Messages;
028 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
029 import org.apache.tapestry5.ioc.services.PropertyAccess;
030 import org.apache.tapestry5.runtime.Component;
031 import org.apache.tapestry5.services.BindingSource;
032 import org.apache.tapestry5.services.ComponentDefaultProvider;
033 import org.apache.tapestry5.services.FieldTranslatorSource;
034 import org.apache.tapestry5.services.FieldValidatorDefaultSource;
035 import org.apache.tapestry5.services.ValueEncoderSource;
036
037 public class ComponentDefaultProviderImpl implements ComponentDefaultProvider
038 {
039 private final PropertyAccess propertyAccess;
040
041 private final BindingSource bindingSource;
042
043 private final ValueEncoderSource valueEncoderSource;
044
045 private final FieldTranslatorSource fieldTranslatorSource;
046
047 private final FieldValidatorDefaultSource fieldValidatorDefaultSource;
048
049 static final FieldValidator NOOP_VALIDATOR = new FieldValidator()
050 {
051 public void validate(Object value) throws ValidationException
052 {
053 // Do nothing
054 }
055
056 public void render(MarkupWriter writer)
057 {
058 }
059
060 public boolean isRequired()
061 {
062 return false;
063 }
064 };
065
066 public ComponentDefaultProviderImpl(PropertyAccess propertyAccess, BindingSource bindingSource,
067 ValueEncoderSource valueEncoderSource,
068 FieldTranslatorSource fieldTranslatorSource,
069 FieldValidatorDefaultSource fieldValidatorDefaultSource)
070 {
071 this.propertyAccess = propertyAccess;
072 this.bindingSource = bindingSource;
073 this.valueEncoderSource = valueEncoderSource;
074 this.fieldTranslatorSource = fieldTranslatorSource;
075 this.fieldValidatorDefaultSource = fieldValidatorDefaultSource;
076 }
077
078 public String defaultLabel(ComponentResources resources)
079 {
080 assert resources != null;
081 String componentId = resources.getId();
082 String key = componentId + "-label";
083
084 Messages containerMessages = resources.getContainerResources().getMessages();
085
086 if (containerMessages.contains(key)) return containerMessages.get(key);
087
088 return TapestryInternalUtils.toUserPresentable(componentId);
089 }
090
091 public Binding defaultBinding(String parameterName, ComponentResources resources)
092 {
093 assert InternalUtils.isNonBlank(parameterName);
094 assert resources != null;
095 String componentId = resources.getId();
096
097 Component container = resources.getContainer();
098
099 // Only provide a default binding if the container actually contains the property.
100 // This sets up an error condition for when the parameter is not bound, and
101 // the binding can't be deduced.
102
103 if (propertyAccess.getAdapter(container).getPropertyAdapter(componentId) == null)
104 return null;
105
106 ComponentResources containerResources = resources.getContainerResources();
107
108 return bindingSource.newBinding(
109 "default " + parameterName,
110 containerResources,
111 BindingConstants.PROP,
112 componentId);
113 }
114
115 @SuppressWarnings({ "unchecked" })
116 public ValueEncoder defaultValueEncoder(String parameterName, ComponentResources resources)
117 {
118 assert InternalUtils.isNonBlank(parameterName);
119 assert resources != null;
120 Class parameterType = resources.getBoundType(parameterName);
121
122 if (parameterType == null) return null;
123
124 return valueEncoderSource.getValueEncoder(parameterType);
125 }
126
127 public FieldTranslator defaultTranslator(String parameterName, ComponentResources resources)
128 {
129 return fieldTranslatorSource.createDefaultTranslator(resources, parameterName);
130 }
131
132 public Binding defaultTranslatorBinding(final String parameterName, final ComponentResources resources)
133 {
134 String description = String.format("default translator, parameter %s of %s",
135 parameterName, resources.getCompleteId());
136
137 return new InvariantBinding(resources.getLocation(), FieldTranslator.class, description)
138 {
139 public Object get()
140 {
141 return defaultTranslator(parameterName, resources);
142 }
143 };
144 }
145
146 public FieldValidator defaultValidator(String parameterName, ComponentResources resources)
147 {
148 FieldValidator result = fieldValidatorDefaultSource.createDefaultValidator(resources, parameterName);
149
150 return result == null ? NOOP_VALIDATOR : result;
151 }
152
153 public Binding defaultValidatorBinding(final String parameterName, final ComponentResources resources)
154 {
155 String description = String.format("default validator, parameter %s of %s", parameterName,
156 resources.getCompleteId());
157
158 return new InvariantBinding(resources.getLocation(), FieldValidator.class, description)
159 {
160 public Object get()
161 {
162 return defaultValidator(parameterName, resources);
163 }
164 };
165 }
166 }