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.validator.ValidationTrace;
22  import org.kuali.rice.krad.datadictionary.validator.Validator;
23  import org.kuali.rice.krad.uif.component.Component;
24  import org.kuali.rice.krad.uif.util.MessageStructureUtils;
25  import org.kuali.rice.krad.uif.view.View;
26  import org.kuali.rice.krad.util.KRADConstants;
27  
28  import java.util.List;
29  
30  /**
31   * Encapsulates a text message to be displayed
32   *
33   * <p>
34   * The <code>Message</code> is used to display static text in the user
35   * interface
36   * </p>
37   *
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   */
40  @BeanTag(name = "message")
41  public class Message extends ContentElementBase {
42      private static final long serialVersionUID = 4090058533452450395L;
43  
44      private String messageText;
45      private boolean generateSpan;
46  
47      private List<Component> inlineComponents;
48      private List<Component> messageComponentStructure;
49  
50      public Message() {
51          super();
52  
53          generateSpan = true;
54      }
55  
56      /**
57       * Message perfom apply model parses message text for rich text functionality if the messageText contains
58       * [ or ] special characters
59       *
60       * @see Component#performApplyModel(org.kuali.rice.krad.uif.view.View, Object, org.kuali.rice.krad.uif.component.Component)
61       */
62      @Override
63      public void performApplyModel(View view, Object model, Component parent) {
64          super.performApplyModel(view, model, parent);
65  
66          //if messageText contains the special characters [] then parse and fill in the messageComponentStructure
67          //but if messageComponentStructure has already been set it overrides messageText by default
68          if (messageText != null && messageText.contains(KRADConstants.MessageParsing.LEFT_TOKEN) &&
69                  messageText.contains(KRADConstants.MessageParsing.RIGHT_TOKEN) &&
70                  (messageComponentStructure == null || messageComponentStructure.isEmpty())) {
71  
72              messageComponentStructure = MessageStructureUtils.parseMessage(this.getId(), this.getMessageText(),
73                      this.getInlineComponents(), view, true);
74  
75              if (messageComponentStructure != null) {
76                  for (Component component : messageComponentStructure) {
77                      view.getViewHelperService().performComponentInitialization(view, model, component);
78                  }
79              }
80          }
81  
82      }
83  
84      /**
85       * @see Component#performFinalize(org.kuali.rice.krad.uif.view.View, Object, org.kuali.rice.krad.uif.component.Component)
86       */
87      @Override
88      public void performFinalize(View view, Object model, Component parent) {
89          super.performFinalize(view, model, parent);
90          //Message needs to be aware of its own parent because it now contains content that can have validation
91          this.addDataAttribute("parent", parent.getId());
92      }
93  
94      /**
95       * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
96       */
97      @Override
98      public List<Component> getComponentsForLifecycle() {
99          List<Component> components = super.getComponentsForLifecycle();
100 
101         if (messageComponentStructure != null) {
102             for (Component component : messageComponentStructure) {
103                 components.add(component);
104             }
105         }
106 
107         return components;
108     }
109 
110     /**
111      * Override to render only if the message text has been given or there is a conditional expression on the
112      * message text
113      *
114      * @see org.kuali.rice.krad.uif.component.ComponentBase#isRender()
115      */
116     @Override
117     public boolean isRender() {
118         boolean render = super.isRender();
119 
120         if (render) {
121             render = getPropertyExpressions().containsKey("messageText") || (StringUtils.isNotBlank(messageText)
122                     && !StringUtils.equals(messageText, "&nbsp;"));
123         }
124 
125         return render;
126     }
127 
128     /**
129      * Text that makes up the message that will be displayed.
130      *
131      * <p>If special characters [] are detected the message inserts special content at that location.
132      * The types of features supported are (note that &lt;&gt; are not part of the content below,
133      * they specify placeholders):
134      * <ul>
135      * <li>[id=&lt;component id&gt;] - insert component with id specified at that location in the message</li>
136      * <li>[n] - insert component at index n from the inlineComponent list</li>
137      * <li>[&lt;html tag&gt;][/&lt;html tag&gt;] - insert html content directly into the message content at that
138      * location,
139      * without the need to escape the &lt;&gt; characters in xml</li>
140      * <li>[color=&lt;html color code/name&gt;][/color] - wrap content in color tags to make text that color
141      * in the message</li>
142      * <li>[css=&lt;css classes&gt;][/css] - apply css classes specified to the wrapped content - same as wrapping
143      * the content in span with class property set</li>
144      * </ul>
145      * If the [] characters are needed in message text, they need to be declared with an escape character: \\[ \\]
146      * </p>
147      *
148      * @return String message text
149      */
150     @BeanTagAttribute(name = "messageText")
151     public String getMessageText() {
152         return this.messageText;
153     }
154 
155     /**
156      * Setter for the message text
157      *
158      * @param messageText
159      */
160     public void setMessageText(String messageText) {
161         this.messageText = messageText;
162     }
163 
164     /**
165      * If true, generate the span around this message (default).  When false, skip span generation for this
166      * message - this has the additional effect the css classes/style classes will be lost for this message.
167      *
168      * @return true if generating a wrapping span, false otherwise
169      */
170     @BeanTagAttribute(name = "generateSpan")
171     public boolean isGenerateSpan() {
172         return generateSpan;
173     }
174 
175     /**
176      * Sets the generate span flag
177      *
178      * @param generateSpan
179      */
180     public void setGenerateSpan(boolean generateSpan) {
181         this.generateSpan = generateSpan;
182     }
183 
184     /**
185      * The message component structure is a list of components which represent the components that make up a message
186      * when using rich message functionality.
187      *
188      * <p>The structure represents the parsed messageText when not set. Normally this structure is setup by the Message
189      * class and <b>SHOULD NOT BE SET</b> in xml, unless full control over the structure is needed.  </p>
190      *
191      * @return list of components which represent the message structure
192      */
193     public List<Component> getMessageComponentStructure() {
194         return messageComponentStructure;
195     }
196 
197     /**
198      * Set the message component structure.  This will override/ignore messageText when set. Normally
199      * this <b>SHOULD NOT BE SET</b> by the xml configuration.
200      *
201      * @param messageComponentStructure list of components which represent the message structure
202      */
203     public void setMessageComponentStructure(List<Component> messageComponentStructure) {
204         this.messageComponentStructure = messageComponentStructure;
205     }
206 
207     /**
208      * The inlineComponents are a list of components in order by index.
209      *
210      * <p>inlineComponents is only used when the message is using rich message functionality.  A message
211      * with [0] will reference component at index 0 of this list and insert it at that place in the message,
212      * and likewise [1] will reference item 1, etc.  If the index referenced is out of bounds (or list doesnt exist),
213      * an error will be thrown during message parse.</p>
214      *
215      * @return the inlineComponents to be filled in at indexes referenced by [n] in the message
216      */
217     @BeanTagAttribute(name = "inlineComponents", type = BeanTagAttribute.AttributeType.LISTBEAN)
218     public List<Component> getInlineComponents() {
219         return inlineComponents;
220     }
221 
222     /**
223      * Set the inlineComponents to be filled in at indexes referenced by [n] in the message
224      *
225      * @param inlineComponents the inlineComponents to be filled in at indexes referenced by [n] in the message
226      */
227     public void setInlineComponents(List<Component> inlineComponents) {
228         this.inlineComponents = inlineComponents;
229     }
230 
231     /**
232      * @see org.kuali.rice.krad.uif.component.Component#completeValidation
233      */
234     @Override
235     public void completeValidation(ValidationTrace tracer) {
236         tracer.addBean(this);
237 
238         // Checks that text is set
239         if (getMessageText() == null) {
240             if (Validator.checkExpressions(this, "messageText")) {
241                 String currentValues[] = {"messageText  =" + getMessageText()};
242                 tracer.createWarning("MessageText should be set", currentValues);
243             }
244         }
245 
246         super.completeValidation(tracer.getCopy());
247     }
248 }