001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009     *
010     * This library is free software; you can redistribute it and/or modify it under the terms
011     * of the GNU Lesser General Public License as published by the Free Software Foundation;
012     * either version 2.1 of the License, or (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public License along with this
019     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020     * Boston, MA 02111-1307, USA.
021     *
022     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023     * in the United States and other countries.]
024     *
025     * ------------
026     * $Id: DefaultLayoutControllerFactory.java 3048 2007-07-28 18:02:42Z tmorgner $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.flow.layoutprocessor;
033    
034    import java.util.HashMap;
035    import java.util.Iterator;
036    
037    import org.jfree.report.DataSourceException;
038    import org.jfree.report.ReportDataFactoryException;
039    import org.jfree.report.ReportProcessingException;
040    import org.jfree.report.flow.FlowController;
041    import org.jfree.report.flow.ReportJob;
042    import org.jfree.report.structure.Node;
043    import org.jfree.util.Configuration;
044    import org.jfree.util.ObjectUtilities;
045    
046    /**
047     * A layout controller factory that selects layout controllers by their node
048     * implementation type.
049     *
050     * @author Thomas Morgner
051     */
052    public class DefaultLayoutControllerFactory implements LayoutControllerFactory
053    {
054      private HashMap registry;
055      private static final String PREFIX = "org.jfree.report.flow.structure.";
056    
057      public DefaultLayoutControllerFactory()
058      {
059        registry = new HashMap();
060    
061      }
062    
063      public void initialize (final ReportJob job)
064      {
065        final Configuration configuration = job.getConfiguration();
066    
067        final Iterator propertyKeys =
068            configuration.findPropertyKeys(DefaultLayoutControllerFactory.PREFIX);
069        while (propertyKeys.hasNext())
070        {
071          final String key = (String) propertyKeys.next();
072          final String nodeClassName = key.substring
073              (DefaultLayoutControllerFactory.PREFIX.length());
074          final String procClassName = configuration.getConfigProperty(key);
075    
076          final Class nodeClass = load(nodeClassName);
077          final Object processor = ObjectUtilities.loadAndInstantiate
078              (procClassName, DefaultLayoutControllerFactory.class, LayoutController.class);
079          if (nodeClass == null || processor == null)
080          {
081            // sanity check ..
082            continue;
083          }
084    
085          registry.put(nodeClassName, procClassName);
086        }
087      }
088    
089      private Class load (final String className)
090      {
091        if (className == null)
092        {
093          return null;
094        }
095    
096        final ClassLoader classLoader = ObjectUtilities.getClassLoader
097            (DefaultLayoutControllerFactory.class);
098        try
099        {
100          return classLoader.loadClass(className);
101        }
102        catch (ClassNotFoundException e)
103        {
104          return null;
105        }
106      }
107    
108      public LayoutController create(final FlowController controller,
109                                     final Object node,
110                                     final LayoutController parent)
111          throws ReportProcessingException, ReportDataFactoryException, DataSourceException
112      {
113        Class nodeClass = node.getClass();
114        while (Node.class.isAssignableFrom(nodeClass))
115        {
116          final String targetClass = (String) registry.get(nodeClass.getName());
117          if (targetClass != null)
118          {
119            final LayoutController lc = (LayoutController)
120                ObjectUtilities.loadAndInstantiate (targetClass,
121                    DefaultLayoutControllerFactory.class, LayoutController.class);
122            if (lc != null)
123            {
124              lc.initialize(node, controller, parent);
125              return lc;
126            }
127          }
128          nodeClass = nodeClass.getSuperclass();
129        }
130    
131        throw new ReportProcessingException("No processor for node " + node);
132      }
133    }