001 /**
002 * ========================================
003 * JFreeReport : a free Java report library
004 * ========================================
005 *
006 * Project Info: http://reporting.pentaho.org/
007 *
008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 * ------------
026 * $Id: AbstractExpressionReadHandler.java,v 1.9 2007/04/01 18:49:27 taqua Exp $
027 * ------------
028 * (C) Copyright 2000-2005, by Object Refinery Limited.
029 * (C) Copyright 2005-2007, by Pentaho Corporation.
030 */
031 package org.jfree.report.modules.factories.report.flow;
032
033 import java.beans.IntrospectionException;
034
035 import org.jfree.report.expressions.Expression;
036 import org.jfree.report.expressions.FormulaExpression;
037 import org.jfree.report.expressions.FormulaFunction;
038 import org.jfree.report.util.CharacterEntityParser;
039 import org.jfree.report.util.beans.BeanUtility;
040 import org.jfree.util.ObjectUtilities;
041 import org.jfree.xmlns.parser.AbstractXmlReadHandler;
042 import org.jfree.xmlns.parser.ParseException;
043 import org.jfree.xmlns.parser.XmlReadHandler;
044 import org.xml.sax.Attributes;
045 import org.xml.sax.SAXException;
046
047 /**
048 * Creation-Date: 09.04.2006, 13:23:32
049 *
050 * @author Thomas Morgner
051 */
052 public abstract class AbstractExpressionReadHandler
053 extends AbstractXmlReadHandler
054 {
055 private Expression expression;
056 private BeanUtility expressionBeanUtility;
057 private CharacterEntityParser characterEntityParser;
058
059 public AbstractExpressionReadHandler()
060 {
061 this.characterEntityParser = CharacterEntityParser.createXMLEntityParser();
062 }
063
064 protected String getDefaultClassName()
065 {
066 return null;
067 }
068
069 /**
070 * Starts parsing.
071 *
072 * @param attrs the attributes.
073 * @throws SAXException if there is a parsing error.
074 */
075 protected void startParsing(final Attributes attrs) throws SAXException
076 {
077 String name = attrs.getValue(getUri(), "name");
078 String className = attrs.getValue(getUri(), "class");
079 String formula = attrs.getValue(getUri(), "formula");
080 if (className == null)
081 {
082 if (formula != null)
083 {
084 String initial = attrs.getValue(getUri(), "initial");
085 if (initial != null)
086 {
087 FormulaFunction function = new FormulaFunction();
088 function.setInitial(initial);
089 function.setFormula(formula);
090 this.expression = function;
091 }
092 else
093 {
094 FormulaExpression expression = new FormulaExpression();
095 expression.setFormula(formula);
096 this.expression = expression;
097 }
098 }
099 else
100 {
101 className = getDefaultClassName();
102 if (className == null)
103 {
104 throw new ParseException("Required attribute 'class' is missing.",
105 getRootHandler().getDocumentLocator());
106 }
107 }
108 }
109
110 if (expression == null)
111 {
112 expression = (Expression) ObjectUtilities.loadAndInstantiate
113 (className, AbstractExpressionReadHandler.class, Expression.class);
114 if (expression == null)
115 {
116 throw new ParseException("Expression '" + className +
117 "' is not valid. The specified class is not an expression or function.",
118 getRootHandler().getDocumentLocator());
119 }
120 }
121
122 expression.setName(name);
123 expression.setDeepTraversing("true".equals(attrs.getValue(getUri(), "deep-traversing")));
124 expression.setPrecompute("true".equals(attrs.getValue(getUri(), "precompute")));
125 expression.setPreserve("true".equals(attrs.getValue(getUri(), "preserve")));
126
127 try
128 {
129 expressionBeanUtility = new BeanUtility(expression);
130 }
131 catch (ClassCastException e)
132 {
133 throw new ParseException("Expression '" + className +
134 "' is not valid. The specified class is not an expression or function.",
135 e, getRootHandler().getDocumentLocator());
136 }
137 catch (IntrospectionException e)
138 {
139 throw new ParseException("Expression '" + className +
140 "' is not valid. Introspection failed for this expression.",
141 e, getRootHandler().getDocumentLocator());
142 }
143
144 }
145
146 /**
147 * Returns the handler for a child element.
148 *
149 * @param tagName the tag name.
150 * @param atts the attributes.
151 * @return the handler or null, if the tagname is invalid.
152 * @throws SAXException if there is a parsing error.
153 */
154 protected XmlReadHandler getHandlerForChild(final String uri,
155 final String tagName,
156 final Attributes atts)
157 throws SAXException
158 {
159 if (isSameNamespace(uri) == false)
160 {
161 return null;
162 }
163 if (tagName.equals("property"))
164 {
165 return new TypedPropertyReadHandler
166 (expressionBeanUtility, expression.getName(),
167 characterEntityParser);
168 }
169 return null;
170 }
171
172 public Expression getExpression()
173 {
174 return expression;
175 }
176
177 /**
178 * Returns the object for this element or null, if this element does not
179 * create an object.
180 *
181 * @return the object.
182 * @throws SAXException if there is a parsing error.
183 */
184 public Object getObject() throws SAXException
185 {
186 return expression;
187 }
188 }