Package org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.helper

Source Code of org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.helper.RTFPrinter

/*
* 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.output.table.rtf.helper;

import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;

import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Rectangle;
import com.lowagie.text.Table;
import com.lowagie.text.rtf.RtfWriter2;
import com.lowagie.text.rtf.table.RtfBorder;
import com.lowagie.text.rtf.table.RtfCell;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.ClassicEngineInfo;
import org.pentaho.reporting.engine.classic.core.ElementAlignment;
import org.pentaho.reporting.engine.classic.core.InvalidReportStateException;
import org.pentaho.reporting.engine.classic.core.layout.model.BorderEdge;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.PhysicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderBox;
import org.pentaho.reporting.engine.classic.core.layout.output.ContentProcessingException;
import org.pentaho.reporting.engine.classic.core.layout.output.LogicalPageKey;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorFeature;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.AbstractTableOutputProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.CellBackground;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.CellBackgroundProducer;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.SheetLayout;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.TableContentProducer;
import org.pentaho.reporting.engine.classic.core.style.BorderStyle;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleKeys;
import org.pentaho.reporting.engine.classic.core.util.NoCloseOutputStream;
import org.pentaho.reporting.engine.classic.core.util.geom.StrictGeomUtility;
import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;

/**
* Creation-Date: 09.05.2007, 14:52:05
*
* @author Thomas Morgner
*/
public class RTFPrinter
{
  private static final Log logger = LogFactory.getLog(RTFPrinter.class);

  private static final String CREATOR =
      ClassicEngineInfo.getInstance().getName() + " version " +
          ClassicEngineInfo.getInstance().getVersion();

  private OutputStream outputStream;
  private Configuration config;
  private ResourceManager resourceManager;
  private RTFImageCache imageCache;
  private Document document;
  private Table table;
  private CellBackgroundProducer cellBackgroundProducer;

  public RTFPrinter()
  {
  }

  public void init(final Configuration config,
                   final OutputStream outputStream,
                   final ResourceManager resourceManager)
  {
    this.outputStream = outputStream;
    this.config = config;
    this.resourceManager = resourceManager;
  }

  /**
   * @noinspection IOResourceOpenedButNotSafelyClosed
   */
  public void print(final LogicalPageKey logicalPageKey,
                    final LogicalPageBox logicalPage,
                    final TableContentProducer contentProducer,
                    final RTFOutputProcessorMetaData metaData,
                    final boolean incremental)
      throws ContentProcessingException
  {
    if (document == null)
    {
      this.cellBackgroundProducer = new CellBackgroundProducer
          (metaData.isFeatureSupported(AbstractTableOutputProcessor.TREAT_ELLIPSE_AS_RECTANGLE),
            metaData.isFeatureSupported(OutputProcessorFeature.UNALIGNED_PAGEBANDS));

      final PhysicalPageBox pageFormat = logicalPage.getPageGrid().getPage(0, 0);
      final float urx = (float) StrictGeomUtility.toExternalValue(pageFormat.getWidth());
      final float ury = (float) StrictGeomUtility.toExternalValue(pageFormat.getHeight());

      final float marginLeft = (float) StrictGeomUtility.toExternalValue(pageFormat.getImageableX());
      final float marginRight =
          (float) StrictGeomUtility.toExternalValue(pageFormat.getWidth()
              - pageFormat.getImageableWidth() - pageFormat.getImageableX());
      final float marginTop = (float) StrictGeomUtility.toExternalValue(pageFormat.getImageableY());
      final float marginBottom =
          (float) StrictGeomUtility.toExternalValue(pageFormat.getHeight()
              - pageFormat.getImageableHeight() - pageFormat.getImageableY());
      final Rectangle pageSize = new Rectangle(urx, ury);

      document = new Document(pageSize, marginLeft, marginRight, marginTop, marginBottom);
      imageCache = new RTFImageCache(resourceManager);

      // rtf does not support PageFormats or other meta data...
      final RtfWriter2 instance = RtfWriter2.getInstance(document, new NoCloseOutputStream(outputStream));
      instance.getDocumentSettings().setAlwaysUseUnicode(true);

      final String author = config.getConfigProperty
          ("org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.Author");
      if (author != null)
      {
        document.addAuthor(author);
      }

      final String title = config.getConfigProperty(
          "org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.Title");
      if (title != null)
      {
        document.addTitle(title);
      }

      document.addProducer();
      document.addCreator(RTFPrinter.CREATOR);

      try
      {
        document.addCreationDate();
      }
      catch (Exception e)
      {
        RTFPrinter.logger.debug("Unable to add creation date. It will have to work without it.", e);
      }

      document.open();
    }

    // Start a new page.
    try
    {
      final SheetLayout sheetLayout = contentProducer.getSheetLayout();
      final int columnCount = contentProducer.getColumnCount();
      if (table == null)
      {
        final int rowCount = contentProducer.getRowCount();
        table = new Table(columnCount, rowCount);
        table.setAutoFillEmptyCells(false);
        table.setWidth(100); // span the full page..
        // and finally the content ..

        final float[] cellWidths = new float[columnCount];
        for (int i = 0; i < columnCount; i++)
        {
          cellWidths[i] = (float) StrictGeomUtility.toExternalValue(sheetLayout.getCellWidth(i, i + 1));
        }
        table.setWidths(cellWidths);
      }

      final int startRow = contentProducer.getFinishedRows();
      final int finishRow = contentProducer.getFilledRows();
      //logger.debug ("Processing: " + startRow + " " + finishRow + " " + incremental);

      for (int row = startRow; row < finishRow; row++)
      {
        for (short col = 0; col < columnCount; col++)
        {
          final RenderBox content = contentProducer.getContent(row, col);
          final int sectionType = contentProducer.getSectionType(row, col);

          if (content == null)
          {
            final CellBackground background = cellBackgroundProducer.getBackgroundAt
                (logicalPage, sheetLayout, col, row, false, sectionType);
            if (background == null)
            {
              // An empty cell .. ignore
              final RtfCell cell = new RtfCell();
              cell.setBorderWidth(0);
              table.addCell(cell, row, col);
              continue;
            }

            // A empty cell with a defined background ..
            final RtfCell cell = new RtfCell();
            cell.setBorderWidth(0);
            updateCellStyle(cell, background);
            table.addCell(cell, row, col);
            continue;
          }

          if (content.isCommited() == false)
          {
            throw new InvalidReportStateException("Uncommited content encountered");
          }

          final long contentOffset = contentProducer.getContentOffset(row, col);
          final long colPos = sheetLayout.getXPosition(col);
          final long rowPos = sheetLayout.getYPosition(row);
          if (content.getX() != colPos || (content.getY() + contentOffset) != rowPos)
          {
            // A spanned cell ..
            continue;
          }

          final int colSpan = sheetLayout.getColSpan(col, content.getX() + content.getWidth());
          final int rowSpan = sheetLayout.getRowSpan(row, content.getY() + content.getHeight() + contentOffset);

          final CellBackground realBackground = cellBackgroundProducer.getBackgroundAt
              (logicalPage, sheetLayout, col, row, colSpan, rowSpan, false, sectionType);

          final Cell cell = new Cell();
          cell.setRowspan(rowSpan);
          cell.setColspan(colSpan);
          cell.setBorderWidth(0);
          // Sadly RTF-Cell does not provide a setter for the row-span. Therefore we have to "import" a plain cell
          // for that. The design of the iText RTF writer seems to be seriously flawed here ..
          if (realBackground != null)
          {
            updateCellStyle(cell, realBackground);
          }

          computeCellStyle(content, cell);

          // export the cell and all content ..
          final RTFTextExtractor etx = new RTFTextExtractor(metaData);
          etx.compute(content, cell, imageCache);

          table.addCell(cell, row, col);
          content.setFinished(true);
          //logger.debug("set Finished to cell (" + col + ", " + row + "," + content.getName() + ")");
        }

      }

      if (incremental == false)
      {
        document.add(table);
        table = null;
      }
    }
    catch (DocumentException e)
    {
      throw new ContentProcessingException("Failed to generate RTF-Document", e);
    }
  }

  private void computeCellStyle(final RenderBox content, final Cell cell)
  {
    final ElementAlignment verticalAlign = content.getNodeLayoutProperties().getVerticalAlignment();
    if (ElementAlignment.BOTTOM.equals(verticalAlign))
    {
      cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
    }
    else if (ElementAlignment.MIDDLE.equals(verticalAlign))
    {
      cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
    }
    else
    {
      cell.setVerticalAlignment(Element.ALIGN_TOP);
    }

    final ElementAlignment textAlign = (ElementAlignment)
        content.getStyleSheet().getStyleProperty(ElementStyleKeys.ALIGNMENT);
    if (ElementAlignment.RIGHT.equals(textAlign))
    {
      cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
    }
    else if (ElementAlignment.CENTER.equals(textAlign))
    {
      cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    }
    else
    {
      cell.setHorizontalAlignment(Element.ALIGN_LEFT);
    }
  }

  public void close()
  {
    if (document != null)
    {
      // cleanup..
      document.close();
      try
      {
        outputStream.flush();
      }
      catch (IOException e)
      {
        RTFPrinter.logger.info("Failed to flush the RTF-Output stream.");
      }
      finally
      {
        document = null;
      }
    }
  }

  private int translateBorderStyle(final BorderStyle borderStyle)
  {
    if (BorderStyle.DASHED.equals(borderStyle))
    {
      return RtfBorder.BORDER_DASHED;
    }
    if (BorderStyle.DOT_DASH.equals(borderStyle))
    {
      return RtfBorder.BORDER_DOT_DASH;
    }
    if (BorderStyle.DOT_DOT_DASH.equals(borderStyle))
    {
      return RtfBorder.BORDER_DOT_DOT_DASH;
    }
    if (BorderStyle.DOTTED.equals(borderStyle))
    {
      return RtfBorder.BORDER_DOTTED;
    }
    if (BorderStyle.DOUBLE.equals(borderStyle))
    {
      return RtfBorder.BORDER_DOUBLE;
    }
    if (BorderStyle.HIDDEN.equals(borderStyle))
    {
      return RtfBorder.BORDER_NONE;
    }
    if (BorderStyle.NONE.equals(borderStyle))
    {
      return RtfBorder.BORDER_NONE;
    }
    if (BorderStyle.GROOVE.equals(borderStyle))
    {
      return RtfBorder.BORDER_ENGRAVE;
    }
    if (BorderStyle.RIDGE.equals(borderStyle))
    {
      return RtfBorder.BORDER_EMBOSS;
    }
    if (BorderStyle.INSET.equals(borderStyle))
    {
      return RtfBorder.BORDER_SINGLE;
    }
    if (BorderStyle.OUTSET.equals(borderStyle))
    {
      return RtfBorder.BORDER_SINGLE;
    }
    if (BorderStyle.SOLID.equals(borderStyle))
    {
      return RtfBorder.BORDER_SINGLE;
    }
    if (BorderStyle.WAVE.equals(borderStyle))
    {
      return RtfBorder.BORDER_WAVY;
    }
    return RtfBorder.BORDER_NONE;
  }

  private void updateCellStyle(final Cell cell, final CellBackground background)
  {

    final Color backgroundColor = background.getBackgroundColor();
    if (backgroundColor != null)
    {
      cell.setBackgroundColor(backgroundColor);
    }
    final BorderEdge top = background.getTop();
    if (BorderEdge.EMPTY.equals(top) == false)
    {
      cell.setBorderColorTop(top.getColor());
      cell.setBorderWidthTop((float) StrictGeomUtility.toExternalValue(top.getWidth()));
    }

    final BorderEdge left = background.getLeft();
    if (BorderEdge.EMPTY.equals(left) == false)
    {
      cell.setBorderColorLeft(left.getColor());
      cell.setBorderWidthLeft((float) StrictGeomUtility.toExternalValue(left.getWidth()));
    }

    final BorderEdge bottom = background.getBottom();
    if (BorderEdge.EMPTY.equals(bottom) == false)
    {
      cell.setBorderColorBottom(bottom.getColor());
      cell.setBorderWidthBottom((float) StrictGeomUtility.toExternalValue(bottom.getWidth()));
    }

    final BorderEdge right = background.getRight();
    if (BorderEdge.EMPTY.equals(right) == false)
    {
      cell.setBorderColorRight(right.getColor());
      cell.setBorderWidthRight((float) StrictGeomUtility.toExternalValue(right.getWidth()));
    }
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.helper.RTFPrinter

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.