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

Source Code of org.pentaho.reporting.engine.classic.core.modules.parser.extwriter.ReportDescriptionWriter

/*
* 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.extwriter;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.pentaho.reporting.engine.classic.core.Band;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.RelationalGroup;
import org.pentaho.reporting.engine.classic.core.RootLevelBand;
import org.pentaho.reporting.engine.classic.core.SubReport;
import org.pentaho.reporting.engine.classic.core.filter.DataSource;
import org.pentaho.reporting.engine.classic.core.filter.EmptyDataSource;
import org.pentaho.reporting.engine.classic.core.filter.templates.Template;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.layout.BandLayoutManager;
import org.pentaho.reporting.engine.classic.core.layout.StaticLayoutManager;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.ExtParserModule;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.base.ClassFactoryCollector;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.base.ObjectDescription;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.base.ObjectFactoryException;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.datasource.DataSourceCollector;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.templates.TemplateCollector;
import org.pentaho.reporting.engine.classic.core.modules.parser.ext.factory.templates.TemplateDescription;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleSheet;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
import org.pentaho.reporting.libraries.xmlns.common.AttributeList;
import org.pentaho.reporting.libraries.xmlns.writer.XmlWriter;
import org.pentaho.reporting.libraries.xmlns.writer.XmlWriterSupport;

/**
* A report description writer.  The {@link ReportDefinitionWriter} class is responsible for writing the complete XML
* report definition file, but it delegates one large section (the report description) to this class.
*
* @author Thomas Morgner.
*/
public class ReportDescriptionWriter extends AbstractXMLDefinitionWriter
{
  /**
   * The 'band' tag.
   */
  public static final String BAND_TAG = "band";

  /**
   * The 'element' tag.
   */
  public static final String ELEMENT_TAG = "element";


  /**
   * The 'fields' tag name.
   */
  public static final String FIELDS_TAG = "fields";

  /**
   * The 'field' tag name.
   */
  public static final String FIELD_TAG = "field";

  /**
   * The 'group-header' tag name.
   */
  public static final String GROUP_HEADER_TAG = "group-header";

  /**
   * The 'group-footer' tag name.
   */
  public static final String GROUP_FOOTER_TAG = "group-footer";

  /**
   * The 'group' tag name.
   */
  public static final String GROUP_TAG = "group";

  /**
   * The 'groups' tag name.
   */
  public static final String GROUPS_TAG = "groups";

  /**
   * The 'watermark' tag name.
   */
  public static final String WATERMARK_TAG = "watermark";

  /**
   * The report description tag name.
   */
  public static final String REPORT_DESCRIPTION_TAG = "report-description";

  /**
   * The 'report-header' tag name.
   */
  public static final String REPORT_HEADER_TAG = "report-header";

  /**
   * The 'report-footer' tag name.
   */
  public static final String REPORT_FOOTER_TAG = "report-footer";

  /**
   * The 'page-header' tag name.
   */
  public static final String PAGE_HEADER_TAG = "page-header";

  /**
   * The 'page-footer' tag name.
   */
  public static final String PAGE_FOOTER_TAG = "page-footer";

  /**
   * The 'itemband' tag name.
   */
  public static final String ITEMBAND_TAG = "itemband";
  public static final String NO_DATA_BAND_TAG = "no-data-band";

  /**
   * Creates a new report description writer.
   *
   * @param reportWriter the report writer.
   * @param indent       the current indention level.
   */
  public ReportDescriptionWriter(final ReportWriterContext reportWriter,
                                 final XmlWriter indent)
  {
    super(reportWriter, indent);
  }

  /**
   * Writes a report description element to a character stream writer.
   *
   * @throws IOException           if there is an I/O problem.
   * @throws ReportWriterException if there is a problem writing the report.
   */
  public void write()
      throws IOException, ReportWriterException
  {
    final XmlWriter writer = getXmlWriter();
    writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.REPORT_DESCRIPTION_TAG, XmlWriterSupport.OPEN);

    writeRootBand(ReportDescriptionWriter.REPORT_HEADER_TAG, getReport().getReportHeader());
    writeRootBand(ReportDescriptionWriter.REPORT_FOOTER_TAG, getReport().getReportFooter());
    writeRootBand(ReportDescriptionWriter.PAGE_HEADER_TAG, getReport().getPageHeader());
    writeRootBand(ReportDescriptionWriter.PAGE_FOOTER_TAG, getReport().getPageFooter());
    writeRootBand(ReportDescriptionWriter.WATERMARK_TAG, getReport().getWatermark());
    writeGroups();
    writeRootBand(ReportDescriptionWriter.ITEMBAND_TAG, getReport().getItemBand());
    writeRootBand(ReportDescriptionWriter.NO_DATA_BAND_TAG, getReport().getNoDataBand());

    writer.writeCloseTag();
  }

  private void writeSubReports(final RootLevelBand band)
      throws IOException, ReportWriterException
  {
    final int subReportCount = band.getSubReportCount();
    for (int i = 0; i < subReportCount; i++)
    {
      final SubReport sreport = band.getSubReport(i);
      final ReportWriterContext context =
          new ReportWriterContext(sreport, getReportWriter());
      final SubReportDefinitionWriter writer =
          new SubReportDefinitionWriter(context, getXmlWriter());
      writer.write();
    }
  }

  /**
   * Writes an element for a report band.
   *
   * @param tagName the tag name (for the band).
   * @param band    the band.
   * @throws IOException           if there is an I/O problem.
   * @throws ReportWriterException if there is a problem writing the report.
   */
  private void writeBand(final String tagName,
                         final Band band)
      throws IOException, ReportWriterException
  {
    final XmlWriter writer = getXmlWriter();
    if (band.getName().startsWith(Band.ANONYMOUS_BAND_PREFIX) ||
        band.getName().startsWith(Element.ANONYMOUS_ELEMENT_PREFIX))
    {
      writer.writeTag(ExtParserModule.NAMESPACE, tagName, XmlWriterSupport.OPEN);
    }
    else
    {
      writer.writeTag(ExtParserModule.NAMESPACE, tagName,
          "name", band.getName(), XmlWriterSupport.OPEN);
    }

    writeStyleInfo(band);

    final Element[] list = band.getElementArray();
    for (int i = 0; i < list.length; i++)
    {
      if (list[i] instanceof Band)
      {
        final Band b = (Band) list[i];
        writeBand(ReportDescriptionWriter.BAND_TAG, b);
      }
      else
      {
        writeElement(list[i]);
      }
    }

    if (band instanceof RootLevelBand)
    {
      writeSubReports((RootLevelBand) band);
    }

    writer.writeCloseTag();
  }

  private void writeStyleInfo(final Element band)
      throws IOException, ReportWriterException
  {
    final XmlWriter writer = getXmlWriter();
    final ElementStyleSheet styleSheet = band.getStyle();
    if (isStyleSheetEmpty(styleSheet) == false)
    {
      writer.writeTag(ExtParserModule.NAMESPACE, AbstractXMLDefinitionWriter.STYLE_TAG, XmlWriterSupport.OPEN);

      final StyleWriter styleWriter =
          new StyleWriter(getReportWriter(), band.getStyle(), writer);
      styleWriter.write();
      writer.writeCloseTag();
    }


    final Map styleExpressions = band.getStyleExpressions();
    final Iterator styleExpressionsIt = styleExpressions.entrySet().iterator();
    if (styleExpressionsIt.hasNext())
    {
      final FunctionsWriter fnWriter =
          new FunctionsWriter(getReportWriter(), writer);
      while (styleExpressionsIt.hasNext())
      {
        final Map.Entry entry = (Map.Entry) styleExpressionsIt.next();
        final StyleKey key = (StyleKey) entry.getKey();
        final Expression ex = (Expression) entry.getValue();
        fnWriter.writeStyleExpression(ex, key);
      }
    }
  }

  /**
   * Checks whether the given stylesheet is empty and does not inherit values from modifiable or user defined parents.
   *
   * @param es the element stylesheet to test
   * @return true, if the sheet is empty, false otherwise.
   */
  private boolean isStyleSheetEmpty(final ElementStyleSheet es)
  {
    if (es.getParents().length > 0)
    {
      return false;
    }
    final Iterator definedPropertyNames = es.getDefinedPropertyNames();
    if (definedPropertyNames.hasNext() == false)
    {
      return true;
    }
    final StyleKey name = (StyleKey) definedPropertyNames.next();
    if (BandLayoutManager.LAYOUTMANAGER.equals(name) == false)
    {
      return false;
    }

    final Object styleProperty =
        es.getStyleProperty(BandLayoutManager.LAYOUTMANAGER);
    if (styleProperty instanceof StaticLayoutManager || styleProperty == null)
    {
      if (definedPropertyNames.hasNext() == false)
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Writes an element to a character stream writer.
   *
   * @param element the element.
   * @throws IOException           if there is an I/O problem.
   * @throws ReportWriterException if there is a problem writing the report.
   */
  private void writeElement(final Element element)
      throws IOException, ReportWriterException
  {
    final AttributeList attList = new AttributeList();
    if (element.getName().startsWith(Element.ANONYMOUS_ELEMENT_PREFIX) == false)
    {
      attList.setAttribute(ExtParserModule.NAMESPACE, "name", element.getName());
    }

    final XmlWriter writer = getXmlWriter();
    writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.ELEMENT_TAG, attList, XmlWriterSupport.OPEN);

    writeStyleInfo(element);
    writeDataSourceForElement(element);

    writer.writeCloseTag();
  }

  /**
   * Writes the datasource- or template-tag for an given element.
   *
   * @param element the element, which should be written.
   * @throws ReportWriterException if there is a problem writing the report
   * @throws IOException           if there is an IO error.
   */
  protected void writeDataSourceForElement(final Element element)
      throws ReportWriterException, IOException
  {
    if ((element.getDataSource() instanceof EmptyDataSource))
    {
      return;
    }

    if (element.getDataSource() instanceof Template == false)
    {
      writeDataSource(element.getDataSource());
      return;
    }

    final TemplateCollector tc = getReportWriter().getTemplateCollector();
    final Template template = (Template) element.getDataSource();

    // the template description of the element template will get the
    // template name as its name.
    final TemplateDescription templateDescription =
        tc.getDescription(template);

    if (templateDescription == null)
    {
      throw new ReportWriterException("Unknown template type: " + template);
    }

    // create the parent description before the template description is filled.
    final TemplateDescription parentTemplate = (TemplateDescription) templateDescription.getInstance();

    try
    {
      templateDescription.setParameterFromObject(template);
    }
    catch (ObjectFactoryException ofe)
    {
      throw new ReportWriterException("Error while preparing the template", ofe);
    }

    final TemplateWriter templateWriter = new TemplateWriter
        (getReportWriter(), getXmlWriter(), templateDescription, parentTemplate);
    templateWriter.write();
  }

  /**
   * Writes a data source to a character stream writer.
   *
   * @param datasource the datasource.
   * @throws IOException           if there is an I/O problem.
   * @throws ReportWriterException if there is a problem writing the report.
   */
  private void writeDataSource(final DataSource datasource)
      throws IOException, ReportWriterException
  {
    final ReportWriterContext reportWriter = getReportWriter();
    final ClassFactoryCollector classFactoryCollector =
        reportWriter.getClassFactoryCollector();
    ObjectDescription od =
        classFactoryCollector.getDescriptionForClass(datasource.getClass());
    if (od == null)
    {
      od = classFactoryCollector.
          getSuperClassObjectDescription(datasource.getClass(), null);
    }

    if (od == null)
    {
      throw new ReportWriterException("Unable to resolve DataSource: " + datasource.getClass());
    }

    final DataSourceCollector dataSourceCollector =
        reportWriter.getDataSourceCollector();
    final String dsname = dataSourceCollector.getDataSourceName(od);
    if (dsname == null)
    {
      throw new ReportWriterException("No name for DataSource " + datasource);
    }

    final XmlWriter writer = getXmlWriter();
    writer.writeTag(ExtParserModule.NAMESPACE,
        AbstractXMLDefinitionWriter.DATASOURCE_TAG, "type", dsname, XmlWriterSupport.OPEN);

    final DataSourceWriter dsWriter =
        new DataSourceWriter(reportWriter, datasource, od, writer);
    dsWriter.write();

    writer.writeCloseTag();
  }

  /**
   * Writes groups to a character stream writer.
   * <p/>
   * 9   * @throws IOException           if there is an I/O problem.
   *
   * @throws ReportWriterException if there is a problem writing the report.
   */
  private void writeGroups()
      throws IOException, ReportWriterException
  {
    final XmlWriter writer = getXmlWriter();
    writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.GROUPS_TAG, XmlWriterSupport.OPEN);

    //logComment = true;
    final int groupSize = getReport().getGroupCount();
    for (int i = 0; i < groupSize; i++)
    {

      // todo: This is probably not correct.
      final RelationalGroup g = (RelationalGroup) getReport().getGroup(i);
      writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.GROUP_TAG,
          "name", g.getName(), XmlWriterSupport.OPEN);

      final List fields = g.getFields();
      if (fields.isEmpty() == false)
      {
        writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.FIELDS_TAG, XmlWriterSupport.OPEN);

        for (int f = 0; f < fields.size(); f++)
        {
          final String field = (String) fields.get(f);
          writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.FIELD_TAG, XmlWriterSupport.OPEN);
          writer.writeTextNormalized(field, false);
          writer.writeCloseTag();
        }
        writer.writeCloseTag();
      }
      else
      {
        writer.writeTag(ExtParserModule.NAMESPACE, ReportDescriptionWriter.FIELDS_TAG, XmlWriterSupport.CLOSE);
      }

      writeRootBand(ReportDescriptionWriter.GROUP_HEADER_TAG, g.getHeader());
      writeRootBand(ReportDescriptionWriter.GROUP_FOOTER_TAG, g.getFooter());

      writer.writeCloseTag();
    }

    writer.writeCloseTag();
  }

  private void writeRootBand(final String tag,
                             final Band band)
      throws IOException, ReportWriterException
  {
    if (isEmptyRootBand(band))
    {
      return;
    }
    writeBand(tag, band);
  }

  private boolean isEmptyRootBand(final Band band)
  {
    if (band.getName().startsWith(Band.ANONYMOUS_BAND_PREFIX) == false)
    {
      return false;
    }
    if (band.getName().startsWith(Element.ANONYMOUS_ELEMENT_PREFIX) == false)
    {
      return false;
    }
    if (band.getElementCount() != 0)
    {
      return false;
    }
    if (band instanceof RootLevelBand)
    {
      final RootLevelBand rlb = (RootLevelBand) band;
      if (rlb.getSubReportCount() > 0)
      {
        return false;
      }
    }
    final ElementStyleSheet styleSheet = band.getStyle();
    if (isStyleSheetEmpty(styleSheet))
    {
      return true;
    }
    return false;
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.parser.extwriter.ReportDescriptionWriter

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.