/**
   * @throws ParseException
   * @throws org.pentaho.platform.plugin.services.importexport.ExportException
   * @throws java.io.IOException
   */
  protected void performExportLegacy() throws ParseException, ExportException, IOException {

    // path is validated before executing
    String filepath =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_NAME"),
            true,
            false);

    String logFile =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LOGFILE_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LOGFILE_NAME"),
            false,
            true);

    if (!isValidExportPath(filepath, logFile)) {
      throw new ExportException("file-path:" + filepath);
    }

    final Exporter exportProcessor = getExportProcessor();
    exportProcessor.doExport();
    // throw new UnsupportedOperationException(); // TODO implement
  }
예제 #2
0
  public void testScriptRule() {
    startTest();

    SimpleParameterProvider parameterProvider = new SimpleParameterProvider();
    parameterProvider.setParameter("customer", "Acme"); // $NON-NLS-1$ //$NON-NLS-2$

    IRuntimeContext context =
        run(
            "/test/rules/script_rule1.xaction",
            parameterProvider); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_SUCCESS,
        context.getStatus()); // $NON-NLS-1$

    assertNotNull(
        Messages.getInstance().getString("RulesTest.ERROR_0001_NULL_RESULT"),
        context.getOutputParameter("rule-result")); // $NON-NLS-1$ //$NON-NLS-2$
    assertEquals(
        Messages.getInstance().getString("RulesTest.ERROR_0002_WRONG_RESULT"),
        "Central",
        context
            .getOutputParameter("rule-result")
            .getStringValue()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    info(
        Messages.getInstance()
            .getString(
                "RulesTest.DEBUG_0003_SCRIPT_RULE_SUCCESS",
                context
                    .getOutputParameter("rule-result")
                    .getStringValue())); //$NON-NLS-1$ //$NON-NLS-2$
    finishTest();
  }
예제 #3
0
  public void testScriptCompoundResult() {
    startTest();
    info(
        Messages.getInstance()
            .getString("RulesTest.USER_ERRORS_EXPECTED_SCRIPT_INVALID")); // $NON-NLS-1$
    IRuntimeContext context =
        run("/test/rules/script_rule3.xaction"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_SUCCESS,
        context.getStatus()); // $NON-NLS-1$

    assertNotNull(context.getOutputParameter("fruit")); // $NON-NLS-1$
    assertNotNull(context.getOutputParameter("veg")); // $NON-NLS-1$
    assertEquals(
        "bad",
        "apples",
        context
            .getOutputParameter("fruit")
            .getStringValue()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        "bad",
        "carrots",
        context
            .getOutputParameter("veg")
            .getStringValue()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
    finishTest();
  }
 protected static void printHelp() {
   HelpFormatter formatter = new HelpFormatter();
   formatter.printHelp(
       Messages.getInstance().getString("CommandLineProcessor.INFO_PRINTHELP_CMDLINE"),
       Messages.getInstance().getString("CommandLineProcessor.INFO_PRINTHELP_HEADER"),
       options,
       Messages.getInstance().getString("CommandLineProcessor.INFO_PRINTHELP_FOOTER"));
 }
 /**
  * this process must run on the same box as the JCR repository does not use REST
  *
  * @throws Exception ;
  * @throws org.pentaho.platform.plugin.services.importexport.ImportException
  */
 protected void performImportLegacy() throws Exception, ImportException {
   final ImportProcessor importProcessor = getImportProcessor();
   importProcessor.setImportSource(createImportSource());
   addImportHandlers(importProcessor);
   String overwrite =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_OVERWRITE_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_OVERWRITE_NAME"),
           false,
           true);
   importProcessor.performImport(
       Boolean.valueOf(overwrite == null ? "true" : overwrite).booleanValue());
 }
 /**
  * Returns the option value from the command line
  *
  * @param option the option whose value should be returned (NOTE: {@code null} will be returned if
  *     the option was not provided)
  * @param required indicates if the option is required
  * @param emptyOk indicates if a blank value is acceptable
  * @return the value provided from the command line, or {@code null} if none was provided
  * @throws ParseException indicates the required or non-blank value was not provided
  */
 protected String getOptionValue(
     final String option, final boolean required, final boolean emptyOk) throws ParseException {
   final String value = StringUtils.trim(commandLine.getOptionValue(option));
   if (required && StringUtils.isEmpty(value)) {
     throw new ParseException(
         Messages.getInstance()
             .getErrorString("CommandLineProcessor.ERROR_0001_MISSING_ARG", option));
   }
   if (!emptyOk && StringUtils.isEmpty(value)) {
     throw new ParseException(
         Messages.getInstance()
             .getErrorString("CommandLineProcessor.ERROR_0001_MISSING_ARG", option));
   }
   return value;
 }
 /**
  * Determines the {@link org.pentaho.platform.plugin.services.importexport.ImportProcessor} to be
  * used by evaluating the command line
  *
  * @return the @{link ImportProcessor} to be used for importing - or the {@link
  *     org.pentaho.platform.plugin.services.importexport.SimpleImportProcessor} if one can not be
  *     determined
  */
 protected ImportProcessor getImportProcessor() throws ParseException {
   final String comment =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_COMMENT_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_COMMENT_NAME"),
           false,
           true);
   final String destinationPath =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_NAME"),
           true,
           false);
   return new SimpleImportProcessor(destinationPath, comment);
 }
 public void testHelloWorldComponent() {
   startTest();
   String testName = HW_TEST_NAME + System.currentTimeMillis();
   SimpleParameterProvider parameterProvider = new SimpleParameterProvider();
   IRuntimeContext context =
       run(
           "/test/platform/HelloWorld.xaction",
           parameterProvider,
           testName,
           HW_TEST_EXTN); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
   assertEquals(
       Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
       IRuntimeContext.RUNTIME_STATUS_SUCCESS,
       context.getStatus()); // $NON-NLS-1$
   if (context != null) {
     // do nothing...
   }
   InputStream is = this.getInputStreamFromOutput(testName, HW_TEST_EXTN);
   assertNotNull(is); // Did the test execute properly...
   String lookingFor =
       "\nHello World. (2B || !2B) That is the question\n"; //$NON-NLS-1$ //$NON-NLS-2$
   String wasRead = FileHelper.getStringFromInputStream(is);
   assertEquals(wasRead, lookingFor);
   finishTest();
 }
  public void testIPreparedComponentXQueryShareConnection() {
    startTest();
    info("Expected: Successful execution with object available"); // $NON-NLS-1$
    IRuntimeContext context =
        run(
            "test",
            "ipreparedcomponents",
            "ipreparedcomponent_xquery_shareconn.xaction"); //$NON-NLS-1$ //$NON-NLS-2$
                                                            // //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_SUCCESS,
        context.getStatus()); // $NON-NLS-1$

    IActionParameter rtn1 = context.getOutputParameter("prepared_component"); // $NON-NLS-1$
    assertNotNull(rtn1);
    IPreparedComponent preparedComponent1 = (IPreparedComponent) rtn1.getValue();
    assertNotNull(preparedComponent1);
    IPentahoResultSet resultset1 = preparedComponent1.executePrepared(null);
    assertTrue(resultset1.getRowCount() >= 1);
    Object val1 = resultset1.getValueAt(0, 0);
    assertNotNull(val1);

    finishTest();
  }
 private Exporter getExportProcessor() throws ParseException {
   final IUnifiedRepository repository = getRepository();
   String path =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_NAME"),
           true,
           false);
   String filepath =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_NAME"),
           true,
           false);
   final Exporter exportProcess = new Exporter(repository, path, filepath);
   return exportProcess;
 }
예제 #11
0
  public void testScriptRuleError4() {
    startTest();

    info(
        "This should generate errors because the input to the script has a minus sign in the input name."); //$NON-NLS-1$
    IRuntimeContext context =
        run("/test/rules/script_rule_error4.xaction"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_FAILURE,
        context.getStatus()); // $NON-NLS-1$
    assertEquals(
        Messages.getInstance().getString("RulesTest.ERROR_0005_RESULT_WHEN_NULL_EXPECTED"),
        null,
        context.getOutputParameter("rule-result").getStringValue()); // $NON-NLS-1$//$NON-NLS-2$
    finishTest();
  }
  /**
   * Parses the command line and handles the situation where it isn't a valid import or export or
   * rest request
   *
   * @param args the command line arguments
   * @throws ParseException indicates that neither (or both) an import and/or export have been
   *     request
   */
  protected CommandLineProcessor(String[] args) throws ParseException {
    // parse the command line arguments
    commandLine = new PosixParser().parse(options, args);
    if (commandLine.hasOption(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_HELP_NAME"))
        || commandLine.hasOption(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_HELP_KEY"))) {
      requestType = RequestType.HELP;
    } else {
      if (commandLine.hasOption(
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_REST_NAME"))
          || commandLine.hasOption(
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_REST_KEY"))) {
        requestType = RequestType.REST;
      } else {
        final boolean importRequest =
            commandLine.hasOption(
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_IMPORT_KEY"));
        final boolean exportRequest =
            commandLine.hasOption(
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_EXPORT_KEY"));

        if (importRequest == exportRequest) {
          throw new ParseException(
              Messages.getInstance()
                  .getErrorString("CommandLineProcessor.ERROR_0003_PARSE_EXCEPTION"));
        }
        requestType = (importRequest ? RequestType.IMPORT : RequestType.EXPORT);
      }
    }
  }
예제 #13
0
  public void testScriptRuleError2() {
    startTest();
    info(
        Messages.getInstance()
            .getString("RulesTest.USER_ERRORS_EXPECTED_OUTPUT_NOT_DEFINED")); // $NON-NLS-1$
    IRuntimeContext context =
        run("/test/rules/script_rule_error2.xaction"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_CONTEXT_VALIDATE_FAIL,
        context.getStatus()); // $NON-NLS-1$

    assertEquals(
        Messages.getInstance().getString("RulesTest.ERROR_0006_RESULT_WHEN_ERROR_EXPECTED"),
        false,
        context.getOutputNames().contains("rule-result")); // $NON-NLS-1$//$NON-NLS-2$
    finishTest();
  }
예제 #14
0
  public void testScriptRuleError3() {
    startTest();
    info(
        Messages.getInstance()
            .getString("RulesTest.USER_ERRORS_EXPECTED_SCRIPT_INVALID")); // $NON-NLS-1$
    IRuntimeContext context =
        run("/test/rules/script_rule_error3.xaction"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_FAILURE,
        context.getStatus()); // $NON-NLS-1$

    assertEquals(
        Messages.getInstance().getString("RulesTest.ERROR_0005_RESULT_WHEN_NULL_EXPECTED"),
        null,
        context.getOutputParameter("rule-result").getStringValue()); // $NON-NLS-1$//$NON-NLS-2$
    finishTest();
  }
  /**
   * How this class is executed from the command line. It will create an instance of an {@link
   * org.pentaho.platform.plugin.services.importexport.ImportProcessor} and initialize it base on
   * the options provided on the command line.
   *
   * @param args
   */
  public static void main(String[] args) throws Exception {

    try {
      // reset the exception information
      exception = null;

      final CommandLineProcessor commandLineProcessor = new CommandLineProcessor(args);
      String legacy =
          commandLineProcessor.getOptionValue(
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_KEY"),
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_NAME"),
              false,
              true);

      useRestService =
          "false".equals(legacy) ? false : true; // default to new REST version if not provided
      // new service only
      switch (commandLineProcessor.getRequestType()) {
        case HELP:
          printHelp();
          break;

        case IMPORT:
          commandLineProcessor.performImport();
          break;

        case EXPORT:
          commandLineProcessor.performExport();
          break;
        case REST:
          commandLineProcessor.performREST();
          break;
      }
    } catch (ParseException parseException) {
      exception = parseException;
      System.err.println(parseException.getLocalizedMessage());
      printHelp();
    } catch (Exception e) {
      exception = e;
      e.printStackTrace();
      log.error(e.getMessage(), e);
    }
  }
 /**
  * Used only for REST Jersey calls
  *
  * @throws ParseException
  */
 private void initRestService() throws ParseException {
   // get information about the remote connection
   String username =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_NAME"),
           true,
           false);
   String password =
       getOptionValue(
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_KEY"),
           Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_NAME"),
           true,
           false);
   ClientConfig clientConfig = new DefaultClientConfig();
   clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
   client = Client.create(clientConfig);
   client.addFilter(new HTTPBasicAuthFilter(username, password));
 }
  /**
   * Creates and adds the set of {@link
   * org.pentaho.platform.plugin.services.importexport.ImportHandler}s to be used with this import
   * process
   *
   * @param importProcessor the import processor in which the import handlers should be created
   */
  protected void addImportHandlers(final ImportProcessor importProcessor) throws ParseException {
    // TODO - Need a way to either (a) have all ImportProcessors use the
    // same set or (b) use spring to initialize this
    final IUnifiedRepository repository = getRepository();

    String username =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_NAME"),
            true,
            false);
    String password =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_NAME"),
            true,
            false);
    String url =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_NAME"),
            true,
            false);

    importProcessor.addImportHandler(new MondrianImportHandler(username, password, url));
    importProcessor.addImportHandler(new MetadataImportHandler(username, password, url));
    importProcessor.addImportHandler(new DefaultImportHandler(repository));
  }
 /**
  * Returns the option value from the command line
  *
  * @param shortOption the single character option whose value should be returned (NOTE: {@code
  *     null} will be returned if the option was not provided)
  * @param longOption the string option whose value should be returned (NOTE: {@code null} will be
  *     returned if the option was not provided)
  * @param required indicates if the option is required
  * @param emptyOk indicates if a blank value is acceptable
  * @return the value provided from the command line, or {@code null} if none was provided
  * @throws ParseException indicates the required or non-blank value was not provided
  */
 protected String getOptionValue(
     final String shortOption,
     final String longOption,
     final boolean required,
     final boolean emptyOk)
     throws ParseException {
   // first try the short option parameter
   String value = StringUtils.trim(commandLine.getOptionValue(shortOption));
   if (StringUtils.isEmpty(value)) {
     // if its empty, try the long option
     value = StringUtils.trim(commandLine.getOptionValue(longOption));
   }
   if (required && StringUtils.isEmpty(value)) {
     throw new ParseException(
         Messages.getInstance()
             .getErrorString("CommandLineProcessor.ERROR_0001_MISSING_ARG", longOption));
   }
   if (!emptyOk && StringUtils.isEmpty(value)) {
     throw new ParseException(
         Messages.getInstance()
             .getErrorString("CommandLineProcessor.ERROR_0001_MISSING_ARG", longOption));
   }
   return value;
 }
  public void testIPreparedComponentXQueryAvailableErrorNoPrepareComponent() {
    startTest();
    info("Expected: Successful execution with object available"); // $NON-NLS-1$
    IRuntimeContext context =
        run(
            "test",
            "ipreparedcomponents",
            "ipreparedcomponent_xquery_available_error_nopreparedcomponent.xaction"); //$NON-NLS-1$
                                                                                      // //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_CONTEXT_VALIDATE_FAIL,
        context.getStatus()); // $NON-NLS-1$

    finishTest();
  }
  /** Load the web services from the list of web service wrappers */
  public void loadServices() {

    List<IServiceConfig> wsDfns = getWebServiceDefinitions();

    for (IServiceConfig wsDef : wsDfns) {
      try {
        loadService(wsDef);
      } catch (Exception e) {
        // Axis cannot handle a typed exception from this method, we must just log the error and
        // continue on
        Logger.error(
            getClass().getName(),
            Messages.getInstance()
                .getErrorString(
                    "AbstractAxisConfigurator.ERROR_0001_COULD_NOT_LOAD_SERVICE", wsDef.getId()),
            e); //$NON-NLS-1$
      }
    }
  }
예제 #21
0
  public void testQueryRule() {
    startTest();

    IPentahoResultSet resultSet = null;
    try {
      IRuntimeContext context =
          run("/test/rules/query_rule1.xaction"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      assertEquals(
          Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
          IRuntimeContext.RUNTIME_STATUS_SUCCESS,
          context.getStatus()); // $NON-NLS-1$

      Object result = context.getOutputParameter("rule-result").getValue(); // $NON-NLS-1$
      assertNotNull(
          Messages.getInstance().getString("RulesTest.ERROR_0001_NULL_RESULT"),
          result); //$NON-NLS-1$

      assertTrue(
          Messages.getInstance().getString("RulesTest.ERROR_0007_LOOKUP_RULE_INVALID_RESULT"),
          (result instanceof IPentahoResultSet)); // $NON-NLS-1$

      resultSet = (IPentahoResultSet) result;
      IPentahoMetaData metaData = resultSet.getMetaData();
      Object[][] columnHeaders = metaData.getColumnHeaders();

      String columnHeader = columnHeaders[0][0].toString();

      assertEquals(
          Messages.getInstance().getString("RulesTest.ERROR_0009_LOOKUP_RULE_COLUMN_MISSING"),
          "POSITIONTITLE",
          columnHeader); //$NON-NLS-1$ //$NON-NLS-2$

      Object[] row = resultSet.next();
      assertNotNull(
          Messages.getInstance().getString("RulesTest.ERROR_0007_LOOKUP_RULE_INVALID_RESULT"),
          row); //$NON-NLS-1$

      info(
          Messages.getInstance()
              .getString("RulesTest.DEBUG_LOOKUP_RULE_SUCCESS", row[0].toString())); // $NON-NLS-1$

    } finally {
      if (resultSet != null) {
        resultSet.closeConnection();
      }
    }

    finishTest();
  }
  public void testIPreparedComponentSQLAvailable() {
    startTest();
    info("Expected: Successful execution with object available"); // $NON-NLS-1$
    IRuntimeContext context =
        run(
            "test",
            "ipreparedcomponents",
            "ipreparedcomponent_sql_available.xaction"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_SUCCESS,
        context.getStatus()); // $NON-NLS-1$

    IActionParameter rtn = context.getOutputParameter("prepared_component"); // $NON-NLS-1$
    assertNotNull(rtn);
    IPreparedComponent preparedComponent = (IPreparedComponent) rtn.getValue();

    assertNotNull(preparedComponent);

    finishTest();
  }
  public void testIPreparedComponentXQueryPrepareLater() {
    startTest();
    info("Expected: Successful execution with object available"); // $NON-NLS-1$
    IRuntimeContext context =
        run(
            "test",
            "ipreparedcomponents",
            "ipreparedcomponent_xquery_preparelater.xaction"); //$NON-NLS-1$ //$NON-NLS-2$
                                                               // //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_SUCCESS,
        context.getStatus()); // $NON-NLS-1$

    IActionParameter rtn1 = context.getOutputParameter("prepared_component"); // $NON-NLS-1$
    assertNotNull(rtn1);
    IPreparedComponent preparedComponent1 = (IPreparedComponent) rtn1.getValue();
    assertNotNull(preparedComponent1);
    IPentahoResultSet resultset1 = preparedComponent1.executePrepared(null);
    assertTrue(resultset1.getRowCount() >= 1);
    Object val1 = resultset1.getValueAt(0, 0);

    IActionParameter rtn2 = context.getOutputParameter("second_prepared_component"); // $NON-NLS-1$
    assertNotNull(rtn2);
    IPreparedComponent preparedComponent2 = (IPreparedComponent) rtn2.getValue();
    assertNotNull(preparedComponent2);
    HashMap map = new HashMap();
    map.put("POSITIONTITLE", "Engineer"); // $NON-NLS-1$ //$NON-NLS-2$
    IPentahoResultSet resultset2 = preparedComponent2.executePrepared(map);
    assertTrue(resultset2.getRowCount() >= 1);
    assertEquals(resultset1.getRowCount(), resultset2.getRowCount());

    Object val2 = resultset2.getValueAt(0, 0);

    assertEquals(
        "Values from the first and second query should be equal", val1, val2); // $NON-NLS-1$

    finishTest();
  }
  public void testIPreparedComponentXQueryAvailableErrorNoDocument() {
    startTest();
    IRuntimeContext context =
        run(
            "test",
            "ipreparedcomponents",
            "ipreparedcomponent_xquery_available_error_nodocument.xaction"); //$NON-NLS-1$
                                                                             // //$NON-NLS-2$
                                                                             // //$NON-NLS-3$
    assertEquals(
        Messages.getInstance().getString("BaseTest.USER_RUNNING_ACTION_SEQUENCE"),
        IRuntimeContext.RUNTIME_STATUS_FAILURE,
        context.getStatus()); // $NON-NLS-1$

    IActionParameter rtn = context.getOutputParameter("prepared_component"); // $NON-NLS-1$
    assertNotNull(rtn);
    IPreparedComponent preparedComponent = (IPreparedComponent) rtn.getValue();

    assertNull(preparedComponent);

    finishTest();
  }
예제 #25
0
  protected void init(Util.PropertyList properties) {
    try {
      if (nativeConnection != null) { // Assume we're open
        close();
      }

      // Set a locale for this connection if specified in the platform's mondrian metadata
      // This is required if mondrian.i18n.LocalizingDynamicSchemaProcessor is being used
      if (properties.get(RolapConnectionProperties.Locale.name()) == null) {
        properties.put(
            RolapConnectionProperties.Locale.name(), LocaleHelper.getLocale().toString());
      }

      String dataSourceName = properties.get(RolapConnectionProperties.DataSource.name());

      mapPlatformRolesToMondrianRoles(properties);

      if (dataSourceName != null) {
        IDBDatasourceService datasourceService =
            PentahoSystem.getObjectFactory().get(IDBDatasourceService.class, null);
        DataSource dataSourceImpl = datasourceService.getDataSource(dataSourceName);
        if (dataSourceImpl != null) {
          properties.remove(RolapConnectionProperties.DataSource.name());
          nativeConnection = DriverManager.getConnection(properties, null, dataSourceImpl);
        } else {
          nativeConnection = DriverManager.getConnection(properties, null);
        }
      } else {
        nativeConnection = DriverManager.getConnection(properties, null);
      }

      if (nativeConnection != null) {
        if (role != null) {
          nativeConnection.setRole(role);
        }
      }

      if (nativeConnection == null) {
        logger.error(
            Messages.getInstance()
                .getErrorString(
                    "MDXConnection.ERROR_0002_INVALID_CONNECTION",
                    properties != null
                        ? properties.toString()
                        : "null")); //$NON-NLS-1$ //$NON-NLS-2$
      }
    } catch (Throwable t) {
      if (logger != null) {
        logger.error(
            Messages.getInstance()
                .getErrorString(
                    "MDXConnection.ERROR_0002_INVALID_CONNECTION",
                    properties != null ? properties.toString() : "null"),
            t); //$NON-NLS-1$ //$NON-NLS-2$
      } else {
        Logger.error(
            this.getClass().getName(),
            Messages.getInstance()
                .getErrorString(
                    "MDXConnection.ERROR_0002_INVALID_CONNECTION",
                    properties != null ? properties.toString() : "null"),
            t); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
  }
/**
 * Handles the storage and retrieval of Pentaho Metada Domain objects in a repository. It does this
 * by using a pre-defined system location (defined by {@link PentahoMetadataDomainRepositoryInfo})
 * as the storage location for the Domain files and associated locale files. Since Domain IDs are
 * the unique identifier for Pentaho Metadata domains and may contain any character (including
 * repository folder separator character(s) like '/', a {@link UUID} will be created to store each
 * file. The metadata for the file will be used to store the information (such as the Domain ID).
 *
 * @author <a href="mailto:[email protected]">David M. Kincade</a>
 */
public class PentahoMetadataDomainRepository
    implements IMetadataDomainRepository,
        IModelAnnotationsAwareMetadataDomainRepositoryImporter,
        IAclAwarePentahoMetadataDomainRepositoryImporter,
        IPentahoMetadataDomainRepositoryExporter {
  // The logger for this class
  private static final Log logger = LogFactory.getLog(PentahoMetadataDomainRepository.class);

  // The messages object used in generating messages that may be seen by the user
  private static final Messages messages = Messages.getInstance();

  private static final Map<IUnifiedRepository, PentahoMetadataInformationMap> metaMapStore =
      new HashMap<IUnifiedRepository, PentahoMetadataInformationMap>();

  // The type of repository file (domain, locale)
  private static final String PROPERTY_NAME_TYPE = "file-type";

  private static final String TYPE_DOMAIN = "domain";
  private static final String TYPE_LOCALE = "locale";

  // The repository file metadata key used to store the file's domain id
  private static final String PROPERTY_NAME_DOMAIN_ID = "domain-id";

  // The repository file metadata key used to store the file's locale (properties files)
  private static final String PROPERTY_NAME_LOCALE = "locale";

  // The default encoding for file storage
  private static final String DEFAULT_ENCODING = "UTF-8";

  // The default mime-type for the Pentaho Domain files
  private static final String DOMAIN_MIME_TYPE = "text/xml";

  // The default mime-type for locale files
  private static final String LOCALE_MIME_TYPE = "text/plain";

  // caching immutable object
  private static final EnumSet<RepositoryFilePermission> READ =
      EnumSet.of(RepositoryFilePermission.READ);

  // The repository used to store / retrieve objects
  private IUnifiedRepository repository;

  // Mapping between the Pentaho Metadata Domain ID and the repository files for that Domain
  private final PentahoMetadataInformationMap metadataMapping;

  // The parser used to serialize / deserialize metadata files
  private XmiParser xmiParser;

  // The repository utility class
  private RepositoryUtils repositoryUtils;

  // The localization utility class (used to load side-car properties files into a Domain object)
  private LocalizationUtil localizationUtil;

  private IAclNodeHelper aclHelper;

  private final ReentrantReadWriteLock lock;
  private boolean needToReload;

  /**
   * Creates an instance of this class providing the {@link IUnifiedRepository} repository backend.
   *
   * @param repository the {@link IUnifiedRepository} in which data will be stored / retrieved
   */
  public PentahoMetadataDomainRepository(final IUnifiedRepository repository) {
    this(repository, null, null, null);
  }

  /**
   * Helper constructor used for setting other objects in this class
   *
   * @param repository the {@link IUnifiedRepository} in which data will be stored / retrieved
   * @param repositoryUtils utility class for working inside the repository </br>(NOTE: {@code null}
   *     is acceptable and will create a default instance)
   * @param xmiParser the parser class for serializing / de-serializing Domain objects </br>(NOTE:
   *     {@code null} is acceptable and will create a default instance)
   * @param localizationUtil the object used to add locale bundles into a Pentaho Metadata Domain
   *     object </br>(NOTE: {@code null} is acceptable and will create a default instance)
   */
  protected PentahoMetadataDomainRepository(
      final IUnifiedRepository repository,
      final RepositoryUtils repositoryUtils,
      final XmiParser xmiParser,
      final LocalizationUtil localizationUtil) {
    if (null == repository) {
      throw new IllegalArgumentException();
    }
    this.metadataMapping = getMetadataMapping(repository);
    setRepository(repository);
    setRepositoryUtils(repositoryUtils);
    setLocalizationUtil(localizationUtil);
    setXmiParser(xmiParser);
    this.lock = new ReentrantReadWriteLock();
    this.needToReload = true;
  }

  /**
   * Store a domain to the repository. The domain should persist between JVM restarts.
   *
   * @param domain domain object to store
   * @param overwrite if true, overwrite existing domain
   * @throws DomainIdNullException if domain id is null or empty
   * @throws DomainAlreadyExistsException if a domain with the same Domain ID already exists in the
   *     repository and {@code overwrite == false}
   * @throws DomainStorageException if there is a problem storing the domain
   */
  @Override
  public void storeDomain(final Domain domain, final boolean overwrite)
      throws DomainIdNullException, DomainAlreadyExistsException, DomainStorageException {
    if (logger.isDebugEnabled()) {
      logger.debug(
          "storeDomain(domain(id="
              + (domain != null ? domain.getId() : "")
              + ", "
              + overwrite
              + ")");
    }
    if (null == domain || StringUtils.isEmpty(domain.getId())) {
      throw new DomainIdNullException(
          messages.getErrorString("PentahoMetadataDomainRepository.ERROR_0001_DOMAIN_ID_NULL"));
    }

    String xmi = "";
    try {
      // NOTE - a ByteArrayInputStream doesn't need to be closed ...
      // ... so this is safe AS LONG AS we use a ByteArrayInputStream
      xmi = xmiParser.generateXmi(domain);
      // final InputStream inputStream = new ByteArrayInputStream( xmi.getBytes( DEFAULT_ENCODING )
      // );
      final InputStream inputStream = new ByteArrayInputStream(xmi.getBytes("UTF8"));
      storeDomain(inputStream, domain.getId(), overwrite);
    } catch (DomainStorageException dse) {
      throw dse;
    } catch (DomainAlreadyExistsException dae) {
      throw dae;
    } catch (Exception e) {
      final String errorMessage =
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0003_ERROR_STORING_DOMAIN",
              domain.getId(),
              e.getLocalizedMessage());
      logger.error(errorMessage, e);
      throw new DomainStorageException(xmi + errorMessage, e);
    }
  }

  protected String endsWithXmi(String value) {
    if (value.endsWith(".xmi")) {
      return value;
    } else {
      return value + ".xmi";
    }
  }

  protected String noXmi(String value) {
    if (value.endsWith(".xmi")) {
      return value.substring(0, value.length() - 4);
    } else {
      return value;
    }
  }

  protected String replaceDomainId(StringBuilder sb, String domainId) {
    int datasourceModelTagPosition = sb.indexOf("datasourceModel");
    if (datasourceModelTagPosition != -1) {
      String xmiDomainId = endsWithXmi(domainId);
      String noXmiDomainId = StringEscapeUtils.escapeXml(noXmi(domainId));
      String tag = "<CWM:Description body=";

      int startTagPosition = sb.indexOf(tag, datasourceModelTagPosition);
      int startPosition = startTagPosition + tag.length() + 1;
      int endPosition = sb.indexOf("\"", startPosition);

      String oldDomainId = sb.substring(startPosition, endPosition);
      sb.delete(startPosition, endPosition);
      if (oldDomainId.endsWith(".xmi")) {
        sb.insert(startPosition, xmiDomainId);
      } else {
        sb.insert(startPosition, noXmiDomainId);
      }
      return xmiDomainId;
    } else {
      return domainId;
    }
  }

  protected String getDomainIdFromXmi(StringBuilder sb) {
    int datasourceModelTagPosition = sb.indexOf("datasourceModel");
    if (datasourceModelTagPosition != -1) {
      String tag = "<CWM:Description body=";
      int startTagPosition = sb.indexOf(tag, datasourceModelTagPosition);

      int startPosition = startTagPosition + tag.length() + 1;
      int endPosition = sb.indexOf("\"", startPosition);

      return StringEscapeUtils.unescapeXml(sb.substring(startPosition, endPosition));
    } else {
      return null;
    }
  }

  protected boolean isDomainIdXmiEqualsOrNotPresent(String domainId, String domainIdXmi) {
    return domainIdXmi == null || noXmi(domainIdXmi).equals(noXmi(domainId));
  }

  /**
   * Stores a domain to the repository directly as an Input Stream
   *
   * @param inputStream
   * @param domainId
   * @param overwrite
   */
  @Override
  public void storeDomain(
      final InputStream inputStream, final String domainId, final boolean overwrite)
      throws DomainIdNullException, DomainAlreadyExistsException, DomainStorageException {
    storeDomain(inputStream, domainId, overwrite, null);
  }

  @Override
  public void storeDomain(
      InputStream inputStream, String domainId, boolean overwrite, RepositoryFileAcl acl)
      throws DomainIdNullException, DomainAlreadyExistsException, DomainStorageException {
    if (logger.isDebugEnabled()) {
      logger.debug(String.format("storeDomain(inputStream, %s, %s, %s)", domainId, overwrite, acl));
    }
    if (null == inputStream) {
      throw new IllegalArgumentException();
    }
    if (StringUtils.isEmpty(domainId)) {
      throw new DomainIdNullException(
          messages.getErrorString("PentahoMetadataDomainRepository.ERROR_0001_DOMAIN_ID_NULL"));
    }

    // Check to see if the domain already exists
    final RepositoryFile domainFile = getMetadataRepositoryFile(domainId);
    if (!overwrite && domainFile != null) {
      final String errorString =
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0002_DOMAIN_ALREADY_EXISTS", domainId);
      logger.error(errorString);
      throw new DomainAlreadyExistsException(errorString);
    }

    // Check if this is valid xml
    InputStream inputStream2;
    String xmi;
    try {
      // try to see if the xmi can be parsed (ie, check if it's valid xmi)
      // first, convert our input stream to a string
      StringBuilder stringBuilder = new StringBuilder();
      BufferedReader reader =
          new BufferedReader(new InputStreamReader(inputStream, DEFAULT_ENCODING));
      try {
        while ((xmi = reader.readLine()) != null) {
          stringBuilder.append(xmi);
        }
      } finally {
        inputStream.close();
      }

      if (!isDomainIdXmiEqualsOrNotPresent(domainId, getDomainIdFromXmi(stringBuilder))) {
        domainId = replaceDomainId(stringBuilder, domainId);
      }

      xmi = stringBuilder.toString();
      // now, try to see if the xmi can be parsed (ie, check if it's valid xmi)
      byte[] xmiBytes = xmi.getBytes(DEFAULT_ENCODING);
      inputStream2 = new java.io.ByteArrayInputStream(xmiBytes);
      xmiParser.parseXmi(inputStream2);
      // xmi is valid. Create a new inputstream for the actual import action.
      inputStream2.reset();
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      // throw new
      // DomainStorageException(messages.getErrorString("PentahoMetadataDomainRepository.ERROR_0010_ERROR_PARSING_XMI"),
      // ex);
      java.io.ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      ex.printStackTrace(new java.io.PrintStream(byteArrayOutputStream));
      throw new DomainStorageException(byteArrayOutputStream.toString(), ex);
    }

    final SimpleRepositoryFileData data =
        new SimpleRepositoryFileData(inputStream2, DEFAULT_ENCODING, DOMAIN_MIME_TYPE);
    final RepositoryFile newDomainFile;
    if (domainFile == null) {
      newDomainFile = createUniqueFile(domainId, null, data);
    } else {
      newDomainFile = repository.updateFile(domainFile, data, null);
    }

    // This invalidates any caching
    flushDomains();

    getAclHelper().setAclFor(newDomainFile, acl);
  }

  protected synchronized IAclNodeHelper getAclHelper() {
    if (aclHelper == null) {
      aclHelper = new JcrAclNodeHelper(repository);
    }
    return aclHelper;
  }

  @Override
  public void setAclFor(String domainId, RepositoryFileAcl acl) {
    getAclHelper().setAclFor(getMetadataRepositoryFile(domainId), acl);
  }

  @Override
  public RepositoryFileAcl getAclFor(String domainId) {
    return getAclHelper().getAclFor(getMetadataRepositoryFile(domainId));
  }

  @Override
  public boolean hasAccessFor(String domainId) {
    if (logger.isDebugEnabled()) {
      logger.debug("Checking access for: " + domainId);
    }
    return getAclHelper().canAccess(getMetadataRepositoryFile(domainId), READ);
  }

  /**
   * This method can be called to avoid useless obtaining of repository file if the file has already
   * been loaded
   *
   * @param repositoryFile repository file
   * @return delegates the call to <code>getAclHelper().canAccess()</code>
   */
  private boolean hasAccessFor(RepositoryFile repositoryFile) {
    return getAclHelper().canAccess(repositoryFile, READ);
  }

  /*
   * retrieves the data streams for the metadata referenced by domainId. This could be a single .xmi file or an .xmi
   * file and multiple .properties files.
   */
  public Map<String, InputStream> getDomainFilesData(final String domainId) {
    Set<RepositoryFile> metadataFiles;
    lock.readLock().lock();
    try {
      metadataFiles = metadataMapping.getFiles(domainId);
    } finally {
      lock.readLock().unlock();
    }

    Map<String, InputStream> values = new HashMap<String, InputStream>(metadataFiles.size());
    for (RepositoryFile repoFile : metadataFiles) {
      RepositoryFileInputStream is;
      try {
        is = new RepositoryFileInputStream(repoFile);
      } catch (Exception e) {
        return null; // This pretty much ensures an exception will be thrown later and passed to the
        // client
      }
      String fileName =
          repoFile.getName().endsWith(".properties")
              ? repoFile.getName()
              : domainId + (domainId.endsWith(".xmi") ? "" : ".xmi");
      values.put(fileName, is);
    }
    return values;
  }

  /**
   * retrieve a domain from the repo. This does lazy loading of the repo, so it calls
   * reloadDomains() if not already loaded.
   *
   * @param domainId domain to get from the repository
   * @return domain object
   */
  @Override
  public Domain getDomain(final String domainId) {
    if (logger.isDebugEnabled()) {
      logger.debug("getDomain(" + domainId + ")");
    }

    if (StringUtils.isEmpty(domainId)) {
      throw new IllegalArgumentException(
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId));
    }
    Domain domain = null;
    try {
      // Load the domain file
      final RepositoryFile file = getMetadataRepositoryFile(domainId);
      if (file != null) {
        if (hasAccessFor(file)) {
          SimpleRepositoryFileData data =
              repository.getDataForRead(file.getId(), SimpleRepositoryFileData.class);
          if (data != null) {
            domain = xmiParser.parseXmi(data.getStream());
            domain.setId(domainId);
            logger.debug("loaded domain");
            // Load any I18N bundles
            loadLocaleStrings(domainId, domain);
            logger.debug("loaded I18N bundles");
          } else {
            throw new UnifiedRepositoryException(
                messages.getErrorString(
                    "PentahoMetadataDomainRepository.ERROR_0005_ERROR_RETRIEVING_DOMAIN",
                    domainId,
                    "data not found"));
          }
        } else {
          throw new PentahoAccessControlException(
              messages.getErrorString(
                  "PentahoMetadataDomainRepository.ERROR_0005_ERROR_RETRIEVING_DOMAIN",
                  domainId,
                  "access denied"));
        }
      }
    } catch (Exception e) {
      if (!(e instanceof UnifiedRepositoryException
          || e instanceof PentahoAccessControlException)) {
        throw new UnifiedRepositoryException(
            messages.getErrorString(
                "PentahoMetadataDomainRepository.ERROR_0005_ERROR_RETRIEVING_DOMAIN",
                domainId,
                e.getLocalizedMessage()),
            e);
      }
    }

    // Return
    return domain;
  }

  /**
   * return a list of all the domain ids in the repository. triggers a call to reloadDomains if
   * necessary.
   *
   * @return the domain Ids.
   */
  @Override
  public Set<String> getDomainIds() {
    logger.debug("getDomainIds()");
    reloadDomainsIfNeeded();

    Collection<String> domains;
    lock.readLock().lock();
    try {
      domains = new ArrayList<String>(metadataMapping.getDomainIds());
    } finally {
      lock.readLock().unlock();
    }
    Set<String> domainIds = new HashSet<String>(domains.size());
    for (String domain : domains) {
      if (hasAccessFor(domain)) {
        domainIds.add(domain);
      }
    }
    return domainIds;
  }

  /**
   * remove a domain from disk and memory.
   *
   * @param domainId
   */
  @Override
  public void removeDomain(final String domainId) {
    if (logger.isDebugEnabled()) {
      logger.debug("removeDomain(" + domainId + ")");
    }

    if (StringUtils.isEmpty(domainId)) {
      throw new IllegalArgumentException(
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId));
    }

    // Get the metadata domain file
    RepositoryFile domainFile;
    Set<RepositoryFile> domainFiles;
    lock.writeLock().lock();
    try {
      domainFiles = metadataMapping.getFiles(domainId);
      domainFile = metadataMapping.getDomainFile(domainId);
      metadataMapping.deleteDomain(domainId);
    } finally {
      lock.writeLock().unlock();
    }

    if (domainFile != null) {
      // it no node exists, nothing would happen
      getAclHelper().removeAclFor(domainFile);
    }

    for (final RepositoryFile file : domainFiles) {
      if (logger.isTraceEnabled()) {
        logger.trace("Deleting repository file " + toString(file));
      }
      repository.deleteFile(file.getId(), true, null);
    }

    // This invalidates any caching
    if (!domainFiles.isEmpty()) {
      flushDomains();
    }
  }

  /**
   * remove a model from a domain which is stored either on a disk or memory.
   *
   * @param domainId
   * @param modelId
   */
  @Override
  public void removeModel(final String domainId, final String modelId)
      throws DomainIdNullException, DomainStorageException {
    if (logger.isDebugEnabled()) {
      logger.debug("removeModel(" + domainId + ", " + modelId + ")");
    }

    if (StringUtils.isEmpty(domainId)) {
      throw new IllegalArgumentException(
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId));
    }
    if (StringUtils.isEmpty(modelId)) {
      throw new IllegalArgumentException(
          messages.getErrorString("PentahoMetadataDomainRepository.ERROR_0006_MODEL_ID_INVALID"));
    }

    // Get the domain and remove the model
    final Domain domain = getDomain(domainId);
    if (null != domain) {
      boolean found = false;
      final Iterator<LogicalModel> iter = domain.getLogicalModels().iterator();
      while (iter.hasNext()) {
        LogicalModel model = iter.next();
        if (modelId.equals(model.getId())) {
          iter.remove();
          found = true;
          break;
        }
      }

      // Update the domain if we change it
      if (found) {
        try {
          storeDomain(domain, true);
          flushDomains();
        } catch (DomainAlreadyExistsException ignored) {
          // This can't happen since we have setup overwrite to true
        }
      }
    }
  }

  /** reload domains from disk */
  @Override
  public void reloadDomains() {
    logger.debug("reloadDomains()");
    internalReloadDomains();
  }

  /** Performs the process of reloading the domain information from the repository */
  private void internalReloadDomains() {
    lock.writeLock().lock();
    try {
      metadataMapping.reset();

      // Reload the metadata about the metadata (that was fun to say)
      final List<RepositoryFile> children = repository.getChildren(getMetadataDir().getId(), "*");
      if (logger.isTraceEnabled()) {
        logger.trace("\tFound " + children.size() + " files in the repository");
      }
      for (final RepositoryFile child : children) {
        if (getAclHelper().canAccess(child, READ)) {
          // Get the metadata for this file
          final Map<String, Serializable> fileMetadata = repository.getFileMetadata(child.getId());
          if (fileMetadata == null
              || StringUtils.isEmpty((String) fileMetadata.get(PROPERTY_NAME_DOMAIN_ID))) {
            if (logger.isWarnEnabled()) {
              logger.warn(
                  messages.getString(
                      "PentahoMetadataDomainRepository.WARN_0001_FILE_WITHOUT_METADATA",
                      child.getName()));
            }
            continue;
          }
          final String domainId = (String) fileMetadata.get(PROPERTY_NAME_DOMAIN_ID);
          final String type = (String) fileMetadata.get(PROPERTY_NAME_TYPE);
          final String locale = (String) fileMetadata.get(PROPERTY_NAME_LOCALE);
          if (logger.isTraceEnabled()) {
            logger.trace(
                "\tprocessing file [type="
                    + type
                    + " : domainId="
                    + domainId
                    + " : locale="
                    + locale
                    + "]");
          }

          // Save the data in the map
          if (StringUtils.equals(type, TYPE_DOMAIN)) {
            metadataMapping.addDomain(domainId, child);
          } else if (StringUtils.equals(type, TYPE_LOCALE)) {
            metadataMapping.addLocale(domainId, locale, child);
          }
        }
      }

      needToReload = false;
    } finally {
      lock.writeLock().unlock();
    }
  }

  /** flush the domains from memory */
  @Override
  public void flushDomains() {
    logger.debug("flushDomains()");
    internalReloadDomains();
  }

  @Override
  public String generateRowLevelSecurityConstraint(final LogicalModel model) {
    // We will let subclasses handle this issue
    return null;
  }

  /** The aclHolder cannot be null unless the access type requested is ACCESS_TYPE_SCHEMA_ADMIN. */
  @Override
  public boolean hasAccess(final int accessType, final IConcept aclHolder) {
    // We will let subclasses handle this computation
    return true;
  }

  /**
   * Adds a set of properties as a locale properties file for the specified Domain ID
   *
   * @param domainId the domain ID for which this properties file will be added
   * @param locale the locale for which this properties file will be added
   * @param properties the properties to be added
   */
  public void addLocalizationFile(
      final String domainId, final String locale, final Properties properties)
      throws DomainStorageException {
    // This is safe since ByteArray streams don't have to be closed
    if (null != properties) {
      try {
        final OutputStream out = new ByteArrayOutputStream();
        properties.store(out, null);
        addLocalizationFile(
            domainId, locale, new ByteArrayInputStream(out.toString().getBytes()), true);
      } catch (IOException e) {
        throw new DomainStorageException(
            messages.getErrorString(
                "PentahoMetadataDomainRepository.ERROR_0008_ERROR_IN_REPOSITORY",
                e.getLocalizedMessage()),
            e);
      }
    }
  }

  @Override
  public void addLocalizationFile(
      final String domainId,
      final String locale,
      final InputStream inputStream,
      final boolean overwrite)
      throws DomainStorageException {
    if (logger.isDebugEnabled()) {
      logger.debug("addLocalizationFile(" + domainId + ", " + locale + ", inputStream)");
    }
    if (null != inputStream) {
      if (StringUtils.isEmpty(domainId) || StringUtils.isEmpty(locale)) {
        throw new IllegalArgumentException(
            messages.getErrorString(
                "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId));
      }

      lock.writeLock().lock();
      try {
        // Check for duplicates
        final RepositoryFile localeFile = metadataMapping.getLocaleFile(domainId, locale);
        if (!overwrite && localeFile != null) {
          throw new DomainStorageException(
              messages.getErrorString(
                  "PentahoMetadataDomainRepository.ERROR_0009_LOCALE_ALREADY_EXISTS",
                  domainId,
                  locale),
              null);
        }

        final SimpleRepositoryFileData data =
            new SimpleRepositoryFileData(inputStream, DEFAULT_ENCODING, LOCALE_MIME_TYPE);
        if (localeFile == null) {
          final RepositoryFile newLocaleFile = createUniqueFile(domainId, locale, data);
          metadataMapping.addLocale(domainId, locale, newLocaleFile);
        } else {
          repository.updateFile(localeFile, data, null);
        }
        // This invalidates any cached information
        flushDomains();
      } finally {
        lock.writeLock().unlock();
      }
    }
  }

  protected RepositoryFile getMetadataDir() {
    final String metadataDirName = PentahoMetadataDomainRepositoryInfo.getMetadataFolderPath();
    return repository.getFile(metadataDirName);
  }

  protected void loadLocaleStrings(final String domainId, final Domain domain) {
    final Map<String, RepositoryFile> localeFiles = metadataMapping.getLocaleFiles(domainId);
    if (localeFiles != null) {
      for (final String locale : localeFiles.keySet()) {
        final RepositoryFile localeFile = localeFiles.get(locale);
        final Properties properties = loadProperties(localeFile);
        if (logger.isTraceEnabled()) {
          logger.trace("\tLoading properties [" + domain + " : " + locale + "]");
        }
        localizationUtil.importLocalizedProperties(domain, properties, locale);
      }
    }
  }

  protected Properties loadProperties(final RepositoryFile bundle) {
    try {
      Properties properties = null;
      final SimpleRepositoryFileData bundleData =
          repository.getDataForRead(bundle.getId(), SimpleRepositoryFileData.class);
      if (bundleData != null) {
        properties = new Properties();
        properties.load(bundleData.getStream());
      } else {
        if (logger.isWarnEnabled()) {
          logger.warn("Could not load properties from repository file: " + bundle.getName());
        }
      }
      return properties;
    } catch (IOException e) {
      throw new UnifiedRepositoryException(
          messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0008_ERROR_IN_REPOSITORY",
              e.getLocalizedMessage()),
          e);
    }
  }

  /**
   * Creates a new repository file (with the supplied data) and applies the proper metadata to this
   * file.
   *
   * @param domainId the Domain id associated with this file
   * @param locale the locale associated with this file (or null for a domain file)
   * @param data the data to put in the file
   * @return the repository file created
   */
  protected RepositoryFile createUniqueFile(
      final String domainId, final String locale, final SimpleRepositoryFileData data) {
    // Generate a "unique" filename
    final String filename = UUID.randomUUID().toString();

    // Create the new file
    final RepositoryFile file =
        repository.createFile(
            getMetadataDir().getId(), new RepositoryFile.Builder(filename).build(), data, null);

    // Add metadata to the file
    final Map<String, Serializable> metadataMap = new HashMap<String, Serializable>();
    metadataMap.put(PROPERTY_NAME_DOMAIN_ID, domainId);
    if (StringUtils.isEmpty(locale)) {
      // This is a domain file
      metadataMap.put(PROPERTY_NAME_TYPE, TYPE_DOMAIN);
    } else {
      // This is a locale property file
      metadataMap.put(PROPERTY_NAME_TYPE, TYPE_LOCALE);
      metadataMap.put(PROPERTY_NAME_LOCALE, locale);
    }

    // Update the metadata
    repository.setFileMetadata(file.getId(), metadataMap);
    return file;
  }

  protected IUnifiedRepository getRepository() {
    return repository;
  }

  protected XmiParser getXmiParser() {
    return xmiParser;
  }

  protected RepositoryUtils getRepositoryUtils() {
    return repositoryUtils;
  }

  protected LocalizationUtil getLocalizationUtil() {
    return localizationUtil;
  }

  protected void setRepository(final IUnifiedRepository repository) {
    this.repository = repository;
  }

  protected void setXmiParser(final XmiParser xmiParser) {
    this.xmiParser = (xmiParser != null ? xmiParser : new XmiParser());
  }

  protected void setRepositoryUtils(final RepositoryUtils repositoryUtils) {
    this.repositoryUtils =
        (repositoryUtils != null ? repositoryUtils : new RepositoryUtils(repository));
  }

  protected void setLocalizationUtil(final LocalizationUtil localizationUtil) {
    this.localizationUtil = (localizationUtil != null ? localizationUtil : new LocalizationUtil());
  }

  protected String toString(final RepositoryFile file) {
    try {
      final Map<String, Serializable> fileMetadata = repository.getFileMetadata(file.getId());
      return "[type="
          + fileMetadata.get(PROPERTY_NAME_TYPE)
          + " : domain="
          + fileMetadata.get(PROPERTY_NAME_DOMAIN_ID)
          + " : locale="
          + fileMetadata.get(PROPERTY_NAME_LOCALE)
          + " : filename="
          + file.getName()
          + "]";
    } catch (Throwable ignore) {
      // ignore
    }
    return "null";
  }

  /**
   * Accesses the metadata mapping (with 1 retry) to find the metadata file for the specified
   * domainId
   */
  protected RepositoryFile getMetadataRepositoryFile(final String domainId) {
    lock.readLock().lock();
    RepositoryFile domainFile;
    try {
      domainFile = metadataMapping.getDomainFile(domainId);
    } finally {
      lock.readLock().unlock();
    }

    if (domainFile == null) {

      if (logger.isDebugEnabled()) {
        logger.debug(
            "Requested Domain ("
                + domainId
                + ") wasn't found in Metadata Mapping. Domain cache will be reloaded");
      }
      lock.writeLock().lock();
      try {
        domainFile = metadataMapping.getDomainFile(domainId);
        if (domainFile == null) {
          reloadDomainsIfNeeded();
          domainFile = metadataMapping.getDomainFile(domainId);
        }
      } finally {
        lock.writeLock().unlock();
      }
    }

    if (domainFile == null && logger.isDebugEnabled()) {
      logger.debug(
          "Even after reloading all domains, the specified Domain wasn't found in the system: "
              + domainId);
    }

    return domainFile;
  }

  private void reloadDomainsIfNeeded() {
    lock.writeLock().lock();
    try {
      if (needToReload) {
        internalReloadDomains();
      }
    } finally {
      lock.writeLock().unlock();
    }
  }

  /**
   * Returns the MatadataInformationMap for the specified IUnifiedRepository
   *
   * @param repository the repository for which a map is specified
   * @return the MatadataInformationMap for the repository
   */
  private static synchronized PentahoMetadataInformationMap getMetadataMapping(
      final IUnifiedRepository repository) {
    PentahoMetadataInformationMap metaMap = metaMapStore.get(repository);
    if (null == metaMap) {
      metaMap = new PentahoMetadataInformationMap();
      metaMapStore.put(repository, metaMap);
    }
    return metaMap;
  }

  @Override
  public String loadAnnotationsXml(final String domainId) {

    if (StringUtils.isBlank(domainId)) {
      return null; // exit early
    }

    try {
      final RepositoryFile domainFile = getMetadataRepositoryFile(domainId);
      final RepositoryFile annotationFile =
          getRepository().getFile(resolveAnnotationsFilePath(domainFile));

      // Load referenced annotations xml repo file
      SimpleRepositoryFileData data =
          getRepository().getDataForRead(annotationFile.getId(), SimpleRepositoryFileData.class);
      return IOUtils.toString(data.getInputStream()); // return as String
    } catch (Exception e) {
      getLogger().warn("Unable to load annotations xml file for domain: " + domainId);
    }

    return null;
  }

  @Override
  public void storeAnnotationsXml(String domainId, String annotationsXml) {

    if (StringUtils.isBlank(domainId) || StringUtils.isBlank(annotationsXml)) {
      return; // exit early
    }

    RepositoryFile domainFile = getMetadataRepositoryFile(domainId);
    RepositoryFile annotationsFile = getAnnotationsXmlFile(domainFile);
    createOrUpdateAnnotationsXml(domainFile, annotationsFile, annotationsXml);
  }

  public RepositoryFile getAnnotationsXmlFile(final RepositoryFile domainFile) {

    if (domainFile == null) {
      return null; // exit early
    }

    RepositoryFile annotationsFile = null;
    try {
      annotationsFile = getRepository().getFile(resolveAnnotationsFilePath(domainFile));
    } catch (Exception e) {
      getLogger().warn("Unable to find annotations xml file for: " + domainFile.getId());
    }

    return annotationsFile;
  }

  public void createOrUpdateAnnotationsXml(
      final RepositoryFile domainFile,
      final RepositoryFile annotationsFile,
      final String annotationsXml) {

    if (domainFile == null) {
      return; // exit early
    }

    try {
      ByteArrayInputStream in = new ByteArrayInputStream(annotationsXml.getBytes(DEFAULT_ENCODING));
      final SimpleRepositoryFileData data =
          new SimpleRepositoryFileData(in, DEFAULT_ENCODING, DOMAIN_MIME_TYPE);
      if (annotationsFile == null) {
        // Generate a filename based on the domainId
        final String filename = domainFile.getId() + ANNOTATIONS_FILE_ID_POSTFIX;

        // Create the new file
        getRepository()
            .createFile(
                getMetadataDir().getId(), new RepositoryFile.Builder(filename).build(), data, null);
      } else {
        getRepository().updateFile(annotationsFile, data, null);
      }
    } catch (Exception e) {
      getLogger().warn("Unable to save annotations xml", e);
    }
  }

  protected String resolveAnnotationsFilePath(final RepositoryFile domainFile) {

    if (getMetadataDir() != null && domainFile != null) {
      return getMetadataDir().getPath() + "/" + domainFile.getId() + ANNOTATIONS_FILE_ID_POSTFIX;
    }
    return null;
  }

  protected Log getLogger() {
    return logger;
  }
}
  /**
   * Creates an instance of an {@link
   * org.pentaho.platform.plugin.services.importexport.ImportSource} based off the command line
   * options
   */
  protected ImportSource createImportSource() throws ParseException, InitializationException {
    final String source =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_NAME"),
            true,
            false);
    final String requiredCharset =
        getOptionValue(
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_CHARSET_KEY"),
            Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_CHARSET_NAME"),
            true,
            false);

    if (StringUtils.equals(
        source,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_LEGACY_DB"))) {
      final String driver =
          getOptionValue(
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_DRIVER_KEY"),
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_DRIVER_NAME"),
              true,
              false);
      final String url =
          getOptionValue(
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_URL_KEY"),
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_URL_NAME"),
              true,
              false);
      final String dbUsername =
          getOptionValue(
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_USERNAME_KEY"),
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_USERNAME_NAME"),
              true,
              false);
      final String dbPassword =
          getOptionValue(
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_PASSWORD_KEY"),
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_PASSWORD_NAME"),
              true,
              true);
      final String charset =
          getOptionValue(
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_CHARSET_KEY"),
              Messages.getInstance()
                  .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_CHARSET_NAME"),
              true,
              true);
      final DataSource dataSource =
          new DriverManagerDataSource(driver, url, dbUsername, dbPassword);

      final String username =
          getOptionValue(
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_KEY"),
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_NAME"),
              true,
              false);
      return new org.pentaho.platform.plugin.services.importexport.legacy
          .DbSolutionRepositoryImportSource(dataSource, charset, requiredCharset, username);
    }

    if (StringUtils.equals(
        source,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_FILE_SYSTEM"))) {
      final String filePath =
          getOptionValue(
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_KEY"),
              Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_NAME"),
              true,
              false);
      final File file = new File(filePath);
      return new org.pentaho.platform.plugin.services.importexport.legacy
          .FileSolutionRepositoryImportSource(file, requiredCharset);
    }

    // Source is not understood
    throw new ParseException(
        Messages.getInstance()
            .getErrorString("CommandLineProcessor.INFO_OPTION_FILEPATH_NAME", source));
  }
  static {
    // create the Options
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_HELP_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_HELP_NAME"),
        false,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_HELP_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_IMPORT_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_IMPORT_NAME"),
        false,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_IMPORT_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_EXPORT_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_EXPORT_NAME"),
        false,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_EXPORT_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SOURCE_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_TYPE_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_TYPE_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_TYPE_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_FILEPATH_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_CHARSET_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_CHARSET_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_CHARSET_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LOGFILE_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LOGFILE_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LOGFILE_DESCRIPTION"));

    // import only options
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_COMMENT_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_COMMENT_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_COMMENT_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PATH_DESCRIPTION"));

    // import only ACL additions
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_OVERWRITE_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_OVERWRITE_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_OVERWRITE_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PERMISSION_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PERMISSION_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_PERMISSION_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_RETAIN_OWNERSHIP_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_RETAIN_OWNERSHIP_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_RETAIN_OWNERSHIP_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_WITH_MANIFEST_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_WITH_MANIFEST_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_WITH_MANIFEST_DESCRIPTION"));

    // external
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_DRIVER_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_DRIVER_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_DRIVER_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_URL_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_URL_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_URL_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_USERNAME_KEY"),
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_USERNAME_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_USERNAME_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_PASSWORD_KEY"),
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_PASSWORD_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_PASSWORD_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_CHARSET_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_CHARSET_NAME"),
        true,
        Messages.getInstance()
            .getString("CommandLineProcessor.INFO_OPTION_LEGACY_DB_CHARSET_DESCRIPTION"));

    // Legacy Service
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_LEGACY_DESCRIPTION"));

    // rest services
    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_REST_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_REST_NAME"),
        false,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_REST_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SERVICE_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SERVICE_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_SERVICE_DESCRIPTION"));

    options.addOption(
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PARAMS_KEY"),
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PARAMS_NAME"),
        true,
        Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PARAMS_DESCRIPTION"));
  }
  /**
   * Why does this return a web service? Going directly to the IUnifiedRepository requires the
   * following:
   *
   * <p>
   *
   * <ul>
   *   <li>PentahoSessionHolder setup including password and tenant ID. (The server doesn't even
   *       process passwords today-- it assumes that Spring Security processed it. This would
   *       require code changes.)
   *   <li>User must specify path to Jackrabbit files (i.e. system/jackrabbit).
   * </ul>
   */
  protected synchronized IUnifiedRepository getRepository() throws ParseException {
    if (repository != null) {
      return repository;
    }

    final String NAMESPACE_URI = "http://www.pentaho.org/ws/1.0"; // $NON-NLS-1$
    final String SERVICE_NAME = "unifiedRepository"; // $NON-NLS-1$

    String urlString =
        getOptionValue(
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_KEY"),
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_URL_NAME"),
                true,
                false)
            .trim();
    if (urlString.endsWith("/")) {
      urlString = urlString.substring(0, urlString.length() - 1);
    }
    urlString = urlString + "/webservices/" + SERVICE_NAME + "?wsdl";

    URL url;
    try {
      url = new URL(urlString);
    } catch (MalformedURLException e) {
      throw new IllegalArgumentException(e);
    }

    Service service = Service.create(url, new QName(NAMESPACE_URI, SERVICE_NAME));
    IUnifiedRepositoryJaxwsWebService port =
        service.getPort(IUnifiedRepositoryJaxwsWebService.class);
    // http basic authentication
    ((BindingProvider) port)
        .getRequestContext()
        .put(
            BindingProvider.USERNAME_PROPERTY,
            getOptionValue(
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_KEY"),
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_USERNAME_NAME"),
                true,
                false));
    ((BindingProvider) port)
        .getRequestContext()
        .put(
            BindingProvider.PASSWORD_PROPERTY,
            getOptionValue(
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_KEY"),
                Messages.getInstance().getString("CommandLineProcessor.INFO_OPTION_PASSWORD_NAME"),
                true,
                true));
    // accept cookies to maintain session on server
    ((BindingProvider) port)
        .getRequestContext()
        .put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
    // support streaming binary data
    // TODO mlowery this is not portable between JAX-WS implementations
    // (uses com.sun)
    ((BindingProvider) port)
        .getRequestContext()
        .put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
    SOAPBinding binding = (SOAPBinding) ((BindingProvider) port).getBinding();
    binding.setMTOMEnabled(true);
    final UnifiedRepositoryToWebServiceAdapter unifiedRepositoryToWebServiceAdapter =
        new UnifiedRepositoryToWebServiceAdapter(port);
    repository = unifiedRepositoryToWebServiceAdapter;
    return unifiedRepositoryToWebServiceAdapter;
  }
  public void testSimpleRuntime() {
    // The simple runtime is used by the standalone distribution.
    // This provides some simple tests to exercise the code...
    startTest();
    StandaloneSession session =
        new StandaloneSession(
            Messages.getInstance().getString("BaseTest.DEBUG_JUNIT_SESSION")); // $NON-NLS-1$
    IRuntimeRepository srr = new SimpleRuntimeRepository();
    srr.setSession(session);
    IRuntimeElement ele1 = srr.loadElementById("instanceid", null); // $NON-NLS-1$
    IRuntimeElement ele2 =
        srr.newRuntimeElement("parent", "parentType", true); // $NON-NLS-1$ //$NON-NLS-2$
    IRuntimeElement ele3 =
        srr.newRuntimeElement(
            "parentid",
            "parentType",
            "solutionId",
            true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

    SimpleRuntimeElement sre =
        (SimpleRuntimeElement) srr.loadElementById("instanceid", null); // $NON-NLS-1$
    List list = sre.getMessages();
    if (list != null) {
      for (int i = 0; i < list.size(); i++) {
        System.out.println("Message " + (i + 1) + list.get(i)); // $NON-NLS-1$
      }

      sre.setParentId("parentid1"); // $NON-NLS-1$
      sre.setParentType("parentidType1"); // $NON-NLS-1$
      sre.setSolutionId("solutionId1"); // $NON-NLS-1$
      sre.setReadOnly(true);
      boolean isReadOnly = sre.getReadOnly();
      String parentId = sre.getParentId();
      String parentIdType = sre.getParentType();
      String solutionId = sre.getSolutionId();
      assertEquals(isReadOnly, true);
      assertEquals(parentId, "parentid1"); // $NON-NLS-1$
      assertEquals(parentIdType, "parentidType1"); // $NON-NLS-1$
      assertEquals(solutionId, "solutionId1"); // $NON-NLS-1$
    }
    int revision = sre.getRevision();
    System.out.println("Revision Value is" + revision); // $NON-NLS-1$
    sre.setStringProperty("parentId", "value"); // $NON-NLS-1$ //$NON-NLS-2$
    BigDecimal tstBD = new BigDecimal("2.4"); // $NON-NLS-1$
    ele2.setBigDecimalProperty("junkBD", tstBD); // $NON-NLS-1$
    BigDecimal bd = ele2.getBigDecimalProperty("junkBD"); // $NON-NLS-1$
    assertEquals(bd, tstBD);
    Date tstDT = new Date();
    ele3.setDateProperty("junkDT", tstDT); // $NON-NLS-1$
    Date dt = ele3.getDateProperty("junkDT"); // $NON-NLS-1$
    assertEquals(tstDT, dt);
    List l = new ArrayList();
    l.add("one"); // $NON-NLS-1$
    l.add("two"); // $NON-NLS-1$
    ele1.setListProperty("SOMELIST", l); // $NON-NLS-1$
    assertEquals(ele1.getListProperty("SOMELIST"), l); // $NON-NLS-1$
    Long aLong = new Long(5);
    ele2.setLongProperty("SOMELONG", aLong); // $NON-NLS-1$
    assertEquals(ele2.getLongProperty("SOMELONG", null), aLong); // $NON-NLS-1$
    assertEquals(ele2.getLongProperty("SOMELONG", 5), 5); // $NON-NLS-1$
    Map mapProperty = new HashMap();
    mapProperty.put("mapKey", "mapValue"); // $NON-NLS-1$ //$NON-NLS-2$
    ele3.setMapProperty("SOMEMAP", mapProperty); // $NON-NLS-1$
    assertEquals(ele3.getMapProperty("SOMEMAP"), mapProperty); // $NON-NLS-1$
    ele1.setStringProperty("SOMESTRING", "SomeStringValue"); // $NON-NLS-1$ //$NON-NLS-2$
    assertEquals(
        ele1.getStringProperty("SOMESTRING"), "SomeStringValue"); // $NON-NLS-1$ //$NON-NLS-2$
    assertEquals(
        ele2.getStringProperty("DOESNTEXIST", "SomeDefault"),
        "SomeDefault"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

    assertNull(ele1.getStringProperty("DOESNTEXIST")); // $NON-NLS-1$
    assertNull(ele1.getBigDecimalProperty("DOESNTEXIST")); // $NON-NLS-1$
    assertNull(ele2.getDateProperty("DOESNTEXIST")); // $NON-NLS-1$
    assertNull(ele3.getListProperty("DOESNTEXIST")); // $NON-NLS-1$
    assertEquals(ele2.getLongProperty("DOESNTEXIST", 2), 2); // $NON-NLS-1$
    assertEquals(ele2.getLongProperty("DOESNTEXIST", new Long(2)), new Long(2)); // $NON-NLS-1$
    assertEquals(
        ele1.getBigDecimalProperty("DOESNTEXIST", new BigDecimal("0.23")),
        new BigDecimal("0.23")); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    Date tmpDate = new Date();
    assertEquals(ele1.getDateProperty("DOESNTEXIST", tmpDate), tmpDate); // $NON-NLS-1$
    Set parmNames = ele1.getParameterNames();
    assertNotNull(parmNames);

    assertFalse(srr.usesHibernate());

    assertEquals(ele2.getParameterType("SOMELONG"), "java.lang.Long"); // $NON-NLS-1$ //$NON-NLS-2$
    assertEquals(ele2.getParentType(), "parentType"); // $NON-NLS-1$
    assertEquals(ele3.getParentId(), "parentid"); // $NON-NLS-1$
    assertEquals(ele1.getInstanceId(), "instanceid"); // $NON-NLS-1$

    finishTest();
  }