View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.field;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.exception.RiceRuntimeException;
21  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
22  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
23  import org.kuali.rice.krad.datadictionary.parse.BeanTags;
24  import org.kuali.rice.krad.uif.UifConstants;
25  import org.kuali.rice.krad.uif.component.Component;
26  import org.kuali.rice.krad.uif.component.ComponentBase;
27  import org.kuali.rice.krad.uif.component.ComponentSecurity;
28  import org.kuali.rice.krad.uif.component.DelayedCopy;
29  import org.kuali.rice.krad.uif.element.Label;
30  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
31  import org.kuali.rice.krad.uif.util.ComponentFactory;
32  import org.kuali.rice.krad.uif.util.LifecycleElement;
33  import org.kuali.rice.krad.uif.util.MessageStructureUtils;
34  import org.kuali.rice.krad.uif.view.View;
35  import org.kuali.rice.krad.util.KRADUtils;
36  
37  import java.util.List;
38  
39  /**
40   * Base class for <code>Field</code> implementations
41   *
42   * <p>
43   * Sets the component type name so that all field templates have a fixed
44   * contract
45   * </p>
46   *
47   * <p>
48   * Holds a nested <code>Label</code> with configuration for rendering the
49   * label and configuration on label placement.
50   * </p>
51   *
52   * @author Kuali Rice Team (rice.collab@kuali.org)
53   */
54  @BeanTag(name = "fieldBase", parent = "Uif-FieldBase")
55  public class FieldBase extends ComponentBase implements Field {
56      private static final long serialVersionUID = -5888414844802862760L;
57      private static final Logger LOG = Logger.getLogger(FieldBase.class);
58  
59      private String shortLabel;
60      
61      @DelayedCopy
62      private Label fieldLabel;
63  
64      private boolean labelLeft;
65      private boolean labelRendered;
66  
67      public FieldBase() {
68          super();
69  
70          labelRendered = false;
71      }
72  
73      /**
74       * The following finalization is performed:
75       *
76       * <ul>
77       * <li>Make sure that a label is defined for any data fields. If not then create hidden label using property
78       * name.</li>
79       * <li>If no label for a non data field then just log a warning.</li>
80       * </ul>
81       *
82       * {@inheritDoc}
83       */
84      @Override
85      public void performApplyModel(Object model, LifecycleElement parent) {
86          super.performApplyModel(model, parent);
87  
88          if (!labelRendered && fieldLabel == null) {
89              if (this instanceof DataFieldBase) {
90                  LOG.warn("DataField ("
91                          + this.getClass().getName()
92                          + ") ID: "
93                          + this.getId()
94                          + ", propertyName: "
95                          + ((DataFieldBase) this).getPropertyName()
96                          + " has no label. A hidden default label will be created.");
97                  this.setLabel(((DataFieldBase) this).getPropertyName());
98                  this.setLabelRendered(false);
99                  this.setShowLabel(true);
100             } else {
101                 if (this instanceof SpaceField == false) {
102                     LOG.warn("Field (" + this.getClass().getName() + ") ID: " + this.getId() + " has no label.");
103                 }
104             }
105         }
106     }
107     
108     /**
109      * {@inheritDoc}
110      */
111     @Override
112     public void afterEvaluateExpression() {
113         super.afterEvaluateExpression();
114      
115         if (getReadOnly() == null) {
116             Component parent = ViewLifecycle.getPhase().getParent();
117             setReadOnly(parent == null ? null : parent.getReadOnly());
118         }
119     }
120 
121     /**
122      * The following finalization is performed:
123      *
124      * <ul>
125      * <li>Set the labelForComponentId to this component id</li>
126      * <li>Set the label text on the label field from the field's label property</li>
127      * <li>Set the render property on the label's required message field if this field is marked as required</li>
128      * </ul>
129      *
130      * {@inheritDoc}
131      */
132     @Override
133     public void performFinalize(Object model, LifecycleElement parent) {
134         super.performFinalize(model, parent);
135 
136         if (fieldLabel != null) {
137             fieldLabel.setLabelForComponentId(this.getId());
138 
139             if ((getRequired() != null) && getRequired().booleanValue()) {
140                 View view = ViewLifecycle.getView();
141                 if (view.getViewTypeName() != null && view.getViewTypeName().equals(
142                         UifConstants.ViewType.MAINTENANCE)) {
143                     fieldLabel.setRenderRequiredIndicator(!Boolean.TRUE.equals(view.getReadOnly()));
144                 } else {
145                     fieldLabel.setRenderRequiredIndicator(!Boolean.TRUE.equals(getReadOnly()));
146                 }
147             } else {
148                 setRequired(false);
149                 fieldLabel.setRenderRequiredIndicator(false);
150             }
151 
152             if (labelLeft) {
153                 fieldLabel.addStyleClass("uif-labelLeft");
154             }
155             else {
156                 fieldLabel.addStyleClass("uif-labelBlock");
157             }
158 
159             fieldLabel.addDataAttribute(UifConstants.DataAttributes.LABEL_FOR, this.getId());
160             if (StringUtils.isNotBlank(this.getFieldLabel().getLabelText())) {
161                 this.addDataAttribute(UifConstants.DataAttributes.LABEL, MessageStructureUtils.translateStringMessage(
162                         this.getFieldLabel().getLabelText()));
163             }
164         }
165     }
166 
167     /**
168      * Helper method for suffixing the ids of the fields nested components
169      *
170      * @param component component to adjust id for
171      * @param suffix suffix to append to id
172      */
173     protected void setNestedComponentIdAndSuffix(Component component, String suffix) {
174         if (component != null) {
175             String fieldId = getId();
176             fieldId += suffix;
177 
178             component.setId(fieldId);
179         }
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     @Override
186     public final String getComponentTypeName() {
187         return "field";
188     }
189 
190     /**
191      * @see org.kuali.rice.krad.uif.field.Field#getLabel
192      */
193     @BeanTagAttribute
194     public String getLabel() {
195         if (fieldLabel != null) {
196             return fieldLabel.getLabelText();
197         }
198 
199         return "";
200     }
201 
202     /**
203      * @see org.kuali.rice.krad.uif.field.Field#setLabel(java.lang.String)
204      */
205     public void setLabel(String labelText) {
206         if (StringUtils.isNotBlank(labelText) && this.fieldLabel == null) {
207             this.fieldLabel = ComponentFactory.getLabel();
208         }
209 
210         if (this.fieldLabel != null) {
211             this.fieldLabel.setLabelText(labelText);
212         }
213     }
214 
215     /**
216      * @see org.kuali.rice.krad.uif.field.Field#getLabelStyleClasses
217      */
218     @BeanTagAttribute
219     public List<String> getLabelStyleClasses() {
220         if (fieldLabel != null) {
221             return fieldLabel.getCssClasses();
222         }
223 
224         return null;
225     }
226 
227     /**
228      * @see org.kuali.rice.krad.uif.field.Field#setLabelStyleClasses
229      */
230     public void setLabelStyleClasses(List<String> labelStyleClasses) {
231         if (labelStyleClasses != null && this.fieldLabel == null) {
232             this.fieldLabel = ComponentFactory.getLabel();
233         }
234 
235         if (this.fieldLabel != null) {
236             this.fieldLabel.setCssClasses(labelStyleClasses);
237         }
238     }
239 
240     /**
241      * @see org.kuali.rice.krad.uif.field.Field#getLabelColSpan
242      */
243     @BeanTagAttribute
244     public int getLabelColSpan() {
245         if (fieldLabel != null) {
246             return fieldLabel.getColSpan();
247         }
248 
249         return 1;
250     }
251 
252     /**
253      * @see org.kuali.rice.krad.uif.field.Field#setLabelColSpan
254      */
255     public void setLabelColSpan(int labelColSpan) {
256         if (this.fieldLabel == null) {
257             this.fieldLabel = ComponentFactory.getLabel();
258         }
259 
260         if (this.fieldLabel != null) {
261             this.fieldLabel.setColSpan(labelColSpan);
262         }
263     }
264 
265     /**
266      * @see org.kuali.rice.krad.uif.field.Field#getShortLabel()
267      */
268     @BeanTagAttribute
269     public String getShortLabel() {
270         return this.shortLabel;
271     }
272 
273     /**
274      * @see org.kuali.rice.krad.uif.field.Field#setShortLabel(java.lang.String)
275      */
276     public void setShortLabel(String shortLabel) {
277         this.shortLabel = shortLabel;
278     }
279 
280     /**
281      * Sets whether the label should be displayed
282      *
283      * <p>
284      * Convenience method for configuration that sets the hidden indicator on
285      * the fields <code>Label</code> instance. The label is not really hidden
286      * but set off screen for accessibility.
287      * </p>
288      *
289      * @param showLabel true if label should be hidden, false if the label
290      * should not be hidden
291      */
292     public void setShowLabel(boolean showLabel) {
293         if (fieldLabel != null) {
294             fieldLabel.setHidden(showLabel);
295         }
296     }
297 
298     /**
299      * @see org.kuali.rice.krad.uif.field.Field#getLabel
300      */
301     @BeanTagAttribute
302     public Label getFieldLabel() {
303         return this.fieldLabel;
304     }
305 
306     /**
307      * @see org.kuali.rice.krad.uif.field.Field#setFieldLabel
308      */
309     public void setFieldLabel(Label fieldLabel) {
310         this.fieldLabel = fieldLabel;
311     }
312 
313     /**
314      * {@inheritDoc}
315      */
316     @Override
317     @BeanTagAttribute
318     public boolean isLabelLeft() {
319         return labelLeft;
320     }
321 
322     /**
323      * {@inheritDoc}
324      */
325     @Override
326     public void setLabelLeft(boolean labelLeft) {
327         this.labelLeft = labelLeft;
328     }
329 
330     /**
331      * @see org.kuali.rice.krad.uif.field.Field#isLabelRendered()
332      */
333     @BeanTagAttribute
334     public boolean isLabelRendered() {
335         return this.labelRendered;
336     }
337 
338     /**
339      * @see org.kuali.rice.krad.uif.field.Field#setLabelRendered(boolean)
340      */
341     public void setLabelRendered(boolean labelRendered) {
342         this.labelRendered = labelRendered;
343     }
344 
345     /**
346      * @see org.kuali.rice.krad.uif.field.Field#getFieldSecurity()
347      */
348     public FieldSecurity getFieldSecurity() {
349         return (FieldSecurity) super.getComponentSecurity();
350     }
351 
352     /**
353      * Override to assert a {@link FieldSecurity} instance is set
354      *
355      * @param componentSecurity instance of FieldSecurity
356      */
357     @Override
358     public void setComponentSecurity(ComponentSecurity componentSecurity) {
359         if ((componentSecurity != null) && !(componentSecurity instanceof FieldSecurity)) {
360             throw new RiceRuntimeException("Component security for Field should be instance of FieldSecurity");
361         }
362 
363         super.setComponentSecurity(componentSecurity);
364     }
365 
366     /**
367      * {@inheritDoc}
368      */
369     @Override
370     protected void initializeComponentSecurity() {
371         if (getComponentSecurity() == null) {
372             setComponentSecurity(KRADUtils.createNewObjectFromClass(FieldSecurity.class));
373         }
374     }
375 
376     /**
377      * @see org.kuali.rice.krad.uif.field.FieldSecurity#isEditInLineAuthz()
378      */
379     @BeanTagAttribute
380     public Boolean isEditInLineAuthz() {
381         initializeComponentSecurity();
382 
383         return getFieldSecurity().isEditInLineAuthz();
384     }
385 
386     /**
387      * @see org.kuali.rice.krad.uif.field.FieldSecurity#setEditInLineAuthz(Boolean)
388      */
389     public void setEditInLineAuthz(Boolean editInLineAuthz) {
390         initializeComponentSecurity();
391 
392         getFieldSecurity().setEditInLineAuthz(editInLineAuthz);
393     }
394 
395     /**
396      * @see org.kuali.rice.krad.uif.field.FieldSecurity#isViewInLineAuthz()
397      */
398     @BeanTagAttribute
399     public Boolean isViewInLineAuthz() {
400         initializeComponentSecurity();
401 
402         return getFieldSecurity().isViewInLineAuthz();
403     }
404 
405     /**
406      * @see org.kuali.rice.krad.uif.field.FieldSecurity#setViewInLineAuthz(Boolean)
407      */
408     public void setViewInLineAuthz(Boolean viewInLineAuthz) {
409         initializeComponentSecurity();
410 
411         getFieldSecurity().setViewInLineAuthz(viewInLineAuthz);
412     }
413 
414 }