/**
   * called when in prepared-component mode, this method populates the preparedQuery string and
   * preparedParameters object.
   *
   * @param rawQuery
   * @return
   */
  protected boolean prepareQuery(final String rawQuery) {

    try {
      if (connection == null) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return false;
      }
      if (!connection.initialized()) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return false;
      }

      preparedQuery = rawQuery;

      return true;
    } catch (Exception e) {
      error(
          Messages.getInstance()
              .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
          e); //$NON-NLS-1$
    }

    return false;
  }
  @Override
  protected boolean validateAction() {
    PrinterAction printerAction = null;
    boolean actionValidated = true;

    if (getActionDefinition() instanceof PrinterAction) {
      printerAction = (PrinterAction) getActionDefinition();

      if ((printerAction.getPrintfile() == ActionInputConstant.NULL_INPUT)
          && (printerAction.getResourcesPrintFile() == null)
          && (printerAction.getReportOutput() == ActionInputConstant.NULL_INPUT)
          && (printerAction.getOutputPrinterName() == null)) {
        actionValidated = false;
        error(
            Messages.getInstance().getErrorString("PrintComponent.ERROR_0001_NO_PRINT_FILE_DEFINED")
                + getActionName()); //$NON-NLS-1$
      }
    } else {
      actionValidated = false;
      error(
          Messages.getInstance()
              .getErrorString(
                  "ComponentBase.ERROR_0001_UNKNOWN_ACTION_TYPE",
                  getActionDefinition().getElement().asXML())); // $NON-NLS-1$
    }

    return actionValidated;
  }
  public void addHostedCatalog(
      String name,
      String dataSourceInfo,
      InputStream inputStream,
      boolean overwrite,
      IPentahoSession session) {

    // Access
    if (!hasAccess(name, EnumSet.of(RepositoryFilePermission.WRITE), session)) {
      LOG.debug("user does not have access; throwing exception"); // $NON-NLS-1$
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0003_INSUFFICIENT_PERMISSION"), // $NON-NLS-1$
          IOlapServiceException.Reason.ACCESS_DENIED);
    }

    // check for existing vs. the overwrite flag.
    if (getCatalogNames(session).contains(name) && !overwrite) {
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0004_ALREADY_EXISTS"), // $NON-NLS-1$
          IOlapServiceException.Reason.ALREADY_EXISTS);
    }

    try {
      MondrianCatalogRepositoryHelper helper = new MondrianCatalogRepositoryHelper(getRepository());
      helper.addHostedCatalog(inputStream, name, dataSourceInfo);
    } catch (Exception e) {
      throw new IOlapServiceException(e, IOlapServiceException.Reason.convert(e));
    }
  }
  public void addOlap4jCatalog(
      String name,
      String className,
      String URL,
      String user,
      String password,
      Properties props,
      boolean overwrite,
      IPentahoSession session) {

    // Access
    if (!hasAccess(name, EnumSet.of(RepositoryFilePermission.WRITE), session)) {
      LOG.debug("user does not have access; throwing exception"); // $NON-NLS-1$
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0003_INSUFFICIENT_PERMISSION"), // $NON-NLS-1$
          IOlapServiceException.Reason.ACCESS_DENIED);
    }

    // check for existing vs. the overwrite flag.
    if (getCatalogNames(session).contains(name) && !overwrite) {
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0004_ALREADY_EXISTS"), // $NON-NLS-1$
          IOlapServiceException.Reason.ALREADY_EXISTS);
    }

    MondrianCatalogRepositoryHelper helper = new MondrianCatalogRepositoryHelper(getRepository());

    helper.addOlap4jServer(name, className, URL, user, password, props);
  }
 /**
  * This method retrieves a connection based on the components inputs.
  *
  * @param defaultConnection a default connection to use if no other is available
  * @return new connection object
  */
 protected IPentahoConnection getConnection(final IPentahoConnection defaultConnection) {
   IPentahoConnection localConnection = null;
   try {
     String jndiName = null;
     String driver = null;
     String userId = null;
     String password = null;
     String connectionInfo = null;
     if (getActionDefinition() instanceof SqlConnectionAction) {
       SqlConnectionAction sqlConnectionAction = (SqlConnectionAction) getActionDefinition();
       jndiName = sqlConnectionAction.getJndi().getStringValue();
       driver = sqlConnectionAction.getDriver().getStringValue();
       userId = sqlConnectionAction.getUserId().getStringValue();
       password = sqlConnectionAction.getPassword().getStringValue();
       connectionInfo = sqlConnectionAction.getDbUrl().getStringValue();
     } else if (getActionDefinition() instanceof AbstractRelationalDbAction) {
       AbstractRelationalDbAction relationalDbAction =
           (AbstractRelationalDbAction) getActionDefinition();
       jndiName = relationalDbAction.getJndi().getStringValue();
       driver = relationalDbAction.getDriver().getStringValue();
       userId = relationalDbAction.getUserId().getStringValue();
       password = relationalDbAction.getPassword().getStringValue();
       connectionInfo = relationalDbAction.getDbUrl().getStringValue();
     }
     if (jndiName != null) {
       localConnection =
           PentahoConnectionFactory.getConnection(
               IPentahoConnection.SQL_DATASOURCE, jndiName, getSession(), this);
     }
     if (localConnection == null) {
       localConnection =
           PentahoConnectionFactory.getConnection(
               IPentahoConnection.SQL_DATASOURCE,
               driver,
               connectionInfo,
               userId,
               password,
               getSession(),
               this);
     }
     if (localConnection == null) {
       if (defaultConnection == null) {
         error(
             Messages.getInstance()
                 .getErrorString("SQLBaseComponent.ERROR_0005_INVALID_CONNECTION")); // $NON-NLS-1$
         return null;
       } else {
         localConnection = defaultConnection;
       }
     }
     return localConnection;
   } catch (Exception e) {
     error(
         Messages.getInstance()
             .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
         e); //$NON-NLS-1$
   }
   return null;
 }
  /**
   * validates the action. checks to verify inputs are available to execute
   *
   * <p>- verify query is available - verify connection is available, via jndi, connection string,
   * or prepared component - verify output is specified
   */
  @Override
  public boolean validateAction() {
    boolean result = true;

    IActionDefinition actionDefinition = getActionDefinition();
    String actionName = getActionName();

    if (actionDefinition instanceof AbstractRelationalDbAction) {
      AbstractRelationalDbAction relationalDbAction = (AbstractRelationalDbAction) actionDefinition;
      IActionInput query = relationalDbAction.getQuery();
      IActionInput dbUrl = relationalDbAction.getDbUrl();
      IActionInput jndi = relationalDbAction.getJndi();

      IActionInput sharedConnection = relationalDbAction.getSharedConnection();
      if (query == ActionInputConstant.NULL_INPUT) {

        error(
            Messages.getInstance()
                .getErrorString(
                    "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED", actionName)); // $NON-NLS-1$
        result = false;
      }

      if ((jndi == ActionInputConstant.NULL_INPUT)
          && (dbUrl == ActionInputConstant.NULL_INPUT)
          && (sharedConnection == ActionInputConstant.NULL_INPUT)) {
        error(
            Messages.getInstance()
                .getErrorString(
                    "SQLBaseComponent.ERROR_0002_CONNECTION_NOT_SPECIFIED",
                    actionName)); //$NON-NLS-1$
        result = false;
      }
    } else if (actionDefinition instanceof SqlConnectionAction) {
      SqlConnectionAction sqlConnectionAction = (SqlConnectionAction) actionDefinition;
      IActionInput dbUrl = sqlConnectionAction.getDbUrl();
      IActionInput jndi = sqlConnectionAction.getJndi();
      if ((jndi == ActionInputConstant.NULL_INPUT) && (dbUrl == ActionInputConstant.NULL_INPUT)) {
        error(
            Messages.getInstance()
                .getErrorString(
                    "SQLBaseComponent.ERROR_0002_CONNECTION_NOT_SPECIFIED",
                    actionName)); //$NON-NLS-1$
        result = false;
      }
    } else {
      error(
          Messages.getInstance()
              .getErrorString(
                  "ComponentBase.ERROR_0001_UNKNOWN_ACTION_TYPE",
                  actionDefinition.getElement().asXML())); // $NON-NLS-1$
      result = false;
    }
    return result;
  }
  @Override
  protected boolean performExport(final MasterReport report, final OutputStream outputStream) {
    try {
      String dataDirectory =
          getInputStringValue(AbstractJFreeReportComponent.REPORTDIRECTORYHTML_DATADIR);
      if (dataDirectory == null) {
        dataDirectory = "data"; // $NON-NLS-1$
      }

      final ZipRepository zipRepository = new ZipRepository();
      final ContentLocation root = zipRepository.getRoot();
      final ContentLocation data =
          RepositoryUtilities.createLocation(
              zipRepository, RepositoryUtilities.split(dataDirectory, "/")); // $NON-NLS-1$

      final FlowHtmlOutputProcessor outputProcessor =
          new FlowHtmlOutputProcessor(report.getConfiguration());

      final HtmlPrinter printer = new AllItemsHtmlPrinter(report.getResourceManager());
      printer.setContentWriter(root, new DefaultNameGenerator(root, "report.html")); // $NON-NLS-1$
      printer.setDataWriter(data, new DefaultNameGenerator(data, "content")); // $NON-NLS-1$
      printer.setUrlRewriter(new SingleRepositoryURLRewriter());
      outputProcessor.setPrinter(printer);

      final FlowReportProcessor sp = new FlowReportProcessor(report, outputProcessor);
      final int yieldRate = getYieldRate();
      if (yieldRate > 0) {
        sp.addReportProgressListener(new YieldReportListener(yieldRate));
      }
      sp.processReport();
      zipRepository.write(outputStream);
      close();
      return true;
    } catch (ReportProcessingException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportZipHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    } catch (IOException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportZipHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    } catch (ContentIOException e) {
      error(
          Messages.getInstance()
              .getString("JFreeReportZipHtmlComponent.ERROR_0046_FAILED_TO_PROCESS_REPORT"),
          e); //$NON-NLS-1$
      return false;
    }
  }
  public IPentahoResultSet doQuery(
      final SQLConnection sqlConnection, final String query, boolean forwardOnlyResultset)
      throws Exception {
    //
    // At this point, 'connection' and 'sqlConnection' should be pointers to
    // the same object iff the 'connection' is a subclass of pentaho's SQLConnection.
    // It is possible that the sqlConnection will be null, but the connection
    // won't be if someone is using their own implementation of the SQLConnection from
    // the factory.
    //

    IPentahoResultSet resultSet = null;
    if (ComponentBase.debug) {
      dumpQuery(query);
    }

    if (preparedParameters.size() > 0) {
      if (!forwardOnlyResultset) {
        resultSet = connection.prepareAndExecuteQuery(query, preparedParameters);
      } else {
        if (sqlConnection != null) {
          resultSet =
              sqlConnection.prepareAndExecuteQuery(
                  query,
                  preparedParameters,
                  SQLConnection.RESULTSET_FORWARDONLY,
                  SQLConnection.CONCUR_READONLY);
        } else {
          throw new IllegalStateException(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$
        }
      }
    } else {
      if (!forwardOnlyResultset) {
        resultSet = connection.executeQuery(query);
      } else {
        if (sqlConnection != null) {
          resultSet =
              sqlConnection.executeQuery(
                  query, SQLConnection.RESULTSET_FORWARDONLY, SQLConnection.CONCUR_READONLY);
        } else {
          throw new IllegalStateException(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$
        }
      }
    }
    return resultSet;
  }
 private void dumpQuery(final String query) {
   if (timeout == 0) {
     debug(
         Messages.getInstance()
             .getString("SQLBaseComponent.DEBUG_RUNNING_QUERY", query)); // $NON-NLS-1$
   } else {
     debug(
         Messages.getInstance()
             .getString(
                 "SQLBaseComponent.DEBUG_RUNNING_QUERY_TIMEOUT",
                 query,
                 "" + timeout)); // $NON-NLS-1$ //$NON-NLS-2$
   }
 }
 @Override
 public String publish(final IPentahoSession localSession) {
   try {
     PentahoSystem.refreshSettings();
   } catch (Throwable t) {
     error(
         Messages.getInstance().getErrorString("SettingsPublisher.ERROR_0001_PUBLISH_FAILED"),
         t); //$NON-NLS-1$
     return Messages.getInstance().getString("SettingsPublisher.USER_ERROR_PUBLISH_FAILED")
         + t.getLocalizedMessage(); // $NON-NLS-1$
   }
   return Messages.getInstance()
       .getString("SettingsPublisher.USER_SYSTEM_SETTINGS_UPDATED"); // $NON-NLS-1$
 }
  @Override
  protected boolean performExport(final MasterReport report) {
    try {
      final File targetFile =
          getInputFileValue(AbstractJFreeReportComponent.REPORTDIRECTORYHTML_TARGETFILE);
      if (targetFile == null) {
        return false;
      }

      File dataDirectory =
          getInputFileValue(AbstractJFreeReportComponent.REPORTDIRECTORYHTML_DATADIR);
      if (dataDirectory == null) {
        dataDirectory = new File(targetFile, "data/"); // $NON-NLS-1$
      }

      final File targetDirectory = targetFile.getParentFile();
      if (dataDirectory.exists() && (dataDirectory.isDirectory() == false)) {
        dataDirectory = dataDirectory.getParentFile();
        if (dataDirectory.isDirectory() == false) {
          String msg =
              Messages.getInstance()
                  .getErrorString(
                      "JFreeReportDirectoryComponent.ERROR_0001_INVALID_DIR", //$NON-NLS-1$
                      dataDirectory.getPath());
          throw new ReportProcessingException(msg);
        }
      } else if (dataDirectory.exists() == false) {
        dataDirectory.mkdirs();
      }

      final FileRepository targetRepository = new FileRepository(targetDirectory);
      final ContentLocation targetRoot = targetRepository.getRoot();

      final FileRepository dataRepository = new FileRepository(dataDirectory);
      final ContentLocation dataRoot = dataRepository.getRoot();

      final FlowHtmlOutputProcessor outputProcessor = new FlowHtmlOutputProcessor();

      final HtmlPrinter printer = new AllItemsHtmlPrinter(report.getResourceManager());
      printer.setContentWriter(
          targetRoot, new DefaultNameGenerator(targetRoot, targetFile.getName()));
      printer.setDataWriter(
          dataRoot, new DefaultNameGenerator(targetRoot, "content")); // $NON-NLS-1$
      printer.setUrlRewriter(new FileSystemURLRewriter());
      outputProcessor.setPrinter(printer);

      final FlowReportProcessor sp = new FlowReportProcessor(report, outputProcessor);
      final int yieldRate = getYieldRate();
      if (yieldRate > 0) {
        sp.addReportProgressListener(new YieldReportListener(yieldRate));
      }
      sp.processReport();
      sp.close();
      return true;
    } catch (ReportProcessingException e) {
      return false;
    } catch (ContentIOException e) {
      return false;
    }
  }
  /**
   * Takes a printer name and find the associated PrintService. If no match can be made it randomly
   * picks the first printer listed from the call to lookupPrintServices.
   *
   * @param printerName
   * @return PrintService referenced by the printerName
   */
  public PrintService getPrinterInternal(final String printerName, final String lastPrinterName) {
    // The parameter value was not provided, and we are allowed to create
    // user interface forms

    PrintService[] services = PrinterJob.lookupPrintServices();
    for (PrintService element : services) {
      if (element.getName().equals(printerName)) {
        return element;
      }
    }
    if (feedbackAllowed()) {
      // If it's not valid then lets find one and end this current run.
      ArrayList values = new ArrayList();
      for (PrintService element : services) {
        String value = element.getName();
        values.add(value);
      }
      createFeedbackParameter(
          StandardSettings.PRINTER_NAME,
          Messages.getInstance().getString("PrintComponent.USER_PRINTER_NAME"),
          "",
          lastPrinterName,
          values,
          null,
          "select"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      promptNeeded();
      return null;
    }
    return services[0];
  }
  public IPentahoResultSet getResultSet(final ReportSpec reportSpec) throws Exception {
    String jndiName = reportSpec.getReportSpecChoice().getJndiSource();
    IPentahoConnection connection = null;
    if (reportSpec.getIsMDX()) {
      // did this ever work??
      String connectStr = ""; // $NON-NLS-1$
      IDBDatasourceService datasourceService =
          PentahoSystem.getObjectFactory().get(IDBDatasourceService.class, null);
      String dsName = datasourceService.getDSBoundName(jndiName);
      if (dsName != null) {
        connectStr = "dataSource=" + dsName + "; Catalog=mondrian"; // $NON-NLS-1$ //$NON-NLS-2$
      } else {
        error(
            Messages.getInstance()
                .getErrorString("MDXBaseComponent.ERROR_0005_INVALID_CONNECTION")); // $NON-NLS-1$
        return null;
      }
      Properties props = new Properties();
      props.setProperty(IPentahoConnection.CONNECTION, connectStr);
      props.setProperty(IPentahoConnection.PROVIDER, reportSpec.getMondrianCubeDefinitionPath());

      connection =
          PentahoConnectionFactory.getConnection(
              IPentahoConnection.MDX_DATASOURCE, props, getSession(), this);
    } else {
      connection =
          PentahoConnectionFactory.getConnection(
              IPentahoConnection.SQL_DATASOURCE, jndiName, getSession(), this);
    }
    String query = ReportParameterUtility.setupParametersForActionSequence(reportSpec.getQuery());
    query = setupQueryParameters(query);
    IPentahoResultSet res = connection.executeQuery(query);
    return res;
  }
 public String getDescription() {
   return Messages.getInstance()
       .getString(
           "SettingsPublisher.USER_DESCRIPTION",
           PentahoSystem.getApplicationContext()
               .getSolutionPath("system")
               .replace('\\', '/')); // $NON-NLS-1$ //$NON-NLS-2$
 }
 @Override
 public void validateData() {
   super.validateData();
   if (getColumnCount() < 3) {
     throw new RuntimeException(
         Messages.getInstance()
             .getErrorString("BubbleChartFactory.ERROR_0001_XYZ_COLUMN_COUNT")); // $NON-NLS-1$
   }
 }
  public void removeCatalog(String name, IPentahoSession session) {

    // Check Access
    if (!hasAccess(name, EnumSet.of(RepositoryFilePermission.DELETE), session)) {
      LOG.debug("user does not have access; throwing exception"); // $NON-NLS-1$
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0003_INSUFFICIENT_PERMISSION"), // $NON-NLS-1$
          IOlapServiceException.Reason.ACCESS_DENIED);
    }

    if (!getCatalogNames(session).contains(name)) {
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("MondrianCatalogHelper.ERROR_0015_CATALOG_NOT_FOUND", name));
    }

    // This could be a remote connection
    getHelper().deleteCatalog(name);
  }
 /**
  * pause the thread a certain number of milliseconds
  *
  * @param millis time to sleep
  */
 protected void waitFor(final int millis) {
   try {
     if (ComponentBase.debug) {
       debug(
           Messages.getInstance()
               .getString(
                   "SQLBaseComponent.DEBUG_WAITING_FOR_CONNECTION",
                   Integer.toString(millis))); // $NON-NLS-1$
     }
     Thread.sleep(millis);
   } catch (Exception ex) {
     // ignore the interrupted exception, if it happens
   }
 }
    @Override
    public void stopRenderer() throws IOException {
      super.stopRenderer();

      try {
        printerJob.print();
      } catch (PrinterException e) {
        e.printStackTrace();
        throw new IOException(
            Messages.getInstance()
                .getString(
                    "PrintComponent.ERROR_0003_UNABLE_TO_PRINT",
                    e.getClass().getName(),
                    e.getMessage())); // $NON-NLS-1$
      }
    }
 private boolean isParameterUIAvailable() {
   /*
    * See if we are allowed to generate a parameter selection user interface. If
    * we are being called as part of a process, this will not be allowed.
    */
   if (!feedbackAllowed()) {
     // We could not get an output stream for the feedback, but we are
     // allowed
     // to generate UI, so return an error
     error(
         Messages.getInstance()
             .getErrorString("JFreeReport.ERROR_0020_INVALID_FEEDBACK_STREAM")); // $NON-NLS-1$
     return false;
   }
   // We need input from the user, we have delivered an input form into the
   // feeback stream
   setFeedbackMimeType("text/html"); // $NON-NLS-1$
   return true;
 }
 /**
  * Flushes all catalogs in the catalogNames collection. If hosted=true the method breaks after the
  * first successful schemaCacheFlush, since we know that all schemas will be flushed by the
  * operation. For remote we assume that each needs to be flushed separately, since there are
  * possibly multiple servers.
  */
 private void flushCatalogs(Collection<String> catalogNames, IPentahoSession session)
     throws SQLException {
   for (String name : catalogNames) {
     OlapConnection connection = null;
     try {
       connection = getConnection(name, session);
       XmlaHandler.XmlaExtra xmlaExtra = getXmlaExtra(connection);
       if (xmlaExtra != null) {
         xmlaExtra.flushSchemaCache(connection);
       }
     } catch (Exception e) {
       LOG.warn(
           Messages.getInstance()
               .getErrorString("MondrianCatalogHelper.ERROR_0019_FAILED_TO_FLUSH", name),
           e);
     } finally {
       if (connection != null) {
         connection.close();
       }
     }
   }
 }
 public String getName() {
   return Messages.getInstance()
       .getString("SettingsPublisher.USER_SYSTEM_SETTINGS"); // $NON-NLS-1$
 }
  @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;
    }
  }
  public OlapConnection getConnection(String catalogName, IPentahoSession session)
      throws IOlapServiceException {

    if (catalogName == null) {
      // This is normal. It happens on XMLA's DISCOVER_DATASOURCES
      try {
        return getServer().getConnection(DATASOURCE_NAME, null, null, new Properties());
      } catch (Exception e) {
        throw new IOlapServiceException(e);
      }
    }

    // Check Access
    if (!hasAccess(catalogName, EnumSet.of(RepositoryFilePermission.READ), session)) {
      LOG.debug("user does not have access; throwing exception"); // $NON-NLS-1$
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("OlapServiceImpl.ERROR_0003_INSUFFICIENT_PERMISSION"), // $NON-NLS-1$
          IOlapServiceException.Reason.ACCESS_DENIED);
    }

    // Check its existence.
    if (!getCatalogNames(session).contains(catalogName)) {
      throw new IOlapServiceException(
          Messages.getInstance()
              .getErrorString("MondrianCatalogHelper.ERROR_0015_CATALOG_NOT_FOUND", catalogName));
    }

    // Check if it is a remote server
    if (getHelper().getOlap4jServers().contains(catalogName)) {
      return makeOlap4jConnection(catalogName);
    }

    final StringBuilder roleName = new StringBuilder();
    Entry roleMonikor = null;
    if (this.role != null) {
      // We must use a custom role implementation.
      // Register the instance with the mondrian server.
      roleMonikor = getServer().getLockBox().register(this.role);
      roleName.append(roleMonikor.getMoniker());
    } else {
      final IConnectionUserRoleMapper mapper =
          PentahoSystem.get(
              IConnectionUserRoleMapper.class,
              MDXConnection.MDX_CONNECTION_MAPPER_KEY,
              null); // Don't use the user session here yet.

      String[] effectiveRoles = new String[0];

      /*
       * If Catalog/Schema are null (this happens with high level metadata requests,
       * like DISCOVER_DATASOURCES) we can't use the role mapper, even if it
       * is present and configured.
       */
      if (session != null && mapper != null) {
        // Use the role mapper.
        try {
          effectiveRoles = mapper.mapConnectionRoles(session, catalogName);
          if (effectiveRoles == null) {
            effectiveRoles = new String[0];
          }
        } catch (PentahoAccessControlException e) {
          throw new IOlapServiceException(e);
        }
      }

      // Now we tokenize that list.
      boolean addComma = false;
      for (String role : effectiveRoles) {
        if (addComma) {
          roleName.append(","); // $NON-NLS-1$
        }
        roleName.append(role);
        addComma = true;
      }
    }

    // Populate some properties, like locale.
    final Properties properties = new Properties();
    properties.put(RolapConnectionProperties.Locale.name(), getLocale().toString());

    // Return a connection
    try {
      return getServer()
          .getConnection(
              DATASOURCE_NAME,
              catalogName,
              Util.isEmpty(roleName.toString()) ? null : roleName.toString(),
              properties);
    } catch (Exception e) {
      throw new IOlapServiceException(e);
    } finally {
      // Cleanup our lockbox entry.
      if (roleMonikor != null) {
        getServer().getLockBox().deregister(roleMonikor);
      }
    }
  }
Esempio n. 24
0
  public static int saveAnalysis(
      final IPentahoSession session,
      final HashMap props,
      final String path,
      String fileName,
      final boolean overwrite) {

    if ("true"
        .equals(
            PentahoSystem.getSystemSetting(
                "kiosk-mode", "false"))) { // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      throw new RuntimeException(
          Messages.getInstance()
              .getErrorString("ANALYSISSAVER.ERROR_0006_SAVE_IS_DISABLED")); // $NON-NLS-1$
    }

    int result = 0;
    try {
      AnalysisSaver.logger = LogFactory.getLog(AnalysisSaver.class);
      String baseUrl = PentahoSystem.getApplicationContext().getSolutionPath(""); // $NON-NLS-1$
      ISolutionRepository solutionRepository =
          PentahoSystem.get(ISolutionRepository.class, session);

      // We will (at this point in time) always have an original action sequence to start from...
      String originalActionReference = (String) props.get("actionreference"); // $NON-NLS-1$

      if (originalActionReference == null) {
        throw new MissingParameterException(
            Messages.getInstance()
                .getErrorString(
                    "ANALYSISSAVER.ERROR_0001_MISSING_ACTION_REFERENCE")); //$NON-NLS-1$
      }

      Document document = null;
      try {
        org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
        reader.setEntityResolver(new SolutionURIResolver());
        document =
            reader.read(
                ActionSequenceResource.getInputStream(
                    originalActionReference, LocaleHelper.getLocale()));
      } catch (Throwable t) {
        // XML document can't be read. We'll just return a null document.
      }

      // Update the document with the stuff we passed in on the props
      document = AnalysisSaver.updateDocument(document, props);
      fileName =
          fileName.endsWith(AnalysisSaver.SUFFIX) ? fileName : fileName + AnalysisSaver.SUFFIX;
      result =
          solutionRepository.publish(
              baseUrl,
              path,
              fileName,
              document.asXML().getBytes(document.getXMLEncoding()),
              overwrite);

      // Now save the resource files
      ActionInfo actionInfo = ActionInfo.parseActionString(originalActionReference);
      String originalPath =
          actionInfo.getSolutionName() + "/" + actionInfo.getPath(); // $NON-NLS-1$
      String originalFileName = actionInfo.getActionName();
      originalFileName =
          originalFileName.substring(0, originalFileName.lastIndexOf(AnalysisSaver.SUFFIX));
      ISolutionFile[] parentFiles =
          solutionRepository
              .getSolutionFile(originalPath, ISolutionRepository.ACTION_EXECUTE)
              .listFiles();
      String baseFileName = fileName.substring(0, fileName.lastIndexOf(AnalysisSaver.SUFFIX));
      for (ISolutionFile aSolutionFile : parentFiles) {
        if (!aSolutionFile.isDirectory()
            && aSolutionFile.getFileName().startsWith(originalFileName)
            && aSolutionFile
                .getFileName()
                .toLowerCase()
                .endsWith(AnalysisSaver.PROPERTIES_SUFFIX)) {
          String newFileName =
              aSolutionFile.getFileName().replaceFirst(originalFileName, baseFileName);
          result =
              result
                  & solutionRepository.publish(
                      baseUrl, path, newFileName, aSolutionFile.getData(), overwrite);
        }
      }

      solutionRepository.resetRepository();
    } catch (Exception e) {
      AnalysisSaver.logger.error(
          Messages.getInstance().getErrorString("ANALYSISSAVER.ERROR_0000_UNKNOWN"),
          e); //$NON-NLS-1$
      result = ISolutionRepository.FILE_ADD_FAILED;
    }

    return result;
  }
Esempio n. 25
0
  /**
   * @param document
   * @param props
   * @return
   */
  private static Document updateDocument(final Document document, final HashMap props) {
    try {
      Element componentDefinition = null;
      Element actionOutput = null;
      Element actionSequenceOutput = null;

      Node actionSequence = document.selectSingleNode("/action-sequence"); // $NON-NLS-1$
      if (actionSequence == null) {
        throw new InvalidDocumentException(
            Messages.getInstance()
                .getErrorString("ANALYSISSAVER.ERROR_0004_INVALID_ORIGIN_DOCUMENT")); // $NON-NLS-1$
      }
      Element asElement = ((Element) actionSequence);
      Node title = null;
      String propertyTitle = (String) props.get(AnalysisSaver.TITLE_NODE_NAME);
      title = asElement.selectSingleNode(AnalysisSaver.TITLE_NODE_NAME);
      if ((title == null) && (propertyTitle != null)) {
        title = asElement.addElement(AnalysisSaver.TITLE_NODE_NAME);
      }

      if ((title != null) && (propertyTitle != null)) {
        // remove existing text if it's there
        title.setText(""); // $NON-NLS-1$
        ((Element) title).addCDATA(propertyTitle); // adds CDATA
      }

      // Next, we need to retrieve the PivotViewComponent action and
      // process/update it.. there could possibly be more than one
      // PivotViewComponent in an action sequence, however, we have no idea
      // how to figure out which one to process, so we default to picking the last one we found.

      componentDefinition =
          (Element)
              document.selectSingleNode(
                  "//action-definition[component-name='PivotViewComponent']/component-definition"); //$NON-NLS-1$
      if (componentDefinition == null) {
        throw new InvalidDocumentException(
            Messages.getInstance()
                .getErrorString("ANALYSISSAVER.ERROR_0005_INVALID_NO_PIVOT_ACTION")); // $NON-NLS-1$
      }

      AnalysisSaver.updateComponent(componentDefinition, props);

      // Get the action's root action-output node, in case we need to add the
      // appropriate outputs for the pivot view...
      actionOutput =
          (Element)
              document.selectSingleNode(
                  "//action-definition[component-name='PivotViewComponent']/action-outputs"); //$NON-NLS-1$
      AnalysisSaver.updateOutput(actionOutput, props);

      // Get the action's root action sequence output node, in case we need to add the
      // appropriate outputs for the pivot view...
      actionSequenceOutput =
          (Element) document.selectSingleNode("//action-sequence/outputs"); // $NON-NLS-1$
      AnalysisSaver.updateOutput(actionSequenceOutput, props);

    } catch (Exception e) {
      e.printStackTrace();
    }
    return document;
  }
  /**
   * determines state of component, and executes accordingly.
   *
   * <p>various inputs that impact the state include:
   *
   * <p>live - returns a live result set vs. an in memory copy transform - transform a result set
   * based on additional inputs prepared_component - if available, use existing connection from
   * prepared component max_rows - sets the number of rows that should be returned in result sets
   *
   * <p>The specified output also impacts the state of the execution. If prepared_component is
   * defined as an output, setup the query but delay execution.
   */
  @Override
  protected boolean executeAction() {
    IActionDefinition actionDefinition = getActionDefinition();
    try {

      if (actionDefinition instanceof AbstractRelationalDbAction) {
        AbstractRelationalDbAction relationalDbAction =
            (AbstractRelationalDbAction) actionDefinition;
        // Added by Arijit Chatterjee
        IActionInput queryTimeoutInput = relationalDbAction.getQueryTimeout();
        IActionInput maxRowsInput = relationalDbAction.getMaxRows();
        IActionInput readOnlyInput = relationalDbAction.getReadOnly();

        String baseQuery = getQuery();
        if (baseQuery == null) {
          error(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED",
                      actionDefinition.getDescription())); // $NON-NLS-1$
          return false;
        }

        IPreparedComponent sharedConnection =
            (IPreparedComponent) relationalDbAction.getSharedConnection().getValue();

        if (readOnlyInput != ActionInputConstant.NULL_INPUT) {
          this.setReadOnly(readOnlyInput.getBooleanValue());
        }

        if (sharedConnection != null) {
          connectionOwner = false;
          IPentahoConnection conn = sharedConnection.shareConnection();
          if (conn == null) {
            error(
                Messages.getInstance()
                    .getErrorString(
                        "IPreparedComponent.ERROR_0002_CONNECTION_NOT_AVAILABLE",
                        getActionName())); //$NON-NLS-1$
            return false;
          } else if (conn.getDatasourceType() == IPentahoConnection.SQL_DATASOURCE) {
            connection = conn;
          } else {
            error(
                Messages.getInstance()
                    .getErrorString(
                        "IPreparedComponent.ERROR_0001_INVALID_CONNECTION_TYPE",
                        getActionName())); //$NON-NLS-1$
            return false;
          }
        } else {
          dispose();
          connection = getDatasourceConnection();
        }

        if (connection == null) {
          return false;
        }

        // Check if this is a prepared query that will be executed later. If so cache the
        // query and set this component as the output. This query will be run later from a
        // subreport.
        if (relationalDbAction.getOutputPreparedStatement() != null) {
          prepareQuery(baseQuery);
          IActionOutput actionOutput = relationalDbAction.getOutputPreparedStatement();
          if (actionOutput != null) {
            actionOutput.setValue(this);
          }
          return true;
        }

        // TODO not sure if this should be allowed without connection ownership?
        // int maxRows = relationalDbAction.getMaxRows().getIntValue(-1);
        if (maxRowsInput != ActionInputConstant.NULL_INPUT) {
          this.setMaxRows(maxRowsInput.getIntValue());
        }

        // Added by Arijit Chatterjee.Sets the value of timeout. Default is -1, if parameter not
        // found.
        if (queryTimeoutInput != ActionInputConstant.NULL_INPUT) {
          this.setQueryTimeout(queryTimeoutInput.getIntValue());
        }

        if (relationalDbAction.getPerformTransform().getBooleanValue(false)) {
          runQuery(baseQuery, false); // The side effect of
          // transform rSet here

          rSet =
              PentahoDataTransmuter.crossTab(
                  rSet,
                  relationalDbAction.getTransformPivotColumn().getIntValue(-1) - 1,
                  relationalDbAction.getTransformMeasuresColumn().getIntValue(-1) - 1,
                  relationalDbAction.getTransformSortColumn().getIntValue(0) - 1,
                  (Format) relationalDbAction.getTransformPivotDataFormat().getValue(),
                  (Format) relationalDbAction.getTransformSortDataFormat().getValue(),
                  relationalDbAction.getTransformOrderOutputColumns().getBooleanValue(false));

          IActionOutput actionOutput = relationalDbAction.getOutputResultSet();
          if (actionOutput != null) {
            actionOutput.setValue(rSet);
          }
          return true;
        } else {
          return runQuery(baseQuery, relationalDbAction.getLive().getBooleanValue(false));
        }
      } else if (actionDefinition instanceof SqlConnectionAction) {
        SqlConnectionAction sqlConnectionAction = (SqlConnectionAction) actionDefinition;
        dispose();
        connection = getDatasourceConnection();
        if (connection == null) {
          return false;
        } else {
          IActionOutput actionOutput = sqlConnectionAction.getOutputConnection();
          if (actionOutput != null) {
            actionOutput.setValue(this);
            return true;
          } else {
            return false;
          }
        }
      }
    } catch (Exception e) {
      error(
          Messages.getInstance()
              .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
          e); //$NON-NLS-1$
    }

    return false;
  }
  /**
   * executes a prepared method that returns a result set executePrepared looks up any
   * "PREPARELATER" params in the preparedParams map.
   *
   * @param preparedParams a map of possible parameters.
   * @return result set
   */
  public IPentahoResultSet executePrepared(final Map preparedParams) {
    try {
      if (connection == null) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return null;
      }
      if (!connection.initialized()) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return null;
      }

      if (preparedQuery == null) {
        error(
            Messages.getInstance()
                .getErrorString(
                    "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED",
                    getActionName())); //$NON-NLS-1$
        return null;
      }

      // copy the preparedParams list, so it can be used multiple times.
      ArrayList copyOfPreparedParameters = new ArrayList(preparedParameters);

      // parse preparedQuery, replacing any {PREPARELATER:NAME} with appropriate values
      String query =
          TemplateUtil.applyTemplate(
              preparedQuery,
              getRuntimeContext(),
              new ParamResolver(copyOfPreparedParameters, preparedParams));

      if (ComponentBase.debug) {
        dumpQuery(query);
      }

      // evaluate
      IPentahoResultSet resultSet = null;
      if (preparedParameters.size() > 0) {
        resultSet = connection.prepareAndExecuteQuery(query, copyOfPreparedParameters);
      } else {
        resultSet = connection.executeQuery(query);
      }

      if (connection instanceof SQLConnection) {
        if (((SQLConnection) connection).isForcedForwardOnly()) {
          warn(
              Messages.getInstance()
                  .getString("SQLBaseComponent.WARN_FALL_BACK_TO_NONSCROLLABLE")); // $NON-NLS-1$
        }
      }

      boolean live = true;
      IActionDefinition actionDefinition = getActionDefinition();
      if (actionDefinition instanceof AbstractRelationalDbAction) {
        AbstractRelationalDbAction relationalDbAction =
            (AbstractRelationalDbAction) actionDefinition;
        live = relationalDbAction.getLive().getBooleanValue(false);
      }

      IPentahoResultSet rs = resultSet;

      // BISERVER-5915, BISERVER-5875 - if the live setting is false, return an in memory resultset.
      if (!live) {
        rs = resultSet.memoryCopy();
      }

      rSet = rs;
      return rs;

    } catch (Exception e) {
      error(
          Messages.getInstance()
              .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
          e); //$NON-NLS-1$
    }
    return null;
  }
  /**
   * executes the specified query template. The query template is first formatted and then executed.
   * If live, the original result set is made available as an output. If not live, the result set is
   * converted into memory and the connection and live result set are closed.
   *
   * @param rawQuery query template
   * @param live returns original result set if true, memory result set if false
   * @return true if successful
   */
  protected boolean runQuery(final String rawQuery, boolean live) {
    try {
      if ((connection == null) || !connection.initialized()) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return false;
      }

      String query = applyInputsToFormat(rawQuery);
      SQLConnection sqlConnection = null;
      if ((connection instanceof SQLConnection)) {
        sqlConnection = (SQLConnection) connection;
      }
      // Some of the following Added by Arijit Chatterjee passing the timeout value to SQLConnection
      // class
      if (sqlConnection != null) {
        if (this.getQueryTimeout() >= 0) {
          sqlConnection.setQueryTimeout(this.getQueryTimeout());
        }
        if (this.getMaxRows() >= 0) {
          sqlConnection.setMaxRows(this.getMaxRows());
        }
        if (this.getReadOnly()) {
          sqlConnection.setReadOnly(true);
        }
      }

      AbstractRelationalDbAction relationalDbAction =
          (AbstractRelationalDbAction) getActionDefinition();

      IPentahoResultSet resultSet = null;
      boolean isForwardOnly =
          relationalDbAction.getUseForwardOnlyResultSet().getBooleanValue(false);

      resultSet = doQuery(sqlConnection, query, isForwardOnly);

      if (sqlConnection.isForcedForwardOnly()) {
        isForwardOnly = true;
        live = false;
        warn(
            Messages.getInstance()
                .getString("SQLBaseComponent.WARN_FALL_BACK_TO_NONSCROLLABLE")); // $NON-NLS-1$
      }

      if (live) {

        // set the result set as the output
        rSet = resultSet;

        // After preparation and execution, we need to clear out the
        // prepared parameters.
        preparedParameters.clear();
        if (resultSet != null) {
          getMetadata(resultSet, true);
          IActionOutput actionOutput = relationalDbAction.getOutputResultSet();
          if (actionOutput != null) {
            actionOutput.setValue(resultSet);
          }
          return true;
        } else {
          // close the connection if owner
          error(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0006_EXECUTE_FAILED",
                      getActionName())); //$NON-NLS-1$
          if (connectionOwner) {
            connection.close();
          }
          return false;
        }

      } else {
        // execute the query, read the results and cache them
        try {
          // After preparation and execution, we need to clear out the
          // prepared parameters.
          preparedParameters.clear();

          IPentahoResultSet cachedResultSet = resultSet.memoryCopy();
          rSet = cachedResultSet;

          IActionOutput actionOutput = relationalDbAction.getOutputResultSet();
          if (actionOutput != null) {
            actionOutput.setValue(cachedResultSet);
          }
        } finally {
          // close the connection if owner
          if (connectionOwner) {
            connection.close();
            connection = null;
          }
        }
      }
      return true;
    } catch (Exception e) {
      error(
          Messages.getInstance()
              .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
          e); //$NON-NLS-1$
    }

    return false;
  }
  /**
   * This method is called when TemplateUtil.applyTemplate() encounters a parameter.
   * TemplateUtil.applyTemplate is called when someone makes a call to applyInputsToFormat() In this
   * class it is called in the above "runQuery()" method.
   *
   * @param template the source string
   * @param parameter the parameter value
   * @param parameterMatcher the regex parameter matcher
   * @param copyStart the start of the copy
   * @param results the output result
   * @return the next copystart
   */
  @Override
  public int resolveParameter(
      final String template,
      final String parameter,
      final Matcher parameterMatcher,
      int copyStart,
      final StringBuffer results) {

    StringTokenizer tokenizer = new StringTokenizer(parameter, ":"); // $NON-NLS-1$
    if (tokenizer.countTokens() == 2) { // Currently, the component only handles one bit of metadata
      String parameterPrefix = tokenizer.nextToken();
      String inputName = tokenizer.nextToken();

      // if the template contains a prepare later prefix,
      // mark a spot in the preparedParameters list and move on.
      if (parameterPrefix.equals(IPreparedComponent.PREPARE_LATER_PREFIX)) {
        if (!isDefinedOutput(IPreparedComponent.PREPARED_COMPONENT_NAME)) {
          error(
              Messages.getInstance()
                  .getErrorString(
                      "IPreparedComponent.ERROR_0003_INVALID_PARAMETER_STATE")); //$NON-NLS-1$
          return -1;
        }
        preparedParameters.add(IPreparedComponent.PREPARE_LATER_PLACEHOLDER);
        int start = parameterMatcher.start();
        int end = parameterMatcher.end();
        results.append(template.substring(copyStart, start));
        results.append(
            "{"
                + IPreparedComponent.PREPARE_LATER_INTER_PREFIX
                + ":"
                + inputName
                + "}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        return end;
      }

      if (parameterPrefix.equals(SQLBaseComponent.PREPARE_PARAMETER_PREFIX)) {
        // We know this parameter is for us.
        // First, is this a special input
        Object parameterValue = TemplateUtil.getSystemInput(inputName, getRuntimeContext());
        if ((parameterValue == null) && isDefinedInput(inputName)) {
          parameterValue = this.getInputValue(inputName);
        }
        if (parameterValue != null) {
          // We have a parameter value - now, it's time to create a parameter and build up the
          // parameter string
          int start = parameterMatcher.start();
          int end = parameterMatcher.end();
          // First, find out if the parameter was quoted...
          if ((start > 0) && (end < template.length())) {
            if ((template.charAt(start - 1) == '\'') && (template.charAt(end) == '\'')) {
              // Ok, the parameter was quoted as near as we can tell. So, we need
              // to increase the size of the amount we overwrite by one in each
              // direction. This is for backward compatibility.
              start--;
              end++;
            }
          }
          // We now have a valid start and end. It's time to see whether we're dealing
          // with an array, a result set, or a scalar.
          StringBuffer parameterBuffer = new StringBuffer();
          if (parameterValue instanceof String) {
            preparedParameters.add(parameterValue);
            parameterBuffer.append('?');
          } else if (parameterValue instanceof Object[]) {
            Object[] pObj = (Object[]) parameterValue;
            for (Object element : pObj) {
              preparedParameters.add(element);
              parameterBuffer.append(
                  (parameterBuffer.length() == 0) ? "?" : ",?"); // $NON-NLS-1$ //$NON-NLS-2$
            }
          } else if (parameterValue instanceof IPentahoResultSet) {
            IPentahoResultSet rs = (IPentahoResultSet) parameterValue;
            // See if we can find a column in the metadata with the same
            // name as the input
            IPentahoMetaData md = rs.getMetaData();
            int columnIdx = -1;
            if (md.getColumnCount() == 1) {
              columnIdx = 0;
            } else {
              columnIdx = md.getColumnIndex(new String[] {parameter});
            }
            if (columnIdx < 0) {
              error(
                  Messages.getInstance()
                      .getErrorString(
                          "Template.ERROR_0005_COULD_NOT_DETERMINE_COLUMN")); //$NON-NLS-1$
              return -1;
            }
            int rowCount = rs.getRowCount();
            Object valueCell = null;
            // TODO support non-string columns
            for (int i = 0; i < rowCount; i++) {
              valueCell = rs.getValueAt(i, columnIdx);
              preparedParameters.add(valueCell);
              parameterBuffer.append(
                  (parameterBuffer.length() == 0) ? "?" : ",?"); // $NON-NLS-1$ //$NON-NLS-2$
            }
          } else if (parameterValue instanceof List) {
            List pObj = (List) parameterValue;
            for (int i = 0; i < pObj.size(); i++) {
              preparedParameters.add(pObj.get(i));
              parameterBuffer.append(
                  (parameterBuffer.length() == 0) ? "?" : ",?"); // $NON-NLS-1$ //$NON-NLS-2$
            }
          } else {
            // If we're here, we know parameterValue is not null and not a string
            this.preparedParameters.add(parameterValue);
            parameterBuffer.append('?');
          }

          // OK - We have a parameterBuffer and have filled out the preparedParameters
          // list. It's time to change the SQL to insert our parameter marker and tell
          // the caller we've done our job.
          results.append(template.substring(copyStart, start));
          copyStart = end;
          results.append(parameterBuffer);
          return copyStart;
        }
      }
    }

    return -1; // Nothing here for us - let default behavior through
  }
  @Override
  protected boolean executeAction() {
    String printFileName = null;
    IActionSequenceResource printFileResource = null;
    PrinterAction printAction = (PrinterAction) getActionDefinition();

    if (printAction.getPrintfile() != ActionInputConstant.NULL_INPUT) {
      printFileName = printAction.getPrintfile().getStringValue();
    } else if (printAction.getResourcesPrintFile() != null) {
      org.pentaho.actionsequence.dom.IActionResource tempResource =
          printAction.getResourcesPrintFile();
      printFileResource = getResource(tempResource.getName());
    }

    InputStream inStream = null;
    String printerName =
        printAction.getPrinterName().getStringValue(PrintComponent.DEFAULT_PRINTER);
    String lastPrinter = printAction.getDefaultPrinter().getStringValue();

    if ((printAction.getOutputPrinterName() != null) && !printerName.equals("")) { // $NON-NLS-1$
      IActionOutput output = printAction.getOutputPrinterName();
      output.setValue(printerName);
      if (printAction.getOutputDefaultPrinter() != null) {
        IActionOutput defaultPrinterOutput = printAction.getOutputDefaultPrinter();
        defaultPrinterOutput.setValue(printerName);
      }
      return true;
    }

    PrintService printer = getPrinterInternal(printerName, lastPrinter);
    if (printer == null) {
      if (!feedbackAllowed()) {
        error(
            Messages.getInstance()
                .getErrorString("PrintComponent.ERROR_0002_NO_SUITABLE_PRINTER")); // $NON-NLS-1$
        return false;
      }
      // we created the printer feedback entry already
      return true;
    }

    if (printAction.getOutputDefaultPrinter() != null) {
      IActionOutput defaultPrinterOutput = printAction.getOutputDefaultPrinter();
      defaultPrinterOutput.setValue(printerName);
    }

    // Get the number of copies
    int copies = printAction.getCopies().getIntValue(1);

    // Check for a valid printFileName or printFile Resource
    if (printFileName != null) {
      inStream = ActionSequenceResource.getInputStream(printFileName, LocaleHelper.getLocale());
    } else if (printFileResource != null) {
      try {
        inStream = getResourceInputStream(printFileResource);
      } catch (FileNotFoundException e) {
        return false;
      }
    } else if (printAction.getReportOutput() != ActionInputConstant.NULL_INPUT) {
      inStream = getInputStream(PrinterAction.REPORT_OUTPUT);
    } else { // This should never happen if we validated ok.
      return false;
    }
    try {

      // Set the input source for sending to the driver.
      //      InputSource source = new InputSource(inStream);
      try {

        FopFactory fopFactory = FopFactory.newInstance();
        FOUserAgent userAgent = fopFactory.newFOUserAgent();
        PrinterJob printerJob = PrinterJob.getPrinterJob();

        // Set up our own PrintRenderer instance so we can supply a special PrinterJob instance.
        PrintRenderer renderer = new PrintRenderer(printerJob, copies);
        renderer.setUserAgent(userAgent);
        userAgent.setRendererOverride(renderer);

        // Construct fop with desired output format (here, it is set through the user agent)
        Fop fop = fopFactory.newFop(userAgent);

        // Setup JAXP using identity transformer
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(); // identity transformer

        // Setup input stream
        Source src = new StreamSource(inStream);

        // Resulting SAX events (the generated FO) must be piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        // Start XSLT transformation and FOP processing
        transformer.transform(src, res);

      } catch (Exception ex) {
        return false;
      }
    } finally {
      try {
        inStream.close();
      } catch (IOException ex) {
        // TODO: Provide message here...
        ex.printStackTrace();
      }
    }
    return true;
  }