KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > repo > component > property > UIProperty


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.ui.repo.component.property;
18
19 import java.io.IOException JavaDoc;
20 import java.text.MessageFormat JavaDoc;
21
22 import javax.faces.FacesException;
23 import javax.faces.component.UIInput;
24 import javax.faces.component.UIOutput;
25 import javax.faces.component.UISelectBoolean;
26 import javax.faces.context.FacesContext;
27 import javax.faces.convert.Converter;
28 import javax.faces.el.ValueBinding;
29
30 import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
31 import org.alfresco.service.cmr.dictionary.PropertyDefinition;
32 import org.alfresco.service.namespace.QName;
33 import org.alfresco.web.app.Application;
34 import org.alfresco.web.bean.repository.DataDictionary;
35 import org.alfresco.web.bean.repository.Node;
36 import org.alfresco.web.ui.common.ComponentConstants;
37 import org.alfresco.web.ui.common.Utils;
38 import org.alfresco.web.ui.common.converter.XMLDateConverter;
39 import org.alfresco.web.ui.repo.RepoConstants;
40 import org.alfresco.web.ui.repo.component.UICategorySelector;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.springframework.web.jsf.FacesContextUtils;
44
45 /**
46  * Component to represent an individual property within a property sheet
47  *
48  * @author gavinc
49  */

50 public class UIProperty extends PropertySheetItem
51 {
52    private static final String JavaDoc MSG_ERROR_PROPERTY = "error_property";
53    private static final String JavaDoc MSG_DATE_TIME = "date_time_pattern";
54    private static final String JavaDoc MSG_DATE = "date_pattern";
55
56    private static Log logger = LogFactory.getLog(UIProperty.class);
57
58    /**
59     * Default constructor
60     */

61    public UIProperty()
62    {
63       // set the default renderer
64
setRendererType("org.alfresco.faces.PropertyRenderer");
65    }
66    
67    /**
68     * @see javax.faces.component.UIComponent#getFamily()
69     */

70    public String JavaDoc getFamily()
71    {
72       return "org.alfresco.faces.Property";
73    }
74
75    /**
76     * @see org.alfresco.web.ui.repo.component.property.PropertySheetItem#getIncorrectParentMsg()
77     */

78    protected String JavaDoc getIncorrectParentMsg()
79    {
80       return "The property component must be nested within a property sheet component";
81    }
82
83    /**
84     * @see org.alfresco.web.ui.repo.component.property.PropertySheetItem#generateItem(javax.faces.context.FacesContext, org.alfresco.web.bean.repository.Node, java.lang.String)
85     */

86    protected void generateItem(FacesContext context, Node node, String JavaDoc var) throws IOException JavaDoc
87    {
88       String JavaDoc propertyName = (String JavaDoc)getName();
89
90       DataDictionary dd = (DataDictionary)FacesContextUtils.getRequiredWebApplicationContext(
91             context).getBean(Application.BEAN_DATA_DICTIONARY);
92       PropertyDefinition propDef = dd.getPropertyDefinition(node, propertyName);
93       
94       if (propDef == null)
95       {
96          // there is no definition for the node, so it may have been added to
97
// the node as an additional property, so look for it in the node itself
98
if (node.hasProperty(propertyName))
99          {
100             String JavaDoc displayLabel = (String JavaDoc)getDisplayLabel();
101             if (displayLabel == null)
102             {
103                displayLabel = propertyName;
104             }
105             
106             // generate the label and generic control
107
generateLabel(context, displayLabel);
108             generateControl(context, propertyName, var);
109          }
110          else
111          {
112             if (logger.isDebugEnabled())
113                logger.debug("Failed to find property definition for property '" + propertyName + "' for node: " + node.getNodeRef().toString());
114             
115             // NOTE: removed the error as it simply serves to confuse users and clutter the screen,
116
// the debugging log level should be used instead when developing property screens.
117
// add an error message as the property is not defined in the data dictionary and
118
// not in the node's set of properties
119
//String msg = MessageFormat.format(Application.getMessage(context, MSG_ERROR_PROPERTY), new Object[] {propertyName});
120
//Utils.addErrorMessage(msg);
121
}
122       }
123       else
124       {
125          String JavaDoc displayLabel = (String JavaDoc)getDisplayLabel();
126          if (displayLabel == null)
127          {
128             // try and get the repository assigned label
129
displayLabel = propDef.getTitle();
130             
131             // if the label is still null default to the local name of the property
132
if (displayLabel == null)
133             {
134                displayLabel = propDef.getName().getLocalName();
135             }
136          }
137          
138          // generate the label and type specific control
139
generateLabel(context, displayLabel);
140          generateControl(context, propDef, var);
141       }
142    }
143    
144    /**
145     * Generates an appropriate control for the given property
146     *
147     * @param context JSF context
148     * @param propDef The definition of the property to create the control for
149     * @param varName Name of the variable the node is stored in the session as
150     * (used for value binding expression)
151     * @param parent The parent component for the control
152     */

153    private void generateControl(FacesContext context, PropertyDefinition propDef,
154                                 String JavaDoc varName)
155    {
156       UIOutput control = null;
157       ValueBinding vb = context.getApplication().
158                         createValueBinding("#{" + varName + ".properties[\"" +
159                         propDef.getName().toString() + "\"]}");
160       
161       UIPropertySheet propSheet = (UIPropertySheet)this.getParent();
162       
163       DataTypeDefinition dataTypeDef = propDef.getDataType();
164       QName typeName = dataTypeDef.getName();
165          
166       if (propSheet.getMode().equalsIgnoreCase(UIPropertySheet.VIEW_MODE))
167       {
168          // if we are in view mode simply output the text to the screen unless the type
169
// of the property is a category
170
if (typeName.equals(DataTypeDefinition.CATEGORY))
171          {
172             control = (UICategorySelector)context.getApplication().
173                   createComponent(RepoConstants.ALFRESCO_FACES_CATEGORY_SELECTOR);
174             ((UICategorySelector)control).setDisabled(true);
175          }
176          else
177          {
178             control = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
179             control.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
180          }
181          
182          // if it is a date or datetime property add the converter
183
if (typeName.equals(DataTypeDefinition.DATETIME) )
184          {
185             XMLDateConverter conv = (XMLDateConverter)context.getApplication().
186                createConverter(RepoConstants.ALFRESCO_FACES_XMLDATA_CONVERTER);
187             conv.setType("both");
188             conv.setPattern(Application.getMessage(context, MSG_DATE_TIME));
189             control.setConverter(conv);
190          }
191          else if (typeName.equals(DataTypeDefinition.DATE))
192          {
193             XMLDateConverter conv = (XMLDateConverter)context.getApplication().
194                createConverter(RepoConstants.ALFRESCO_FACES_XMLDATA_CONVERTER);
195             conv.setType("date");
196             conv.setPattern(Application.getMessage(context, MSG_DATE));
197             control.setConverter(conv);
198          }
199       }
200       else
201       {
202          // generate the appropriate input field
203
if (typeName.equals(DataTypeDefinition.BOOLEAN))
204          {
205             control = (UISelectBoolean)context.getApplication().
206                   createComponent(ComponentConstants.JAVAX_FACES_SELECT_BOOLEAN);
207             control.setRendererType(ComponentConstants.JAVAX_FACES_CHECKBOX);
208          }
209          else if (typeName.equals(DataTypeDefinition.CATEGORY))
210          {
211             control = (UICategorySelector)context.getApplication().
212                   createComponent(RepoConstants.ALFRESCO_FACES_CATEGORY_SELECTOR);
213          }
214          else if (typeName.equals(DataTypeDefinition.DATETIME))
215          {
216             control = (UIInput)context.getApplication().
217                   createComponent(ComponentConstants.JAVAX_FACES_INPUT);
218             control.setRendererType(RepoConstants.ALFRESCO_FACES_DATE_PICKER_RENDERER);
219             control.getAttributes().put("yearCount", new Integer JavaDoc(30));
220             control.getAttributes().put("showTime", Boolean.valueOf(true));
221             control.getAttributes().put("style", "margin-right: 7px;");
222          }
223          else if (typeName.equals(DataTypeDefinition.DATE))
224          {
225             control = (UIInput)context.getApplication().
226                   createComponent(ComponentConstants.JAVAX_FACES_INPUT);
227             control.setRendererType(RepoConstants.ALFRESCO_FACES_DATE_PICKER_RENDERER);
228             control.getAttributes().put("yearCount", new Integer JavaDoc(30));
229             control.getAttributes().put("style", "margin-right: 7px;");
230          }
231          else
232          {
233             // any other type is represented as an input text field
234
control = (UIInput)context.getApplication().
235                   createComponent(ComponentConstants.JAVAX_FACES_INPUT);
236             control.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
237             control.getAttributes().put("size", "35");
238             control.getAttributes().put("maxlength", "1024");
239          }
240          
241          // if we are trying to edit a NodeRef or Path property type set it to read-only as
242
// these are internal properties that shouldn't be edited.
243
if (typeName.equals(DataTypeDefinition.NODE_REF) || typeName.equals(DataTypeDefinition.PATH))
244          {
245             logger.warn("Setting property " + propDef.getName().toString() + " to read-only as it can not be edited");
246             control.getAttributes().put("disabled", Boolean.TRUE);
247          }
248       
249          // set control to disabled state if set to read only or if the
250
// property definition says it is protected
251
if (isReadOnly() || propDef.isProtected())
252          {
253             control.getAttributes().put("disabled", Boolean.TRUE);
254          }
255          
256          // for now we can not handle multi valued properties in the client so if the property
257
// is defined as such make sure it is rendered as disabled
258
if (propDef.isMultiValued())
259          {
260             logger.warn("Setting property " + propDef.getName().toString() + " to read-only, it can not be edited as it is defined as multi-valued");
261             control.getAttributes().put("disabled", Boolean.TRUE);
262          }
263          
264          // add a validator if the field is required
265
// if (propDef.isMandatory())
266
// {
267
// control.setRequired(true);
268
// LengthValidator val = (LengthValidator)context.getApplication().
269
// createValidator("javax.faces.Length");
270
// val.setMinimum(1);
271
// control.addValidator(val);
272
// }
273
}
274       
275       // set up the common aspects of the control
276
control.setId(context.getViewRoot().createUniqueId());
277       control.setValueBinding("value", vb);
278       
279       // if a converter has been specified we need to instantiate it
280
// and apply it to the control
281
if (getConverter() != null)
282       {
283          // catch null pointer exception to workaround bug in myfaces
284
try
285          {
286             Converter conv = context.getApplication().createConverter(getConverter());
287             control.setConverter(conv);
288          }
289          catch (FacesException fe)
290          {
291             logger.warn("Converter " + getConverter() + " could not be applied");
292          }
293       }
294       
295       // add the control itself
296
this.getChildren().add(control);
297       
298       if (logger.isDebugEnabled())
299          logger.debug("Created control " + control + "(" +
300                       control.getClientId(context) +
301                       ") for '" + propDef.getName().toString() +
302                       "' and added it to component " + this);
303    }
304    
305    /**
306     * Generates an appropriate control for the given property name
307     *
308     * @param context JSF context
309     * @param propName The name of the property to create a control for
310     * @param varName Name of the variable the node is stored in the session as
311     * (used for value binding expression)
312     * @param parent The parent component for the control
313     */

314    private void generateControl(FacesContext context, String JavaDoc propName,
315                                 String JavaDoc varName)
316    {
317       ValueBinding vb = context.getApplication().
318                         createValueBinding("#{" + varName + ".properties[\"" +
319                         propName + "\"]}");
320       
321       UIOutput control = null;
322       UIPropertySheet propSheet = (UIPropertySheet)this.getParent();
323       if (propSheet.getMode().equalsIgnoreCase(UIPropertySheet.VIEW_MODE))
324       {
325          // if we are in view mode simply output the text to the screen
326
control = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
327          control.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
328       }
329       else
330       {
331          // as we don't know the type of the property we can only output a text field
332
control = (UIInput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_INPUT);
333          control.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
334          control.getAttributes().put("size", "35");
335          control.getAttributes().put("maxlength", "1024");
336       
337          // set control to disabled state if set to read only
338
if (isReadOnly())
339          {
340             control.getAttributes().put("disabled", Boolean.TRUE);
341          }
342       }
343       
344       // set the common attributes
345
control.setId(context.getViewRoot().createUniqueId());
346       control.setValueBinding("value", vb);
347       
348       // if a converter has been specified we need to instantiate it
349
// and apply it to the control
350
if (getConverter() != null)
351       {
352          try
353          {
354             Converter conv = context.getApplication().createConverter(getConverter());
355             control.setConverter(conv);
356          }
357          catch (FacesException fe)
358          {
359             logger.warn("Converter " + getConverter() + " could not be applied");
360          }
361       }
362       
363       // add the control itself
364
this.getChildren().add(control);
365       
366       if (logger.isDebugEnabled())
367          logger.debug("Created control " + control + "(" +
368                       control.getClientId(context) +
369                       ") for '" + propName +
370                       "' and added it to component " + this);
371    }
372 }
373
Popular Tags