Package org.pentaho.reporting.engine.classic.core.modules.parser.base

Source Code of org.pentaho.reporting.engine.classic.core.modules.parser.base.ReportGenerator

/*
* 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 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.parser.base;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;

import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.util.MemoryByteArrayOutputStream;
import org.pentaho.reporting.libraries.base.util.IOUtils;
import org.pentaho.reporting.libraries.resourceloader.FactoryParameterKey;
import org.pentaho.reporting.libraries.resourceloader.Resource;
import org.pentaho.reporting.libraries.resourceloader.ResourceCreationException;
import org.pentaho.reporting.libraries.resourceloader.ResourceException;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
import org.pentaho.reporting.libraries.resourceloader.ResourceLoadingException;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
import org.xml.sax.InputSource;

/**
* The reportgenerator initializes the parser and provides an interface the the default parser.
* <p/>
* To create a report from an URL, use <code> ReportGenerator.getInstance().parseReport (URL myURl, URL contentBase);
* </code>
*
* @author Thomas Morgner
* @deprecated Use LibLoader directly.
*/
public class ReportGenerator
{
  /**
   * Enable DTD validation of the parsed XML.
   */
  public static final String PARSER_VALIDATE_KEY
      = "org.pentaho.reporting.engine.classic.core.modules.parser.base.Validate";

  /**
   * disable DTD validation by default.
   */
  public static final boolean PARSER_VALIDATE_DEFAULT = true;

  /**
   * The report generator.
   */
  private static ReportGenerator generator;

  private HashMap helperObjects;
  private boolean validateDTD;

  /**
   * Creates a new report generator. The generator uses the singleton pattern by default, so use generator.getInstance()
   * to get the generator.
   */
  protected ReportGenerator()
  {
    helperObjects = new HashMap();
  }

  /**
   * Set to false, to globaly disable the xml-validation.
   *
   * @param validate true, if the parser should validate the xml files.
   */
  public void setValidateDTD(final boolean validate)
  {
    this.validateDTD = validate;
  }

  /**
   * returns true, if the parser should validate the xml files against the DTD supplied with JFreeReport.
   *
   * @return true, if the parser should validate, false otherwise.
   */
  public boolean isValidateDTD()
  {
    return validateDTD;
  }


  /**
   * Parses a report using the given parameter as filename and the directory containing the file as content base.
   *
   * @param file the file name.
   * @return the report.
   * @throws java.io.IOException if an I/O error occurs.
   */
  public MasterReport parseReport(final String file)
      throws IOException, ResourceException
  {
    if (file == null)
    {
      throw new NullPointerException("File may not be null");
    }

    return parseReport(new File(file));
  }

  /**
   * Parses an XML file which is loaded using the given URL. All needed relative file- and resourcespecification are
   * loaded using the URL <code>file</code> as base.
   *
   * @param file the URL for the report template file.
   * @return the report.
   * @throws java.io.IOException if an I/O error occurs.
   */
  public MasterReport parseReport(final URL file)
      throws IOException, ResourceException
  {
    return parseReport(file, file);
  }

  /**
   * Parses an XML file which is loaded using the given URL. All needed relative file- and resourcespecification are
   * loaded using the URL <code>contentBase</code> as base.
   * <p/>
   * After the report is generated, the ReportDefinition-source and the contentbase are stored as string in the
   * reportproperties.
   *
   * @param file        the URL for the report template file.
   * @param contentBase the URL for the report template content base.
   * @return the parsed report.
   */
  public MasterReport parseReport(final URL file, final URL contentBase)
      throws ResourceException
  {
    return parse(file, contentBase);
  }

  /**
   * Parses the report from a given URL.
   *
   * @param file        the report definition location.
   * @param contentBase the report's context (used to load content that has been referenced with relative URLs).
   * @return the parsed report.
   * @throws ResourceException if parsing or loading failed for some reason.
   */
  private MasterReport parse(final URL file, final URL contentBase)
      throws ResourceException
  {
    final ResourceManager resourceManager = new ResourceManager();
    resourceManager.registerDefaults();

    final ResourceKey contextKey = resourceManager.createKey(contentBase);

    // Build the main key. That key also contains all context/parse-time
    // parameters as they will influence the resulting report. It is not
    // wise to keep caching independent from that.
    final HashMap map = new HashMap();
    final Iterator it = this.helperObjects.keySet().iterator();
    while (it.hasNext())
    {
      final String name = (String) it.next();
      map.put(new FactoryParameterKey(name), helperObjects.get(name));
    }

    final ResourceKey key = resourceManager.createKey(file, map);
    final Resource resource = resourceManager.create(key, contextKey, MasterReport.class);
    return (MasterReport) resource.getResource();
  }

  /**
   * @noinspection IOResourceOpenedButNotSafelyClosed
   */
  private byte[] extractData(final InputSource input) throws IOException
  {
    final InputStream byteStream = input.getByteStream();
    if (byteStream != null)
    {
      try
      {
        final MemoryByteArrayOutputStream bout = new MemoryByteArrayOutputStream();
        IOUtils.getInstance().copyStreams(byteStream, bout);
        return bout.toByteArray();
      }
      finally
      {
        byteStream.close();
      }
    }

    final Reader characterStream = input.getCharacterStream();
    if (characterStream == null)
    {
      throw new IOException
          ("InputSource has neither an Byte nor a CharacterStream");
    }

    try
    {
      final MemoryByteArrayOutputStream bout = new MemoryByteArrayOutputStream();
      final OutputStreamWriter owriter = new OutputStreamWriter(bout);
      IOUtils.getInstance().copyWriter(characterStream, owriter);
      owriter.close();
      return bout.toByteArray();
    }
    finally
    {
      characterStream.close();
    }
  }

  /**
   * Parses an XML file which is loaded using the given file. All needed relative file- and resourcespecification are
   * loaded using the parent directory of the file <code>file</code> as base.
   *
   * @param file the report template file.
   * @return the parsed report.
   * @throws java.io.IOException if an I/O error occurs.
   */
  public MasterReport parseReport(final File file)
      throws IOException, ResourceException
  {
    if (file == null)
    {
      throw new NullPointerException();
    }
    if (file.isDirectory())
    {
      throw new IOException("File is not a directory.");
    }
    final File contentBase = file.getCanonicalFile().getParentFile();
    final ResourceManager resourceManager = new ResourceManager();
    resourceManager.registerDefaults();

    final ResourceKey contextKey = resourceManager.createKey(contentBase);

    // Build the main key. That key also contains all context/parse-time
    // parameters as they will influence the resulting report. It is not
    // wise to keep caching independent from that.
    final HashMap map = new HashMap();
    final Iterator it = this.helperObjects.keySet().iterator();
    while (it.hasNext())
    {
      final String name = (String) it.next();
      map.put(new FactoryParameterKey(name), helperObjects.get(name));
    }

    final ResourceKey key = resourceManager.createKey(file, map);
    final Resource resource = resourceManager.create(key, contextKey, MasterReport.class);
    return (MasterReport) resource.getResource();
  }

  /**
   * Parses the report from a given SAX-InputSource.
   *
   * @param input       the report definition location.
   * @param contentBase the report's context (used to load content that has been referenced with relative URLs).
   * @return the parsed report.
   * @throws ResourceException if parsing or loading failed for some reason.
   * @throws IOException       if an IO-related error occurs.
   */
  public MasterReport parseReport(final InputSource input, final URL contentBase)
      throws IOException, ResourceException
  {
    if (input.getCharacterStream() != null)
    {
      // Sourceforge Bug #1712734. We cannot safely route the character-stream through libloader.
      // Therefore we skip libloader and parse the report directly. This is for backward compatibility,
      // all other xml-based objects will still rely on LibLoader.

      return parseReportDirectly(input, contentBase);
    }

    final byte[] bytes = extractData(input);
    final ResourceManager resourceManager = new ResourceManager();
    resourceManager.registerDefaults();

    final ResourceKey contextKey;
    if (contentBase != null)
    {
      contextKey = resourceManager.createKey(contentBase);
    }
    else
    {
      contextKey = null;
    }
    final HashMap map = new HashMap();

    final Iterator it = this.helperObjects.keySet().iterator();
    while (it.hasNext())
    {
      final String name = (String) it.next();
      map.put(new FactoryParameterKey(name), helperObjects.get(name));
    }

    final ResourceKey key = resourceManager.createKey(bytes, map);
    final Resource resource = resourceManager.create(key, contextKey, MasterReport.class);
    return (MasterReport) resource.getResource();
  }

  private MasterReport parseReportDirectly(final InputSource input, final URL contentBase)
      throws ResourceKeyCreationException, ResourceCreationException, ResourceLoadingException
  {
    final ResourceManager manager = new ResourceManager();
    manager.registerDefaults();

    final HashMap map = new HashMap();

    final Iterator it = this.helperObjects.keySet().iterator();
    while (it.hasNext())
    {
      final String name = (String) it.next();
      map.put(new FactoryParameterKey(name), helperObjects.get(name));
    }

    final MasterReportXmlResourceFactory resourceFactory = new MasterReportXmlResourceFactory();
    resourceFactory.initializeDefaults();
    if (contentBase != null)
    {
      return (MasterReport) resourceFactory.parseDirectly(manager, input, manager.createKey(contentBase), map);
    }
    else
    {
      return (MasterReport) resourceFactory.parseDirectly(manager, input, null, map);
    }
  }

  /**
   * Parses the report using the provided resource manager.
   *
   * @param manager    the resource manager (can be null).
   * @param input      the resource key pointing to the report definition.
   * @param contextKey the report's context (used to load content that has been referenced with relative URLs).
   * @return the parsed report.
   * @throws ResourceException if parsing or loading failed for some reason.
   */
  public MasterReport parseReport(ResourceManager manager,
                                  final ResourceKey input,
                                  final ResourceKey contextKey)
      throws ResourceException
  {
    if (manager == null)
    {
      manager = new ResourceManager();
      manager.registerDefaults();
    }

    final HashMap map = new HashMap(input.getFactoryParameters());
    final Iterator it = this.helperObjects.keySet().iterator();
    while (it.hasNext())
    {
      final String name = (String) it.next();
      map.put(new FactoryParameterKey(name), helperObjects.get(name));
    }

    final ResourceKey key = new ResourceKey(input.getParent(),
        input.getSchema(), input.getIdentifier(), input.getFactoryParameters());
    final Resource resource = manager.create(key, contextKey, MasterReport.class);
    return (MasterReport) resource.getResource();
  }

  /**
   * Returns a single shared instance of the <code>ReportGenerator</code>. This instance cannot add helper objects to
   * configure the report parser.
   *
   * @return The shared report generator.
   */
  public static synchronized ReportGenerator getInstance()
  {
    if (generator == null)
    {
      generator = new ReportGenerator();
    }
    return generator;
  }

  /**
   * Returns a private (non-shared) instance of the <code>ReportGenerator</code>. Use this instance when defining helper
   * objects.
   *
   * @return The shared report generator.
   */
  public static ReportGenerator createInstance()
  {
    return new ReportGenerator();
  }

  /**
   * Assigns a parse-context object.
   *
   * @param key   the parse-context key used to lookup the object later.
   * @param value the value.
   */
  public void setObject(final String key, final Object value)
  {
    if (key == null)
    {
      throw new NullPointerException();
    }
    if (value == null)
    {
      helperObjects.remove(key);
    }
    else
    {
      helperObjects.put(key, value);
    }
  }

  /**
   * Returns the parse context object for the given key.
   *
   * @param key the key.
   * @return the value or null if there is no such value.
   */
  public Object getObject(final String key)
  {
    return helperObjects.get(key);
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.parser.base.ReportGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.