View Javadoc

1   /**
2    * Copyright 2005-2012 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 org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21  import org.kuali.rice.krad.datadictionary.parse.BeanTags;
22  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23  import org.kuali.rice.krad.datadictionary.validator.Validator;
24  import org.kuali.rice.krad.uif.component.Component;
25  import org.kuali.rice.krad.uif.container.Group;
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.ArrayList;
31  import java.util.List;
32  
33  /**
34   * Content element that renders a header element and optionally a <code>Group</code> to
35   * present along with the header text
36   *
37   * <p>
38   * Generally the group is used to display content to the right of the header,
39   * such as links for the group or other information
40   * </p>
41   *
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  @BeanTags({@BeanTag(name = "header", parent = "Uif-HeaderBase"), @BeanTag(name = "headerOne", parent = "Uif-HeaderOne"),
45          @BeanTag(name = "headerTwo", parent = "Uif-HeaderTwo"),
46          @BeanTag(name = "headerThree", parent = "Uif-HeaderThree"),
47          @BeanTag(name = "headerFour", parent = "Uif-HeaderFour"),
48          @BeanTag(name = "headerFive", parent = "Uif-HeaderFive"),
49          @BeanTag(name = "headerSix", parent = "Uif-HeaderSix"),
50          @BeanTag(name = "viewHeader", parent = "Uif-ViewHeader"),
51          @BeanTag(name = "pageHeader", parent = "Uif-PageHeader"),
52          @BeanTag(name = "sectionHeader", parent = "Uif-SectionHeader"),
53          @BeanTag(name = "subSectionHeader", parent = "Uif-SubSectionHeader"),
54          @BeanTag(name = "subCollectionHeader", parent = "Uif-SubCollectionHeader"),
55          @BeanTag(name = "editablePageHeader", parent = "Uif-EditablePageHeader"),
56          @BeanTag(name = "readOnlyPageHeader", parent = "Uif-ReadOnlyPageHeader"),
57          @BeanTag(name = "imageCaptionHeader", parent = "Uif-ImageCaptionHeader"),
58          @BeanTag(name = "documentViewHeader", parent = "Uif-DocumentViewHeader"),
59          @BeanTag(name = "lookupPageHeader", parent = "Uif-LookupPageHeader")})
60  public class Header extends ContentElementBase {
61      private static final long serialVersionUID = -6950408292923393244L;
62  
63      private String headerText;
64      private String headerLevel;
65  
66      private String headerTagStyle;
67      private List<String> headerTagCssClasses;
68  
69      private Message richHeaderMessage;
70      private List<Component> inlineComponents;
71  
72      private Group upperGroup;
73      private Group rightGroup;
74      private Group lowerGroup;
75  
76      public Header() {
77          super();
78  
79          headerTagCssClasses = new ArrayList<String>();
80      }
81  
82      /**
83       * Sets up rich message content for the label, if any exists
84       *
85       * @see Component#performApplyModel(org.kuali.rice.krad.uif.view.View, Object,
86       *      org.kuali.rice.krad.uif.component.Component)
87       */
88      @Override
89      public void performApplyModel(View view, Object model, Component parent) {
90          super.performApplyModel(view, model, parent);
91  
92          if (richHeaderMessage == null && headerText != null && headerText.contains(
93                  KRADConstants.MessageParsing.LEFT_TOKEN) && headerText.contains(
94                  KRADConstants.MessageParsing.RIGHT_TOKEN)) {
95              Message message = ComponentFactory.getMessage();
96              view.assignComponentIds(message);
97              message.setMessageText(headerText);
98              message.setInlineComponents(inlineComponents);
99              message.setGenerateSpan(false);
100             view.getViewHelperService().performComponentInitialization(view, model, message);
101             this.setRichHeaderMessage(message);
102         }
103     }
104 
105     /**
106      * The following finalization is performed:
107      *
108      * <ul>
109      * <li>Set render on header group to false if no items are configured</li>
110      * </ul>
111      *
112      * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
113      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
114      */
115     @Override
116     public void performFinalize(View view, Object model, Component parent) {
117         super.performFinalize(view, model, parent);
118 
119         // don't render header groups if no items were configured
120         if ((getUpperGroup() != null) && (getUpperGroup().getItems().isEmpty())) {
121             getUpperGroup().setRender(false);
122         }
123 
124         if ((getRightGroup() != null) && (getRightGroup().getItems().isEmpty())) {
125             getRightGroup().setRender(false);
126         }
127 
128         if ((getLowerGroup() != null) && (getLowerGroup().getItems().isEmpty())) {
129             getLowerGroup().setRender(false);
130         }
131 
132         //add preset styles to header groups
133         if (getUpperGroup() != null) {
134             getUpperGroup().addStyleClass("uif-header-upperGroup");
135         }
136 
137         if (getRightGroup() != null) {
138             getRightGroup().addStyleClass("uif-header-rightGroup");
139         }
140 
141         if (getLowerGroup() != null) {
142             getLowerGroup().addStyleClass("uif-header-lowerGroup");
143         }
144     }
145 
146     /**
147      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
148      */
149     @Override
150     public List<Component> getComponentsForLifecycle() {
151         List<Component> components = super.getComponentsForLifecycle();
152 
153         components.add(richHeaderMessage);
154         components.add(upperGroup);
155         components.add(rightGroup);
156         components.add(lowerGroup);
157 
158         return components;
159     }
160 
161     /**
162      * Text that should be displayed on the header
163      *
164      * @return String header text
165      */
166     @BeanTagAttribute(name = "headerText")
167     public String getHeaderText() {
168         return this.headerText;
169     }
170 
171     /**
172      * Setter for the header text
173      *
174      * @param headerText
175      */
176     public void setHeaderText(String headerText) {
177         this.headerText = headerText;
178     }
179 
180     /**
181      * HTML header level (h1 ... h6) that should be applied to the header text
182      *
183      * @return String header level
184      */
185     @BeanTagAttribute(name = "headerLevel")
186     public String getHeaderLevel() {
187         return this.headerLevel;
188     }
189 
190     /**
191      * Setter for the header level
192      *
193      * @param headerLevel
194      */
195     public void setHeaderLevel(String headerLevel) {
196         this.headerLevel = headerLevel;
197     }
198 
199     /**
200      * Style classes that should be applied to the header text (h tag)
201      *
202      * <p>
203      * Note the style class given here applies to only the header text. The
204      * style class property inherited from the <code>Component</code> interface
205      * can be used to set the class for the whole field div (which could
206      * include a nested <code>Group</code>)
207      * </p>
208      *
209      * @return List<String> list of style classes
210      * @see org.kuali.rice.krad.uif.component.Component#getCssClasses()
211      */
212     @BeanTagAttribute(name = "headerTagCssClasses", type = BeanTagAttribute.AttributeType.LISTVALUE)
213     public List<String> getHeaderTagCssClasses() {
214         return this.headerTagCssClasses;
215     }
216 
217     /**
218      * Setter for the list of classes to apply to the header h tag
219      *
220      * @param headerTagCssClasses
221      */
222     public void setHeaderTagCssClasses(List<String> headerTagCssClasses) {
223         this.headerTagCssClasses = headerTagCssClasses;
224     }
225 
226     /**
227      * Builds the HTML class attribute string by combining the headerStyleClasses list
228      * with a space delimiter
229      *
230      * @return String class attribute string
231      */
232     public String getHeaderStyleClassesAsString() {
233         if (headerTagCssClasses != null) {
234             return StringUtils.join(headerTagCssClasses, " ");
235         }
236 
237         return "";
238     }
239 
240     /**
241      * Style that should be applied to the header h tag
242      *
243      * <p>
244      * Note the style given here applies to only the header text. The style
245      * property inherited from the <code>Component</code> interface can be used
246      * to set the style for the whole header div (which could include a nested
247      * <code>Group</code>)
248      * </p>
249      *
250      * @return String header style
251      * @see org.kuali.rice.krad.uif.component.Component#getStyle()
252      */
253     @BeanTagAttribute(name = "headerTagStyle")
254     public String getHeaderTagStyle() {
255         return this.headerTagStyle;
256     }
257 
258     /**
259      * Setter for the header h tag style
260      *
261      * @param headerTagStyle
262      */
263     public void setHeaderTagStyle(String headerTagStyle) {
264         this.headerTagStyle = headerTagStyle;
265     }
266 
267     /**
268      * Nested group instance that can be used to render contents above the header text
269      *
270      * <p>
271      * The header group is useful for adding content such as links or actions that is presented with the header
272      * </p>
273      *
274      * @return Group instance
275      */
276     @BeanTagAttribute(name = "upperGroup", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
277     public Group getUpperGroup() {
278         return upperGroup;
279     }
280 
281     /**
282      * Setter for the header group instance that is rendered above the header text
283      *
284      * @param upperGroup
285      */
286     public void setUpperGroup(Group upperGroup) {
287         this.upperGroup = upperGroup;
288     }
289 
290     /**
291      * Nested group instance that can be used to render contents to the right of the header text
292      *
293      * <p>
294      * The header group is useful for adding content such as links or actions that is presented with the header
295      * </p>
296      *
297      * @return Group instance
298      */
299     @BeanTagAttribute(name = "rightGroup", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
300     public Group getRightGroup() {
301         return rightGroup;
302     }
303 
304     /**
305      * Setter for the header group instance that is rendered to the right of the header text
306      *
307      * @param rightGroup
308      */
309     public void setRightGroup(Group rightGroup) {
310         this.rightGroup = rightGroup;
311     }
312 
313     /**
314      * Nested group instance that can be used to render contents below the header text
315      *
316      * <p>
317      * The header group is useful for adding content such as links or actions that is presented with the header
318      * </p>
319      *
320      * @return Group instance
321      */
322     @BeanTagAttribute(name = "lowerGroup", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
323     public Group getLowerGroup() {
324         return lowerGroup;
325     }
326 
327     /**
328      * Setter for the header group instance that is rendered below the header text
329      *
330      * @param lowerGroup
331      */
332     public void setLowerGroup(Group lowerGroup) {
333         this.lowerGroup = lowerGroup;
334     }
335 
336     /**
337      * List of <code>Component</code> instances contained in the lower header group
338      *
339      * <p>
340      * Convenience method for configuration to get the items List from the
341      * lower header group
342      * </p>
343      *
344      * @return List<? extends Component> items
345      */
346     @BeanTagAttribute(name = "items", type = BeanTagAttribute.AttributeType.LISTBEAN)
347     public List<? extends Component> getItems() {
348         if (lowerGroup != null) {
349             return lowerGroup.getItems();
350         }
351 
352         return null;
353     }
354 
355     /**
356      * Setter for the lower group's items
357      *
358      * <p>
359      * Convenience method for configuration to set the items List for the
360      * lower header group
361      * </p>
362      *
363      * @param items
364      */
365     public void setItems(List<? extends Component> items) {
366         if (lowerGroup != null) {
367             lowerGroup.setItems(items);
368         }
369     }
370 
371     /**
372      * @see org.kuali.rice.krad.uif.component.Component#completeValidation
373      */
374     @Override
375     public void completeValidation(ValidationTrace tracer) {
376         tracer.addBean(this);
377 
378         // Checks that a correct header level is set
379         String headerLevel = getHeaderLevel().toUpperCase();
380         boolean correctHeaderLevel = false;
381         if (headerLevel.compareTo("H1") == 0) {
382             correctHeaderLevel = true;
383         } else if (headerLevel.compareTo("H2") == 0) {
384             correctHeaderLevel = true;
385         } else if (headerLevel.compareTo("H3") == 0) {
386             correctHeaderLevel = true;
387         } else if (headerLevel.compareTo("H4") == 0) {
388             correctHeaderLevel = true;
389         } else if (headerLevel.compareTo("H5") == 0) {
390             correctHeaderLevel = true;
391         } else if (headerLevel.compareTo("H6") == 0) {
392             correctHeaderLevel = true;
393         } else if (headerLevel.compareTo("LABEL") == 0) {
394             correctHeaderLevel = true;
395         }
396         if (!correctHeaderLevel) {
397             String currentValues[] = {"headerLevel =" + getHeaderLevel()};
398             tracer.createError("HeaderLevel must be of values h1, h2, h3, h4, h5, h6, or label", currentValues);
399         }
400 
401         // Checks that header text is set
402         if (getHeaderText() == null) {
403             if (!Validator.checkExpressions(this, "headerText")) {
404                 String currentValues[] = {"headertText =" + getHeaderText()};
405                 tracer.createWarning("HeaderText should be set", currentValues);
406             }
407         }
408 
409         super.completeValidation(tracer.getCopy());
410     }
411 
412     /**
413      * Gets the Message that represents the rich message content of the header if headerText is using rich message
414      * tags.
415      * <b>DO NOT set this
416      * property directly unless you need full control over the message structure.</b>
417      *
418      * @return Message with rich message structure, null if no rich message structure
419      */
420     @BeanTagAttribute(name = "richHeaderMessage", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
421     public Message getRichHeaderMessage() {
422         return richHeaderMessage;
423     }
424 
425     /**
426      * Sets the Message that represents the rich message content of the header if headerText is using rich message
427      * tags.
428      * <b>DO
429      * NOT set this
430      * property directly unless you need full control over the message structure.</b>
431      *
432      * @param richHeaderMessage
433      */
434     public void setRichHeaderMessage(Message richHeaderMessage) {
435         this.richHeaderMessage = richHeaderMessage;
436     }
437 
438     /**
439      * Gets the inlineComponents used by index in a Header that has rich message component index tags in its headerText
440      *
441      * @return the Label's inlineComponents
442      */
443     @BeanTagAttribute(name = "inlineComponents", type = BeanTagAttribute.AttributeType.LISTBEAN)
444     public List<Component> getInlineComponents() {
445         return inlineComponents;
446     }
447 
448     /**
449      * Sets the inlineComponents used by index in a Header that has rich message component index tags in its headerText
450      *
451      * @param inlineComponents
452      */
453     public void setInlineComponents(List<Component> inlineComponents) {
454         this.inlineComponents = inlineComponents;
455     }
456 }