Package org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.elements

Source Code of org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.elements.AbstractElementReadHandler

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.elements;

import java.beans.PropertyEditor;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.ReportAttributeMap;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.metadata.AttributeMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementTypeRegistry;
import org.pentaho.reporting.engine.classic.core.modules.parser.ClassicEngineFactoryParameters;
import org.pentaho.reporting.engine.classic.core.modules.parser.base.common.StyleExpressionHandler;
import org.pentaho.reporting.engine.classic.core.modules.parser.bundle.BundleNamespaces;
import org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.ElementReadHandler;
import org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.ElementStyleReadHandler;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
import org.pentaho.reporting.engine.classic.core.util.beans.BeanException;
import org.pentaho.reporting.engine.classic.core.util.beans.ConverterRegistry;
import org.pentaho.reporting.engine.classic.core.util.beans.ValueConverter;
import org.pentaho.reporting.libraries.resourceloader.ResourceData;
import org.pentaho.reporting.libraries.resourceloader.ResourceException;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
import org.pentaho.reporting.libraries.xmlns.parser.AbstractXmlReadHandler;
import org.pentaho.reporting.libraries.xmlns.parser.ParseException;
import org.pentaho.reporting.libraries.xmlns.parser.XmlReadHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
* Todo: Document Me
*
* @author Thomas Morgner
*/
public abstract class AbstractElementReadHandler extends AbstractXmlReadHandler implements ElementReadHandler
{
  private static final Log logger = LogFactory.getLog(AbstractElementReadHandler.class);

  private Element element;
  private ElementMetaData metaData;
  private ArrayList<StyleExpressionHandler> styleExpressions;
  private ArrayList<AttributeExpressionReadHandler> attributeExpressions;
  private ArrayList<BulkAttributeReadHandler> bulkattributes;
  private ArrayList<BulkExpressionReadHandler> bulkexpressions;


  protected AbstractElementReadHandler()
  {
    styleExpressions = new ArrayList<StyleExpressionHandler>();
    attributeExpressions = new ArrayList<AttributeExpressionReadHandler>();
    bulkattributes = new ArrayList<BulkAttributeReadHandler>();
    bulkexpressions = new ArrayList<BulkExpressionReadHandler>();
  }

  protected AbstractElementReadHandler(final String elementType) throws ParseException
  {
    this();
    initialize(elementType);
  }

  protected void initialize(final String elementType)
      throws ParseException
  {
    metaData = ElementTypeRegistry.getInstance().getElementType(elementType);

    element = createElement(elementType);
    try
    {
      element.setElementType(metaData.create());
    }
    catch (InstantiationException e)
    {
      // This should not happen at this point, as there is no way to instantiate the class if the
      // element is not there. But it could happen if the element is not registered, which indicates
      // a user error (Engine not booted).
      throw new ParseException("Unable to instantiate element for type '" + elementType + '"');
    }
  }

  protected Element createElement(final String elementType) throws ParseException
  {
    return new Element();
  }

  /**
   * Starts parsing.
   *
   * @param attrs the attributes.
   * @throws SAXException if there is a parsing error.
   */
  protected void startParsing(final Attributes attrs) throws SAXException
  {
    final Element element = getElement();
    final int length = attrs.getLength();
    for (int i = 0; i < length; i++)
    {
      if ("xmlns".equals(attrs.getQName(i)) ||
          attrs.getQName(i).startsWith("xmlns:"))
      {
        // workaround for buggy parsers
        continue;
      }
      final String name = attrs.getLocalName(i);
      if (name.indexOf(':') > -1)
      {
        // attribute with ':' are not valid and indicate a namespace definition or so
        continue;
      }
      final String namespace = attrs.getURI(i);
      final String attributeValue = attrs.getValue(i);

      setAttributeValue(element, namespace, name, attributeValue, ReportAttributeMap.EMPTY_MAP);
    }
  }

  private void setAttributeValue(final Element element,
                                 final String namespace,
                                 final String name,
                                 final String attributeValue,
                                 final ReportAttributeMap attributes) throws ParseException
  {
    final AttributeMetaData attributeMetaData = metaData.getAttributeDescription(namespace, name);
    if (attributeMetaData == null || attributeValue == null)
    {
      element.setAttribute(namespace, name, attributeValue);
      return;
    }

    if (attributeMetaData.isTransient())
    {
      return;
    }

    if ("Resource".equals(attributeMetaData.getValueRole()))
    {
      try
      {
        final Object type = attributes.getAttribute(AttributeNames.Core.NAMESPACE, "resource-type");
        if ("url".equals(type))
        {
          element.setAttribute(namespace, name, new URL(attributeValue));
          return;
        }
        if ("file".equals(type))
        {
          element.setAttribute(namespace, name, new File(attributeValue));
          return;
        }
        if ("local-ref".equals(type))
        {
          element.setAttribute(namespace, name, attributeValue);
          return;
        }
        if ("resource-key".equals(type))
        {
          final ResourceManager resourceManager = getRootHandler().getResourceManager();
          final ResourceKey key = getRootHandler().getContext();
          final ResourceKey parent = key.getParent();
          final ResourceKey valueKey = resourceManager.deserialize(parent, attributeValue);

          // make local ..
          final ResourceKey resourceKey = localizeKey(resourceManager, valueKey);
          element.setAttribute(namespace, name, resourceKey);
          return;
        }
        element.setAttribute(namespace, name, attributeValue);
        return;
      }
      catch (MalformedURLException e)
      {
        throw new ParseException("Failed to parse URL value", e);
      }
      catch (ResourceKeyCreationException e)
      {
        throw new ParseException("Failed to parse resource-key value", e);
      }
    }

    final Class type = attributeMetaData.getTargetType();
    if (String.class.equals(type))
    {
      element.setAttribute(namespace, name, attributeValue);
    }
    else
    {
      try
      {
        final PropertyEditor propertyEditor = attributeMetaData.getEditor();
        if (propertyEditor != null)
        {
          propertyEditor.setAsText(attributeValue);
          element.setAttribute(namespace, name, propertyEditor.getValue());
        }
        else
        {
          final ConverterRegistry instance = ConverterRegistry.getInstance();
          final ValueConverter valueConverter = instance.getValueConverter(type);
          if (valueConverter != null)
          {
            final Object o = ConverterRegistry.toPropertyValue(attributeValue, type);
            element.setAttribute(namespace, name, o);
          }
          else if (String.class.isAssignableFrom(type))
          {
            // the attribute would allow raw-string values, so copy the element ..
            element.setAttribute(namespace, name, attributeValue);
          }
        }

      }
      catch (BeanException e)
      {
        // ignore.
        AbstractElementReadHandler.logger.warn(
            "Attribute '" + namespace + '|' + name + "' is not convertible with the bean-methods " + getLocator());
      }
    }
  }

  private ResourceKey localizeKey(final ResourceManager resourceManager, final ResourceKey valueKey)
  {
    final Object object = valueKey.getFactoryParameters().get(ClassicEngineFactoryParameters.EMBED);
    if ("false".equals(object))
    {
      return valueKey;
    }
    if ("org.pentaho.reporting.libraries.docbundle.bundleloader.RepositoryResourceBundleLoader".equals(valueKey.getSchema()) == false &&
        object == null)
    {
      return valueKey;
    }

    try
    {
      final ResourceData resourceData = resourceManager.load(valueKey);
      final byte[] resource = resourceData.getResource(resourceManager);
      return resourceManager.createKey(resource, valueKey.getFactoryParameters());
    }
    catch (ResourceException e)
    {
      if (logger.isDebugEnabled())
      {
        logger.info("Unable to normalize embedded resource-key, using ordinary key-object instead.", e);
      }
      else
      {
        logger.info("Unable to normalize embedded resource-key, using ordinary key-object instead.");
      }
    }
    return valueKey;
  }

  /**
   * Returns the handler for a child element.
   *
   * @param uri     the URI of the namespace of the current element.
   * @param tagName the tag name.
   * @param atts    the attributes.
   * @return the handler or null, if the tagname is invalid.
   * @throws SAXException if there is a parsing error.
   */
  protected XmlReadHandler getHandlerForChild(final String uri,
                                              final String tagName,
                                              final Attributes atts) throws SAXException
  {
    if (BundleNamespaces.LAYOUT.equals(uri))
    {
      if ("attribute-expression".equals(tagName))
      {
        final AttributeExpressionReadHandler readHandler = new AttributeExpressionReadHandler();
        attributeExpressions.add(readHandler);
        return readHandler;
      }
      else if ("style-expression".equals(tagName))
      {
        final StyleExpressionHandler readHandler = new StyleExpressionHandler();
        styleExpressions.add(readHandler);
        return readHandler;
      }
      else if ("expression".equals(tagName))
      {
        final BulkExpressionReadHandler readHandler = new BulkExpressionReadHandler();
        bulkexpressions.add(readHandler);
        return readHandler;
      }
    }
    if (BundleNamespaces.STYLE.equals(uri))
    {
      if ("element-style".equals(tagName))
      {
        return new ElementStyleReadHandler(getElement().getStyle());
      }
    }

    final BulkAttributeReadHandler readHandler = new BulkAttributeReadHandler(uri, tagName);
    bulkattributes.add(readHandler);
    return readHandler;
  }

  /**
   * Done parsing.
   *
   * @throws SAXException if there is a parsing error.
   */
  protected void doneParsing() throws SAXException
  {
    for (int i = 0; i < styleExpressions.size(); i++)
    {
      final StyleExpressionHandler handler = styleExpressions.get(i);
      final StyleKey key = handler.getKey();
      if (handler.getKey() != null)
      {
        final Expression expression = handler.getExpression();
        element.setStyleExpression(key, expression);
      }
    }

    for (int i = 0; i < attributeExpressions.size(); i++)
    {
      final AttributeExpressionReadHandler handler = attributeExpressions.get(i);
      final Expression expression = handler.getExpression();
      element.setAttributeExpression(handler.getNamespace(), handler.getName(), expression);
    }

    for (int i = 0; i < bulkattributes.size(); i++)
    {
      final BulkAttributeReadHandler attributeReadHandler = bulkattributes.get(i);
      setAttributeValue(element, attributeReadHandler.getNamespace(),
          attributeReadHandler.getName(), attributeReadHandler.getResult(),
          attributeReadHandler.getAttributes());
    }
    for (int i = 0; i < bulkexpressions.size(); i++)
    {
      final BulkExpressionReadHandler expressionReadHandler = bulkexpressions.get(i);
      element.setAttribute(expressionReadHandler.getAttributeNameSpace(),
          expressionReadHandler.getAttributeName(), expressionReadHandler.getObject());
    }
  }

  /**
   * Returns the object for this element or null, if this element does not create an object.
   *
   * @return the object.
   * @throws SAXException if an parser error occured.
   */
  public Object getObject() throws SAXException
  {
    return getElement();
  }

  public Element getElement()
  {
    return element;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.parser.bundle.layout.elements.AbstractElementReadHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.