/*! * 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) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.designer.core.model; import org.pentaho.reporting.designer.core.ReportDesignerBoot; import org.pentaho.reporting.designer.core.model.lineal.LinealModel; import org.pentaho.reporting.designer.core.model.lineal.LinealModelEvent; import org.pentaho.reporting.designer.core.model.lineal.LinealModelListener; import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition; import org.pentaho.reporting.engine.classic.core.CompoundDataFactory; import org.pentaho.reporting.engine.classic.core.DataFactory; import org.pentaho.reporting.engine.classic.core.Element; import org.pentaho.reporting.engine.classic.core.Group; import org.pentaho.reporting.engine.classic.core.ReportDefinition; import org.pentaho.reporting.engine.classic.core.ReportElement; import org.pentaho.reporting.engine.classic.core.RootLevelBand; import org.pentaho.reporting.engine.classic.core.Section; import org.pentaho.reporting.engine.classic.core.SubReport; import org.pentaho.reporting.engine.classic.core.function.FunctionUtilities; import org.pentaho.reporting.engine.classic.core.layout.model.RenderNode; import org.pentaho.reporting.engine.classic.core.util.InstanceID; import org.pentaho.reporting.engine.classic.extensions.parsers.reportdesigner.ReportDesignerParserModule; import org.pentaho.reporting.libraries.base.config.Configuration; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; /** * Todo: Document Me * * @author Thomas Morgner */ public class ModelUtility { private static final String CACHED_LAYOUT_DATA = "CachedLayoutData"; private static final String NUMBER_FORMAT_CONFIG_PREFIX = "NumberFormat.String."; private static final String DATE_FORMAT_CONFIG_PREFIX = "DateFormat.String."; private ModelUtility() { } private static class LinealUpdateHandler implements LinealModelListener { private Element element; private LinealModel model; private String attribute; private LinealUpdateHandler( final Element element, final LinealModel model, final String attribute ) { this.element = element; this.model = model; this.attribute = attribute; } public void modelChanged( final LinealModelEvent event ) { element.setAttribute( ReportDesignerParserModule.NAMESPACE, attribute, model.externalize(), false ); } } public static boolean isHideInLayoutGui( final RenderNode node ) { final Object attribute = node.getAttributes().getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerParserModule.HIDE_IN_LAYOUT_GUI_ATTRIBUTE ); return attribute != null && Boolean.TRUE.equals( attribute ); } public static boolean isHideInLayoutGui( final ReportElement element ) { final Object attribute = element.getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerParserModule.HIDE_IN_LAYOUT_GUI_ATTRIBUTE ); return attribute != null && Boolean.TRUE.equals( attribute ); } public static LinealModel getVerticalLinealModel( final Element rootBand ) { final Object maybeLinealModel = rootBand.getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerBoot.DESIGNER_LINEAL_MODEL_OBJECT ); if ( maybeLinealModel instanceof LinealModel ) { return (LinealModel) maybeLinealModel; } final LinealModel verticalLinealModel = new LinealModel(); final Object attribute = rootBand.getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerParserModule.VERTICAL_GUIDE_LINES_ATTRIBUTE ); if ( attribute instanceof String ) { verticalLinealModel.parse( attribute.toString() ); } verticalLinealModel.addLinealModelListener( new LinealUpdateHandler ( rootBand, verticalLinealModel, ReportDesignerParserModule.VERTICAL_GUIDE_LINES_ATTRIBUTE ) ); rootBand.setAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerBoot.DESIGNER_LINEAL_MODEL_OBJECT, verticalLinealModel, false ); return verticalLinealModel; } public static LinealModel getHorizontalLinealModel( final AbstractReportDefinition rootBand ) { final Object maybeLinealModel = rootBand.getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerBoot.DESIGNER_LINEAL_MODEL_OBJECT ); if ( maybeLinealModel instanceof LinealModel ) { return (LinealModel) maybeLinealModel; } final LinealModel linealModel = new LinealModel(); final Object attribute = rootBand.getAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerParserModule.HORIZONTAL_GUIDE_LINES_ATTRIBUTE ); if ( attribute instanceof String ) { linealModel.parse( attribute.toString() ); } linealModel.addLinealModelListener( new LinealUpdateHandler ( rootBand, linealModel, ReportDesignerParserModule.HORIZONTAL_GUIDE_LINES_ATTRIBUTE ) ); rootBand.setAttribute( ReportDesignerParserModule.NAMESPACE, ReportDesignerBoot.DESIGNER_LINEAL_MODEL_OBJECT, linealModel, false ); return linealModel; } public static CachedLayoutData getCachedLayoutData( final Element element ) { final Object attribute = element.getAttribute( ReportDesignerParserModule.NAMESPACE, CACHED_LAYOUT_DATA ); if ( attribute instanceof CachedLayoutData ) { return (CachedLayoutData) attribute; } final CachedLayoutData retval = new CachedLayoutData(); element.setAttribute( ReportDesignerParserModule.NAMESPACE, CACHED_LAYOUT_DATA, retval, false ); return retval; } public static boolean isDescendant( final Section definition, final ReportElement element ) { ReportElement band = element; while ( band != null ) { if ( band == definition ) { return true; } band = band.getParentSection(); } return false; } public static List<Element> filterParents( final List<Element> elements ) { if ( elements.size() == 1 ) { return elements; } final ArrayList<Element> retval = new ArrayList<Element>( elements.size() ); for ( Element element : elements ) { if ( element instanceof Section ) { final Section s = (Section) element; if ( isParentSection( s, elements ) ) { continue; } } retval.add( element ); } return retval; } private static boolean isParentSection( final Section s, final List<Element> elements ) { for ( Element potentialChild : elements ) { if ( potentialChild != s ) { if ( ModelUtility.isDescendant( s, potentialChild ) ) { return true; } } } return false; } public static SubReport[] findSubReports( final Section section ) { final ArrayList<SubReport> result = new ArrayList<SubReport>(); findSubReportsInteral( section, result ); return result.toArray( new SubReport[ result.size() ] ); } private static void findSubReportsInteral( final Section section, final ArrayList<SubReport> result ) { final int count = section.getElementCount(); for ( int i = 0; i < count; i++ ) { final ReportElement element = section.getElement( i ); if ( element instanceof Section ) { findSubReportsInteral( (Section) element, result ); } } if ( section instanceof SubReport ) { result.add( (SubReport) section ); } } public static ReportElement findElementById( final AbstractReportDefinition definition, final InstanceID id ) { return FunctionUtilities.findElementByInstanceId( (ReportDefinition) definition, id ); } public static int findIndexOf( final Section parent, final Element visualElement ) { final int count = parent.getElementCount(); for ( int i = 0; i < count; i++ ) { final ReportElement element = parent.getElement( i ); if ( element == visualElement ) { return i; } } return -1; } public static int findSubreportIndexOf( final RootLevelBand parent, final SubReport visualElement ) { final int count = parent.getSubReportCount(); for ( int i = 0; i < count; i++ ) { final ReportElement element = parent.getSubReport( i ); if ( element == visualElement ) { return i; } } return -1; } public static String[] getGroups( final AbstractReportDefinition reportDefinition ) { final LinkedHashSet<String> groups = new LinkedHashSet<String>(); final int count = reportDefinition.getGroupCount(); for ( int i = 0; i < count; i++ ) { final Group g = reportDefinition.getGroup( i ); final String groupName = g.getName(); if ( groupName != null ) { groups.add( groupName ); } } for ( int i = 0; i < count; i++ ) { final Group g = reportDefinition.getGroup( i ); final String groupName = g.getGeneratedName(); if ( groupName != null ) { groups.add( groupName ); } } return groups.toArray( new String[ groups.size() ] ); } public static String[] getNumberFormats() { return getMessageSeries( NUMBER_FORMAT_CONFIG_PREFIX ); } public static String[] getDateFormats() { return getMessageSeries( DATE_FORMAT_CONFIG_PREFIX ); } private static String[] getMessageSeries( final String seriesPrefix ) { final ArrayList<String> stringSeries = new ArrayList<String>(); int index = 0; final Configuration configuration = ReportDesignerBoot.getInstance().getGlobalConfig(); String message = configuration.getConfigProperty( seriesPrefix + index ); while ( message != null ) { stringSeries.add( message ); index++; message = configuration.getConfigProperty( seriesPrefix + index ); } return stringSeries.toArray( new String[ stringSeries.size() ] ); } public static DataFactory findDataFactoryForQuery( AbstractReportDefinition definition, final String query ) { while ( definition != null ) { final DataFactory dataFactory = definition.getDataFactory(); if ( dataFactory instanceof CompoundDataFactory ) { final CompoundDataFactory cdf = (CompoundDataFactory) dataFactory; final DataFactory factoryForQuery = cdf.getDataFactoryForQuery( query ); if ( factoryForQuery != null ) { return factoryForQuery; } } final Section parentSection = definition.getParentSection(); if ( parentSection == null ) { definition = null; } else { definition = (AbstractReportDefinition) parentSection.getReportDefinition(); } } return null; } }