001: /*
002: * Copyright 2006-2007 Dan Shellman
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.iscreen.ognl;
017:
018: import java.util.Locale;
019:
020: import ognl.Ognl;
021: import ognl.OgnlException;
022:
023: import org.iscreen.FailureMessage;
024: import org.iscreen.ConfigurationException;
025:
026: /**
027: * An OGNL message wraps a "template" that is a String of characters. This
028: * template may contain "OGNL tags" that look like this: ${some ognl}.
029: * When a ${} is found within the template, it's removed, and the contents
030: * are considered an OGNL expression, which is evaluated based upon an
031: * OGNL root (either set separately or passed in when generating the message).
032: *
033: * @author Shellman, Dan
034: */
035: public class OgnlMessage implements FailureMessage {
036: protected String template;
037: protected Object root;
038:
039: /**
040: * Constructor taking the template of this message. The template should
041: * never be null.
042: *
043: * @param theTemplate The template (which may or may not contain OGNL tags)
044: */
045: public OgnlMessage(String theTemplate) {
046: if (theTemplate == null) {
047: template = "";
048: } else {
049: template = theTemplate;
050: }
051: } //end OgnlMessage()
052:
053: /**
054: * For sub-classes to over-ride how this works.
055: */
056: protected OgnlMessage() {
057: } //end OgnlMessage()
058:
059: /**
060: * Sets the OGNL root to be used when getMessage() is called.
061: *
062: * @param ognlRoot The OGNL root object.
063: */
064: public void setOgnlRoot(Object ognlRoot) {
065: root = ognlRoot;
066: } //end setOgnlRoot()
067:
068: /**
069: * Generates a message based upon the template of this message and the
070: * OGNL root passed in to the setOgnlRoot() method. If the OGNL root object
071: * is null, then this method will return the template unchanged.
072: *
073: * @return Returns the message, which is constructed based upon the OGNL
074: * root and the template.
075: */
076: public String getMessage() {
077: if (root == null) {
078: return getTemplate(Locale.getDefault());
079: }
080:
081: return constructMessage(getTemplate(Locale.getDefault()), root);
082: } //end getMessage()
083:
084: /**
085: * Generates a message based upon the template of this message and the
086: * OGNL root passed in. If the OGNL root is null, then the OGNL root
087: * passed in to the setOgnlRoot() method is used. If that's null,
088: * then the template is returned unchanged.
089: *
090: * @param ognlRoot The OGNL root to use for generating the message.
091: *
092: * @return Returns the message, which is constructed based upon the OGNL
093: * root passed in and the template.
094: */
095: public String getMessage(Object ognlRoot, Locale locale) {
096: if (ognlRoot == null) {
097: ognlRoot = root;
098: }
099:
100: if (ognlRoot == null) {
101: return getTemplate(locale);
102: }
103:
104: return constructMessage(getTemplate(locale), ognlRoot);
105: } //end getMessage()
106:
107: /**
108: * Returns the OGNL root previously set using the setOgnlRoot() method.
109: *
110: * @return Returns the OGNL root for this message.
111: */
112: public Object getOgnlRoot() {
113: return root;
114: } //end getOgnlRoot()
115:
116: /**
117: * Returns the template previously set during construction.
118: *
119: * @param locale The locale to use.
120: *
121: * @return Returns the template.
122: */
123: public String getTemplate(Locale locale) {
124: return template;
125: } //end getTemplate()
126:
127: // ***
128: // Protected methods
129: // ***
130:
131: /**
132: * Searches through the template and replaces all ${} with the evaluation
133: * of their OGNL expressions.
134: *
135: * @param theTemplate The template to use.
136: * @param ognlRoot The OGNL root.
137: *
138: * @return Returns the constructed String.
139: */
140: protected String constructMessage(String theTemplate,
141: Object ognlRoot) {
142: StringBuffer buf = new StringBuffer();
143: int currentIndex = 0;
144: int lastIndex = 0;
145:
146: if (theTemplate == null) {
147: return "";
148: }
149:
150: currentIndex = theTemplate.indexOf("${");
151: while (currentIndex != -1) {
152: String ognlExp;
153:
154: if (currentIndex > lastIndex) {
155: buf.append(theTemplate.substring(lastIndex,
156: currentIndex));
157: }
158:
159: lastIndex = theTemplate.indexOf('}', currentIndex);
160: if (lastIndex == -1) {
161: buf.append(theTemplate.substring(currentIndex));
162:
163: break;
164: }
165:
166: ognlExp = theTemplate
167: .substring(currentIndex + 2, lastIndex);
168:
169: try {
170: //Process the OGNL expression.
171: buf.append(Ognl.getValue(ognlExp, ognlRoot));
172: } catch (OgnlException e) {
173: throw new ConfigurationException(
174: "Error executing OGNL expression [" + ognlExp
175: + "] within template [" + theTemplate
176: + "].", e);
177: }
178:
179: lastIndex++;
180: currentIndex = theTemplate.indexOf("${", lastIndex);
181: }
182:
183: //Grab the last part of the template, if there is any.
184: if (lastIndex < theTemplate.length() && lastIndex != -1) {
185: buf.append(theTemplate.substring(lastIndex));
186: }
187:
188: return buf.toString();
189: } //end constructMessage()
190: } //end OgnlMessage
|