/**
  * Reads an external module description. This describes either an optional or a required module.
  *
  * @param reader the reader from where to read the module
  * @param prefix the property-key prefix.
  * @return the read module, never null
  */
 private DefaultModuleInfo readExternalModule(final Configuration reader, final String prefix) {
   final DefaultModuleInfo mi = new DefaultModuleInfo();
   mi.setModuleClass(reader.getConfigProperty(prefix + ".module"));
   mi.setMajorVersion(reader.getConfigProperty(prefix + ".version.major"));
   mi.setMinorVersion(reader.getConfigProperty(prefix + ".version.minor"));
   mi.setPatchLevel(reader.getConfigProperty(prefix + ".version.patchlevel"));
   return mi;
 }
  /** Initializes the Swing components of this dialog. */
  private void initialize() {
    cbxWriteStateColumns =
        new JCheckBox(
            getResources().getString("csvexportdialog.write-state-columns")); // $NON-NLS-1$
    cbxColumnNamesAsFirstRow =
        new JCheckBox(
            getResources().getString("cvsexportdialog.export.columnnames")); // $NON-NLS-1$

    getFormValidator().registerButton(cbxColumnNamesAsFirstRow);
    cbxEnableReportHeader =
        new JCheckBox(
            getResources().getString("csvexportdialog.enable-report-header")); // $NON-NLS-1$
    cbxEnableReportFooter =
        new JCheckBox(
            getResources().getString("csvexportdialog.enable-report-footer")); // $NON-NLS-1$
    cbxEnableItemband =
        new JCheckBox(getResources().getString("csvexportdialog.enable-itemband")); // $NON-NLS-1$
    cbxEnableGroupHeader =
        new JCheckBox(
            getResources().getString("csvexportdialog.enable-group-header")); // $NON-NLS-1$
    cbxEnableGroupFooter =
        new JCheckBox(
            getResources().getString("csvexportdialog.enable-group-footer")); // $NON-NLS-1$

    getFormValidator().registerButton(cbxEnableGroupFooter);
    getFormValidator().registerButton(cbxEnableGroupHeader);
    getFormValidator().registerButton(cbxEnableItemband);
    getFormValidator().registerButton(cbxEnableReportFooter);
    getFormValidator().registerButton(cbxEnableReportHeader);

    txFilename = new JTextField();
    txFilename.setColumns(30);
    encodingModel = EncodingComboBoxModel.createDefaultModel(Locale.getDefault());
    encodingModel.sort();
    cbEncoding = new JComboBox(encodingModel);

    final JPanel exportPane = createExportPane();

    final JTabbedPane tabbedPane = new JTabbedPane();
    tabbedPane.add(
        getResources().getString("csvexportdialog.export-settings"), exportPane); // $NON-NLS-1$
    tabbedPane.add(
        getResources().getString("csvexportdialog.parameters"),
        getParametersPanel()); //$NON-NLS-1$
    final Configuration config = ClassicEngineBoot.getInstance().getGlobalConfig();
    if ("true"
        .equals(
            config.getConfigProperty(
                "org.pentaho.reporting.engine.classic.core.modules.gui.csv.data.AdvancedSettingsAvailable"))) {
      tabbedPane.add(
          getResources().getString("csvexportdialog.advanced-settings"),
          createAdvancedOptionsPanel()); //$NON-NLS-1$
    }
    setContentPane(createContentPane(tabbedPane));

    getFormValidator().registerTextField(txFilename);
    getFormValidator().registerComboBox(cbEncoding);
  }
  /** Invoked when an action occurs. */
  public void actionPerformed(final ActionEvent e) {
    final Configuration config = ReportDesignerBoot.getInstance().getGlobalConfig();
    final String docUrl =
        config.getConfigProperty(
            "org.pentaho.reporting.designer.core.documentation.report_designer_user_guide");

    try {
      ExternalToolLauncher.openURL(docUrl);
    } catch (IOException ex) {
      log.warn("Could not load " + docUrl, ex); // NON-NLS
    }
  }
 private void preComputeEnvironmentMapping() {
   if (cachedEnvironmentMapping == null) {
     final Configuration configuration = ClassicEngineBoot.getInstance().getGlobalConfig();
     final Iterator propertyKeys = configuration.findPropertyKeys(ENV_MAPPING_KEY_PREFIX);
     final LinkedHashMap<String, String> names = new LinkedHashMap<String, String>();
     while (propertyKeys.hasNext()) {
       final String key = (String) propertyKeys.next();
       final String value = configuration.getConfigProperty(key);
       final String shortKey = key.substring(ENV_MAPPING_KEY_PREFIX.length());
       names.put(shortKey, value);
     }
     cachedEnvironmentMapping = Collections.unmodifiableMap(names);
   }
 }
 private DocumentBuilderFactory calculateDocumentBuilderFactory(final Configuration configuration)
     throws ParserConfigurationException {
   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
   dbf.setXIncludeAware(false);
   if (!"true".equals(configuration.getConfigProperty(XPATH_ENABLE_DTDS))) {
     dbf.setFeature(DISALLOW_DOCTYPE_DECL, true);
   }
   return dbf;
 }
    /**
     * Returns the configuration property with the specified key (or the specified default value if
     * there is no such property).
     *
     * <p>If the property is not defined in this configuration, the code will lookup the property in
     * the parent configuration.
     *
     * @param key the property key.
     * @param defaultValue the default value.
     * @return the property value.
     */
    public String getConfigProperty(final String key, final String defaultValue) {
      if (wrappedConfiguration == null) {
        return getParentConfig().getConfigProperty(key, defaultValue);
      }

      final String retval = wrappedConfiguration.getConfigProperty(key, null);
      if (retval != null) {
        return retval;
      }
      return getParentConfig().getConfigProperty(key, defaultValue);
    }
  /** @noinspection ProhibitedExceptionCaught */
  public static synchronized void registerDefaults() {
    final Configuration config = ClassicEngineBoot.getInstance().getGlobalConfig();
    final Iterator it =
        config.findPropertyKeys("org.pentaho.reporting.engine.classic.core.stylekeys.");
    final ClassLoader classLoader = ObjectUtilities.getClassLoader(StyleKey.class);

    while (it.hasNext()) {
      final String key = (String) it.next();
      final String keyClass = config.getConfigProperty(key);
      try {
        final Class c = Class.forName(keyClass, false, classLoader);
        registerClass(c);
      } catch (ClassNotFoundException e) {
        // ignore that class
        logger.warn("Unable to register keys from " + keyClass);
      } catch (NullPointerException e) {
        // ignore invalid values as well.
        logger.warn("Unable to register keys from " + keyClass);
      }
    }
  }
 /**
  * Reads the module definition header. This header contains information about the module itself.
  *
  * @param config the properties from where to read the content.
  */
 private void readModuleInfo(final Configuration config) {
   setName(config.getConfigProperty("module.name"));
   setProducer(config.getConfigProperty("module.producer"));
   setDescription(config.getConfigProperty("module.description"));
   setMajorVersion(config.getConfigProperty("module.version.major"));
   setMinorVersion(config.getConfigProperty("module.version.minor"));
   setPatchLevel(config.getConfigProperty("module.version.patchlevel"));
   setSubSystem(config.getConfigProperty("module.subsystem"));
 }
  /**
   * Extracts the to be generated PDF version as iText parameter from the given property value. The
   * value has the form "1.x" where x is the extracted version.
   *
   * @return the itext character defining the version.
   */
  private char getVersion() {
    final String version =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Version");

    if (version == null) {
      return '5';
    }
    if (version.length() < 3) {
      PdfDocumentWriter.logger.warn(
          "PDF version specification is invalid, using default version '1.4'.");
      return '5';
    }
    final char retval = version.charAt(2);
    if (retval < '2' || retval > '9') {
      PdfDocumentWriter.logger.warn(
          "PDF version specification is invalid, using default version '1.4'.");
      return '5';
    }
    return retval;
  }
  /**
   * Initialises the CSV export dialog from the settings in the report configuration.
   *
   * @param config the report configuration.
   */
  protected void setDialogContents(final Configuration config) {
    // the CSV separator has two sources, either the data CSV or the
    // table CSV. As we have only one input field for that property,
    // we use a cascading schema to resolve this. The data oriented
    // separator is preferred ...
    final String tableCSVSeparator =
        config.getConfigProperty(CSVTableModule.SEPARATOR, CSVDataExportDialog.COMMA_SEPARATOR);
    setSeparatorString(config.getConfigProperty(CSVProcessor.CSV_SEPARATOR, tableCSVSeparator));

    final String colNames =
        config.getConfigProperty(CSVProcessor.CSV_DATAROWNAME, "false"); // $NON-NLS-1$
    setColumnNamesAsFirstRow("true".equals(colNames)); // $NON-NLS-1$

    final String encoding =
        config.getConfigProperty(
            CSVProcessor.CSV_ENCODING, CSVDataExportDialog.CSV_OUTPUT_ENCODING_DEFAULT);
    encodingModel.ensureEncodingAvailable(encoding);
    setEncoding(encoding);

    final String stateCols =
        config.getConfigProperty(CSVProcessor.CSV_WRITE_STATECOLUMNS, "false"); // $NON-NLS-1$
    setWriteStateColumns("true".equals(stateCols)); // $NON-NLS-1$

    final String enableReportHeader =
        config.getConfigProperty(CSVProcessor.CSV_ENABLE_REPORTHEADER, "false"); // $NON-NLS-1$
    setEnableReportHeader("true".equals(enableReportHeader)); // $NON-NLS-1$

    final String enableReportFooter =
        config.getConfigProperty(CSVProcessor.CSV_ENABLE_REPORTFOOTER, "false"); // $NON-NLS-1$
    setEnableReportFooter("true".equals(enableReportFooter)); // $NON-NLS-1$

    final String enableGroupHeader =
        config.getConfigProperty(CSVProcessor.CSV_ENABLE_GROUPHEADERS, "false"); // $NON-NLS-1$
    setEnableGroupHeader("true".equals(enableGroupHeader)); // $NON-NLS-1$

    final String enableGroupFooter =
        config.getConfigProperty(CSVProcessor.CSV_ENABLE_GROUPFOOTERS, "false"); // $NON-NLS-1$
    setEnableGroupFooter("true".equals(enableGroupFooter)); // $NON-NLS-1$

    final String enableItemBand =
        config.getConfigProperty(CSVProcessor.CSV_ENABLE_ITEMBANDS, "false"); // $NON-NLS-1$
    setEnableItembands("true".equals(enableItemBand)); // $NON-NLS-1$

    final String defaultFileName =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.gui.csv.FileName"); //$NON-NLS-1$
    if (defaultFileName != null) {
      setFilename(resolvePath(defaultFileName).getAbsolutePath());
    } else {
      setFilename(""); // $NON-NLS-1$
    }
  }
  /** @noinspection IOResourceOpenedButNotSafelyClosed */
  public void print(
      final LogicalPageKey logicalPageKey,
      final LogicalPageBox logicalPage,
      final TableContentProducer contentProducer,
      final RTFOutputProcessorMetaData metaData,
      final boolean incremental)
      throws ContentProcessingException {
    final int startRow = contentProducer.getFinishedRows();
    final int finishRow = contentProducer.getFilledRows();
    if (incremental && startRow == finishRow) {
      return;
    }

    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 PatchRtfWriter2 instance =
          PatchRtfWriter2.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);
      }

      // 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 CellMarker.SectionType sectionType = contentProducer.getSectionType(row, col);

          if (content == null) {
            final RenderBox backgroundBox = contentProducer.getBackground(row, col);
            final CellBackground background;
            if (backgroundBox != null) {
              background =
                  cellBackgroundProducer.getBackgroundForBox(
                      logicalPage, sheetLayout, col, row, 1, 1, true, sectionType, backgroundBox);
            } else {
              background =
                  cellBackgroundProducer.getBackgroundAt(
                      logicalPage, sheetLayout, col, row, true, sectionType);
            }
            if (background == null) {
              // An empty cell .. ignore
              final PatchRtfCell cell = new PatchRtfCell();
              cell.setBorderWidth(0);
              cell.setMinimumHeight(
                  (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row)));
              table.addCell(cell, row, col);
              continue;
            }

            // A empty cell with a defined background ..
            final PatchRtfCell cell = new PatchRtfCell();
            cell.setBorderWidth(0);
            cell.setMinimumHeight(
                (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row)));
            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.getBackgroundForBox(
                  logicalPage,
                  sheetLayout,
                  col,
                  row,
                  colSpan,
                  rowSpan,
                  false,
                  sectionType,
                  content);

          final PatchRtfCell cell = new PatchRtfCell();
          cell.setRowspan(rowSpan);
          cell.setColspan(colSpan);
          cell.setBorderWidth(0);
          cell.setMinimumHeight(
              (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row)));
          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.setFinishedTable(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);
    }
  }
  public void initialize(final Configuration config, final Locale locale, final TimeZone timeZone) {
    if (config == null) {
      throw new NullPointerException();
    }

    if (locale == null) {
      // setting locale
      final String declaredLocale =
          config.getConfigProperty(CONFIG_LOCALE_KEY, Locale.getDefault().toString());
      final String[] declaredLocaleParts = createLocale(declaredLocale);
      this.locale =
          new Locale(declaredLocaleParts[0], declaredLocaleParts[1], declaredLocaleParts[2]);
    } else {
      this.locale = locale;
    }

    // setting timezone
    if (timeZone == null) {
      final String timeZoneId =
          config.getConfigProperty(CONFIG_TIMEZONE_KEY, TimeZone.getDefault().getID());
      this.timeZone = TimeZone.getTimeZone(timeZoneId);
    } else {
      this.timeZone = TimeZone.getDefault();
    }

    final Locale[] locales = new Locale[] {getLocale(), Locale.US};
    for (int i = 0; i < locales.length; i++) {
      final Locale activeLocale = locales[i];

      datetimeFormats.add(
          DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, activeLocale));
      dateFormats.add(DateFormat.getDateInstance(DateFormat.FULL, activeLocale));
      timeFormats.add(DateFormat.getTimeInstance(DateFormat.FULL, activeLocale));

      datetimeFormats.add(
          DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, activeLocale));
      dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, activeLocale));
      timeFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, activeLocale));

      datetimeFormats.add(
          DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, activeLocale));
      dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, activeLocale));
      timeFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, activeLocale));

      datetimeFormats.add(
          DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, activeLocale));
      dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT, activeLocale));
      timeFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT, activeLocale));

      numberFormats.add(
          new DecimalFormat(
              "#0.#############################", new DecimalFormatSymbols(activeLocale)));
      numberFormats.add(NumberFormat.getCurrencyInstance(activeLocale));
      numberFormats.add(NumberFormat.getInstance(activeLocale));
      numberFormats.add(NumberFormat.getIntegerInstance(activeLocale));
      numberFormats.add(NumberFormat.getNumberInstance(activeLocale));
      numberFormats.add(NumberFormat.getPercentInstance(activeLocale));
    }

    // adding default ISO8 dateformats
    datetimeFormats.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US));
    datetimeFormats.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US));

    dateFormats.add(new SimpleDateFormat("yyyy-MM-dd", Locale.US));
    timeFormats.add(new SimpleDateFormat("HH:mm:ss", Locale.US));
    timeFormats.add(new SimpleDateFormat("HH:mm", Locale.US));

    for (int i = 0; i < dateFormats.size(); i++) {
      final DateFormat dateFormat = dateFormats.get(i);
      dateFormat.setLenient(false);
    }

    for (int i = 0; i < datetimeFormats.size(); i++) {
      final DateFormat dateFormat = datetimeFormats.get(i);
      dateFormat.setLenient(false);
    }

    for (int i = 0; i < timeFormats.size(); i++) {
      final DateFormat dateFormat = timeFormats.get(i);
      dateFormat.setLenient(false);
    }

    for (int i = 0; i < numberFormats.size(); i++) {
      final NumberFormat format = numberFormats.get(i);
      if (format instanceof DecimalFormat) {
        final DecimalFormat fmt = (DecimalFormat) format;
        fmt.setParseBigDecimal(true);
      }
    }
  }
  /**
   * Configures this factory from the given configuration using the speoified prefix as filter.
   *
   * @param conf the configuration.
   * @param prefix the key-prefix.
   * @noinspection ObjectAllocationInLoop as this is a factory configuration method.
   */
  public void configure(final Configuration conf, final String prefix) {
    if (conf == null) {
      throw new NullPointerException();
    }

    if (prefix == null) {
      throw new NullPointerException();
    }

    final HashMap<String, String> knownNamespaces = new HashMap<String, String>();

    final String nsConfPrefix = prefix + "namespace.";
    final Iterator<String> namespaces = conf.findPropertyKeys(nsConfPrefix);
    while (namespaces.hasNext()) {
      final String key = namespaces.next();
      final String nsPrefix = key.substring(nsConfPrefix.length());
      final String nsUri = conf.getConfigProperty(key);
      knownNamespaces.put(nsPrefix, nsUri);
    }

    setDefaultNamespace(knownNamespaces.get(conf.getConfigProperty(prefix + "namespace")));

    final String globalDefaultKey = prefix + "default";
    final boolean globalValue = "allow".equals(conf.getConfigProperty(globalDefaultKey)) == false;
    setNamespaceHasCData(null, globalValue);

    final String nsDefaultPrefix = prefix + "default.";
    final Iterator<String> defaults = conf.findPropertyKeys(nsDefaultPrefix);
    while (defaults.hasNext()) {
      final String key = defaults.next();
      final String nsPrefix = key.substring(nsDefaultPrefix.length());
      final String nsUri = knownNamespaces.get(nsPrefix);
      if (nsUri == null) {
        continue;
      }

      final boolean value = "allow".equals(conf.getConfigProperty(key)) == false;
      setNamespaceHasCData(nsUri, value);
    }

    final String nsTagsPrefix = prefix + "tag.";
    final Iterator<String> tags = conf.findPropertyKeys(nsTagsPrefix);
    while (tags.hasNext()) {
      final String key = tags.next();
      final String tagDef = key.substring(nsTagsPrefix.length());
      final boolean value = "allow".equals(conf.getConfigProperty(key)) == false;

      final int delim = tagDef.indexOf('.');
      if (delim == -1) {
        setElementHasCData(tagDef, value);
      } else {
        final String nsPrefix = tagDef.substring(0, delim);
        final String nsUri = knownNamespaces.get(nsPrefix);
        if (nsUri == null) {
          continue;
        }

        final String tagName = tagDef.substring(delim + 1);
        setElementHasCData(nsUri, tagName, value);
      }
    }
  }
  /**
   * This method iterates through the rows and columns to populate a DefaultCategoryDataset. Since a
   * CategoryDataset stores values based on a multikey hash we supply as the keys either the
   * metadata column name or the column number and the metadata row name or row number as the keys.
   *
   * <p>As it's processing the data from the ChartTableModel into the DefaultCategoryDataset it
   * applies the scale specified in the
   *
   * @param chartDocContext - Chart document context for the current chart.
   * @param data - Data for the current chart.
   * @param columnIndexArr - Contains column position information. When not null, we would get data
   *     from specified columns.
   * @return DefaultCategoryDataset that can be used as a source for JFreeChart
   */
  private DefaultCategoryDataset createDefaultCategoryDataset(
      final ChartDocumentContext chartDocContext,
      final ChartTableModel data,
      final Integer[] columnIndexArr) {
    final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    final int rowCount = data.getRowCount();
    final int colCount = data.getColumnCount();
    final Configuration config = ChartBoot.getInstance().getGlobalConfig();
    final String noRowNameSpecified =
        config.getConfigProperty("org.pentaho.chart.namespace.row_name_not_defined"); // $NON-NLS-1$
    final String noColumnName =
        config.getConfigProperty(
            "org.pentaho.chart.namespace.column_name_not_defined"); //$NON-NLS-1$
    final ChartDocument chartDocument = chartDocContext.getChartDocument();
    final double scale = JFreeChartUtils.getScale(chartDocument);

    // Only if we have to separate datasets then do we do some column processing in the given data
    // else we simply process all rows and all columns
    if (columnIndexArr != null) {
      final int columnIndexArrLength = columnIndexArr.length;
      for (int row = 0; row < rowCount; row++) {
        int columnIndexArrCounter = 0;
        for (int column = 0; column < colCount; column++) {
          if (columnIndexArrCounter < columnIndexArrLength) {
            // if the current column is what we want in the dataset (based on column indexes in
            // columnIndexArr),
            // then process the data
            // Else move to the next column
            if (column == columnIndexArr[columnIndexArrCounter]) {
              updateDatasetBasedOnScale(
                  chartDocument,
                  data,
                  dataset,
                  row,
                  column,
                  noRowNameSpecified,
                  noColumnName,
                  scale);
              // Increment the counter so that we can process the next column in the columnIndexArr
              columnIndexArrCounter++;
            }
          } else {
            // if we have reached beyond the last element in the column index array then simply
            // start processing
            // the next row of data.
            break;
          }
        }
      }
    }
    // If we do not want to process entire data as is (without dividing the dataset)
    // then simply process all the dataset
    else {
      for (int row = 0; row < rowCount; row++) {
        for (int column = 0; column < colCount; column++) {
          updateDatasetBasedOnScale(
              chartDocument, data, dataset, row, column, noRowNameSpecified, noColumnName, scale);
        }
      }
    }
    return dataset;
  }
  @SuppressWarnings("deprecation")
  @Override
  protected boolean performExport(final MasterReport report, final OutputStream outputStream) {
    try {
      IContentRepository contentRepository = null;
      try {
        contentRepository = PentahoSystem.get(IContentRepository.class, getSession());
      } catch (Throwable t) {
        debug(
            Messages.getInstance()
                .getString("JFreeReportHtmlComponent.DEBUG_0044_PROCESSING_WITHOUT_CONTENT_REPOS"),
            t); //$NON-NLS-1$
      }

      String contentHandlerPattern =
          getInputStringValue(AbstractJFreeReportComponent.REPORTHTML_CONTENTHANDLER);
      if (contentHandlerPattern == null) {
        final Configuration globalConfig = ClassicEngineBoot.getInstance().getGlobalConfig();
        contentHandlerPattern =
            globalConfig.getConfigProperty("org.pentaho.web.ContentHandler"); // $NON-NLS-1$
      }

      final IApplicationContext ctx = PentahoSystem.getApplicationContext();

      final URLRewriter rewriter;
      final ContentLocation dataLocation;
      final NameGenerator dataNameGenerator;
      if ((contentRepository == null)
          || JFreeReportHtmlComponent.DO_NOT_USE_THE_CONTENT_REPOSITORY) {
        debug(
            Messages.getInstance()
                .getString(
                    "JFreeReportHtmlComponent.DEBUG_0044_PROCESSING_WITHOUT_CONTENT_REPOS")); //$NON-NLS-1$
        if (ctx != null) {
          File dataDirectory = new File(ctx.getFileOutputPath("system/tmp/")); // $NON-NLS-1$
          if (dataDirectory.exists() && (dataDirectory.isDirectory() == false)) {
            dataDirectory = dataDirectory.getParentFile();
            if (dataDirectory.isDirectory() == false) {
              throw new ReportProcessingException(
                  Messages.getInstance()
                      .getErrorString(
                          "JFreeReportDirectoryComponent.ERROR_0001_INVALID_DIR",
                          dataDirectory.getPath())); // $NON-NLS-1$
            }
          } else if (dataDirectory.exists() == false) {
            dataDirectory.mkdirs();
          }

          final FileRepository dataRepository = new FileRepository(dataDirectory);
          dataLocation = dataRepository.getRoot();
          dataNameGenerator = new DefaultNameGenerator(dataLocation);
          rewriter = new PentahoURLRewriter(contentHandlerPattern);
        } else {
          dataLocation = null;
          dataNameGenerator = null;
          rewriter = new PentahoURLRewriter(contentHandlerPattern);
        }
      } else {
        debug(
            Messages.getInstance()
                .getString(
                    "JFreeReportHtmlComponent.DEBUG_045_PROCESSING_WITH_CONTENT_REPOS")); //$NON-NLS-1$
        final String thePath =
            getSolutionName()
                + "/"
                + getSolutionPath()
                + "/"
                + getSession().getId(); // $NON-NLS-1$//$NON-NLS-2$
        final IContentLocation pentahoContentLocation =
            contentRepository.newContentLocation(
                thePath, getActionName(), getActionTitle(), getSolutionPath(), true);
        // todo
        final ReportContentRepository repository =
            new ReportContentRepository(pentahoContentLocation, getActionName());
        dataLocation = repository.getRoot();
        dataNameGenerator = new DefaultNameGenerator(dataLocation);
        rewriter = new PentahoURLRewriter(contentHandlerPattern);
      }

      final StreamRepository targetRepository = new StreamRepository(null, outputStream);
      final ContentLocation targetRoot = targetRepository.getRoot();

      final HtmlOutputProcessor outputProcessor =
          new StreamHtmlOutputProcessor(report.getConfiguration());
      final HtmlPrinter printer = new AllItemsHtmlPrinter(report.getResourceManager());
      printer.setContentWriter(
          targetRoot,
          new DefaultNameGenerator(targetRoot, "index", "html")); // $NON-NLS-1$//$NON-NLS-2$
      printer.setDataWriter(dataLocation, dataNameGenerator);
      printer.setUrlRewriter(rewriter);
      outputProcessor.setPrinter(printer);

      final StreamReportProcessor sp = new StreamReportProcessor(report, outputProcessor);
      final int yieldRate = getYieldRate();
      if (yieldRate > 0) {
        sp.addReportProgressListener(new YieldReportListener(yieldRate));
      }
      sp.processReport();
      sp.close();

      outputStream.flush();
      close();
      return true;
    } catch (ReportProcessingException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    } catch (IOException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    } catch (ContentIOException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    }
  }
  /**
   * Extracts the permissions for this PDF. The permissions are returned as flags in the integer
   * value. All permissions are defined as properties which have to be set before the target is
   * opened.
   *
   * @return the permissions.
   */
  private int getPermissions() {
    final String printLevel =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PrintLevel");

    final boolean allowPrinting = "none".equals(printLevel) == false;
    final boolean allowDegradedPrinting = "degraded".equals(printLevel);

    final boolean allowModifyContents =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowModifyContents"));
    final boolean allowModifyAnn =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowModifyAnnotations"));

    final boolean allowCopy =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowCopy"));
    final boolean allowFillIn =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowFillIn"));
    final boolean allowScreenReaders =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowScreenReader"));
    final boolean allowAssembly =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowAssembly"));

    int permissions = 0;
    if (allowPrinting) {
      permissions |= PdfWriter.ALLOW_PRINTING;
    }
    if (allowModifyContents) {
      permissions |= PdfWriter.ALLOW_MODIFY_CONTENTS;
    }
    if (allowModifyAnn) {
      permissions |= PdfWriter.ALLOW_MODIFY_ANNOTATIONS;
    }
    if (allowCopy) {
      permissions |= PdfWriter.ALLOW_COPY;
    }
    if (allowFillIn) {
      permissions |= PdfWriter.ALLOW_FILL_IN;
    }
    if (allowScreenReaders) {
      permissions |= PdfWriter.ALLOW_SCREENREADERS;
    }
    if (allowAssembly) {
      permissions |= PdfWriter.ALLOW_ASSEMBLY;
    }
    if (allowDegradedPrinting) {
      permissions |= PdfWriter.ALLOW_DEGRADED_PRINTING;
    }
    return permissions;
  }
  /**
   * Extracts the Page Layout and page mode settings for this PDF (ViewerPreferences). All
   * preferences are defined as properties which have to be set before the target is opened.
   *
   * @return the ViewerPreferences.
   */
  private int getViewerPreferences() {
    final String pageLayout =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PageLayout");
    final String pageMode =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PageMode");
    final String fullScreenMode =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.FullScreenMode");
    final boolean hideToolBar =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideToolBar"));
    final boolean hideMenuBar =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideMenuBar"));
    final boolean hideWindowUI =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideWindowUI"));
    final boolean fitWindow =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.FitWindow"));
    final boolean centerWindow =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.CenterWindow"));
    final boolean displayDocTitle =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.DisplayDocTitle"));
    final boolean printScalingNone =
        "true"
            .equals(
                config.getConfigProperty(
                    "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PrintScalingNone"));
    final String direction =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Direction");

    int viewerPreferences = 0;
    if ("PageLayoutOneColumn".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutOneColumn;
    } else if ("PageLayoutSinglePage".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutSinglePage;
    } else if ("PageLayoutTwoColumnLeft".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutTwoColumnLeft;
    } else if ("PageLayoutTwoColumnRight".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutTwoColumnRight;
    } else if ("PageLayoutTwoPageLeft".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutTwoPageLeft;
    } else if ("PageLayoutTwoPageRight".equals(pageLayout)) {
      viewerPreferences = PdfWriter.PageLayoutTwoPageRight;
    }

    if ("PageModeUseNone".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeUseNone;
    } else if ("PageModeUseOutlines".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeUseOutlines;
    } else if ("PageModeUseThumbs".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeUseThumbs;
    } else if ("PageModeFullScreen".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeFullScreen;
      if ("NonFullScreenPageModeUseNone".equals(fullScreenMode)) {
        viewerPreferences = PdfWriter.NonFullScreenPageModeUseNone;
      } else if ("NonFullScreenPageModeUseOC".equals(fullScreenMode)) {
        viewerPreferences |= PdfWriter.NonFullScreenPageModeUseOC;
      } else if ("NonFullScreenPageModeUseOutlines".equals(fullScreenMode)) {
        viewerPreferences |= PdfWriter.NonFullScreenPageModeUseOutlines;
      } else if ("NonFullScreenPageModeUseThumbs".equals(fullScreenMode)) {
        viewerPreferences |= PdfWriter.NonFullScreenPageModeUseThumbs;
      }
    } else if ("PageModeUseOC".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeUseOC;
    } else if ("PageModeUseAttachments".equals(pageMode)) {
      viewerPreferences |= PdfWriter.PageModeUseAttachments;
    }

    if (hideToolBar) {
      viewerPreferences |= PdfWriter.HideToolbar;
    }

    if (hideMenuBar) {
      viewerPreferences |= PdfWriter.HideMenubar;
    }

    if (hideWindowUI) {
      viewerPreferences |= PdfWriter.HideWindowUI;
    }

    if (fitWindow) {
      viewerPreferences |= PdfWriter.FitWindow;
    }
    if (centerWindow) {
      viewerPreferences |= PdfWriter.CenterWindow;
    }
    if (displayDocTitle) {
      viewerPreferences |= PdfWriter.DisplayDocTitle;
    }
    if (printScalingNone) {
      viewerPreferences |= PdfWriter.PrintScalingNone;
    }

    if ("DirectionL2R".equals(direction)) {
      viewerPreferences |= PdfWriter.DirectionL2R;
    } else if ("DirectionR2L".equals(direction)) {
      viewerPreferences |= PdfWriter.DirectionR2L;
    }

    if (logger.isDebugEnabled()) {
      logger.debug("viewerPreferences = 0b" + Integer.toBinaryString(viewerPreferences));
    }
    return viewerPreferences;
  }
  public void open() throws DocumentException {
    this.document = new Document();
    // pageSize, marginLeft, marginRight, marginTop, marginBottom));

    writer = PdfWriter.getInstance(document, out);
    writer.setLinearPageMode();

    version = getVersion();
    writer.setPdfVersion(version);
    writer.setViewerPreferences(getViewerPreferences());

    final String encrypt =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Encryption");

    if (encrypt != null) {
      if (encrypt.equals(PdfPageableModule.SECURITY_ENCRYPTION_128BIT) == true
          || encrypt.equals(PdfPageableModule.SECURITY_ENCRYPTION_40BIT) == true) {
        final String userpassword =
            config.getConfigProperty(
                "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.UserPassword");
        final String ownerpassword =
            config.getConfigProperty(
                "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.OwnerPassword");
        // Log.debug ("UserPassword: "******" - OwnerPassword: "******"org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Title",
            config.getConfigProperty("org.pentaho.reporting.engine.classic.core.metadata.Title"));
    final String subject =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Description",
            config.getConfigProperty(
                "org.pentaho.reporting.engine.classic.core.metadata.Description"));
    final String author =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Author",
            config.getConfigProperty("org.pentaho.reporting.engine.classic.core.metadata.Author"));
    final String keyWords =
        config.getConfigProperty(
            "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Keywords",
            config.getConfigProperty(
                "org.pentaho.reporting.engine.classic.core.metadata.Keywords"));

    if (title != null) {
      document.addTitle(title);
    }
    if (author != null) {
      document.addAuthor(author);
    }
    if (keyWords != null) {
      document.addKeywords(keyWords);
    }
    if (keyWords != null) {
      document.addSubject(subject);
    }

    document.addCreator(PdfDocumentWriter.CREATOR);
    document.addCreationDate();

    // getDocument().open();
    awaitOpenDocument = true;
  }