/*! * 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.editor.expressions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.designer.core.ReportDesignerBoot; import org.pentaho.reporting.designer.core.settings.WorkspaceSettings; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.function.StructureFunction; import org.pentaho.reporting.engine.classic.core.metadata.ExpressionMetaData; import org.pentaho.reporting.engine.classic.core.metadata.ExpressionRegistry; import org.pentaho.reporting.engine.classic.core.metadata.GroupedMetaDataComparator; import org.pentaho.reporting.libraries.base.util.HashNMap; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Locale; public class ExpressionsTreeModel implements TreeModel { private static class ExpressionGroupingRoot { private ExpressionGroupingRoot() { } public String toString() { return "<Root> You should not see this </root>"; // NON-NLS } } private static ExpressionsTreeModel model; public static ExpressionsTreeModel getTreeModel() { if ( model != null ) { return model; } if ( ClassicEngineBoot.getInstance().isBootDone() ) { model = new ExpressionsTreeModel(); return model; } // not booted yet, return a temporary object. throw new IllegalStateException( "ExpressionsTree: Requesting tree without booting is not a sane thing to do." ); } private static Log logger = LogFactory.getLog( ExpressionsTreeModel.class ); private ExpressionGroupingRoot root; private String[] groupings; private HashNMap<String, ExpressionMetaData> expressionsByGroup; private ExpressionsTreeModel() { final ExpressionMetaData[] metaData = ExpressionRegistry.getInstance().getAllExpressionMetaDatas(); Arrays.sort( metaData, new GroupedMetaDataComparator() ); final Locale locale = Locale.getDefault(); final ArrayList<String> groupingsList = new ArrayList<String>( metaData.length ); final HashMap<String, String> diagnosticMap = new HashMap<String, String>(); String group = null; for ( int sourceIdx = 0; sourceIdx < metaData.length; sourceIdx++ ) { final ExpressionMetaData data = metaData[ sourceIdx ]; if ( data.isHidden() ) { continue; } if ( !WorkspaceSettings.getInstance().isVisible( data ) ) { continue; } if ( StructureFunction.class.isAssignableFrom( data.getExpressionType() ) ) { continue; } if ( logger.isDebugEnabled() ) { logger.debug( "Grouping : " + data.getGrouping( locale ) + " - " + data.getGroupingOrdinal( locale ) + " -> " + data .getExpressionType() ); } final String diagnosticGroup = group; if ( sourceIdx == 0 ) { group = data.getGrouping( locale ); groupingsList.add( group ); } else { final String newgroup = data.getGrouping( locale ); if ( ( ObjectUtilities.equal( newgroup, group ) ) == false ) { if ( groupingsList.contains( newgroup ) == false ) { group = newgroup; groupingsList.add( newgroup ); } else { logger.warn( "Warning: Misconfigured Expression-metadata: Group already processed: '" + newgroup + "' - " + // NON-NLS data.getExpressionType() + " - Previous: " + diagnosticMap.get( diagnosticGroup ) ); } } } diagnosticMap.put( group, data.getExpressionType().getName() ); } root = new ExpressionGroupingRoot(); groupings = groupingsList.toArray( new String[ groupingsList.size() ] ); expressionsByGroup = new HashNMap<String, ExpressionMetaData>(); for ( int i = 0; i < metaData.length; i++ ) { final ExpressionMetaData exMetaData = metaData[ i ]; if ( StructureFunction.class.isAssignableFrom( exMetaData.getExpressionType() ) ) { continue; } if ( exMetaData.isHidden() ) { continue; } if ( WorkspaceSettings.getInstance().isShowExpertItems() == false && exMetaData.isExpert() ) { continue; } if ( WorkspaceSettings.getInstance().isShowDeprecatedItems() == false && exMetaData.isDeprecated() ) { continue; } expressionsByGroup.add( exMetaData.getGrouping( Locale.getDefault() ), exMetaData ); } } public Object getRoot() { return root; } public Object getChild( final Object parent, final int index ) { if ( parent == root ) { return groupings[ index ]; } else if ( parent instanceof String ) { return expressionsByGroup.get( (String) parent, index ); } return null; } public int getChildCount( final Object parent ) { if ( parent == root ) { return groupings.length; } else if ( parent instanceof String ) { return expressionsByGroup.getValueCount( (String) parent ); } return 0; } public boolean isLeaf( final Object node ) { return node instanceof ExpressionMetaData; } public void valueForPathChanged( final TreePath path, final Object newValue ) { // cannot happen, we are not editable .. } public int getIndexOfChild( final Object parent, final Object child ) { if ( parent == null ) { return -1; } if ( parent == root && child instanceof String ) { final int idx = Arrays.binarySearch( groupings, child ); if ( idx < 0 || idx >= groupings.length ) { return -1; } return idx; } else if ( parent instanceof String ) { final Object[] metas = expressionsByGroup.toArray( (String) parent ); if ( metas == null ) { return -1; } for ( int i = 0; i < metas.length; i++ ) { if ( child == metas[ i ] ) { return i; } } return -1; } return -1; } public void addTreeModelListener( final TreeModelListener l ) { } public void removeTreeModelListener( final TreeModelListener l ) { } public static void main( String[] args ) { ReportDesignerBoot.getInstance().start(); ExpressionsTreeModel.getTreeModel(); } }