001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005//     http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.corelib.pages;
014
015import org.apache.tapestry5.FieldTranslator;
016import org.apache.tapestry5.FieldValidator;
017import org.apache.tapestry5.SelectModel;
018import org.apache.tapestry5.ValueEncoder;
019import org.apache.tapestry5.annotations.Component;
020import org.apache.tapestry5.annotations.Environmental;
021import org.apache.tapestry5.beanmodel.BeanModel;
022import org.apache.tapestry5.beanmodel.services.BeanModelSource;
023import org.apache.tapestry5.commons.services.TypeCoercer;
024import org.apache.tapestry5.corelib.components.BeanEditForm;
025import org.apache.tapestry5.corelib.components.Checkbox;
026import org.apache.tapestry5.corelib.components.DateField;
027import org.apache.tapestry5.corelib.components.PasswordField;
028import org.apache.tapestry5.corelib.components.Select;
029import org.apache.tapestry5.corelib.components.TextArea;
030import org.apache.tapestry5.corelib.components.TextField;
031import org.apache.tapestry5.ioc.annotations.Inject;
032import org.apache.tapestry5.services.BeanBlockContribution;
033import org.apache.tapestry5.services.BeanBlockSource;
034import org.apache.tapestry5.services.PropertyEditContext;
035import org.apache.tapestry5.services.compatibility.Compatibility;
036import org.apache.tapestry5.services.compatibility.Trait;
037import org.apache.tapestry5.util.EnumSelectModel;
038import org.apache.tapestry5.util.EnumValueEncoder;
039
040/**
041 * A page that exists to contain blocks used to edit different types of properties. The blocks on this page are
042 * contributed into the {@link BeanBlockSource} service configuration.
043 *
044 * @see BeanBlockContribution
045 * @see BeanEditForm
046 */
047public class PropertyEditBlocks
048{
049    @Environmental
050    private PropertyEditContext context;
051    
052    @Inject
053    private Compatibility compatibility;
054
055    @Component(
056            parameters = {"value=context.propertyValue", "label=prop:context.label",
057                    "translate=prop:textFieldTranslator", "validate=prop:textFieldValidator",
058                    "clientId=prop:context.propertyId", "annotationProvider=context",
059                    "ensureClientIdUnique=true"})
060    private TextField textField;
061
062    @Component(
063            parameters = {"value=context.propertyValue", "label=prop:context.label",
064                    "translate=prop:numberFieldTranslator", "validate=prop:numberFieldValidator",
065                    "clientId=prop:context.propertyId", "annotationProvider=context",
066                    "ensureClientIdUnique=true"})
067    private TextField numberField;
068
069
070    @Component(
071            parameters = {"value=context.propertyValue", "label=prop:context.label", "encoder=valueEncoderForProperty",
072                    "model=selectModelForProperty", "validate=prop:selectValidator",
073                    "clientId=prop:context.propertyId", "ensureClientIdUnique=true"})
074    private Select select;
075
076    @SuppressWarnings("unused")
077    @Component(
078            parameters = {"value=context.propertyValue", "label=prop:context.label",
079                    "clientId=prop:context.propertyId", "ensureClientIdUnique=true"})
080    private Checkbox checkboxField3;
081
082    @SuppressWarnings("unused")
083    @Component(
084            parameters = {"value=context.propertyValue", "label=prop:context.label",
085                    "clientId=prop:context.propertyId", "ensureClientIdUnique=true"})
086    private Checkbox checkboxField;
087
088    @SuppressWarnings("unused")
089    @Component(
090            parameters = {"value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyid",
091                    "validate=prop:dateFieldValidator", "ensureClientIdUnique=true"})
092    private DateField dateField;
093
094    @SuppressWarnings("unused")
095    @Component(
096            parameters = {"value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyid",
097                    "validate=prop:calendarFieldValidator", "ensureClientIdUnique=true"})
098    private DateField calendarField;
099
100    @Component(
101            parameters = {"value=context.propertyValue", "label=prop:context.label",
102                    "translate=prop:passwordFieldTranslator", "validate=prop:passwordFieldValidator",
103                    "clientId=prop:context.propertyId", "annotationProvider=context", "ensureClientIdUnique=true"})
104    private PasswordField passwordField;
105
106    @Component(
107            parameters = {"value=context.propertyValue", "label=prop:context.label",
108                    "translate=prop:textAreaTranslator",
109                    "validate=prop:textAreaValidator", "clientId=prop:context.propertyId",
110                    "annotationProvider=context", "ensureClientIdUnique=true"})
111    private TextArea textArea;
112
113
114    @Inject
115    private TypeCoercer typeCoercer;
116
117    public PropertyEditContext getContext()
118    {
119        return context;
120    }
121
122
123    public FieldTranslator getTextFieldTranslator()
124    {
125        return context.getTranslator(textField);
126    }
127
128    public FieldValidator getTextFieldValidator()
129    {
130        return context.getValidator(textField);
131    }
132
133    public FieldTranslator getNumberFieldTranslator()
134    {
135        return context.getTranslator(numberField);
136    }
137
138    public FieldValidator getNumberFieldValidator()
139    {
140        return context.getValidator(numberField);
141    }
142
143    public FieldTranslator getPasswordFieldTranslator()
144    {
145        return context.getTranslator(passwordField);
146    }
147
148    public FieldValidator getPasswordFieldValidator()
149    {
150        return context.getValidator(passwordField);
151    }
152
153    public FieldTranslator getTextAreaTranslator()
154    {
155        return context.getTranslator(textArea);
156    }
157
158    public FieldValidator getTextAreaValidator()
159    {
160        return context.getValidator(textArea);
161    }
162
163
164    public FieldValidator getDateFieldValidator()
165    {
166        return context.getValidator(dateField);
167    }
168
169    public FieldValidator getCalendarFieldValidator()
170    {
171        return context.getValidator(calendarField);
172    }
173
174    public FieldValidator getSelectValidator()
175    {
176        return context.getValidator(select);
177    }
178
179    /**
180     * Provide a value encoder for an enum type.
181     */
182    @SuppressWarnings("unchecked")
183    public ValueEncoder getValueEncoderForProperty()
184    {
185        return new EnumValueEncoder(typeCoercer, context.getPropertyType());
186    }
187
188    /**
189     * Provide a select mode for an enum type.
190     */
191    @SuppressWarnings("unchecked")
192    public SelectModel getSelectModelForProperty()
193    {
194        Class propertyType = context.getPropertyType();
195        if (!Enum.class.isAssignableFrom(propertyType))
196        {
197            throw new IllegalStateException("Cannot create a select model for property " + context.getPropertyId()
198              + ". The property type is " + propertyType + " which is not an enum class.");
199        }
200        return new EnumSelectModel(propertyType, context.getContainerMessages());
201    }
202
203    @Inject
204    private BeanModelSource beanModelSource;
205
206    @SuppressWarnings("unchecked")
207    public BeanModel<?> getModel()
208    {
209        return beanModelSource.createEditModel(context.getPropertyType(), context.getContainerMessages());
210    }
211    
212    public boolean isBootstrap3Enabled()
213    {
214        return compatibility.enabled(Trait.BOOTSTRAP_3);
215    }
216    
217}