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.corelib.components.*;
022import org.apache.tapestry5.ioc.annotations.Inject;
023import org.apache.tapestry5.ioc.services.TypeCoercer;
024import org.apache.tapestry5.services.BeanBlockContribution;
025import org.apache.tapestry5.services.BeanBlockSource;
026import org.apache.tapestry5.services.PropertyEditContext;
027import org.apache.tapestry5.util.EnumSelectModel;
028import org.apache.tapestry5.util.EnumValueEncoder;
029
030/**
031 * A page that exists to contain blocks used to edit different types of properties. The blocks on this page are
032 * contributed into the {@link BeanBlockSource} service configuration.
033 *
034 * @see BeanBlockContribution
035 * @see BeanEditForm
036 */
037public class PropertyEditBlocks
038{
039    @Environmental
040    private PropertyEditContext context;
041
042    @Component(
043            parameters = {"value=context.propertyValue", "label=prop:context.label",
044                    "translate=prop:textFieldTranslator", "validate=prop:textFieldValidator",
045                    "clientId=prop:context.propertyId", "annotationProvider=context",
046                    "ensureClientIdUnique=true"})
047    private TextField textField;
048
049    @Component(
050            parameters = {"value=context.propertyValue", "label=prop:context.label",
051                    "translate=prop:numberFieldTranslator", "validate=prop:numberFieldValidator",
052                    "clientId=prop:context.propertyId", "annotationProvider=context",
053                    "ensureClientIdUnique=true"})
054    private TextField numberField;
055
056
057    @Component(
058            parameters = {"value=context.propertyValue", "label=prop:context.label", "encoder=valueEncoderForProperty",
059                    "model=selectModelForProperty", "validate=prop:selectValidator",
060                    "clientId=prop:context.propertyId", "ensureClientIdUnique=true"})
061    private Select select;
062
063    @SuppressWarnings("unused")
064    @Component(
065            parameters = {"value=context.propertyValue", "label=prop:context.label",
066                    "clientId=prop:context.propertyId", "ensureClientIdUnique=true"})
067    private Checkbox checkboxField;
068
069    @SuppressWarnings("unused")
070    @Component(
071            parameters = {"value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyid",
072                    "validate=prop:dateFieldValidator", "ensureClientIdUnique=true"})
073    private DateField dateField;
074
075    @SuppressWarnings("unused")
076    @Component(
077            parameters = {"value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyid",
078                    "validate=prop:calendarFieldValidator", "ensureClientIdUnique=true"})
079    private DateField calendarField;
080
081    @Component(
082            parameters = {"value=context.propertyValue", "label=prop:context.label",
083                    "translate=prop:passwordFieldTranslator", "validate=prop:passwordFieldValidator",
084                    "clientId=prop:context.propertyId", "annotationProvider=context", "ensureClientIdUnique=true"})
085    private PasswordField passwordField;
086
087    @Component(
088            parameters = {"value=context.propertyValue", "label=prop:context.label",
089                    "translate=prop:textAreaTranslator",
090                    "validate=prop:textAreaValidator", "clientId=prop:context.propertyId",
091                    "annotationProvider=context", "ensureClientIdUnique=true"})
092    private TextArea textArea;
093
094
095    @Inject
096    private TypeCoercer typeCoercer;
097
098    public PropertyEditContext getContext()
099    {
100        return context;
101    }
102
103
104    public FieldTranslator getTextFieldTranslator()
105    {
106        return context.getTranslator(textField);
107    }
108
109    public FieldValidator getTextFieldValidator()
110    {
111        return context.getValidator(textField);
112    }
113
114    public FieldTranslator getNumberFieldTranslator()
115    {
116        return context.getTranslator(numberField);
117    }
118
119    public FieldValidator getNumberFieldValidator()
120    {
121        return context.getValidator(numberField);
122    }
123
124    public FieldTranslator getPasswordFieldTranslator()
125    {
126        return context.getTranslator(passwordField);
127    }
128
129    public FieldValidator getPasswordFieldValidator()
130    {
131        return context.getValidator(passwordField);
132    }
133
134    public FieldTranslator getTextAreaTranslator()
135    {
136        return context.getTranslator(textArea);
137    }
138
139    public FieldValidator getTextAreaValidator()
140    {
141        return context.getValidator(textArea);
142    }
143
144
145    public FieldValidator getDateFieldValidator()
146    {
147        return context.getValidator(dateField);
148    }
149
150    public FieldValidator getCalendarFieldValidator()
151    {
152        return context.getValidator(calendarField);
153    }
154
155    public FieldValidator getSelectValidator()
156    {
157        return context.getValidator(select);
158    }
159
160    /**
161     * Provide a value encoder for an enum type.
162     */
163    @SuppressWarnings("unchecked")
164    public ValueEncoder getValueEncoderForProperty()
165    {
166        return new EnumValueEncoder(typeCoercer, context.getPropertyType());
167    }
168
169    /**
170     * Provide a select mode for an enum type.
171     */
172    @SuppressWarnings("unchecked")
173    public SelectModel getSelectModelForProperty()
174    {
175        Class propertyType = context.getPropertyType();
176        if (!Enum.class.isAssignableFrom(propertyType))
177        {
178            throw new IllegalStateException("Cannot create a select model for property " + context.getPropertyId()
179              + ". The property type is " + propertyType + " which is not an enum class.");
180        }
181        return new EnumSelectModel(propertyType, context.getContainerMessages());
182    }
183}