Package org.pentaho.reporting.engine.classic.core.modules.parser.bundle.writer

Source Code of org.pentaho.reporting.engine.classic.core.modules.parser.bundle.writer.ResourceWriter

/*
* 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) 2009 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.parser.bundle.writer;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
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.metadata.AttributeMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementMetaData;
import org.pentaho.reporting.engine.classic.core.modules.parser.ClassicEngineFactoryParameters;
import org.pentaho.reporting.libraries.base.util.IOUtils;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.docbundle.BundleUtilities;
import org.pentaho.reporting.libraries.docbundle.WriteableDocumentBundle;
import org.pentaho.reporting.libraries.docbundle.WriteableDocumentBundleUtils;
import org.pentaho.reporting.libraries.repository.DefaultMimeRegistry;
import org.pentaho.reporting.libraries.repository.MimeRegistry;
import org.pentaho.reporting.libraries.resourceloader.ResourceData;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.loader.raw.RawResourceLoader;

/**
* A handler that writes resources into the document bundle based on the resource keys found inside the report definition.
*
* @author David Kincade
*/
public class ResourceWriter implements BundleWriterHandler
{
  // The logger used in this class
  private static final Log log = LogFactory.getLog(ResourceWriter.class);

  public ResourceWriter()
  {
  }

  /**
   * Returns a relatively low ing order indicating this BundleWriterHandler should be one of the first processed.
   * This is due to the fact that any Resource which is writen into the DocumentBundle will cause the report's
   * definition to be modified with a new Resource Key.
   *
   * @return the relative processing order for this BundleWriterHandler
   */
  public int getProcessingOrder()
  {
    return 0;
  }

  /**
   * Writes a certain aspect into a own file. The name of file inside the bundle is returned as string. The file name
   * returned is always absolute and can be made relative by using the IOUtils of LibBase. If the writer-handler did not
   * generate a file on its own, it should return null.
   *
   * @param bundle the bundle where to write to.
   * @param state  the writer state to hold the current processing information.
   * @return the name of the newly generated file or null if no file was created.
   * @throws IOException           if any error occured
   * @throws BundleWriterException if a bundle-management error occured.
   */
  public String writeReport(final WriteableDocumentBundle bundle,
                            final BundleWriterState state) throws IOException, BundleWriterException
  {
    BundleUtilities.copyStickyInto(bundle, state.getGlobalBundle());

    // Process all nodes starting at the top
    processSection(bundle, state.getMasterReport(), state.getMasterReport());

    // Don't return anything ... we may have created none-or-more files
    return null;
  }

  private void processSection(final WriteableDocumentBundle documentBundle,
                              final MasterReport report,
                              final Section section) throws BundleWriterException
  {
    final int count = section.getElementCount();
    for (int i = 0; i < count; i++)
    {
      final ReportElement element = section.getElement(i);
      if (element instanceof Section)
      {
        processSection(documentBundle, report, (Section) element);
      }

      if (element instanceof RootLevelBand)
      {
        final RootLevelBand rl = (RootLevelBand) element;
        final SubReport[] reports = rl.getSubReports();
        for (int j = 0; j < reports.length; j++)
        {
          final SubReport subReport = reports[j];
          processSection(documentBundle, report, subReport);
        }
      }

      // Process the attributes if they are a resource key
      final ElementMetaData metaData = element.getMetaData();
      final AttributeMetaData[] attributeDescriptions = metaData.getAttributeDescriptions();
      for (int j = 0; j < attributeDescriptions.length; j++)
      {
        final AttributeMetaData attributeDescription = attributeDescriptions[j];
        if ("Resource".equals(attributeDescription.getValueRole()) == false)
        {
          continue;
        }

        final Object attribute = element.getAttribute(attributeDescription.getNameSpace(), attributeDescription.getName());
        if (attribute instanceof ResourceKey == false)
        {
          continue;
        }

        final ResourceKey resourceKey = (ResourceKey) attribute;
        final ResourceKey replacementKey = processResourceKeyAttribute(documentBundle, report, resourceKey);
        if (replacementKey != null)
        {
          element.setAttribute(attributeDescription.getNameSpace(), attributeDescription.getName(), replacementKey);
        }
      }
    }
  }

  /**
   * Processes the resource key to see if it refers to a resource which should be embedded. If it should be embedded,
   * the data will be embedded and a replacement resource key will be generated.
   *
   * @param documentBundle the document budle in which the resources will be embedded
   * @param resourceKey    the resource key which may refer to a resource which should be embedded
   * @return a resource key which should replace the key passed in
   * @throws BundleWriterException indicates an error trying to embed the resource into the document bundle
   */
  private static ResourceKey processResourceKeyAttribute(final WriteableDocumentBundle documentBundle,
                                                         final MasterReport report,
                                                         final ResourceKey resourceKey) throws BundleWriterException
  {
    // See if this key is already embedded
    if (documentBundle.isEmbeddedKey(resourceKey))
    {
      return null;
    }

    final boolean embedded = isEmbeddedKey(report, resourceKey);
    final DefaultMimeRegistry mimeRegistry = new DefaultMimeRegistry();

    // Determine if this key should be embedded
    final Map factoryParameters = resourceKey.getFactoryParameters();
    if (embedded == false &&
        "true".equals(factoryParameters.get(ClassicEngineFactoryParameters.EMBED)) == false &&
        RawResourceLoader.SCHEMA_NAME.equals(resourceKey.getSchema()) == false)
    {
      return null;
    }

    try
    {
      // Embed the key into the document bundle
      String mimeType = (String) factoryParameters.get(ClassicEngineFactoryParameters.MIME_TYPE);
      final String originalValue = (String) factoryParameters.get(ClassicEngineFactoryParameters.ORIGINAL_VALUE);
      if (mimeType == null)
      {
        final ResourceData resourceData = report.getResourceManager().load(resourceKey);
        final Object originalMimeType = resourceData.getAttribute(ResourceData.CONTENT_TYPE);
        if (originalMimeType instanceof String)
        {
          mimeType = (String) originalMimeType;
        }
        else
        {
          mimeType = mimeRegistry.getMimeType(originalValue);
        }
      }

      String pattern = (String) factoryParameters.get(ClassicEngineFactoryParameters.PATTERN);
      if (pattern == null)
      {
        pattern = derivePatternFromPath(mimeRegistry, mimeType, resourceKey.getIdentifierAsString());
      }

      log.debug("Embedding resource : originalValue=[" + originalValue + "] pattern=[" + pattern + "] mimeType=[" + mimeType + "]");

      // Clean up the factory parameters - we are only keeping the Original Value parameter
      Map newFactoryParameters = null;
      if (originalValue != null)
      {
        newFactoryParameters = new HashMap();
        newFactoryParameters.put(ClassicEngineFactoryParameters.ORIGINAL_VALUE, originalValue);
      }

      // Embed the resource
      final ResourceKey newResourceKey = WriteableDocumentBundleUtils.embedResource
          (documentBundle, report.getResourceManager(), resourceKey, pattern, mimeType, newFactoryParameters);
      if (log.isDebugEnabled())
      {
        log.debug("Resouce Embedded: [" + newResourceKey.getIdentifierAsString() + "]");
      }
      return newResourceKey;
    }
    catch (Exception e)
    {
      throw new BundleWriterException("Error embedding the resource into the document bundle: " + e.getMessage(), e);
    }
  }

  public static boolean isEmbeddedKey(final MasterReport report, final ResourceKey resourceKey)
  {
    final ResourceKey contentBase = report.getContentBase();
    if (contentBase == null)
    {
      return false;
    }

    ResourceKey bundleKey = contentBase.getParent();
    while (bundleKey != null)
    {
      if (bundleKey.equals(resourceKey.getParent()))
      {
        return true;
      }
      bundleKey = bundleKey.getParent();
    }
    return false;
  }

  public static String derivePatternFromPath(final MimeRegistry mimeRegistry,
                                             final String mimeType, final String path)
  {
    if (mimeType == null)
    {
      throw new NullPointerException();
    }
    if (path == null)
    {
      if (mimeType.startsWith("image/"))
      {
        return "resources/image{0}." + mimeRegistry.getSuffix(mimeType);
      }
      else
      {
        return "resources/data{0}." + mimeRegistry.getSuffix(mimeType);
      }
    }

    final String directory = IOUtils.getInstance().getPath(path);
    final String fileNameWExt = IOUtils.getInstance().getFileName(path);
    String fileExtension = IOUtils.getInstance().getFileExtension(fileNameWExt);
    if (StringUtils.isEmpty(fileExtension))
    {
      fileExtension = "." + mimeRegistry.getSuffix(mimeType);
    }
    final String fileName = IOUtils.getInstance().stripFileExtension(fileNameWExt);
    String pattern = stripTrailingNumbers(fileName);
    if (pattern == null)
    {
      if (mimeType.startsWith("image/"))
      {
        pattern = "image{0}";
      }
      else
      {
        pattern = "data{0}";
      }
    }
    else
    {
      pattern = pattern + "{0}";
    }

    return directory + "/" + pattern + fileExtension;
  }

  private static String stripTrailingNumbers(final String path)
  {
    for (int i = path.length() - 1; i >= 0; i--)
    {
      if (Character.isDigit(path.charAt(i)) == false)
      {
        return path.substring(0, i + 1);
      }
    }
    // if its empty or all numbers, return null.
    return null;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.parser.bundle.writer.ResourceWriter

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.