/* * 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 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core.metadata.parser; import java.beans.PropertyEditor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.engine.classic.core.metadata.AttributeCore; import org.pentaho.reporting.engine.classic.core.metadata.AttributeMetaData; import org.pentaho.reporting.engine.classic.core.metadata.DefaultAttributeCore; import org.pentaho.reporting.engine.classic.core.metadata.DefaultAttributeMetaData; import org.pentaho.reporting.engine.classic.core.metadata.ElementTypeRegistry; import org.pentaho.reporting.engine.classic.core.metadata.builder.AttributeMetaDataBuilder; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.xmlns.parser.ParseException; import org.xml.sax.Attributes; import org.xml.sax.SAXException; public class AttributeReadHandler extends AbstractMetaDataReadHandler { private static final Log logger = LogFactory.getLog( AttributeReadHandler.class ); private AttributeMetaDataBuilder builder; private String prefix; public AttributeReadHandler( final String defaultBundle, final String prefix ) { super( defaultBundle ); this.prefix = prefix; this.builder = new AttributeMetaDataBuilder(); } public AttributeMetaDataBuilder getBuilder() { return builder; } /** * Starts parsing. * * @param attrs * the attributes. * @throws SAXException * if there is a parsing error. */ protected void startParsing( final Attributes attrs ) throws SAXException { super.startParsing( attrs ); getBuilder().namespace( parseNamespace( attrs ) ); getBuilder().namespacePrefix( parseNamespacePrefix( attrs ) ); getBuilder().mandatory( "true".equals( attrs.getValue( getUri(), "mandatory" ) ) ); // NON-NLS getBuilder().computed( "true".equals( attrs.getValue( getUri(), "computed" ) ) ); // NON-NLS getBuilder().transientFlag( "true".equals( attrs.getValue( getUri(), "transient" ) ) ); // NON-NLS getBuilder().bulk( "true".equals( attrs.getValue( getUri(), "prefer-bulk" ) ) ); // NON-NLS getBuilder().designTime( "true".equals( attrs.getValue( getUri(), "design-time-value" ) ) ); // NON-NLS getBuilder().targetClass( parseValueType( attrs ) ); getBuilder().valueRole( parseValueRole( attrs ) ); getBuilder().propertyEditor( ObjectUtilities.loadAndValidate( attrs.getValue( getUri(), "propertyEditor" ), AttributeReadHandler.class, PropertyEditor.class ) ); // NON-NLS getBuilder().core( parseAttributeCore( attrs ) ); getBuilder().bundle( getBundle(), computePrefix() ); } private String computePrefix() { final String namespace = getNamespace(); final String attrName = getName(); final String namespacePrefix = ElementTypeRegistry.getInstance().getNamespacePrefix( namespace ); if ( namespacePrefix == null ) { logger.warn( "Invalid namespace-prefix, skipping attribute " + namespace + ':' + attrName ); // NON-NLS return null; } return prefix + "attribute." + namespacePrefix + '.'; // NON-NLS } private AttributeCore parseAttributeCore( final Attributes attrs ) throws ParseException { final AttributeCore attributeCore; final String metaDataCoreClass = attrs.getValue( getUri(), "impl" ); // NON-NLS if ( metaDataCoreClass != null ) { attributeCore = ObjectUtilities.loadAndInstantiate( metaDataCoreClass, AttributeReadHandler.class, AttributeCore.class ); if ( attributeCore == null ) { throw new ParseException( "Attribute 'impl' references a invalid AttributeCore implementation.", getLocator() ); } } else { attributeCore = new DefaultAttributeCore(); } return attributeCore; } private String parseValueRole( final Attributes attrs ) { String valueRole = attrs.getValue( getUri(), "value-role" ); // NON-NLS if ( valueRole == null ) { valueRole = "Value"; // NON-NLS } return valueRole; } private Class<?> parseValueType( final Attributes attrs ) throws ParseException { final String valueTypeText = attrs.getValue( getUri(), "value-type" ); // NON-NLS if ( valueTypeText == null ) { throw new ParseException( "Attribute 'value-type' is undefined", getLocator() ); } try { final ClassLoader classLoader = ObjectUtilities.getClassLoader( getClass() ); return Class.forName( valueTypeText, false, classLoader ); } catch ( final Exception e ) { throw new ParseException( "Attribute 'value-type' is not valid", e, getLocator() ); } } private String parseNamespace( final Attributes attrs ) throws ParseException { String namespace = attrs.getValue( getUri(), "namespace" ); if ( namespace == null ) { throw new ParseException( "Attribute 'namespace' is undefined", getLocator() ); } return namespace; } private String parseNamespacePrefix( final Attributes attrs ) throws ParseException { String namespacePrefix = attrs.getValue( getUri(), "namespace-prefix" ); // NON-NLS if ( namespacePrefix == null ) { namespacePrefix = ElementTypeRegistry.getInstance().getNamespacePrefix( parseNamespace( attrs ) ); } return namespacePrefix; } public AttributeCore getAttributeCore() { return getBuilder().getCore(); } public String getPropertyEditor() { return getBuilder().getPropertyEditor().getName(); } public String getNamespace() { return getBuilder().getNamespace(); } public boolean isMandatory() { return getBuilder().isMandatory(); } public boolean isComputed() { return getBuilder().isComputed(); } public boolean isTransient() { return getBuilder().isTransientFlag(); } public Class<?> getValueType() { return getBuilder().getTargetClass(); } public boolean isBulk() { return getBuilder().isBulk(); } public String getValueRole() { return getBuilder().getValueRole(); } /** * 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 AttributeDefinition getObject() throws SAXException { return new AttributeDefinition( getBuilder() ); } public AttributeMetaData getMetaData() { return new DefaultAttributeMetaData( getBuilder() ); } }