View Javadoc
1   /**
2    * Copyright 2005-2016 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.element;
17  
18  import com.google.common.collect.Lists;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
21  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
22  import org.kuali.rice.krad.datadictionary.validator.Validator;
23  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
24  import org.kuali.rice.krad.uif.UifConstants.Position;
25  import org.kuali.rice.krad.uif.component.Component;
26  import org.kuali.rice.krad.uif.util.ComponentFactory;
27  import org.kuali.rice.krad.uif.view.View;
28  import org.kuali.rice.krad.util.KRADConstants;
29  
30  import java.util.List;
31  
32  /**
33   * Content element that renders a label
34   *
35   * <p>
36   * Contains options for adding a colon to the label along with a required message
37   * </p>
38   *
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  @BeanTag(name = "label-bean", parent = "Uif-Label")
42  public class Label extends ContentElementBase {
43      private static final long serialVersionUID = -6491546893195180114L;
44  
45      private String labelText;
46      private String labelForComponentId;
47  
48      private boolean renderColon;
49  
50      private Position requiredMessagePlacement;
51      private Message requiredMessage;
52  
53      private Message richLabelMessage;
54      private List<Component> inlineComponents;
55  
56      public Label() {
57          renderColon = true;
58  
59          requiredMessagePlacement = Position.LEFT;
60      }
61  
62      /**
63       * Sets up rich message content for the label, if any exists
64       *
65       * @see Component#performApplyModel(org.kuali.rice.krad.uif.view.View, Object, org.kuali.rice.krad.uif.component.Component)
66       */
67      @Override
68      public void performApplyModel(View view, Object model, Component parent) {
69          super.performApplyModel(view, model, parent);
70  
71          if (richLabelMessage == null && labelText != null &&
72                  labelText.contains(KRADConstants.MessageParsing.LEFT_TOKEN) &&
73                  labelText.contains(KRADConstants.MessageParsing.RIGHT_TOKEN)) {
74              Message message = ComponentFactory.getMessage();
75              view.assignComponentIds(message);
76  
77              message.setMessageText(labelText);
78              message.setInlineComponents(inlineComponents);
79              message.setGenerateSpan(false);
80  
81              view.getViewHelperService().performComponentInitialization(view, model, message);
82  
83              this.setRichLabelMessage(message);
84          }
85      }
86  
87      /**
88       * The following finalization is performed:
89       *
90       * <ul>
91       * <li>If label text is blank, set render to false for field</li>
92       *
93       * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
94       *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
95       */
96      @Override
97      public void performFinalize(View view, Object model, Component parent) {
98          super.performFinalize(view, model, parent);
99  
100         if (StringUtils.isBlank(getLabelText())) {
101             setRender(false);
102         }
103     }
104 
105     /**
106      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
107      */
108     @Override
109     public List<Component> getComponentsForLifecycle() {
110         List<Component> components = super.getComponentsForLifecycle();
111 
112         components.add(requiredMessage);
113         components.add(richLabelMessage);
114 
115         return components;
116     }
117 
118     /**
119      * Indicates the id for the component the label applies to
120      * <p>
121      * Used for setting the labelFor attribute of the corresponding HTML
122      * element. Note this gets set automatically by the framework during the
123      * initialize phase
124      * </p>
125      *
126      * @return component id
127      */
128     @BeanTagAttribute(name="labelForComponentId")
129     public String getLabelForComponentId() {
130         return this.labelForComponentId;
131     }
132 
133     /**
134      * Setter for the component id the label applies to
135      *
136      * @param labelForComponentId
137      */
138     public void setLabelForComponentId(String labelForComponentId) {
139         this.labelForComponentId = labelForComponentId;
140     }
141 
142     /**
143      * Text that will display as the label
144      *
145      * @return label text
146      */
147     @BeanTagAttribute(name="labelText")
148     public String getLabelText() {
149         return this.labelText;
150     }
151 
152     /**
153      * Setter for the label text
154      *
155      * @param labelText
156      */
157     public void setLabelText(String labelText) {
158         this.labelText = labelText;
159     }
160 
161     /**
162      * Indicates whether a colon should be rendered after the label text,
163      * generally used when the label appears to the left of the field's control
164      * or value
165      *
166      * @return true if a colon should be rendered, false if it should not be
167      */
168     @BeanTagAttribute(name="renderColon")
169     public boolean isRenderColon() {
170         return this.renderColon;
171     }
172 
173     /**
174      * Setter for the render colon indicator
175      *
176      * @param renderColon
177      */
178     public void setRenderColon(boolean renderColon) {
179         this.renderColon = renderColon;
180     }
181 
182     /**
183      * <code>Message</code> instance that will display a required indicator
184      *
185      * <p>
186      * To indicate a field must have a value (required input) the required
187      * message field can be set to display an indicator or message along with
188      * the label. The message field also dictates the styling of the required
189      * message
190      * </p>
191      *
192      * @return Message instance
193      */
194     @BeanTagAttribute(name="requiredMessage",type= BeanTagAttribute.AttributeType.SINGLEBEAN)
195     public Message getRequiredMessage() {
196         return this.requiredMessage;
197     }
198 
199     /**
200      * Setter for the required message field
201      *
202      * @param requiredMessage
203      */
204     public void setRequiredMessage(Message requiredMessage) {
205         this.requiredMessage = requiredMessage;
206     }
207 
208     /**
209      * Indicates where the required message field should be placed in relation
210      * to the label field, valid options are 'LEFT' and 'RIGHT'
211      *
212      * @return the requiredMessage placement
213      */
214     @BeanTagAttribute(name="requiredMessagePlacement",type= BeanTagAttribute.AttributeType.SINGLEBEAN)
215     public Position getRequiredMessagePlacement() {
216         return this.requiredMessagePlacement;
217     }
218 
219     /**
220      * Setter for the required message field placement
221      *
222      * @param requiredMessagePlacement
223      */
224     public void setRequiredMessagePlacement(Position requiredMessagePlacement) {
225         this.requiredMessagePlacement = requiredMessagePlacement;
226     }
227 
228     /**
229      * Gets the Message that represents the rich message content of the label if labelText is using rich message tags.
230      * <b>DO NOT set this
231      * property directly unless you need full control over the message structure.</b>
232      *
233      * @return rich message structure, null if no rich message structure
234      */
235     @BeanTagAttribute(name="richLabelMessage",type= BeanTagAttribute.AttributeType.SINGLEBEAN)
236     public Message getRichLabelMessage() {
237         return richLabelMessage;
238     }
239 
240     /**
241      * Sets the Message that represents the rich message content of the label if it is using rich message tags.  <b>DO
242      * NOT set this
243      * property directly unless you need full control over the message structure.</b>
244      *
245      * @param richLabelMessage
246      */
247     public void setRichLabelMessage(Message richLabelMessage) {
248         this.richLabelMessage = richLabelMessage;
249     }
250 
251     /**
252      * Gets the inlineComponents used by index in a Label that has rich message component index tags in its labelText
253      *
254      * @return the Label's inlineComponents
255      */
256     @BeanTagAttribute(name="inlineComponents",type= BeanTagAttribute.AttributeType.LISTBEAN)
257     public List<Component> getInlineComponents() {
258         return inlineComponents;
259     }
260 
261     /**
262      * Sets the inlineComponents used by index in a Label that has rich message component index tags in its labelText
263      *
264      * @param inlineComponents
265      */
266     public void setInlineComponents(List<Component> inlineComponents) {
267         this.inlineComponents = inlineComponents;
268     }
269 
270     /**
271      * @see org.kuali.rice.krad.uif.component.Component#completeValidation
272      */
273     @Override
274     public void completeValidation(ValidationTrace tracer){
275         tracer.addBean(this);
276 
277         if(tracer.getValidationStage()== ValidationTrace.BUILD){
278             // Checks that text is set if the component is rendered
279             if(isRender() && getLabelText()==null){
280                 if(!Validator.checkExpressions(this, "labelText")) {
281                     String currentValues [] = {"render = "+isRender(),"labelText ="+getLabelText()};
282                     tracer.createError("LabelText should be set if render is true",currentValues);
283                 }
284             }
285         }
286 
287         super.completeValidation(tracer.getCopy());
288     }
289 
290     /**
291      * @see org.kuali.rice.krad.uif.component.ComponentBase#copy()
292      */
293     @Override
294     protected <T> void copyProperties(T component) {
295         super.copyProperties(component);
296         Label labelCopy = (Label) component;
297 
298         if (this.inlineComponents != null) {
299             List<Component> inlineComponents = Lists.newArrayListWithExpectedSize(this.inlineComponents.size());
300 
301             for (Component inlineComponent : this.inlineComponents) {
302                 inlineComponents.add((Component) inlineComponent.copy());
303             }
304 
305             labelCopy.setInlineComponents(inlineComponents);
306         }
307 
308         labelCopy.setLabelForComponentId(this.labelForComponentId);
309         labelCopy.setLabelText(this.labelText);
310         labelCopy.setRenderColon(this.renderColon);
311 
312         if (this.requiredMessage != null) {
313             labelCopy.setRequiredMessage((Message)this.requiredMessage.copy());
314         }
315 
316         if (this.richLabelMessage != null) {
317             labelCopy.setRichLabelMessage((Message)this.richLabelMessage.copy());
318         }
319 
320         labelCopy.setRequiredMessagePlacement(this.requiredMessagePlacement);
321     }
322 }