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: TypedPropertyReadHandler.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: */package org.jfree.report.modules.factories.report.flow;
031:
032: import java.beans.IntrospectionException;
033: import java.io.ByteArrayInputStream;
034: import java.io.IOException;
035: import java.io.ObjectInputStream;
036:
037: import org.jfree.report.util.CharacterEntityParser;
038: import org.jfree.report.util.beans.BeanException;
039: import org.jfree.report.util.beans.BeanUtility;
040: import org.jfree.util.Log;
041: import org.jfree.util.ObjectUtilities;
042: import org.jfree.xmlns.parser.Base64;
043: import org.jfree.xmlns.parser.ParseException;
044: import org.jfree.xmlns.parser.PropertyReadHandler;
045: import org.jfree.xmlns.parser.XmlReadHandler;
046: import org.xml.sax.Attributes;
047: import org.xml.sax.SAXException;
048:
049: /**
050: * Creation-Date: 09.04.2006, 12:58:24
051: *
052: * @author Thomas Morgner
053: */
054: public class TypedPropertyReadHandler extends PropertyReadHandler {
055: private boolean plainContent;
056: private String encoding;
057: private String className;
058: private BeanUtility beanUtility;
059: private String expressionName;
060: private CharacterEntityParser entityParser;
061:
062: public TypedPropertyReadHandler(final BeanUtility beanDescription,
063: final String expressionName,
064: final CharacterEntityParser entityParser) {
065: if (beanDescription == null) {
066: throw new NullPointerException(
067: "Expression must not be null");
068: }
069: if (entityParser == null) {
070: throw new NullPointerException(
071: "EntityParser must not be null");
072: }
073: this .expressionName = expressionName;
074: this .beanUtility = beanDescription;
075: this .entityParser = entityParser;
076: this .plainContent = true;
077: }
078:
079: /**
080: * Done parsing.
081: *
082: * @throws SAXException if there is a parsing error.
083: */
084: protected void doneParsing() throws SAXException {
085: super .doneParsing();
086: try {
087: if (plainContent) {
088: final String result = getResult();
089: if ("base64".equals(encoding)) {
090: final byte[] data = Base64.decode(result.trim()
091: .toCharArray());
092: final ByteArrayInputStream bin = new ByteArrayInputStream(
093: data);
094: final ObjectInputStream oin = new ObjectInputStream(
095: bin);
096: final Object value = oin.readObject();
097: beanUtility.setProperty(getName(), value);
098: } else {
099: if (className != null) {
100: final ClassLoader cl = ObjectUtilities
101: .getClassLoader(TypedPropertyReadHandler.class);
102: final Class c = cl.loadClass(className);
103: beanUtility.setPropertyAsString(getName(), c,
104: entityParser.decodeEntities(result));
105: } else {
106: beanUtility.setPropertyAsString(getName(),
107: entityParser.decodeEntities(result));
108: }
109: }
110: }
111: } catch (BeanException e) {
112: e.printStackTrace();
113: throw new ParseException("Unable to assign property '"
114: + getName() + "' to expression '" + expressionName
115: + "'", e, getLocator());
116: } catch (ClassNotFoundException e) {
117: throw new ParseException("Unable to assign property '"
118: + getName() + "' to expression '" + expressionName
119: + "'", e, getLocator());
120: } catch (IOException e) {
121: throw new ParseException("Unable to assign property '"
122: + getName() + "' to expression '" + expressionName
123: + "'", e, getLocator());
124: }
125: }
126:
127: /**
128: * Starts parsing.
129: *
130: * @param attrs the attributes.
131: * @throws SAXException if there is a parsing error.
132: */
133: protected void startParsing(final Attributes attrs)
134: throws SAXException {
135: super .startParsing(attrs);
136: className = attrs.getValue(getUri(), "class");
137: encoding = attrs.getValue(getUri(), "encoding");
138: if (encoding == null) {
139: encoding = "text";
140: } else if (("text".equals(encoding) == false)
141: && "base64".equals(encoding) == false) {
142: Log
143: .warn("Invalid value for attribute 'encoding'. Defaulting to 'text'");
144: encoding = "text";
145: }
146: }
147:
148: /**
149: * Returns the handler for a child element.
150: *
151: * @param tagName the tag name.
152: * @param atts the attributes.
153: * @return the handler or null, if the tagname is invalid.
154: * @throws SAXException if there is a parsing error.
155: */
156: protected XmlReadHandler getHandlerForChild(final String uri,
157: final String tagName, final Attributes atts)
158: throws SAXException {
159: if (isSameNamespace(uri) == false) {
160: return null;
161: }
162:
163: if ("property".equals(tagName)) {
164: plainContent = false;
165: final String name = atts.getValue(uri, "name");
166: if (name == null) {
167: throw new ParseException(
168: "Required attribute 'name' is missing",
169: getLocator());
170: }
171: try {
172: final Class type = beanUtility.getPropertyType(name);
173: final Object property = type.newInstance();
174: final BeanUtility propertyUtility = new BeanUtility(
175: property);
176: return new TypedPropertyReadHandler(propertyUtility,
177: expressionName, entityParser);
178: } catch (BeanException e) {
179: throw new ParseException(
180: "Property '"
181: + name
182: + "' for expression '"
183: + className
184: + "' is not valid. The specified class was not found.",
185: e, getRootHandler().getDocumentLocator());
186: } catch (IllegalAccessException e) {
187: throw new ParseException(
188: "Property '"
189: + name
190: + "' for expression '"
191: + className
192: + "' is not valid. The specified class was not found.",
193: e, getRootHandler().getDocumentLocator());
194: } catch (InstantiationException e) {
195: throw new ParseException(
196: "Property '"
197: + name
198: + "' for expression '"
199: + className
200: + "' is not valid. The specified class cannot be instantiated.",
201: e, getRootHandler().getDocumentLocator());
202: } catch (IntrospectionException e) {
203: throw new ParseException(
204: "Property '"
205: + name
206: + "' for expression '"
207: + className
208: + "' is not valid. Introspection failed for this expression.",
209: e, getRootHandler().getDocumentLocator());
210: }
211: }
212: return null;
213: }
214: }
|