Package org.pentaho.platform.uifoundation.component

Source Code of org.pentaho.platform.uifoundation.component.FilterDefinition

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, version 2 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* Copyright 2006 - 2013 Pentaho Corporation.  All rights reserved.
*/

package org.pentaho.platform.uifoundation.component;

import org.dom4j.Element;
import org.pentaho.commons.connection.IPentahoMetaData;
import org.pentaho.commons.connection.IPentahoResultSet;
import org.pentaho.platform.api.engine.ComponentException;
import org.pentaho.platform.api.engine.ILogger;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.uifoundation.component.xml.FilterPanelException;
import org.pentaho.platform.uifoundation.messages.Messages;
import org.pentaho.platform.util.xml.XForm;
import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
* TODO sbarkdull, may be worth breaking into 4 separate classes, one for each of the ITEM_SOURCE_*'s of course
* they would all implement the same interface or abstr class A factory class would look at the xml, and create the
* appropriate instance/type
*
* @author unknow, probably James Dixon
*
*/
public abstract class FilterDefinition {

  private static final String RE_HAS_WHITE_SPACE = ".+\\s+.+"; //$NON-NLS-1$

  /**
   * the name of the title, identified by the element <title> in the filter panel definition file
   */
  private String title;

  private String elementName;

  /**
   * a resultSet containing the text and values for the items to be displayed in the filter panel's control. The
   * result set may be a scoped variable, in which case it is retrieved by the key specified in the
   * <global-attribute> or <session-attribute> element in the filter panel definition file. Or, it is the output of
   * the action sequence, in which case it is retrieved from the action sequence's output specified by the name of
   * the <data-output> element of the filter panel definition file.
   */
  private IPentahoResultSet resultSet;

  /**
   *
   * the type of the control in the filter panel, identified by the element <type> in the filter panel definition
   * file. Valid values are: radio,list,list-multi,check-multi,check-multi-scroll,check-multi-scroll-2-column,
   * check-multi-scroll-3-column,check-multi-scroll-4-column
   */
  private int type;

  /**
   * name of the column to retrieve the names of the items placed in the filter panel's control related to the
   * member variable nameColumnNo
   */
  protected String descriptionItem;

  /**
   * name of the column to retrieve the values of the items placed in the filter panel's control related to the
   * member variable valueColumnNo
   */
  protected String valueItem;

  private String[] defaultValue;

  protected Element node;

  protected String formName;

  protected ILogger logger;

  protected IPentahoSession session;

  /**
   * index of the column to retrieve the names of the items placed in the filter panel's control related to the
   * member variable descriptionItem
   */
  private int nameColumnNo = -1;

  /**
   * index of the column to retrieve the values of the items placed in the filter panel's control related to the
   * member variable valueItem
   */
  private int valueColumnNo = -1;

  /**
   * Ctor, duh.
   *
   * @param node
   * @param formName
   * @param logger
   */
  protected FilterDefinition( final Element node, final IPentahoSession session, final ILogger logger ) {

    this.logger = logger;
    this.node = node;
    this.session = session;
  }

  // public void setFormName(String formName) {
  // this.formName = formName;
  // }

  public String getTitle() {
    return title;
  }

  public String getName() {
    return elementName;
  }

  /**
   * order of precedence: session-attribute, global-attribute, data-solution, static-list
   *
   * @param xMLnode
   * @throws FilterPanelException
   */
  public void fromXml( final Element xMLnode ) throws FilterPanelException {
    title = XmlDom4JHelper.getNodeText( "title", xMLnode ); //$NON-NLS-1$
    elementName = XmlDom4JHelper.getNodeText( "name", xMLnode ); //$NON-NLS-1$
    descriptionItem = XmlDom4JHelper.getNodeText( "data-display", xMLnode ); //$NON-NLS-1$
    valueItem = XmlDom4JHelper.getNodeText( "data-value", xMLnode ); //$NON-NLS-1$
    formName = XmlDom4JHelper.getNodeText( "name", xMLnode ); //$NON-NLS-1$

    String typeStr = XmlDom4JHelper.getNodeText( "type", xMLnode ); //$NON-NLS-1$
    if ( "radio".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_RADIO;
    } else if ( "list".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_LIST;
    } else if ( "list-multi".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_LIST_MULTI;
    } else if ( "check-multi".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_CHECK_MULTI;
    } else if ( "check-multi-scroll".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_CHECK_MULTI_SCROLL;
    } else if ( "check-multi-scroll-2-column".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_CHECK_MULTI_SCROLL_2_COLUMN;
    } else if ( "check-multi-scroll-3-column".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_CHECK_MULTI_SCROLL_3_COLUMN;
    } else if ( "check-multi-scroll-4-column".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_CHECK_MULTI_SCROLL_4_COLUMN;
    } else if ( "text-box".equalsIgnoreCase( typeStr ) ) { //$NON-NLS-1$
      type = XForm.TYPE_TEXT;
    } else {
      type = XForm.TYPE_SELECT;
    }
  }

  public void setDefaultValue( final String[] defaultValue ) {
    this.defaultValue = defaultValue;
  }

  public boolean isValid( final String[] values ) {
    if ( values == null ) {
      return ( false );
    }

    for ( String element : values ) {
      if ( !isValid( element ) ) {
        return ( false );
      }
    }
    return ( true );
  }

  protected boolean isValid( final String value ) {
    // this assume that the list of valid values does not have to be populated

    // This is a new field which let the user specify whether an empty value is a valide value or not
    String empty = XmlDom4JHelper.getNodeText( "empty-accepted", node ); //$NON-NLS-1$
    // This is a new field which let the user specify if the value select has to be in the list or values or not
    String valueInList = XmlDom4JHelper.getNodeText( "value-in-list", node ); //$NON-NLS-1$
    boolean isEmptyAccepted = Boolean.parseBoolean( empty );
    boolean mustExistInList =
        ( ( valueInList != null ) && ( valueInList.length() > 0 ) ) ? Boolean.parseBoolean( valueInList ) : true;

    if ( mustExistInList ) {
      if ( value == null ) {
        return false;
      }
      if ( resultSet == null ) {
        // we cannot determin the values for this filter
        return false;
      }
      Object[] row = resultSet.next();
      String rowValue;
      while ( row != null ) {
        rowValue = row[valueColumnNo].toString();

        if ( value.equals( rowValue ) ) {
          resultSet.close();
          return true;
        }
        row = resultSet.next();
      }
      // close the result set so we can loop through it again later if we need to
      resultSet.close();
      return false;

    } else {
      if ( isEmptyAccepted ) {
        return true;
      } else {
        return ( ( value != null ) && ( value.length() > 0 ) );
      }
    }
  }

  // sbarkdull: doesn't appear to be used anywhere, temporarily removing it from the public interface
  /*
   * private boolean isValid(String[] value, Map parameterProviders) { if (resultSet == null && parameterProviders
   * != null) { populate(parameterProviders, value); } return isValid(value);
   *
   * }
   */
  protected abstract IPentahoResultSet getResultSet( Map parameterProviders );

  public boolean populate( final Map parameterProviders, final String[] value ) {
    // TODO apply session-based security
    // TODO support static lists of values

    defaultValue = value;
    resultSet = getResultSet( parameterProviders );
    if ( resultSet != null ) {
      // find the column that we have been told to you
      IPentahoMetaData metaData = resultSet.getMetaData();
      nameColumnNo = metaData.getColumnIndex( descriptionItem );
      valueColumnNo = metaData.getColumnIndex( valueItem );
    }
    return ( resultSet != null );
  }

  /**
   * Create the XForm header and XForm body, and place the results in the parameters xformHeader and xformBody.
   *
   * @param xformHeader
   *          StringBuffer containing the XForm header
   * @param xformBody
   *          StringBuffer containing the XForm body
   *
   * @throws ComponentException
   *           if this.nameColumnNo is -1, this.valueColumnNo is -1, or the this.resultSet is null. nameColumnNo is
   *           likely to be -1 if this.descriptionItem does not correlate with the value of the <data-display>
   *           element in the filter panel definition file and the name of a column in the resultSet. valueColumnNo
   *           is likely to be -1 if this.valueItem does not correlate with the value of the <data-value> element
   *           in the filter panel definition file and the name of a column in the resultSet. resultSet is likely
   *           to be null if a result-set was not placed in session or global scope under the key identified by the
   *           <global-attribute> or <session-attribute> element in the filter panel definition file, or if the
   *           action sequence identified by <data-action> element in the filter panel definition file failed to
   *           return a result set
   */
  public void getXForm( final StringBuffer xformHeader, final StringBuffer xformBody ) throws ComponentException {

    // iterate thru the values to get the items and the display names
    String value;
    String name;

    HashMap displayNames = null;
    ArrayList items = null;

    // TODO support multiple column headers / row headers
    // TODO support an iteration across columns for a given row
    // If the result is non-empty then we will extract the values from the result set and display to the user
    if ( ( resultSet != null ) && ( resultSet.getRowCount() > 0 ) ) {
      displayNames = new HashMap();
      items = new ArrayList();
      if ( nameColumnNo == -1 ) {
        // we did not find the specified name column
        throw new ComponentException( Messages.getInstance().getErrorString(
            "FilterDefinition.ERROR_0001_NAME_COLUMN_MISSING", descriptionItem ) ); //$NON-NLS-1$
      } else if ( valueColumnNo == -1 ) {
        // we did not find the specified name column
        throw new ComponentException( Messages.getInstance().getErrorString(
            "FilterDefinition.ERROR_0002_VALUE_COLUMN_MISSING", valueItem ) ); //$NON-NLS-1$
      }

      Object[] row = null;
      try {
        row = resultSet.next();
      } catch ( Exception e ) {
        // We will check for null below
      }
      if ( row == null ) {
        logger.warn( Messages.getInstance().getErrorString( "FilterDefinition.ERROR_0004_FILTER_DEFINITION_EMPTY" ) ); //$NON-NLS-1$
      } else {
        while ( row != null ) {
          value = row[valueColumnNo].toString();
          items.add( value );
          name = row[nameColumnNo].toString();
          if ( name != null ) {
            displayNames.put( value, name );
          }

          row = resultSet.next();
        }
      }
      // close the result set so we can loop through it again later if we need
      // to
      resultSet.close();

      // now create the XForm for the item
      if ( displayNames.size() == 0 ) {
        displayNames = null;
      }
    } else {
      // ResultSet is null and it is ok only for a filter type of TEXT_BOX
      if ( type != XForm.TYPE_TEXT ) {
        throw new ComponentException( Messages.getInstance().getErrorString(
            "FilterDefinition.ERROR_0003_FILTER_DEFINITION_NULL" ) ); //$NON-NLS-1$
      }
    }

    assert formName != null : Messages.getInstance().getErrorString( "FilterDefinition.ERROR_0005_NAME_ELEMENT_EMPTY" ); //$NON-NLS-1$
    assert !formName.matches( FilterDefinition.RE_HAS_WHITE_SPACE ) : Messages.getInstance().getErrorString(
        "FilterDefinition.ERROR_0006_NAME_ELEMENT_WHITESPACE" ); //$NON-NLS-1$
    XForm.createXFormControl( type, elementName, defaultValue, items, displayNames, formName, xformHeader, xformBody );
  }

  public static void main( final String[] args ) {
    String[] nm = { " xx", "xx ", " xx ", "x x", "xx", "custome rnumber", " x x " }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$

    for ( String element : nm ) {
      boolean matches = element.matches( FilterDefinition.RE_HAS_WHITE_SPACE );
      System.out.println( "[" + element + "] matches: " + matches ); //$NON-NLS-1$ //$NON-NLS-2$
    }
  }
}
TOP

Related Classes of org.pentaho.platform.uifoundation.component.FilterDefinition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.