/**
   * 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;
  }
 /**
  * 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;
 }
  /**
   * 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;
  }