/* * 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; import org.pentaho.reporting.engine.classic.core.function.Expression; import org.pentaho.reporting.engine.classic.core.function.Function; import org.pentaho.reporting.engine.classic.core.metadata.builder.ExpressionMetaDataBuilder; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Map; public class DefaultExpressionMetaData extends AbstractMetaData implements ExpressionMetaData { public static final int NO_LAYOUT_PROCESSOR = 0; public static final int ELEMENT_LAYOUT_PROCESSOR = 1; public static final int GLOBAL_LAYOUT_PROCESSOR = 2; private Class<? extends Expression> expressionType; private Class<?> resultType; private HashMap<String, ExpressionPropertyMetaData> properties; private int layoutProcessorMode; private transient SharedBeanInfo beanInfo; private transient String[] propertyKeys; private transient ExpressionPropertyMetaData[] propertyMetaData; public DefaultExpressionMetaData( final String bundleLocation, final boolean expert, final boolean preferred, final boolean hidden, final boolean deprecated, final Class<? extends Expression> expressionType, final Class<?> resultType, final Map<String, ExpressionPropertyMetaData> attributes, final SharedBeanInfo beanInfo, final int layoutProcessorMode, final MaturityLevel maturityLevel, final int compatibilityLevel ) { super( expressionType.getName(), bundleLocation, "", expert, preferred, hidden, deprecated, maturityLevel, compatibilityLevel ); if ( resultType == null ) { throw new NullPointerException(); } if ( attributes == null ) { throw new NullPointerException(); } if ( beanInfo == null ) { throw new NullPointerException(); } this.expressionType = expressionType; this.layoutProcessorMode = layoutProcessorMode; this.resultType = resultType; this.properties = new HashMap<String, ExpressionPropertyMetaData>( attributes ); this.beanInfo = beanInfo; } public DefaultExpressionMetaData( final ExpressionMetaDataBuilder builder ) { super( builder ); this.expressionType = builder.getImpl(); this.layoutProcessorMode = builder.getLayoutComputation(); this.resultType = builder.getResultType(); this.properties = builder.getProperties(); this.beanInfo = new SharedBeanInfo( expressionType ); } protected String computePrefix( final String keyPrefix, final String name ) { return ""; } public boolean isStatefull() { return Function.class.isAssignableFrom( getExpressionType() ); } public Class getResultType() { return resultType; } public Class getExpressionType() { return expressionType; } public ExpressionPropertyMetaData getPropertyDescription( final String name ) { return properties.get( name ); } public Expression create() { try { return expressionType.newInstance(); } catch ( Exception e ) { throw new IllegalStateException( e ); } } public String[] getPropertyNames() { if ( propertyKeys == null ) { propertyKeys = properties.keySet().toArray( new String[properties.size()] ); } return propertyKeys; } public ExpressionPropertyMetaData[] getPropertyDescriptions() { if ( propertyMetaData == null ) { propertyMetaData = properties.values().toArray( new ExpressionPropertyMetaData[properties.size()] ); } return propertyMetaData; } public BeanInfo getBeanDescriptor() throws IntrospectionException { return beanInfo.getBeanInfo(); } /** * Checks whether the main purpose of the expression is to modify the layout of the report. This method returns true, * if the expression modifies one or more named elements. * * @return true, if this is a layout-processor that modifies named elements. */ public boolean isElementLayoutProcessor() { return layoutProcessorMode == DefaultExpressionMetaData.ELEMENT_LAYOUT_PROCESSOR; } /** * Checks whether the main purpose of the expression is to modify the layout of the report. This method returns true, * if the expression modifies the global layout only. * * @return true, if this is a layout-processor that modifies the global layout. */ public boolean isGlobalLayoutProcessor() { return layoutProcessorMode == DefaultExpressionMetaData.GLOBAL_LAYOUT_PROCESSOR; } public boolean equals( final Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } final DefaultExpressionMetaData that = (DefaultExpressionMetaData) o; if ( !expressionType.equals( that.expressionType ) ) { return false; } return true; } public int hashCode() { return expressionType.hashCode(); } private void writeObject( ObjectOutputStream out ) throws IOException { out.defaultWriteObject(); out.writeObject( beanInfo.getBeanClass() ); } private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException { in.defaultReadObject(); final Class c = (Class) in.readObject(); beanInfo = new SharedBeanInfo( c ); } }