Source for org.jfree.report.modules.factories.report.flow.TypedPropertyReadHandler

   1: /**
   2:  * ========================================
   3:  * JFreeReport : a free Java report library
   4:  * ========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/
   7:  *
   8:  * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  * ------------
  26:  * $Id: TypedPropertyReadHandler.java 3525 2007-10-16 11:43:48Z tmorgner $
  27:  * ------------
  28:  * (C) Copyright 2000-2005, by Object Refinery Limited.
  29:  * (C) Copyright 2005-2007, by Pentaho Corporation.
  30:  */
  31: package org.jfree.report.modules.factories.report.flow;
  32: 
  33: import java.beans.IntrospectionException;
  34: import java.io.ByteArrayInputStream;
  35: import java.io.IOException;
  36: import java.io.ObjectInputStream;
  37: 
  38: import org.jfree.report.util.CharacterEntityParser;
  39: import org.jfree.report.util.beans.BeanException;
  40: import org.jfree.report.util.beans.BeanUtility;
  41: import org.jfree.util.Log;
  42: import org.jfree.util.ObjectUtilities;
  43: import org.jfree.xmlns.parser.Base64;
  44: import org.jfree.xmlns.parser.ParseException;
  45: import org.jfree.xmlns.parser.PropertyReadHandler;
  46: import org.jfree.xmlns.parser.XmlReadHandler;
  47: import org.xml.sax.Attributes;
  48: import org.xml.sax.SAXException;
  49: 
  50: /**
  51:  * Creation-Date: 09.04.2006, 12:58:24
  52:  *
  53:  * @author Thomas Morgner
  54:  */
  55: public class TypedPropertyReadHandler extends PropertyReadHandler
  56: {
  57:   private boolean plainContent;
  58:   private String encoding;
  59:   private String className;
  60:   private BeanUtility beanUtility;
  61:   private String expressionName;
  62:   private CharacterEntityParser entityParser;
  63: 
  64:   public TypedPropertyReadHandler(final BeanUtility beanDescription,
  65:                                   final String expressionName,
  66:                                   final CharacterEntityParser entityParser)
  67:   {
  68:     if (beanDescription == null)
  69:     {
  70:       throw new NullPointerException(
  71:               "Expression must not be null");
  72:     }
  73:     if (entityParser == null)
  74:     {
  75:       throw new NullPointerException(
  76:               "EntityParser must not be null");
  77:     }
  78:     this.expressionName = expressionName;
  79:     this.beanUtility = beanDescription;
  80:     this.entityParser = entityParser;
  81:     this.plainContent = true;
  82:   }
  83: 
  84:   /**
  85:    * Done parsing.
  86:    *
  87:    * @throws SAXException       if there is a parsing error.
  88:    */
  89:   protected void doneParsing() throws SAXException
  90:   {
  91:     super.doneParsing();
  92:     try
  93:     {
  94:       if (plainContent)
  95:       {
  96:         final String result = getResult();
  97:         if ("base64".equals(encoding))
  98:         {
  99:           final byte[] data = Base64.decode(result.trim().toCharArray());
 100:           final ByteArrayInputStream bin = new ByteArrayInputStream(data);
 101:           final ObjectInputStream oin = new ObjectInputStream(bin);
 102:           final Object value = oin.readObject();
 103:           beanUtility.setProperty(getName(), value);
 104:         }
 105:         else
 106:         {
 107:           if (className != null)
 108:           {
 109:             final ClassLoader cl = ObjectUtilities.getClassLoader
 110:                     (TypedPropertyReadHandler.class);
 111:             final Class c = cl.loadClass(className);
 112:             beanUtility.setPropertyAsString
 113:                     (getName(), c, entityParser.decodeEntities(result));
 114:           }
 115:           else
 116:           {
 117:             beanUtility.setPropertyAsString
 118:                     (getName(), entityParser.decodeEntities(result));
 119:           }
 120:         }
 121:       }
 122:     }
 123:     catch (BeanException e)
 124:     {
 125:       e.printStackTrace();
 126:       throw new ParseException("Unable to assign property '" + getName()
 127:               + "' to expression '" + expressionName + "'", e, getLocator());
 128:     }
 129:     catch (ClassNotFoundException e)
 130:     {
 131:       throw new ParseException("Unable to assign property '" + getName()
 132:               + "' to expression '" + expressionName + "'", e, getLocator());
 133:     }
 134:     catch (IOException e)
 135:     {
 136:       throw new ParseException("Unable to assign property '" + getName()
 137:               + "' to expression '" + expressionName + "'", e, getLocator());
 138:     }
 139:   }
 140: 
 141:   /**
 142:    * Starts parsing.
 143:    *
 144:    * @param attrs the attributes.
 145:    * @throws SAXException if there is a parsing error.
 146:    */
 147:   protected void startParsing(final Attributes attrs) throws SAXException
 148:   {
 149:     super.startParsing(attrs);
 150:     className = attrs.getValue(getUri(), "class");
 151:     encoding = attrs.getValue(getUri(), "encoding");
 152:     if (encoding == null)
 153:     {
 154:       encoding = "text";
 155:     }
 156:     else if (("text".equals(encoding) == false) && "base64".equals(
 157:             encoding) == false)
 158:     {
 159:       Log.warn("Invalid value for attribute 'encoding'. Defaulting to 'text'");
 160:       encoding = "text";
 161:     }
 162:   }
 163: 
 164:   /**
 165:    * Returns the handler for a child element.
 166:    *
 167:    * @param tagName the tag name.
 168:    * @param atts    the attributes.
 169:    * @return the handler or null, if the tagname is invalid.
 170:    * @throws SAXException       if there is a parsing error.
 171:    */
 172:   protected XmlReadHandler getHandlerForChild(final String uri,
 173:                                               final String tagName,
 174:                                               final Attributes atts)
 175:           throws SAXException
 176:   {
 177:     if (isSameNamespace(uri) == false)
 178:     {
 179:       return null;
 180:     }
 181: 
 182:     if ("property".equals(tagName))
 183:     {
 184:       plainContent = false;
 185:       final String name = atts.getValue(uri, "name");
 186:       if (name == null)
 187:       {
 188:         throw new ParseException("Required attribute 'name' is missing", getLocator());
 189:       }
 190:       try
 191:       {
 192:         final Class type = beanUtility.getPropertyType(name);
 193:         final Object property = type.newInstance();
 194:         final BeanUtility propertyUtility = new BeanUtility(property);
 195:         return new TypedPropertyReadHandler
 196:                 (propertyUtility, expressionName, entityParser);
 197:       }
 198:       catch (BeanException e)
 199:       {
 200:         throw new ParseException("Property '" + name + "' for expression '" +
 201:                 className + "' is not valid. The specified class was not found.",
 202:                 e, getRootHandler().getDocumentLocator());
 203:       }
 204:       catch (IllegalAccessException e)
 205:       {
 206:         throw new ParseException(
 207:                 "Property '" + name + "' for expression '" + className +
 208:                         "' is not valid. The specified class was not found.",
 209:                 e, getRootHandler().getDocumentLocator());
 210:       }
 211:       catch (InstantiationException e)
 212:       {
 213:         throw new ParseException(
 214:                 "Property '" + name + "' for expression '" + className +
 215:                         "' is not valid. The specified class cannot be instantiated.",
 216:                 e, getRootHandler().getDocumentLocator());
 217:       }
 218:       catch (IntrospectionException e)
 219:       {
 220:         throw new ParseException(
 221:                 "Property '" + name + "' for expression '" + className +
 222:                         "' is not valid. Introspection failed for this expression.",
 223:                 e, getRootHandler().getDocumentLocator());
 224:       }
 225:     }
 226:     return null;
 227:   }
 228: }