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