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 3525 2007-10-16 11:43:48Z tmorgner $
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        final String name = attrs.getValue(getUri(), "name");
078        String className = attrs.getValue(getUri(), "class");
079        final String formula = attrs.getValue(getUri(), "formula");
080        if (className == null)
081        {
082          if (formula != null)
083          {
084            final String initial = attrs.getValue(getUri(), "initial");
085            if (initial != null)
086            {
087              final FormulaFunction function = new FormulaFunction();
088              function.setInitial(initial);
089              function.setFormula(formula);
090              this.expression = function;
091            }
092            else
093            {
094              final 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 ("property".equals(tagName))
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    }