/** @author Javier Paniza */
public class DescriptionsListTag extends TagSupport {

  private static Log log = LogFactory.getLog(DescriptionsListTag.class);
  private String reference;

  public int doStartTag() throws JspException {
    try {
      HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
      ModuleContext context = (ModuleContext) request.getSession().getAttribute("context");

      String viewObject = request.getParameter("viewObject");
      viewObject = (viewObject == null || viewObject.equals("")) ? "xava_view" : viewObject;
      View view = (View) context.get(request, viewObject);

      MetaReference metaReference = view.getMetaReference(reference).cloneMetaReference();
      metaReference.setName(reference);
      String prefix = request.getParameter("propertyPrefix");
      prefix = prefix == null ? "" : prefix;
      String application = request.getParameter("application");
      String module = request.getParameter("module");
      String referenceKey = Ids.decorate(application, module, prefix + reference);
      request.setAttribute(referenceKey, metaReference);
      String editorURL =
          "reference.jsp?referenceKey="
              + referenceKey
              + "&onlyEditor=true&frame=false&composite=false&descriptionsList=true";
      String editorPrefix = Module.isPortlet() ? "/WEB-INF/jsp/xava/" : "/xava/";
      try {
        pageContext.include(editorPrefix + editorURL);
      } catch (ServletException ex) {
        Throwable cause = ex.getRootCause() == null ? ex : ex.getRootCause();
        log.error(cause.getMessage(), cause);
        pageContext.include(editorPrefix + "editors/notAvailableEditor.jsp");
      } catch (Exception ex) {
        log.error(ex.getMessage(), ex);
        pageContext.include(editorPrefix + "editors/notAvailableEditor.jsp");
      }
    } catch (Exception ex) {
      log.error(ex.getMessage(), ex);
      throw new JspException(XavaResources.getString("descriptionsList_tag_error", reference));
    }
    return SKIP_BODY;
  }

  public String getReference() {
    return reference;
  }

  public void setReference(String property) {
    this.reference = property;
  }
}
// Clase UsuariosMunicipio
// Lee el usuario.
public class UsuariosMunicipio {

  private static Log log = LogFactory.getLog(UsuariosMunicipio.class);
  private static final ThreadLocal municipioUsuario = new ThreadLocal();
  private static final ThreadLocal municipioUsuarioInfo = new ThreadLocal();

  public static String getMunicipioUsuario() {
    return (String) municipioUsuario.get();
  }

  public static UserInfo getMunicipioUsuarioInfo() {
    UserInfo userInfo = (UserInfo) municipioUsuarioInfo.get();
    if (userInfo == null) userInfo = new UserInfo();
    userInfo.setId(getMunicipioUsuario());
    return userInfo;
  }

  public static void setMunicipioUsuario(String userName) {
    municipioUsuario.set(userName);
    municipioUsuarioInfo.set(null);
  }

  public static void setCurrentUserInfo(UserInfo userInfo) {
    municipioUsuario.set(userInfo.getId());
    municipioUsuarioInfo.set(userInfo);
  }

  public static void setCurrent(HttpServletRequest request) {
    Object rundata = request.getAttribute("rundata");
    String portalUser = (String) request.getSession().getAttribute("xava.portal.user");
    String webUser = (String) request.getSession().getAttribute("xava.user");
    String user = portalUser == null ? webUser : portalUser;
    if (Is.emptyString(user) && rundata != null) {
      PropertiesManager pmRundata = new PropertiesManager(rundata);
      try {
        Object jetspeedUser = pmRundata.executeGet("user");
        PropertiesManager pmUser = new PropertiesManager(jetspeedUser);
        user = (String) pmUser.executeGet("userName");
      } catch (Exception ex) {
        log.warn(XavaResources.getString("warning_get_user"), ex);
        user = null;
      }
    }
    municipioUsuario.set(user);
    request.getSession().setAttribute("xava.user", user);

    municipioUsuarioInfo.set(request.getSession().getAttribute("xava.portal.userinfo"));
  }
}
Example #3
0
/** @author Javier Paniza */
public abstract class ModelMapping implements java.io.Serializable {

  private static Log log = LogFactory.getLog(ModelMapping.class);

  private static boolean codeGenerationTime;
  private static boolean codeGenerationTimeObtained = false;
  private MetaComponent metaComponent;
  private String table;
  private Map propertyMappings = new HashMap();
  private Map referenceMappings;
  private Collection modelProperties = new ArrayList(); // of String
  private Collection tableColumns = new ArrayList(); // of String
  private Collection referenceMappingsWithConverter; // of ReferenceMapping
  private boolean databaseMetadataLoaded = false;
  private boolean supportsSchemasInDataManipulation = true;
  private boolean supportsYearFunction = false;
  private boolean supportsMonthFunction = false;
  private boolean supportsTranslateFunction = false;
  private boolean referencePropertyWithFormula = false;

  public abstract String getModelName() throws XavaException;

  public abstract MetaModel getMetaModel() throws XavaException;

  /** Util specially to find out the type of properties that are not in model, only in mapping. */
  public Class getType(String propertyName) throws XavaException {
    try {
      return getMetaModel().getMetaProperty(propertyName).getType();
    } catch (ElementNotFoundException ex) {
      // Try to obtain it from primary key
      if (!(getMetaModel() instanceof MetaEntity)) return java.lang.Object.class;
      throw ex;
    }
  }

  public String getTable() {
    // Change this if by polymorphism ?
    if (isCodeGenerationTime()) return table;
    if (XavaPreferences.getInstance().isJPAPersistence()
        && getSchema() == null
        && !Is.emptyString(XPersistence.getDefaultSchema())) {
      return XPersistence.getDefaultSchema() + "." + table;
    } else if (XavaPreferences.getInstance().isHibernatePersistence()
        && getSchema() == null
        && !Is.emptyString(XHibernate.getDefaultSchema())) {
      return XHibernate.getDefaultSchema() + "." + table;
    }
    return table;
  }

  private static boolean isCodeGenerationTime() {
    if (!codeGenerationTimeObtained) {
      codeGenerationTimeObtained = true;
      try {
        // Class.forName("CodeGenerator");
        ClassLoaderUtil.forName(ModelMapping.class, "CodeGenerator");
        codeGenerationTime = true;
      } catch (Exception ex) {
        codeGenerationTime = false;
      }
    }
    return codeGenerationTime;
  }

  public void setTable(String tabla) {
    this.table = tabla;
  }

  public String getSchema() {
    int idx = table.indexOf('.');
    if (idx < 0) return null;
    return table.substring(0, idx);
  }

  public String getUnqualifiedTable() {
    int idx = table.indexOf('.');
    if (idx < 0) return table;
    return table.substring(idx + 1);
  }

  public String getTableToQualifyColumn() {
    return supportsSchemasInDataManipulation() ? getTable() : getUnqualifiedTable();
  }

  public void addPropertyMapping(PropertyMapping propertyMapping) throws XavaException {
    propertyMappings.put(propertyMapping.getProperty(), propertyMapping);
    modelProperties.add(propertyMapping.getProperty());
    // To keep order
    tableColumns.add(propertyMapping.getColumn());
    if (propertyMapping.hasFormula() && !getMetaModel().isAnnotatedEJB3()) {
      propertyMapping.getMetaProperty().setReadOnly(true);
    }
  }

  public void addReferenceMapping(ReferenceMapping referenceMapping) throws XavaException {
    if (referenceMappings == null) referenceMappings = new HashMap();
    referenceMappings.put(referenceMapping.getReference(), referenceMapping);
    referenceMapping.setContainer(this);
  }

  /** @return Not null */
  public ReferenceMapping getReferenceMapping(String name)
      throws XavaException, ElementNotFoundException {

    ReferenceMapping r =
        referenceMappings == null ? null : (ReferenceMapping) referenceMappings.get(name);
    if (r == null) {
      throw new ElementNotFoundException("reference_mapping_not_found", name, getModelName());
    }
    return r;
  }

  /** @return Not null */
  public PropertyMapping getPropertyMapping(String name)
      throws XavaException, ElementNotFoundException {
    int i = name.indexOf('.');
    if (i >= 0) {
      String rName = name.substring(0, i);
      String pName = name.substring(i + 1);

      if (isReferenceNameInReferenceMappings(rName)) {
        return getReferenceMapping(rName).getReferencedMapping().getPropertyMapping(pName);
      } else {
        // by embedded references: address.city -> address_city
        return getPropertyMapping(name.replace(".", "_"));
      }
    }

    PropertyMapping p =
        propertyMappings == null ? null : (PropertyMapping) propertyMappings.get(name);
    if (p == null) {
      throw new ElementNotFoundException("property_mapping_not_found", name, getModelName());
    }
    return p;
  }

  private boolean isReferenceNameInReferenceMappings(String referenceName) {
    Collection<ReferenceMapping> col = getReferenceMappings();
    for (ReferenceMapping rm : col) if (rm.getReference().equals(referenceName)) return true;
    return false;
  }

  /**
   * In the order that they was added.
   *
   * @return Collection of <tt>String</tt>.
   */
  public Collection getModelProperties() {
    return modelProperties;
  }

  /**
   * In the order that they was added.
   *
   * @return Collection of <tt>String</tt>.
   */
  public Collection getColumns() {
    return tableColumns;
  }

  public String getKeyColumnsAsString() throws XavaException {
    StringBuffer r = new StringBuffer();
    Collection columns = new HashSet();
    for (Iterator it = getMetaModel().getAllKeyPropertiesNames().iterator(); it.hasNext(); ) {
      String pr = (String) it.next();
      String column = getColumn(pr);
      if (columns.contains(column)) continue;
      columns.add(column);
      r.append(column);
      r.append(' ');
    }
    return r.toString().trim();
  }

  private boolean supportsSchemasInDataManipulation() {
    loadDatabaseMetadata();
    return supportsSchemasInDataManipulation;
  }

  /** Wraps the column name with the SQL function for extracting the year from a date. */
  public String yearSQLFunction(String column) {
    if (supportsYearFunction()) return "year(" + column + ")";
    return "extract (year from " + column + ")";
  }

  /** Wraps the column name with the SQL function for extracting the month from a date. */
  public String monthSQLFunction(String column) {
    if (supportsMonthFunction()) return "month(" + column + ")";
    return "extract (month from " + column + ")";
  }

  /**
   * To ignore accents: just to search 'cami�n' or 'camion'
   *
   * <p>Good performance using 'translate' but is very slow when it use 'replace...'
   *
   * @since v4m6
   */
  public String translateSQLFunction(String column) {
    if (supportsTranslateFunction()) return "translate(" + column + ",'aeiouAEIOU','áéíóúÁÉÍÓÚ')";
    return "replace(replace(replace(replace(replace(replace(replace(replace(replace(replace("
        + column
        + ", 'Ú', 'U'), 'ú', 'u'), 'Ó', 'O'), 'ó', 'o'), 'Í', 'I'), "
        + "'í', 'i'), 'É', 'E'), 'é', 'e'), 'Á', 'A'), 'á', 'a')";
  }

  private boolean supportsYearFunction() {
    loadDatabaseMetadata();
    return supportsYearFunction;
  }

  private boolean supportsMonthFunction() {
    loadDatabaseMetadata();
    return supportsMonthFunction;
  }

  /** @since v4m6 */
  private boolean supportsTranslateFunction() {
    loadDatabaseMetadata();
    return supportsTranslateFunction;
  }

  private void loadDatabaseMetadata() {
    if (!databaseMetadataLoaded) {
      String componentName = "UNKNOWN";
      Connection con = null;
      try {
        componentName = getMetaComponent().getName();

        con = DataSourceConnectionProvider.getByComponent(componentName).getConnection();
        DatabaseMetaData metaData = con.getMetaData();
        supportsSchemasInDataManipulation = metaData.supportsSchemasInDataManipulation();
        Collection timeDateFunctions =
            Strings.toCollection(metaData.getTimeDateFunctions().toUpperCase());

        //
        // another solution instead of the use of 'if' would be to use a xml with
        //	the information of the functions from each BBDD
        if ("DB2 UDB for AS/400".equals(metaData.getDatabaseProductName())
            || "Oracle".equals(metaData.getDatabaseProductName())
            || "PostgresSQL".equals(metaData.getDatabaseProductName())) {
          supportsTranslateFunction = true;
        }
        if ("Oracle".equals(metaData.getDatabaseProductName())
            || "PostgreSQL".equals(metaData.getDatabaseProductName())) {
          supportsYearFunction = supportsMonthFunction = false;
        } else {
          supportsYearFunction = timeDateFunctions.contains("YEAR");
          supportsMonthFunction = timeDateFunctions.contains("MONTH");
        }
        databaseMetadataLoaded = true;
      } catch (Exception ex) {
        log.warn(XavaResources.getString("load_database_metadata_warning"));
      } finally {
        try {
          if (con != null) {
            con.close();
          }
        } catch (SQLException e) {
          log.warn(XavaResources.getString("close_connection_warning"));
        }
      }
    }
  }

  public String getQualifiedColumn(String modelProperty) throws XavaException {
    PropertyMapping propertyMapping = (PropertyMapping) propertyMappings.get(modelProperty);
    if (propertyMapping != null && propertyMapping.hasFormula()) return getColumn(modelProperty);

    String tableColumn = getTableColumn(modelProperty, true);
    if (Is.emptyString(tableColumn)) return "'" + modelProperty + "'";
    if (referencePropertyWithFormula) {
      referencePropertyWithFormula = false;
      return tableColumn;
    }
    // for calculated fields or created by multiple converter

    if (modelProperty.indexOf('.') >= 0) {
      if (tableColumn.indexOf('.') < 0) return tableColumn;
      String reference = modelProperty.substring(0, modelProperty.lastIndexOf('.'));
      if (tableColumn.startsWith(getTableToQualifyColumn() + ".")) {
        String member = modelProperty.substring(modelProperty.lastIndexOf('.') + 1);
        if (getMetaModel().getMetaReference(reference).getMetaModelReferenced().isKey(member))
          return tableColumn;
      }

      // The next code uses the alias of the table instead of its name. In order to
      // support multiple references to the same model
      if (reference.indexOf('.') >= 0) {
        if (getMetaModel().getMetaProperty(modelProperty).isKey()) {
          reference = reference.substring(0, reference.lastIndexOf('.'));
        }
        reference = reference.replaceAll("\\.", "_");
      }
      return "T_" + reference + tableColumn.substring(tableColumn.lastIndexOf('.'));
    } else {
      return getTableToQualifyColumn() + "." + tableColumn;
    }
  }

  /** Support the use of references with dots, this is: myreference.myproperty. */
  public String getColumn(String modelProperty) throws ElementNotFoundException, XavaException {
    return getTableColumn(modelProperty, false);
  }

  private String getTableColumn(String modelProperty, boolean qualifyReferenceMappingColumn)
      throws XavaException {

    PropertyMapping propertyMapping = (PropertyMapping) propertyMappings.get(modelProperty);
    if (propertyMapping == null) {
      int idx = modelProperty.indexOf('.');
      if (idx >= 0) {
        String referenceName = modelProperty.substring(0, idx);
        String propertyName = modelProperty.substring(idx + 1);
        if (getMetaModel().getMetaReference(referenceName).isAggregate()
            && !Strings.firstUpper(referenceName).equals(getMetaModel().getContainerModelName())) {
          propertyMapping =
              (PropertyMapping) propertyMappings.get(referenceName + "_" + propertyName);
          if (propertyMapping == null) {
            int idx2 = propertyName.indexOf('.');
            if (idx2 >= 0) {
              String referenceName2 = propertyName.substring(0, idx2);
              String propertyName2 = propertyName.substring(idx2 + 1);
              return getTableColumn(
                  referenceName + "_" + referenceName2 + "." + propertyName2,
                  qualifyReferenceMappingColumn);
            } else {
              throw new ElementNotFoundException(
                  "property_mapping_not_found", referenceName + "_" + propertyName, getModelName());
            }
          }
          return propertyMapping.getColumn();
        }
        ReferenceMapping referenceMapping = getReferenceMapping(referenceName);

        if (referenceMapping.hasColumnForReferencedModelProperty(propertyName)) {
          if (qualifyReferenceMappingColumn) {
            return getTableToQualifyColumn()
                + "."
                + referenceMapping.getColumnForReferencedModelProperty(propertyName);
          } else {
            return referenceMapping.getColumnForReferencedModelProperty(propertyName);
          }
        } else {
          ModelMapping referencedMapping = referenceMapping.getReferencedMapping();

          String tableName = referencedMapping.getTableToQualifyColumn();
          boolean secondLevel = propertyName.indexOf('.') >= 0;
          String columnName = referencedMapping.getTableColumn(propertyName, secondLevel);
          boolean hasFormula = referencedMapping.getPropertyMapping(propertyName).hasFormula();

          if (qualifyReferenceMappingColumn && !secondLevel && !hasFormula) {
            return tableName + "." + columnName;
          } else if (hasFormula) {
            String formula = referencedMapping.getPropertyMapping(propertyName).getFormula();
            referencePropertyWithFormula = true;
            return qualifyFormulaWithReferenceName(
                formula, referencedMapping.getModelName(), modelProperty);
          } else {
            return columnName;
          }
        }
      }
      throw new ElementNotFoundException(
          "property_mapping_not_found", modelProperty, getModelName());
    }
    if (propertyMapping.hasFormula()) return propertyMapping.getFormula();
    return propertyMapping.getColumn();
  }

  /**
   * @exception ElementNotFoundException If property does not exist.
   * @exception XavaException Any problem
   * @return nulo If property exists but it does not have converter.
   */
  public IConverter getConverter(String modelProperty)
      throws ElementNotFoundException, XavaException {
    return getPropertyMapping(modelProperty).getConverter();
  }

  /**
   * @exception ElementNotFoundException If property does not exist.
   * @exception XavaException Any problem
   * @return nulo If property exists but it does not have converter.
   */
  public IMultipleConverter getMultipleConverter(String modelProperty)
      throws ElementNotFoundException, XavaException {
    return getPropertyMapping(modelProperty).getMultipleConverter();
  }

  /** If the property exists and has converter. */
  public boolean hasConverter(String propertyName) {
    try {
      return getPropertyMapping(propertyName).hasConverter();
    } catch (XavaException ex) {
      return false;
    }
  }

  public MetaComponent getMetaComponent() {
    return metaComponent;
  }

  public void setMetaComponent(MetaComponent componente) throws XavaException {
    this.metaComponent = componente;
    setupDefaultConverters();
  }

  /**
   * Change the properties inside ${ } by the database qualified(schema + table) columns. Also if
   * the property inside ${ } is a model name it changes by the table name
   *
   * <p>For example, it would change:
   *
   * <pre>
   * select ${number}, ${name} from ${Tercero}
   * </pre>
   *
   * by
   *
   * <pre>
   * select G4GENBD.GENTGER.TGRCOD, G4GENBD.GENTGER.TGRDEN from G4GENBD.GENTGER
   * </pre>
   */
  public String changePropertiesByColumns(String source) throws XavaException {
    return changePropertiesByColumns(source, true);
  }

  /**
   * Change the properties inside ${ } by the database columns without table and schema as prefix.
   * Also if the property inside ${ } is a model name it changes by the table name.
   *
   * <p>For example, it would change:
   *
   * <pre>
   * select ${number}, ${name} from ${Tercero}
   * </pre>
   *
   * by
   *
   * <pre>
   * select TGRCOD, TGRDEN
   * from G4GENBD.GENTGER
   * </pre>
   */
  public String changePropertiesByNotQualifiedColumns(String source) throws XavaException {
    return changePropertiesByColumns(source, false);
  }

  private String changePropertiesByColumns(String source, boolean qualified) throws XavaException {
    StringBuffer r = new StringBuffer(source);
    int i = r.toString().indexOf("${");
    int f = 0;
    while (i >= 0) {
      f = r.toString().indexOf("}", i + 2);
      if (f < 0) break;
      String property = r.substring(i + 2, f);
      String column = "0"; // thus it remained if it is calculated
      if (!getMetaModel().isCalculated(property)) {
        column =
            Strings.isModelName(property)
                ? getTable(property)
                : qualified ? getQualifiedColumn(property) : getColumn(property);
      }
      r.replace(i, f + 1, column);
      i = r.toString().indexOf("${");
    }
    return r.toString();
  }

  /** @since 4.1 */
  private String getTable(String name) {
    return MetaComponent.get(name).getEntityMapping().getTable();
  }

  public String changePropertiesByCMPAttributes(String source) throws XavaException {
    StringBuffer r = new StringBuffer(source);
    int i = r.toString().indexOf("${");
    int f = 0;
    while (i >= 0) {
      f = r.toString().indexOf("}", i + 2);
      if (f < 0) break;
      String property = r.substring(i + 2, f);
      String cmpAttribute = null;
      if (property.indexOf('.') >= 0) {
        cmpAttribute = "o._" + Strings.firstUpper(Strings.change(property, ".", "_"));
      } else {
        MetaProperty metaProperty = getMetaModel().getMetaProperty(property);
        if (metaProperty.getMapping().hasConverter()) {
          cmpAttribute = "o._" + Strings.firstUpper(property);
        } else {
          cmpAttribute = "o." + property;
        }
      }
      r.replace(i, f + 1, cmpAttribute);
      i = r.toString().indexOf("${");
    }
    return r.toString();
  }

  public boolean hasPropertyMapping(String memberName) {
    return propertyMappings.containsKey(memberName);
  }

  private void setupDefaultConverters() throws XavaException {
    Iterator it = propertyMappings.values().iterator();
    while (it.hasNext()) {
      PropertyMapping propertyMapping = (PropertyMapping) it.next();
      propertyMapping.setDefaultConverter();
    }
  }

  public boolean hasReferenceMapping(MetaReference metaReference) {
    if (referenceMappings == null) return false;
    return referenceMappings.containsKey(metaReference.getName());
  }

  public boolean isReferenceOverlappingWithSomeProperty(
      String reference, String propertiesOfReference) throws XavaException {
    String column =
        getReferenceMapping(reference).getColumnForReferencedModelProperty(propertiesOfReference);
    return containsColumn(getColumns(), column);
  }

  public boolean isReferenceOverlappingWithSomeProperty(String reference) throws XavaException {
    Iterator it = getReferenceMapping(reference).getDetails().iterator();
    while (it.hasNext()) {
      ReferenceMappingDetail d = (ReferenceMappingDetail) it.next();
      if (containsColumn(getColumns(), d.getColumn())) {
        String property = getMappingForColumn(d.getColumn()).getProperty();
        if (!property.startsWith(reference + "_")) {
          return true;
        }
      }
    }
    return false;
  }

  public boolean isReferencePropertyOverlappingWithSomeProperty(String qualifiedProperty)
      throws XavaException {
    int idx = qualifiedProperty.indexOf('.');
    if (idx < 0) return false;
    String ref = qualifiedProperty.substring(0, idx);
    String pr = qualifiedProperty.substring(idx + 1);
    return isReferenceOverlappingWithSomeProperty(ref, pr);
  }

  /** @throws XavaException If it does not have a overlapped property, or any other problem. */
  public String getOverlappingPropertyForReference(String reference, String propertyOfReference)
      throws XavaException {
    String column =
        getReferenceMapping(reference).getColumnForReferencedModelProperty(propertyOfReference);
    if (propertyMappings == null) {
      throw new XavaException("reference_property_not_overlapped", propertyOfReference, reference);
    }
    Iterator it = propertyMappings.values().iterator();
    while (it.hasNext()) {
      PropertyMapping mapping = (PropertyMapping) it.next();
      if (column.equalsIgnoreCase(mapping.getColumn())) return mapping.getProperty();
    }
    throw new XavaException("reference_property_not_overlapped", propertyOfReference, reference);
  }

  /** @return Of <tt>String</tt> and not null. */
  public Collection getOverlappingPropertiesOfReference(String reference) throws XavaException {
    Collection overlappingPropertiesOfReference = new ArrayList();
    Iterator it = getReferenceMapping(reference).getDetails().iterator();
    while (it.hasNext()) {
      ReferenceMappingDetail d = (ReferenceMappingDetail) it.next();
      if (containsColumn(getColumns(), d.getColumn())) {
        String property = getMappingForColumn(d.getColumn()).getProperty();
        if (!property.startsWith(reference + "_")) {
          overlappingPropertiesOfReference.add(d.getReferencedModelProperty());
        }
      }
    }
    return overlappingPropertiesOfReference;
  }

  private boolean containsColumn(Collection columns, String column) {
    if (columns.contains(column)) return true;
    for (Iterator it = columns.iterator(); it.hasNext(); ) {
      if (((String) it.next()).equalsIgnoreCase(column)) return true;
    }
    return false;
  }

  private PropertyMapping getMappingForColumn(String column) throws XavaException {
    if (propertyMappings == null) {
      throw new ElementNotFoundException("mapping_not_found_no_property_mappings", column);
    }
    Iterator it = propertyMappings.values().iterator();
    while (it.hasNext()) {
      PropertyMapping propertyMapping = (PropertyMapping) it.next();
      if (propertyMapping.getColumn().equalsIgnoreCase(column)) {
        return propertyMapping;
      }
    }
    throw new ElementNotFoundException("mapping_for_column_not_found", column);
  }

  String getCMPAttributeForColumn(String column) throws XavaException {
    PropertyMapping mapping = getMappingForColumn(column);
    if (!mapping.hasConverter()) return Strings.change(mapping.getProperty(), ".", "_");
    return "_" + Strings.change(Strings.firstUpper(mapping.getProperty()), ".", "_");
  }

  private Collection getPropertyMappings() {
    return propertyMappings.values();
  }

  public Collection getPropertyMappingsNotInModel() throws XavaException {
    Collection names = new ArrayList(getModelProperties());
    names.removeAll(getMetaModel().getPropertiesNames());
    if (names.isEmpty()) return Collections.EMPTY_LIST;
    Collection result = new ArrayList();
    for (Iterator it = names.iterator(); it.hasNext(); ) {
      String name = (String) it.next();
      if (name.indexOf('_') < 0) {
        result.add(getPropertyMapping(name));
      }
    }
    return result;
  }

  private Collection getReferenceMappings() {
    return referenceMappings == null ? Collections.EMPTY_LIST : referenceMappings.values();
  }

  public Collection getCmpFields() throws XavaException {
    Collection r = new ArrayList();
    Collection mappedColumns = new HashSet();
    for (Iterator it = getPropertyMappings().iterator(); it.hasNext(); ) {
      PropertyMapping pMapping = (PropertyMapping) it.next();
      r.addAll(pMapping.getCmpFields());
      mappedColumns.add(pMapping.getColumn());
    }
    for (Iterator it = getReferenceMappings().iterator(); it.hasNext(); ) {
      ReferenceMapping rMapping = (ReferenceMapping) it.next();
      for (Iterator itFields = rMapping.getCmpFields().iterator(); itFields.hasNext(); ) {
        CmpField field = (CmpField) itFields.next();
        if (!mappedColumns.contains(field.getColumn())) {
          r.add(field);
          mappedColumns.add(field.getColumn());
        }
      }
    }

    return r;
  }

  public boolean hasReferenceConverters() {
    return !getReferenceMappingsWithConverter().isEmpty();
  }

  public Collection getReferenceMappingsWithConverter() {
    if (referenceMappingsWithConverter == null) {
      referenceMappingsWithConverter = new ArrayList();
      Iterator it = getReferenceMappings().iterator();
      while (it.hasNext()) {
        ReferenceMapping referenceMapping = (ReferenceMapping) it.next();
        Collection mrd = referenceMapping.getDetails();
        Iterator itd = mrd.iterator();
        while (itd.hasNext()) {
          ReferenceMappingDetail referenceMappingDetail = (ReferenceMappingDetail) itd.next();
          if (referenceMappingDetail.hasConverter()) {
            referenceMappingsWithConverter.add(referenceMapping);
          }
        }
      }
    }
    return referenceMappingsWithConverter;
  }

  /**
   * Find the columns name in the formula and replace its by qualify columns name: 'name' ->
   * 't_reference.name'
   */
  private String qualifyFormulaWithReferenceName(
      String formula, String referenceName, String modelProperty) {
    EntityMapping em = MetaComponent.get(referenceName).getEntityMapping();

    Iterator<String> it = em.getColumns().iterator();
    while (it.hasNext()) {
      String column = it.next();
      if (formula.contains(column)) {
        formula =
            formula.replace(
                column, getQualifyColumnName(modelProperty, referenceName + "." + column));
      }
    }

    return formula;
  }

  private String getQualifyColumnName(String modelProperty, String tableColumn) {
    if (modelProperty.indexOf('.') >= 0) {
      if (tableColumn.indexOf('.') < 0) return tableColumn;
      String reference = modelProperty.substring(0, modelProperty.lastIndexOf('.'));
      if (tableColumn.startsWith(getTableToQualifyColumn() + ".")) {
        String member = modelProperty.substring(modelProperty.lastIndexOf('.') + 1);
        if (getMetaModel().getMetaReference(reference).getMetaModelReferenced().isKey(member))
          return tableColumn;
      }

      // The next code uses the alias of the table instead of its name. In order to
      // support multiple references to the same model
      if (reference.indexOf('.') >= 0) {
        if (getMetaModel().getMetaProperty(modelProperty).isKey()) {
          reference = reference.substring(0, reference.lastIndexOf('.'));
        }
        reference = reference.substring(reference.lastIndexOf('.') + 1);
      }
      return "T_" + reference + tableColumn.substring(tableColumn.lastIndexOf('.'));
    } else {
      return getTableToQualifyColumn() + "." + tableColumn;
    }
  }
}
/**
 * To generate automatically reports from list mode.
 *
 * <p>Uses JasperReports.
 *
 * @author Javier Paniza
 */
public class GenerateReportServlet extends HttpServlet {

  private static Log log = LogFactory.getLog(GenerateReportServlet.class);

  public static class TableModelDecorator implements TableModel {

    private TableModel original;
    private List metaProperties;
    private boolean withValidValues = false;
    private Locale locale;
    private boolean labelAsHeader = false;
    private HttpServletRequest request;
    private boolean format =
        false; // format or no the values. If format = true, all values to the report are String
    private Integer columnCountLimit;

    public TableModelDecorator(
        HttpServletRequest request,
        TableModel original,
        List metaProperties,
        Locale locale,
        boolean labelAsHeader,
        boolean format,
        Integer columnCountLimit)
        throws Exception {
      this.request = request;
      this.original = original;
      this.metaProperties = metaProperties;
      this.locale = locale;
      this.withValidValues = calculateWithValidValues();
      this.labelAsHeader = labelAsHeader;
      this.format = format;
      this.columnCountLimit = columnCountLimit;
    }

    private boolean calculateWithValidValues() {
      Iterator it = metaProperties.iterator();
      while (it.hasNext()) {
        MetaProperty m = (MetaProperty) it.next();
        if (m.hasValidValues()) return true;
      }
      return false;
    }

    private MetaProperty getMetaProperty(int i) {
      return (MetaProperty) metaProperties.get(i);
    }

    public int getRowCount() {
      return original.getRowCount();
    }

    public int getColumnCount() {
      return columnCountLimit == null ? original.getColumnCount() : columnCountLimit;
    }

    public String getColumnName(int c) {
      return labelAsHeader
          ? getMetaProperty(c).getLabel(locale)
          : Strings.change(getMetaProperty(c).getQualifiedName(), ".", "_");
    }

    public Class getColumnClass(int c) {
      return original.getColumnClass(c);
    }

    public boolean isCellEditable(int row, int column) {
      return original.isCellEditable(row, column);
    }

    public Object getValueAt(int row, int column) {
      if (isFormat()) return getValueWithWebEditorsFormat(row, column);
      else return getValueWithoutWebEditorsFormat(row, column);
    }

    private Object getValueWithoutWebEditorsFormat(int row, int column) {
      Object r = original.getValueAt(row, column);

      if (r instanceof Boolean) {
        if (((Boolean) r).booleanValue()) return XavaResources.getString(locale, "yes");
        return XavaResources.getString(locale, "no");
      }
      if (withValidValues) {
        MetaProperty p = getMetaProperty(column);
        if (p.hasValidValues()) {
          return p.getValidValueLabel(locale, original.getValueAt(row, column));
        }
      }

      if (r instanceof java.util.Date) {
        MetaProperty p =
            getMetaProperty(column); // In order to use the type declared by the developer
        // and not the one returned by JDBC or the JPA engine
        if (java.sql.Time.class.isAssignableFrom(p.getType())) {
          return DateFormat.getTimeInstance(DateFormat.SHORT, locale).format(r);
        }
        if (java.sql.Timestamp.class.isAssignableFrom(p.getType())) {
          DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
          return dateFormat.format(r);
        }
        return DateFormat.getDateInstance(DateFormat.SHORT, locale).format(r);
      }

      if (r instanceof BigDecimal) {
        return formatBigDecimal(r, locale);
      }

      return r;
    }

    private Object getValueWithWebEditorsFormat(int row, int column) {
      Object r = original.getValueAt(row, column);
      MetaProperty metaProperty = getMetaProperty(column);
      String result = WebEditors.format(this.request, metaProperty, r, null, "", true);
      if (isHtml(result)) { // this avoids that the report shows html content
        result = WebEditors.format(this.request, metaProperty, r, null, "", false);
      }
      return result;
    }

    public void setValueAt(Object value, int row, int column) {
      original.setValueAt(value, row, column);
    }

    public void addTableModelListener(TableModelListener l) {
      original.addTableModelListener(l);
    }

    public void removeTableModelListener(TableModelListener l) {
      original.removeTableModelListener(l);
    }

    private boolean isHtml(String value) {
      return value.matches("<.*>");
    }

    public boolean isFormat() {
      return format;
    }

    public void setFormat(boolean format) {
      this.format = format;
    }
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {
      Locales.setCurrent(request);
      if (Users.getCurrent() == null) { // for a bug in websphere portal 5.1 with Domino LDAP
        Users.setCurrent((String) request.getSession().getAttribute("xava.user"));
      }
      request.getParameter("application"); // for a bug in websphere 5.1
      request.getParameter("module"); // for a bug in websphere 5.1
      Tab tab = (Tab) request.getSession().getAttribute("xava_reportTab");
      int[] selectedRowsNumber =
          (int[]) request.getSession().getAttribute("xava_selectedRowsReportTab");
      Map[] selectedKeys = (Map[]) request.getSession().getAttribute("xava_selectedKeysReportTab");
      int[] selectedRows = getSelectedRows(selectedRowsNumber, selectedKeys, tab);
      request.getSession().removeAttribute("xava_selectedRowsReportTab");
      Integer columnCountLimit =
          (Integer) request.getSession().getAttribute("xava_columnCountLimitReportTab");
      request.getSession().removeAttribute("xava_columnCountLimitReportTab");

      setDefaultSchema(request);
      String user = (String) request.getSession().getAttribute("xava_user");
      request.getSession().removeAttribute("xava_user");
      Users.setCurrent(user);
      String uri = request.getRequestURI();
      if (uri.endsWith(".pdf")) {
        InputStream is;
        JRDataSource ds;
        Map parameters = new HashMap();
        synchronized (tab) {
          tab.setRequest(request);
          parameters.put("Title", tab.getTitle());
          parameters.put("Organization", getOrganization());
          parameters.put("Date", getCurrentDate());
          for (String totalProperty : tab.getTotalPropertiesNames()) {
            parameters.put(totalProperty + "__TOTAL__", getTotal(request, tab, totalProperty));
          }
          TableModel tableModel = getTableModel(request, tab, selectedRows, false, true, null);
          tableModel.getValueAt(0, 0);
          if (tableModel.getRowCount() == 0) {
            generateNoRowsPage(response);
            return;
          }
          is = getReport(request, response, tab, tableModel, columnCountLimit);
          ds = new JRTableModelDataSource(tableModel);
        }
        JasperPrint jprint = JasperFillManager.fillReport(is, parameters, ds);
        response.setContentType("application/pdf");
        response.setHeader(
            "Content-Disposition", "inline; filename=\"" + getFileName(tab) + ".pdf\"");
        JasperExportManager.exportReportToPdfStream(jprint, response.getOutputStream());
      } else if (uri.endsWith(".csv")) {
        String csvEncoding = XavaPreferences.getInstance().getCSVEncoding();
        if (!Is.emptyString(csvEncoding)) {
          response.setCharacterEncoding(csvEncoding);
        }
        response.setContentType("text/x-csv");
        response.setHeader(
            "Content-Disposition", "inline; filename=\"" + getFileName(tab) + ".csv\"");
        synchronized (tab) {
          tab.setRequest(request);
          response
              .getWriter()
              .print(
                  TableModels.toCSV(
                      getTableModel(request, tab, selectedRows, true, false, columnCountLimit)));
        }
      } else {
        throw new ServletException(
            XavaResources.getString("report_type_not_supported", "", ".pdf .csv"));
      }
    } catch (Exception ex) {
      log.error(ex.getMessage(), ex);
      throw new ServletException(XavaResources.getString("report_error"));
    } finally {
      request.getSession().removeAttribute("xava_reportTab");
    }
  }

  private void generateNoRowsPage(HttpServletResponse response) throws Exception {
    response.setContentType("text/html");
    response.getWriter().println("<html><head><title>");
    response.getWriter().println(XavaResources.getString("no_rows_report_message_title"));
    response
        .getWriter()
        .println(
            "</title></head><body style='font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;'>");
    response.getWriter().println("<h1 style='font-size:22px;'>");
    response.getWriter().println(XavaResources.getString("no_rows_report_message_title"));
    response.getWriter().println("</h1>");
    response.getWriter().println("<p style='font-size:16px;'>");
    response.getWriter().println(XavaResources.getString("no_rows_report_message_detail"));
    response.getWriter().println("</p></body></html>");
  }

  private String getCurrentDate() {
    return java.text.DateFormat.getDateInstance(DateFormat.MEDIUM, Locales.getCurrent())
        .format(new java.util.Date());
  }

  private String getFileName(Tab tab) {
    String now = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
    return tab.getTitle() + " " + now;
  }

  private Object getTotal(HttpServletRequest request, Tab tab, String totalProperty) {
    Object total = tab.getTotal(totalProperty);
    return WebEditors.format(
        request, tab.getMetaProperty(totalProperty), total, new Messages(), null, true);
  }

  private void setDefaultSchema(HttpServletRequest request) {
    String hibernateDefaultSchemaTab =
        (String) request.getSession().getAttribute("xava_hibernateDefaultSchemaTab");
    if (hibernateDefaultSchemaTab != null) {
      request.getSession().removeAttribute("xava_hibernateDefaultSchemaTab");
      XHibernate.setDefaultSchema(hibernateDefaultSchemaTab);
    }
    String jpaDefaultSchemaTab =
        (String) request.getSession().getAttribute("xava_jpaDefaultSchemaTab");
    if (jpaDefaultSchemaTab != null) {
      request.getSession().removeAttribute("xava_jpaDefaultSchemaTab");
      XPersistence.setDefaultSchema(jpaDefaultSchemaTab);
    }
  }

  protected String getOrganization() throws MissingResourceException, XavaException {
    return ReportParametersProviderFactory.getInstance().getOrganization();
  }

  private InputStream getReport(
      HttpServletRequest request,
      HttpServletResponse response,
      Tab tab,
      TableModel tableModel,
      Integer columnCountLimit)
      throws ServletException, IOException {
    StringBuffer suri = new StringBuffer();
    suri.append("/xava/jasperReport");
    suri.append("?language=");
    suri.append(Locales.getCurrent().getLanguage());
    suri.append("&widths=");
    suri.append(Arrays.toString(getWidths(tableModel)));
    if (columnCountLimit != null) {
      suri.append("&columnCountLimit=");
      suri.append(columnCountLimit);
    }
    response.setCharacterEncoding(XSystem.getEncoding());
    return Servlets.getURIAsStream(request, response, suri.toString());
  }

  private int[] getWidths(TableModel tableModel) {
    int[] widths = new int[tableModel.getColumnCount()];
    for (int r = 0;
        r < Math.min(tableModel.getRowCount(), 500);
        r++) { // 500 is not for performance, but for using only a sample of data with huge table
      for (int c = 0; c < tableModel.getColumnCount(); c++) {
        Object o = tableModel.getValueAt(r, c);
        if (o instanceof String) {
          String s = ((String) o).trim();
          if (s.length() > widths[c]) widths[c] = s.length();
        }
      }
    }
    return widths;
  }

  private TableModel getTableModel(
      HttpServletRequest request,
      Tab tab,
      int[] selectedRows,
      boolean labelAsHeader,
      boolean format,
      Integer columnCountLimit)
      throws Exception {
    TableModel data = null;
    if (selectedRows != null && selectedRows.length > 0) {
      data = new SelectedRowsXTableModel(tab.getTableModel(), selectedRows);
    } else {
      data = tab.getAllDataTableModel();
    }
    return new TableModelDecorator(
        request,
        data,
        tab.getMetaProperties(),
        Locales.getCurrent(),
        labelAsHeader,
        format,
        columnCountLimit);
  }

  private static Object formatBigDecimal(Object number, Locale locale) {
    NumberFormat nf = NumberFormat.getNumberInstance(locale);
    nf.setMinimumFractionDigits(2);
    return nf.format(number);
  }

  private int[] getSelectedRows(int[] selectedRowsNumber, Map[] selectedRowsKeys, Tab tab) {
    if (selectedRowsKeys == null || selectedRowsKeys.length == 0) return new int[0];
    // selectedRowsNumber is the most performant so we use it when possible
    else if (selectedRowsNumber.length == selectedRowsKeys.length) return selectedRowsNumber;
    else {
      // find the rows from the selectedKeys

      // This has a poor performance, but it covers the case when the selected
      // rows are not loaded for the tab, something that can occurs if the user
      // select rows and afterwards reorder the list.
      try {
        int[] s = new int[selectedRowsKeys.length];
        List selectedKeys = Arrays.asList(selectedRowsKeys);
        int end = tab.getTableModel().getTotalSize();
        int x = 0;
        for (int i = 0; i < end; i++) {
          Map key = (Map) tab.getTableModel().getObjectAt(i);
          if (selectedKeys.contains(key)) {
            s[x] = i;
            x++;
          }
        }
        return s;
      } catch (Exception ex) {
        log.warn(XavaResources.getString("fails_selected"), ex);
        throw new XavaException("fails_selected");
      }
    }
  }
}
/** @author Javier Paniza */
public class ColorTest extends ModuleTestBase {
  private static Log log = LogFactory.getLog(ColorTest.class);

  public ColorTest(String testName) {
    super(testName, "Color");
  }

  public void testSharedReport() throws Exception {
    // we need that there is not any report
    execute("ExtendedPrint.myReports");
    assertDialogTitle("My reports");
    assertEditable("name");
    assertNoAction("MyReport.createNew");
    assertNoAction("MyReport.remove");
    assertNoAction("MyReport.share");

    // create a new report
    setValue("name", "This is an report to share");
    checkRowCollection("columns", 2);
    checkRowCollection("columns", 3);
    checkRowCollection("columns", 4);
    checkRowCollection("columns", 5);
    execute("MyReport.removeColumn", "viewObject=xava_view_columns");
    assertCollectionRowCount("columns", 2);
    execute("MyReport.editColumn", "row=1,viewObject=xava_view_columns");
    setValue("value", "rojo");
    execute("MyReport.saveColumn");
    assertDialogTitle("My reports");
    execute("MyReport.generatePdf");
    assertNoDialog();
    assertNoErrors();

    // shared
    execute("ExtendedPrint.myReports");
    assertAction("MyReport.createNew");
    assertAction("MyReport.remove");
    assertAction("MyReport.share");
    assertValidValues(
        "name", new String[][] {{"This is an report to share", "This is an report to share"}});
    execute("MyReport.share", "xava.keyProperty=name");
    assertNoErrors();
    assertDialog();
    assertValidValues(
        "name",
        new String[][] {
          {"This is an report to share__SHARED_REPORT__", "This is an report to share (Shared)"}
        });

    // delete
    execute("MyReport.remove", "xava.keyProperty=name");
    assertNoErrors();
    assertMessage("Report 'This is an report to share' removed");
    assertEditable("name");
    assertNoAction("MyReport.createNew");
    assertNoAction("MyReport.remove");
    assertNoAction("MyReport.share");
  }

  public void testSubcontrollerOnChangeControllers() throws Exception {
    assertAction("ColorSub.firstAction");
    execute("List.addColumns");
    assertNoAction("ColorSub.firstAction");
  }

  public void testSubcontroller() throws Exception {
    String linkXml =
        getHtmlPage().getHtmlElementById("ox_OpenXavaTest_Color__sc-a-ColorSub_list").asXml();
    assertTrue(linkXml.contains("<i class=\"mdi mdi-run\""));
    assertFalse(linkXml.contains("images/"));

    assertNoAction("ColorSub.fourAction");
    execute("ColorSub.firstAction");
    assertDialog();
    closeDialog();
    execute("Mode.detailAndFirst");
    assertAction("ColorSub.fourAction");

    HtmlElement container =
        getHtmlPage().getHtmlElementById("ox_OpenXavaTest_Color__sc-container-ColorSub_detail");
    HtmlElement menu =
        getHtmlPage().getHtmlElementById("ox_OpenXavaTest_Color__sc-ColorSub_detail");
    assertTrue("display:none;".equals(menu.getAttribute("style")));
    assertTrue(container.asText().contains("My processes"));
    assertTrue(container.asText().contains("First action from subcontroller"));
    assertTrue(container.asText().contains("Second action"));
    assertTrue(container.asText().contains("Third action"));
  }

  public void testPrintPDF() throws Exception {
    execute("List.orderBy", "property=number");
    checkRow(1);
    String number1 = getValueInList(1, 0);
    String name1 = getValueInList(1, 1);
    String hexValue1 = getValueInList(1, 2);
    String useTo1 = getValueInList(1, 3);
    String characteristicThing1 = getValueInList(1, 4);
    checkRow(5);
    String number5 = getValueInList(5, 0);
    String name5 = getValueInList(5, 1);
    String hexValue5 = getValueInList(5, 2);
    String useTo5 = getValueInList(5, 3);
    String characteristicThing5 = getValueInList(5, 4);
    execute("List.orderBy", "property=number");
    checkRow(0);
    String number0 = getValueInList(0, 0);
    String name0 = getValueInList(0, 1);
    String hexValue0 = getValueInList(0, 2);
    String useTo0 = getValueInList(0, 3);
    String characteristicThing0 = getValueInList(0, 4);
    execute("Color.seeMessageSelected");
    assertMessage("(before) Rows of selected colors [0]");
    assertMessage(
        "(after) Rows of selected colors [{number="
            + number1
            + "}][{number="
            + number5
            + "}][{number="
            + number0
            + "}]");

    execute("Print.generatePdf");
    assertContentTypeForPopup("application/pdf");
    assertPopupPDFLinesCount(7);
    assertPopupPDFLine(3, getPDFLine(number0, name0, hexValue0, useTo0, characteristicThing0));
    assertPopupPDFLine(4, getPDFLine(number5, name5, hexValue5, useTo5, characteristicThing5));
    assertPopupPDFLine(5, getPDFLine(number1, name1, hexValue1, useTo1, characteristicThing1));
  }

  private String getPDFLine(
      String number, String name, String hexValue, String useTo, String characteristicThing) {
    String s = "";
    s += Is.empty(number) ? "" : number + " ";
    s += Is.empty(name) ? "" : name + " ";
    s += Is.empty(hexValue) ? "" : hexValue + " ";
    s += Is.empty(useTo) ? "" : useTo + " ";
    s += Is.empty(characteristicThing) ? "" : characteristicThing + " ";
    return s.trim();
  }

  public void testActionWithSelectedRowFromAnotherPage() throws Exception {
    checkRow(2);
    String number2 = getValueInList(2, 0);
    checkRow(6);
    String number6 = getValueInList(6, 0);
    execute("List.goNextPage");
    checkRow(10);
    String number10 = getValueInList(0, 0);
    execute("List.goNextPage");
    execute("Color.seeMessageSelected");
    assertMessage("(before) Rows of selected colors [2][6][10]");
    assertMessage(
        "(after) Rows of selected colors [{number="
            + number2
            + "}][{number="
            + number6
            + "}][{number="
            + number10
            + "}]");
    assertNoErrors();
  }

  public void testSelectedAllAndDeselectedAll() throws Exception {
    execute("List.orderBy", "property=number");
    assertLabelInList(1, "Name");
    assertTrue(getValueInList(0, 1).equals("ROJO"));
    checkAll();
    assertAllChecked();
    execute("List.orderBy", "property=number");
    assertFalse(getValueInList(0, 1).equals("ROJO"));
    assertAllUnchecked();
    execute("List.orderBy", "property=number");
    assertTrue(getValueInList(0, 1).equals("ROJO"));
    uncheckRow(0);
    uncheckRow(5);
    execute("List.orderBy", "property=number");
    assertFalse(getValueInList(0, 1).equals("ROJO"));
    assertAllUnchecked();
    checkAll();
    assertRowChecked(0);
    execute("List.orderBy", "property=number");
    assertRowUnchecked(0);
    assertRowUnchecked(5);
    checkAll();
    assertRowChecked(0);
    uncheckAll();
    assertRowUnchecked(0);
    execute("List.orderBy", "property=number");
    assertFalse(getValueInList(0, 1).equals("ROJO"));
    assertAllChecked();
  }

  /*
  This test requires at least 6 pages (more than 50 elements) to work.
  When you did: select, change page, select, order, select and change page. It lost the selection
  */
  public void testSelectAndOrderWithALotOfElements() throws Exception {
    execute("List.orderBy", "property=number");
    checkRow(0);
    checkRow(1);
    execute("List.goPage", "page=2");
    checkRow(12);
    checkRow(13);
    execute("List.goPage", "page=1");
    assertRowUnchecked(2);
    assertRowUnchecked(3);
    execute("List.orderBy", "property=number");
    assertRowUnchecked(0);
    assertRowUnchecked(1);
    assertRowUnchecked(2);
    assertRowUnchecked(3);
    execute("List.goPage", "page=2");
    assertRowUnchecked(10);
    assertRowUnchecked(11);
    assertRowUnchecked(12);
    assertRowUnchecked(13);
    execute("List.goPage", "page=1");
    checkRow(4);
    execute("List.orderBy", "property=number");
    assertRowChecked(0);
    assertRowChecked(1);
    assertRowUnchecked(2);
    assertRowUnchecked(3);
    assertRowUnchecked(4);
    execute("List.goPage", "page=2");
    assertRowUnchecked(10);
    assertRowUnchecked(11);
    assertRowChecked(12);
    assertRowChecked(13);
    assertRowUnchecked(14);
    execute("List.orderBy", "property=number");
    assertRowUnchecked(10);
    assertRowUnchecked(11);
    assertRowUnchecked(12);
    assertRowUnchecked(13);
    assertRowUnchecked(14);
    execute("List.goPage", "page=1");
    assertRowUnchecked(0);
    assertRowUnchecked(1);
    assertRowUnchecked(2);
    assertRowUnchecked(3);
    assertRowChecked(4);
  }

  public void testNavigationByKeyZero() throws Exception {
    assertLabelInList(0, "Number");
    assertValueInList(0, 0, "0");
    assertValueInList(1, 0, "1");
    execute("List.viewDetail", "row=1");
    assertValue("number", "1");
    assertValue("name", "NEGRO");
    execute("Navigation.previous");
    assertValue("number", "0");
    assertValue("name", "ROJO");
    execute("Navigation.previous");
    assertError("We already are at the beginning of the list");
    assertValue("number", "0");
    assertValue("name", "ROJO");
  }

  public void testKeysWithZeroValue() throws Exception {
    assertValueInList(0, "number", "0");
    assertValueInList(0, "name", "ROJO");
    execute("Mode.detailAndFirst");
    assertNoErrors();
    assertValue("number", "0");
    assertValue("name", "ROJO");
    assertValue("sample", "RED");
  }

  public void testMessageScapedWithQuotes() throws Exception {
    assertListNotEmpty();
    execute("List.viewDetail", "row=0");
    execute("Color.seeMessage");
    assertMessage("Message: A.B.C");
  }

  public void testIdentityCalculator() throws Exception {
    execute("CRUD.new");
    assertNoErrors();
    setValue("number", "-1"); // needed in this case because 0 is an existing key
    setValue("name", "JUNIT COLOR " + (int) (Math.random() * 200));
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();
    String last = getValue("number");

    execute("CRUD.new");
    assertNoErrors();
    setValue("number", "-1"); // needed in this case because 0 is an existing key
    setValue("name", "JUNIT COLOR " + (int) (Math.random() * 200));
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();
    String next = String.valueOf(Integer.parseInt(last) + 1);
    assertValue("number", next);
  }

  public void testOptimisticConcurrency() throws Exception {
    // Must be called 2 times in order to fix some problems on second time
    modifyColorFromFirstUser(1);
    modifyColorFromFirstUser(2);
  }

  public void testFilterByNumberZero() throws Exception {
    setConditionValues(new String[] {"0"});
    execute("List.filter");
    assertListRowCount(1);
  }

  public void modifyColorFromFirstUser(int id) throws Exception {
    // First user
    execute("List.viewDetail", "row=2");
    assertNotExists("version");
    setValue("name", "COLOR A" + id);

    // Second user, it's faster, he wins
    ColorTest otherSession = new ColorTest("Color2");
    otherSession.modifyColorFromSecondUser(id);

    // The first user continues
    execute("TypicalNotResetOnSave.save");
    assertError("Impossible to execute Save action: Another user has modified this record");
    execute("Mode.list");
    assertValueInList(2, "name", "COLOR B" + id); // The second user won
  }

  private void modifyColorFromSecondUser(int id) throws Exception {
    setUp();
    execute("List.viewDetail", "row=2");
    setValue("name", "COLOR B" + id);
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();
    tearDown();
  }

  public void testFilterDescriptionsList_forTabsAndNotForTabs() throws Exception {
    try {
      CharacteristicThing.findByNumber(2);
    } catch (NoResultException ex) {
      fail("It must to exist");
    }

    // Color: 'usedTo' without descriptionsList and 'characteristicThing' without descriptionsList
    assertLabelInList(4, "Name of Used to");
    assertLabelInList(5, "Characteristic thing");
    assertValueInList(0, 4, "CAR");
    assertValueInList(0, 5, "3 PLACES");
    setConditionValues(new String[] {"", "", "", "CAR", "3 PLACES"});
    execute("List.filter");
    assertNoErrors();
    assertListRowCount(1);

    // Color2: 'usedTo' with descriptionsList and 'characteristicThing' with descriptionsList and
    // condition
    changeModule("Color2");
    assertLabelInList(4, "Name of Used to");
    assertLabelInList(5, "Characteristic thing");
    assertValueInList(0, 4, "CAR");
    assertValueInList(0, 5, "3 PLACES");
    setConditionValues(new String[] {"", "", "", "1", "0"});
    execute("List.filter");
    assertNoErrors();
    assertListRowCount(1);

    try {
      setConditionValues(
          new String[] {"", "", "", "", "2"}); // descriptionsList has a condition: number < 2
    } catch (IllegalArgumentException ex) {
      assertTrue(ex.getMessage().equals("No option found with value: 2"));
    }
  }

  public void testShowActionOnlyInEachRow() throws Exception {
    // confirmMessage with row
    String html = getHtml();
    assertTrue(html.contains("Delete record on row 2: Are you sure?"));

    // action with mode=NONE: it display only in each row
    assertAction("CRUD.deleteRow");
    setConditionValues(new String[] {"", "ZZZZZ"});
    execute("List.filter");
    assertListRowCount(0);
    assertNoAction("CRUD.deleteRow");
  }

  public void testIgnoreAccentsForStringArgumentsInTheFilter() throws Exception {
    // create record with name 'marrón'
    execute("CRUD.new");
    setValue("name", "marrón");
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();

    // filter by 'marron'
    execute("Mode.list");
    setConditionValues("", "marron");
    execute("List.filter");
    assertListRowCount(1);
    assertValueInList(0, 1, "MARRÓN");

    // filter by 'marrón'
    setConditionValues("", "");
    execute("List.filter");
    assertListRowCount(10);
    setConditionValues("", "marrón");
    execute("List.filter");
    assertListRowCount(1);
    assertValueInList(0, 1, "MARRÓN");

    // delete
    checkAll();
    execute("CRUD.deleteSelected");
    assertNoErrors();
    assertListRowCount(0);
  }

  public void testChangeModelNameInConditions() throws Exception {
    execute("CRUD.new");
    assertNoErrors();
    assertExists("anotherCT.number");
    assertValidValuesCount("anotherCT.number", 3);
    String[][] validValues = {
      {"", ""},
      {"0", "3 PLACES"},
      {"1", "5 PLACES"}
    };
    assertValidValues("anotherCT.number", validValues);
  }

  public void testDescriptionsListWithMultipleKeyAndOneValueInBlank() throws Exception {
    execute("List.viewDetail", "row=0");
    assertExists("mixture.KEY");
    String[][] validValues = {
      {"", ""},
      {"[.          .VERDE     .]", "----------&-----VERDE:complicated"},
      {"[.ROJO      .          .]", "------ROJO&----------:simple"}
    };
    assertValidValues("mixture.KEY", validValues);

    setValue("mixture.KEY", "[.          .VERDE     .]");
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();
    assertMessage("Color modified successfully");
    assertValue("mixture.KEY", "[.          .VERDE     .]");

    setValue("mixture.KEY", "");
    execute("TypicalNotResetOnSave.save");
    assertNoErrors();
    assertMessage("Color modified successfully");
    assertValue("mixture.KEY", "");
  }

  public void testFilterByString() throws Exception {
    assertLabelInList(1, "Name");
    assertLabelInList(5, "Characteristic thing");
    setConditionValues("", "", "", "", "3 places");
    execute("List.filter");
    assertListRowCount(1);
    assertValueInList(0, 1, "ROJO");

    setConditionComparators(
        "=",
        "not_contains_comparator",
        "starts_comparator",
        "starts_comparator",
        "contains_comparator");
    setConditionValues("", "ROJO", "", "", "");
    execute("List.filter");
    assertListNotEmpty();

    setConditionComparators(
        "=",
        "not_contains_comparator",
        "starts_comparator",
        "starts_comparator",
        "contains_comparator");
    setConditionValues("", "ROJO", "", "", "3 places");
    execute("List.filter");
    assertListRowCount(0);

    setConditionComparators(
        "=", "ends_comparator", "starts_comparator", "starts_comparator", "starts_comparator");
    setConditionValues("", "O", "", "", "");
    execute("List.filter");
    assertListRowCount(2);
    assertValueInList(0, 1, "ROJO");
    assertValueInList(1, 1, "NEGRO");
  }
}
/** @author Javier Paniza */
public class MetaFinder implements Serializable {

  private static Log log = LogFactory.getLog(MetaFinder.class);

  private static Map argumentsJBoss11ToEJBQL;
  private static Map argumentsToHQL;
  private static Map tokensToChangeDollarsAndNL;

  private String name;
  private String arguments;
  private boolean collection;
  private String condition;
  private String order;
  private MetaModel metaModel;

  public String getArguments() {
    arguments = Strings.change(arguments, "String", "java.lang.String");
    arguments = Strings.change(arguments, "java.lang.java.lang.String", "java.lang.String");
    return arguments;
  }

  public Collection getMetaPropertiesArguments() throws XavaException {
    StringTokenizer st = new StringTokenizer(getArguments(), ",");
    Collection result = new ArrayList();
    while (st.hasMoreTokens()) {
      String argument = st.nextToken();
      StringTokenizer argumentSt = new StringTokenizer(argument);
      String type = argumentSt.nextToken().trim();
      String name = argumentSt.nextToken().trim();
      MetaProperty p = new MetaProperty();
      p.setName(name);
      p.setTypeName(type);
      result.add(p);
    }
    return result;
  }

  public boolean isCollection() {
    return collection;
  }

  public String getCondition() {
    return condition;
  }

  public String getName() {
    return name;
  }

  public void setArguments(String arguments) {
    this.arguments = arguments;
  }

  public void setCollection(boolean collection) {
    this.collection = collection;
  }

  public void setCondition(String condition) {
    this.condition = condition;
  }

  public void setName(String name) {
    this.name = name;
  }

  public boolean isSupportedForEJB2() throws XavaException {
    return !hasSome3LevelProperty(getCondition()) && !hasSome3LevelProperty(getOrder());
  }

  private boolean hasSome3LevelProperty(String sentence) throws XavaException {
    if (sentence == null) return false;
    int i = sentence.indexOf("${");
    int f = 0;
    while (i >= 0) {
      f = sentence.indexOf("}", i + 2);
      if (f < 0) break;
      String property = sentence.substring(i + 2, f);
      StringTokenizer st = new StringTokenizer(property, ".");
      if (st.countTokens() > 3) {
        log.warn(XavaResources.getString("property_3_level_in_ejb2_finder", property, getName()));
        return true;
      }
      if (st.countTokens() == 3) {
        if (!getMetaModel().getMetaProperty(property).isKey()) {
          log.warn(XavaResources.getString("property_3_level_in_ejb2_finder", property, getName()));
          return true;
        }
      }
      i = sentence.indexOf("${", i + 1);
    }
    return false;
  }

  public String getEJBQLCondition() throws XavaException {
    StringBuffer sb = new StringBuffer("SELECT OBJECT(o) FROM ");
    sb.append(getMetaModel().getName());
    sb.append(" o");
    if (!Is.emptyString(this.condition)) {
      sb.append(" WHERE ");
      String attributesCondition =
          getMetaModel().getMapping().changePropertiesByCMPAttributes(this.condition);
      sb.append(Strings.change(attributesCondition, getArgumentsJBoss11ToEJBQL()));
    }
    if (!Is.emptyString(this.order)) {
      sb.append(" ORDER BY ");
      sb.append(getMetaModel().getMapping().changePropertiesByCMPAttributes(this.order));
    }
    return sb.toString();
  }

  public String getHQLCondition() throws XavaException {
    return getHQLCondition(true);
  }

  private String getHQLCondition(boolean order) throws XavaException {
    StringBuffer sb = new StringBuffer("from ");
    sb.append(getMetaModel().getName());
    sb.append(" as o");
    if (!Is.emptyString(this.condition)) {
      sb.append(" where ");
      String condition = transformAggregateProperties(getCondition());
      condition = Strings.change(condition, getArgumentsToHQL());
      sb.append(Strings.change(condition, getTokensToChangeDollarsAndNL()));
    }
    if (order && !Is.emptyString(this.order)) {
      sb.append(" order by ");
      sb.append(
          Strings.change(
              transformAggregateProperties(this.order), getTokensToChangeDollarsAndNL()));
    }
    return sb.toString();
  }

  /**
   * Transforms ${address.street} in ${address_street} if address if an aggregate of container
   * model.
   *
   * @param condition
   * @return
   */
  private String transformAggregateProperties(String condition) {
    int i = condition.indexOf("${");
    if (i < 0) return condition;
    StringBuffer result = new StringBuffer(condition.substring(0, i + 2));
    while (i >= 0) {
      int f = condition.indexOf("}", i);
      String property = condition.substring(i + 2, f);
      String transformedProperty = transformAgregateProperty(property);
      result.append(transformedProperty);
      i = condition.indexOf("${", f);
      if (i >= 0) result.append(condition.substring(f, i));
      else result.append(condition.substring(f));
    }
    return result.toString();
  }

  private String transformAgregateProperty(String property) {
    StringBuffer result = new StringBuffer();
    StringTokenizer st = new StringTokenizer(property, ".");
    String member = "";
    while (st.hasMoreTokens()) {
      String token = st.nextToken();
      result.append(token);
      if (!st.hasMoreTokens()) break;
      member = member + token;
      try {
        MetaReference ref = getMetaModel().getMetaReference(member);
        if (ref.isAggregate()) result.append('_');
        else result.append('.');
      } catch (XavaException ex) {
        result.append('.');
      }
      member = member + ".";
    }
    return result.toString();
  }

  public String getHQLCountSentence() throws XavaException {
    StringBuffer sb = new StringBuffer("select count(*) ");
    sb.append(getHQLCondition(false));
    return sb.toString();
  }

  public MetaModel getMetaModel() {
    return metaModel;
  }

  public void setMetaModel(MetaModel metaModel) {
    this.metaModel = metaModel;
  }

  public String getOrder() {
    return order;
  }

  public void setOrder(String order) {
    this.order = order;
  }

  private static Map getArgumentsJBoss11ToEJBQL() {
    if (argumentsJBoss11ToEJBQL == null) {
      argumentsJBoss11ToEJBQL = new HashMap();
      for (int i = 0; i < 30; i++) {
        argumentsJBoss11ToEJBQL.put("{" + i + "}", "?" + (i + 1));
      }
    }
    return argumentsJBoss11ToEJBQL;
  }

  private static Map getArgumentsToHQL() {
    if (argumentsToHQL == null) {
      argumentsToHQL = new HashMap();
      for (int i = 0; i < 30; i++) {
        argumentsToHQL.put("{" + i + "}", ":arg" + i);
      }
    }
    return argumentsToHQL;
  }

  static Map getTokensToChangeDollarsAndNL() {
    if (tokensToChangeDollarsAndNL == null) {
      tokensToChangeDollarsAndNL = new HashMap();
      tokensToChangeDollarsAndNL.put("${", "o.");
      tokensToChangeDollarsAndNL.put("}", "");
      tokensToChangeDollarsAndNL.put("\n", "");
    }
    return tokensToChangeDollarsAndNL;
  }

  public boolean equals(Object other) {
    if (!(other instanceof MetaFinder)) return false;
    return toString().equals(other.toString());
  }

  public int hashCode() {
    return toString().hashCode();
  }

  public String toString() {
    return "Finder: " + getMetaModel().getName() + "." + getName();
  }
}
Example #7
0
/** @author Javier Paniza */
public class MetaTab implements java.io.Serializable, Cloneable {

  private static Log log = LogFactory.getLog(MetaTab.class);

  private String defaultOrder;
  private String sQLBaseCondition;
  private Collection metaPropertiesHiddenCalculated;
  private Collection metaPropertiesHidden;
  private String name;
  private MetaComponent metaComponent;
  private List propertiesNames = null;
  private List<String> propertiesNamesWithKeyAndHidden;
  private List metaProperties = null;
  private List metaPropertiesCalculated = null;
  private String properties; // separated by commas, like in xml file
  private String select;
  private Collection tableColumns;
  private String modelName;
  private MetaModel metaModel;
  private boolean excludeAll = false;
  private boolean excludeByKey = false;
  private MetaFilter metaFilter;
  private IFilter filter;
  private List hiddenPropertiesNames;
  private Collection hiddenTableColumns;
  private String baseCondition;
  private Map metaPropertiesTab;
  private Collection rowStyles;
  private String defaultPropertiesNames;
  private String id;
  private Collection<String> sumPropertiesNames;
  private String editor;

  public static String getTitleI18n(Locale locale, String modelName, String tabName)
      throws XavaException {
    String id = null;
    if (Is.emptyString(tabName)) {
      id = modelName + ".tab.title";
    } else {
      id = modelName + ".tabs." + tabName + ".title";
    }
    if (Labels.existsExact(id, locale)) {
      return Labels.get(id, locale);
    } else {
      return null;
    }
  }

  public MetaModel getMetaModel() throws XavaException {
    return metaModel;
  }

  public void setMetaModel(MetaModel metaModel) {
    this.metaModel = metaModel;
    this.metaComponent = metaModel.getMetaComponent();
    this.modelName = metaModel.getName();
  }

  public static MetaTab createDefault(MetaComponent component) throws XavaException {
    MetaTab tab = new MetaTab();
    tab.setMetaComponent(component);
    tab.setDefaultValues();
    return tab;
  }

  public static MetaTab createDefault(MetaModel metaModel) {
    MetaTab tab = new MetaTab();
    tab.setMetaModel(metaModel);
    return tab;
  }

  /** @return Not null, read only and of type <tt>MetaProperty</tt>. */
  public List getMetaProperties() throws XavaException {
    if (metaProperties == null) {
      metaProperties = namesToMetaProperties(getPropertiesNames());
    }
    return metaProperties;
  }

  public Collection getMetaPropertiesHidden() throws XavaException {
    if (metaPropertiesHidden == null) {
      metaPropertiesHidden = namesToMetaProperties(getHiddenPropertiesNames());
    }
    return metaPropertiesHidden;
  }

  public List namesToMetaProperties(Collection names) throws XavaException {
    List metaProperties = new ArrayList();
    Iterator it = names.iterator();
    int i = -1;
    while (it.hasNext()) {
      i++;
      String name = (String) it.next();
      MetaProperty metaPropertyTab = null;
      try {
        MetaProperty metaProperty = getMetaModel().getMetaProperty(name).cloneMetaProperty();
        metaProperty.setQualifiedName(name);
        String labelId = null;
        if (representCollection()) {
          labelId = getId() + "." + name;
          // If there is no specific translation for the collection,
          // we take the translation from the default tab.
          if (!Labels.existsExact(labelId)) {
            labelId = getIdForDefaultTab() + ".properties." + name;
          }
        } else {
          labelId = getId() + ".properties." + name;
        }
        if (Labels.exists(labelId)) {
          metaProperty.setLabelId(labelId);
        } else if (metaPropertiesTab != null) {
          // By now only the label overwritten from the property of tab
          metaPropertyTab = (MetaProperty) metaPropertiesTab.get(name);
          if (metaPropertyTab != null) {
            metaProperty = metaProperty.cloneMetaProperty();
            metaProperty.setLabel(metaPropertyTab.getLabel());
          }
        }
        metaProperties.add(metaProperty);
      } catch (ElementNotFoundException ex) {
        MetaProperty notInEntity = new MetaProperty();
        notInEntity.setName(name);
        notInEntity.setTypeName("java.lang.Object");
        if (metaPropertyTab != null) {
          notInEntity.setLabel(metaPropertyTab.getLabel());
        }
        metaProperties.add(notInEntity);
      }
    }
    return metaProperties;
  }

  private boolean representCollection() {
    return getName().startsWith(Tab.COLLECTION_PREFIX);
  }

  /**
   * Hidden ones are not included
   *
   * @return Not null, read only and of type <tt>MetaProperty</tt>.
   */
  public Collection getMetaPropertiesCalculated() throws XavaException {
    if (metaPropertiesCalculated == null) {
      metaPropertiesCalculated = new ArrayList();
      Iterator it = getMetaProperties().iterator();
      while (it.hasNext()) {
        MetaProperty metaProperty = (MetaProperty) it.next();
        if (metaProperty.isCalculated()) {
          metaPropertiesCalculated.add(metaProperty);
        }
      }
    }
    return metaPropertiesCalculated;
  }

  /** @return Not null, read only and of type <tt>MetaProperty</tt>. */
  public Collection getMetaPropertiesHiddenCalculated() throws XavaException {
    if (metaPropertiesHiddenCalculated == null) {
      metaPropertiesHiddenCalculated = new ArrayList();
      Iterator it = getMetaPropertiesHidden().iterator();
      while (it.hasNext()) {
        MetaProperty metaProperty = (MetaProperty) it.next();
        if (metaProperty.isCalculated()) {
          metaPropertiesHiddenCalculated.add(metaProperty);
        }
      }
    }
    return metaPropertiesHiddenCalculated;
  }

  public boolean hasCalculatedProperties() throws XavaException {
    return !getMetaPropertiesCalculated().isEmpty();
  }

  /** @return Not null, read only and of type <tt>String</tt>. */
  public Collection getTableColumns() throws XavaException {
    if (tableColumns == null) {
      tableColumns = getTableColumns(getPropertiesNames());
    }
    return tableColumns;
  }

  /** @return Not null, read only and of type <tt>String</tt>. */
  public Collection getHiddenTableColumns() throws XavaException {
    if (hiddenTableColumns == null) {
      hiddenTableColumns = getTableColumns(getHiddenPropertiesNames());
      hiddenTableColumns.addAll(getCmpFieldsColumnsInMultipleProperties());
    }
    return hiddenTableColumns;
  }

  private Collection getTableColumns(Collection propertyNames) throws XavaException {
    Collection tableColumns = new ArrayList();
    Iterator it = propertyNames.iterator();
    while (it.hasNext()) {
      String name = (String) it.next();
      try {
        tableColumns.add(getMapping().getQualifiedColumn(name));
      } catch (ElementNotFoundException ex) {
        tableColumns.add("0"); // It will be replaced
      }
    }
    return tableColumns;
  }

  /** @return Not null, read only of type <tt>String</tt>. */
  public List getPropertiesNames() throws XavaException {
    if (propertiesNames == null) {
      if (!areAllProperties()) {
        propertiesNames = createPropertiesNames();
      } else {
        propertiesNames = createAllPropertiesNames();
      }
    }
    return propertiesNames;
  }

  public List<String> getPropertiesNamesWithKeyAndHidden() throws XavaException {
    if (propertiesNamesWithKeyAndHidden == null) {
      propertiesNamesWithKeyAndHidden = new ArrayList<String>();
      propertiesNamesWithKeyAndHidden.addAll(getMetaModel().getAllKeyPropertiesNames());
      propertiesNamesWithKeyAndHidden.addAll(getPropertiesNames());
      propertiesNamesWithKeyAndHidden.addAll(getHiddenPropertiesNames());
    }
    return propertiesNamesWithKeyAndHidden;
  }

  /**
   * Names of properties that must to exist but is not needed show they to users.
   *
   * <p>Usually are properties used to calcualte others. <br>
   * The keys are excluded. <br>
   *
   * @return Not null, read only and of type <tt>String</tt>.
   */
  public List getHiddenPropertiesNames() throws XavaException {
    if (hiddenPropertiesNames == null) {
      hiddenPropertiesNames = obtainPropertiesNamesUsedToCalculate();
    }
    return hiddenPropertiesNames;
  }

  private List obtainPropertiesNamesUsedToCalculate() throws XavaException {
    Set result = new HashSet();
    Iterator itProperties = getMetaPropertiesCalculated().iterator();
    while (itProperties.hasNext()) {
      MetaProperty metaProperty = (MetaProperty) itProperties.next();
      if (!metaProperty.hasCalculator()) continue;
      MetaSetsContainer metaCalculator = metaProperty.getMetaCalculator();
      if (!metaCalculator.containsMetaSets()) continue;
      Iterator itSets = metaCalculator.getMetaSets().iterator();
      while (itSets.hasNext()) {
        MetaSet set = (MetaSet) itSets.next();
        String propertyNameFrom = set.getPropertyNameFrom();
        if (!Is.emptyString(propertyNameFrom)) {
          String qualifiedName = metaProperty.getQualifiedName();
          int idx = qualifiedName.indexOf('.');
          String ref = idx < 0 ? "" : qualifiedName.substring(0, idx + 1);
          String qualifiedPropertyNameFrom = ref + propertyNameFrom;
          if (!getPropertiesNames().contains(qualifiedPropertyNameFrom)) {
            result.add(qualifiedPropertyNameFrom);
          }
        }
      }
    }
    return new ArrayList(result);
  }

  private boolean areAllProperties() {
    return properties == null || properties.trim().equals("*");
  }

  // assert(!areAllProperties());
  private List createPropertiesNames() {
    StringTokenizer st = new StringTokenizer(removeTotalProperties(properties), ",;");
    List result = new ArrayList();
    while (st.hasMoreTokens()) {
      String name = st.nextToken().trim();
      if (name.endsWith("+")) {
        name = name.substring(0, name.length() - 1);
        if (sumPropertiesNames == null) sumPropertiesNames = new HashSet();
        sumPropertiesNames.add(name);
      }
      result.add(name);
    }
    return result;
  }

  private String removeTotalProperties(String properties) {
    if (!properties.contains("[")) return properties;
    return properties.replaceAll("\\[[^\\]]*\\]", "");
  }

  private List createAllPropertiesNames() throws XavaException {
    List result = new ArrayList();
    // First the properties from a possible @EmbeddedId
    for (Iterator itRef = getMetaModel().getMetaReferencesKey().iterator(); itRef.hasNext(); ) {
      MetaReference ref = (MetaReference) itRef.next();
      if (ref.isAggregate()) {
        for (Iterator itKey =
                ref.getMetaModelReferenced()
                    .getPropertiesNamesWithoutHiddenNorTransient()
                    .iterator();
            itKey.hasNext(); ) {
          result.add(ref.getName() + "." + itKey.next());
        }
      }
    }
    // Now the plain properties
    result.addAll(getMetaModel().getPropertiesNamesWithoutHiddenNorTransient());
    return result;
  }

  public void setDefaultPropertiesNames(String properties) {
    this.defaultPropertiesNames = properties;
    setPropertiesNames(properties);
  }

  /** Comma separated. */
  public void setPropertiesNames(String properties) {
    this.properties = properties;

    this.propertiesNames = null;
    this.metaProperties = null;
    this.metaPropertiesHiddenCalculated = null;
    this.metaPropertiesHidden = null;
    this.metaPropertiesCalculated = null;
    this.tableColumns = null;
    this.hiddenPropertiesNames = null;
    this.propertiesNamesWithKeyAndHidden = null;
    this.hiddenTableColumns = null;
    this.metaPropertiesTab = null;

    this.select = null;
  }

  ModelMapping getMapping() throws XavaException {
    return getMetaModel().getMapping();
  }

  public String getSelect() throws XavaException {
    if (select == null) {
      select = createSelect();
    }
    return select;
  }

  private String createSelect() throws XavaException {
    if (hasBaseCondition()) {
      String baseCondition = getBaseCondition();
      if (baseCondition.trim().toUpperCase().startsWith("SELECT ")) {
        return baseCondition;
      }
    }
    // basic select
    StringBuffer select = new StringBuffer("select ");
    Iterator itProperties = getPropertiesNames().iterator();
    while (itProperties.hasNext()) {
      String property = (String) itProperties.next();
      if (Strings.isModelName(property))
        select.append("0"); // the property is a table name not column name
      else {
        select.append("${");
        select.append(property);
        select.append('}');
      }
      if (itProperties.hasNext()) select.append(", ");
    }
    Iterator itHiddenProperties = getHiddenPropertiesNames().iterator();
    while (itHiddenProperties.hasNext()) {
      select.append(", ");
      select.append("${");
      select.append(itHiddenProperties.next());
      select.append('}');
    }
    select.append(" from ${");
    select.append(getModelName());
    select.append('}');
    select.append(' ');
    if (hasBaseCondition()) {
      select.append(" where ");
      select.append(getBaseCondition());
    }
    return select.toString();
  }

  public Collection getCmpFieldsColumnsInMultipleProperties() throws XavaException {
    Collection cmpFieldsColumnsInMultipleProperties = new ArrayList();
    Iterator it = getMetaProperties().iterator();
    String table = getMapping().getTableToQualifyColumn();
    while (it.hasNext()) {
      MetaProperty p = (MetaProperty) it.next();
      PropertyMapping mapping = p.getMapping();
      if (mapping != null) {
        if (mapping.hasMultipleConverter()) {
          Iterator itFields = mapping.getCmpFields().iterator();
          while (itFields.hasNext()) {
            CmpField field = (CmpField) itFields.next();
            cmpFieldsColumnsInMultipleProperties.add(table + "." + field.getColumn());
          }
        }
      }
    }
    return cmpFieldsColumnsInMultipleProperties;
  }

  public MetaComponent getMetaComponent() {
    return metaComponent;
  }

  public void setMetaComponent(MetaComponent component) {
    this.metaComponent = component;
    this.metaModel = this.metaComponent.getMetaEntity();
    this.modelName = this.metaComponent.getName();
  }

  public boolean isExcludeByKey() {
    return excludeByKey;
  }

  public boolean isExcludeAll() {
    return excludeAll;
  }

  public void setExcludeByKey(boolean excludeByKey) {
    this.excludeByKey = excludeByKey;
  }

  public void setExcludeAll(boolean excludeAll) {
    this.excludeAll = excludeAll;
  }

  public String getName() {
    return name == null ? "" : name;
  }

  private boolean hasName() {
    return name != null && !name.trim().equals("");
  }

  public void setName(String name) {
    this.name = name;
    this.id = null;
  }

  public MetaFilter getMetaFilter() {
    return metaFilter;
  }

  public void setMetaFilter(MetaFilter metaFilter) {
    this.metaFilter = metaFilter;
  }

  public boolean hasFilter() {
    return this.metaFilter != null;
  }

  /** Apply the filter associated to this tab if there is is. */
  Object filterParameters(Object o) throws XavaException {
    if (getMetaFilter() == null) return o;
    return getFilter().filter(o);
  }

  private IFilter getFilter() throws XavaException {
    if (filter == null) {
      filter = getMetaFilter().createFilter();
    }
    return filter;
  }

  public void addMetaProperty(MetaProperty metaProperty) {
    if (metaPropertiesTab == null) {
      metaPropertiesTab = new HashMap();
    }
    metaPropertiesTab.put(metaProperty.getName(), metaProperty);
  }

  /** For dynamically add properties to this tab */
  public void addProperty(String propertyName) {
    if (propertiesNames == null) return;
    propertiesNames.add(propertyName);
    resetAfterAddRemoveProperty();
  }

  /** For dynamically add properties to this tab */
  public void addProperty(int index, String propertyName) {
    if (propertiesNames == null) return;
    propertiesNames.add(index, propertyName);
    resetAfterAddRemoveProperty();
  }

  /** For dynamically remove properties to this tab */
  public void removeProperty(String propertyName) {
    if (propertiesNames == null) return;
    propertiesNames.remove(propertyName);
    resetAfterAddRemoveProperty();
  }

  /** For dynamically remove properties to this tab */
  public void removeProperty(int index) {
    if (propertiesNames == null) return;
    propertiesNames.remove(index);
    resetAfterAddRemoveProperty();
  }

  public void movePropertyToRight(int index) {
    if (propertiesNames == null) return;
    if (index >= propertiesNames.size() - 1) return;
    Object aux = propertiesNames.get(index);
    propertiesNames.set(index, propertiesNames.get(index + 1));
    propertiesNames.set(index + 1, aux);
    resetAfterAddRemoveProperty();
  }

  public void movePropertyToLeft(int index) {
    if (propertiesNames == null) return;
    if (index <= 0) return;
    Object aux = propertiesNames.get(index);
    propertiesNames.set(index, propertiesNames.get(index - 1));
    propertiesNames.set(index - 1, aux);
    resetAfterAddRemoveProperty();
  }

  /** For dynamically remove all properties to this tab */
  public void clearProperties() {
    if (propertiesNames == null) return;
    propertiesNames.clear();
    resetAfterAddRemoveProperty();
  }

  public void restoreDefaultProperties() {
    setPropertiesNames(defaultPropertiesNames);
    resetAfterAddRemoveProperty();
  }

  private void resetAfterAddRemoveProperty() {
    metaProperties = null;
    metaPropertiesCalculated = null;
    select = null;
    tableColumns = null;
    hiddenPropertiesNames = null;
    propertiesNamesWithKeyAndHidden = null;
    hiddenTableColumns = null;
  }

  public String getBaseCondition() {
    return baseCondition == null ? "" : baseCondition;
  }

  public void setBaseCondition(String string) {
    baseCondition = string;
    sQLBaseCondition = null;
  }

  public boolean hasBaseCondition() {
    return !Is.emptyString(this.baseCondition);
  }

  /**
   * Apply the tab filter to sent objects.
   *
   * <p>It's used to filter arguments. <br>
   */
  public Object filter(Object[] objects) throws FilterException, XavaException {
    if (getMetaFilter() == null) return objects;
    return getMetaFilter().filter(objects);
  }

  public String getId() {
    if (id == null) {
      if (representCollection()) id = getIdForTabOfCollection();
      else id = getIdForTabOfEntity();
    }
    return id;
  }

  private String getIdForTabOfEntity() {
    if (!hasName()) return getIdForDefaultTab();
    return getMetaComponent().getName() + ".tabs." + getName();
  }

  private String getIdForDefaultTab() {
    return getMetaComponent().getName() + ".tab";
  }

  private String getIdForTabOfCollection() {
    return getName().replaceFirst(Tab.COLLECTION_PREFIX, getMetaComponent().getName() + ".");
  }

  public String getDefaultOrder() {
    return defaultOrder;
  }

  public void setDefaultOrder(String defaultOrder) {
    this.defaultOrder = defaultOrder;
  }

  public boolean hasDefaultOrder() {
    return !Is.emptyString(this.defaultOrder);
  }

  public MetaTab cloneMetaTab() {
    try {
      MetaTab r = (MetaTab) clone();
      if (r.metaPropertiesHiddenCalculated != null) {
        r.metaPropertiesHiddenCalculated = new ArrayList(metaPropertiesHiddenCalculated);
      }
      if (r.metaPropertiesHidden != null) {
        r.metaPropertiesHidden = new ArrayList(metaPropertiesHidden);
      }
      if (r.propertiesNames != null) {
        r.propertiesNames = new ArrayList(propertiesNames);
      }
      if (r.metaProperties != null) {
        r.metaProperties = new ArrayList(metaProperties);
      }
      if (r.metaPropertiesCalculated != null) {
        r.metaPropertiesCalculated = new ArrayList(metaPropertiesCalculated);
      }
      if (r.tableColumns != null) {
        r.tableColumns = new ArrayList(tableColumns);
      }
      if (r.hiddenPropertiesNames != null) {
        r.hiddenPropertiesNames = new ArrayList(hiddenPropertiesNames);
      }
      if (r.propertiesNamesWithKeyAndHidden != null) {
        r.propertiesNamesWithKeyAndHidden = new ArrayList(propertiesNamesWithKeyAndHidden);
      }
      if (r.hiddenTableColumns != null) {
        r.hiddenTableColumns = new ArrayList(hiddenTableColumns);
      }
      if (r.metaPropertiesTab != null) {
        r.metaPropertiesTab = new HashMap(metaPropertiesTab);
      }
      return r;
    } catch (CloneNotSupportedException ex) {
      throw new RuntimeException(XavaResources.getString("clone_error", getClass()));
    }
  }

  public List getRemainingPropertiesNames() throws XavaException {
    List result = new ArrayList(getMetaModel().getRecursiveQualifiedPropertiesNames());
    result.removeAll(getPropertiesNames());
    return result;
  }

  public void addMetaRowStyle(MetaRowStyle style) {
    if (rowStyles == null) rowStyles = new ArrayList();
    rowStyles.add(style);
  }

  public void setMetaRowStyles(Collection styles) {
    rowStyles = styles;
  }

  public boolean hasRowStyles() {
    return rowStyles != null;
  }

  public Collection getMetaRowStyles() {
    return rowStyles == null ? Collections.EMPTY_LIST : rowStyles;
  }

  public String getModelName() {
    return modelName;
  }

  public void setModelName(String modelName) throws XavaException {
    this.modelName = modelName;
    this.metaModel = MetaModel.get(modelName);
    this.metaComponent = this.metaModel.getMetaComponent();
  }

  public void setDefaultValues() {
    for (MetaTab t : MetaTabsDefaultValues.getMetaTabsForModel(getMetaComponent().getName())) {
      if (t.getMetaFilter() != null && getMetaFilter() == null) setMetaFilter(t.getMetaFilter());
      if (t.getMetaRowStyles() != null && getMetaRowStyles() == null)
        setMetaRowStyles(t.getMetaRowStyles());
      if (t.properties != null && properties == null) properties = t.properties;
      if (!Is.emptyString(t.getBaseCondition()) && Is.emptyString(getBaseCondition()))
        setBaseCondition(t.getBaseCondition());
      if (!Is.emptyString(t.getDefaultOrder()) & Is.emptyString(getDefaultOrder()))
        setDefaultOrder(t.getDefaultOrder());
    }
  }

  /**
   * Sum properties names.
   *
   * <p>It was renamed in v4.3 from getTotalPropertiesNames() to getSumPropertiesNames()
   *
   * @since 4.3
   */
  public Collection<String> getSumPropertiesNames() {
    return sumPropertiesNames == null ? Collections.EMPTY_SET : sumPropertiesNames;
  }

  public String getEditor() {
    return editor;
  }

  public void setEditor(String editor) {
    this.editor = editor;
  }
}
/**
 * This is for the case of collections of entities without @AsEmbedded (or without
 * as-aggregate="true").
 *
 * <p>The remainings cases are treated by {@link SaveElementInCollectionAction}.<br>
 * This case add a group of entities from a list.<br>
 *
 * @author Javier Paniza
 */
public class AddElementsToCollectionAction extends SaveElementInCollectionAction
    implements INavigationAction {

  private static Log log = LogFactory.getLog(AddElementsToCollectionAction.class);

  @Inject private Tab tab;
  private int added;
  private int failed;
  private int row = -1;
  @Inject private String currentCollectionLabel;

  public void execute() throws Exception {
    saveIfNotExists(getCollectionElementView().getParent());
    if (row >= 0) {
      associateEntityInRow(row);
    } else {
      Map[] selectedOnes = getTab().getSelectedKeys();
      if (selectedOnes != null && selectedOnes.length > 0) {
        for (int i = 0; i < selectedOnes.length; i++) {
          associateKey(selectedOnes[i]);
        }
      } else {
        addError("choose_element_before_add");
        return;
      }
    }
    addMessage("elements_added_to_collection", new Integer(added), currentCollectionLabel);
    if (failed > 0)
      addError("elements_not_added_to_collection", new Integer(failed), currentCollectionLabel);
    getView().setKeyEditable(false); // To mark as saved
    getTab().deselectAll();
    resetDescriptionsCache();
    closeDialog();
  }

  private void associateEntityInRow(int row) throws FinderException, Exception {
    Map key = (Map) getTab().getTableModel().getObjectAt(row);
    associateKey(key);
  }

  private void associateKey(Map key) {
    try {
      associateEntity(key);
      added++;
    } catch (Exception ex) {
      addValidationMessage(ex);
      failed++;
      log.error(
          XavaResources.getString(
              "add_collection_element_error",
              getCollectionElementView().getModelName(),
              getCollectionElementView().getParent().getModelName()),
          ex);
    }
  }

  private void addValidationMessage(Exception ex) {
    if (ex instanceof ValidationException) {
      addErrors(((ValidationException) ex).getErrors());
    } else if (ex instanceof InvalidStateException) {
      InvalidValue[] invalidValues = ((InvalidStateException) ex).getInvalidValues();
      for (int i = 0; i < invalidValues.length; i++) {
        addError(
            "invalid_state",
            invalidValues[i].getPropertyName(),
            invalidValues[i].getBeanClass().getSimpleName(),
            invalidValues[i].getMessage(),
            invalidValues[i].getValue());
      }
    }
  }

  public String getNextAction() throws Exception {
    // In order to annul the chaining of the action
    return null;
  }

  public Tab getTab() {
    return tab;
  }

  public void setTab(Tab web) {
    tab = web;
  }

  public String[] getNextControllers() {
    return added > 0 ? PREVIOUS_CONTROLLERS : SAME_CONTROLLERS;
  }

  public String getCustomView() {
    return added > 0 ? PREVIOUS_VIEW : SAME_VIEW;
  }

  public int getRow() {
    return row;
  }

  public void setRow(int row) {
    this.row = row;
  }

  // This action is executed from an dialog so it has not viewObject,
  // but it could be injected from a old (not updated) action definition
  // in controllers.xml using use-object. This method is to avoid that
  // viewObject has value in that case
  public void setViewObject(String viewObject) {}
}
Example #9
0
/** @author Javier Paniza */
public class DeliveryTest extends ModuleTestBase {

  private static Log log = LogFactory.getLog(DeliveryTest.class);

  private String[] listActions = {
    "Print.generatePdf",
    "Print.generateExcel",
    "ExtendedPrint.myReports",
    "CRUD.new",
    "CRUD.deleteSelected",
    "CRUD.deleteRow",
    "Remarks.hideRemarks",
    "Mode.detailAndFirst",
    "Mode.split",
    "List.filter",
    "List.customize",
    "List.orderBy",
    "List.viewDetail",
    "List.hideRows",
    "List.sumColumn"
  };

  public DeliveryTest(String testName) {
    super(testName, "Delivery");
  }

  public void
      testFilterDescriptionsListAndEnumLetterType_myReportConditionWithDescriptionsListAndValidValues()
          throws Exception {
    assertLabelInList(3, "Description of Type");
    assertLabelInList(7, "Distance");
    if (usesAnnotatedPOJO()) {
      setConditionValues(new String[] {"", "", "", "1", "", "", "", "1"}); // For annotated POJOs
    } else {
      setConditionValues(new String[] {"", "", "", "1", "", "", "", "2"}); // For XML components
    }
    execute("List.filter");
    assertListRowCount(2);
    assertValueInList(0, 0, "2004");
    assertValueInList(0, 1, "9");
    assertValueInList(0, 2, "1");
    assertValueInList(1, 0, "2004");
    assertValueInList(1, 1, "10");
    assertValueInList(1, 2, "1");

    execute("ExtendedPrint.myReports");
    assertValueInCollection("columns", 3, 0, "Description of Type");
    assertValueInCollection("columns", 3, 1, "=");
    assertValueInCollection("columns", 3, 2, "FACTURABLE MODIFIED");
    execute("MyReport.editColumn", "row=3,viewObject=xava_view_columns");
    assertNotExists("comparator");
    assertNotExists("value");
    assertNotExists("dateValue");
    assertNotExists("booleanValue");
    assertNotExists("validValuesValue");
    assertExists("descriptionsListValue");
    assertExists("order");
    assertDescriptionValue("descriptionsListValue", "FACTURABLE MODIFIED");
    execute("MyReport.saveColumn");
    assertValueInCollection("columns", 3, 0, "Description of Type");
    assertValueInCollection("columns", 3, 1, "=");
    assertValueInCollection("columns", 3, 2, "FACTURABLE MODIFIED");

    assertValueInCollection("columns", 7, 0, "Distance");
    assertValueInCollection("columns", 7, 1, "=");
    assertValueInCollection("columns", 7, 2, "Nachional");
    execute("MyReport.editColumn", "row=7,viewObject=xava_view_columns");
    assertNotExists("comparator");
    assertNotExists("value");
    assertNotExists("dateValue");
    assertNotExists("booleanValue");
    assertExists("validValuesValue");
    assertNotExists("descriptionsListValue");
    assertExists("order");
    assertDescriptionValue("validValuesValue", "Nachional");
    execute("MyReport.saveColumn");
    assertValueInCollection("columns", 7, 0, "Distance");
    assertValueInCollection("columns", 7, 1, "=");
    assertValueInCollection("columns", 7, 2, "Nachional");
  }

  public void testFocusOnlyInEditors() throws Exception {
    execute("CRUD.new");
    assertFocusOn("invoice.year");
    getHtmlPage().tabToNextElement();
    assertFocusOn("invoice.number");
    getHtmlPage().tabToNextElement();
    assertFocusOn("type.number");
    execute("Reference.createNew", "model=Invoice,keyProperty=invoice.number");
    assertFocusOn("year");
    getHtmlPage().tabToNextElement();
    assertFocusOn("number");
    getHtmlPage().tabToNextElement();
    assertFocusOn("date");
    getHtmlPage().tabToNextElement();
    assertFocusOn("paid");
    getHtmlPage().tabToNextElement();
    assertFocusOn("comment");
    getHtmlPage().tabToNextElement();
    assertFocusOn("customer.number");
  }

  public void testModifyEmptyReferenceFromADialog() throws Exception {
    execute("CRUD.new");
    setValue("deliveredBy", usesAnnotatedPOJO() ? "1" : "2");
    setValue("carrier.number", "1");
    execute("Reference.modify", "model=Carrier,keyProperty=carrier.number");
    assertDialog();
    assertValue("drivingLicence.KEY", "");
    assertExists("warehouse.name"); // We are in the Carrier dialog
    assertNoAction("CRUD.new");
    assertAction("Modification.update");
    execute("Reference.modify", "model=DrivingLicence,keyProperty=drivingLicence__KEY__");
    assertDialog();
    assertExists("warehouse.name"); // We still are in the Carrier dialog
    assertError("Impossible to modify an empty reference");
    assertNoAction("CRUD.new");
    assertAction("Modification.update");
  }

  public void testSaveElementInCollectionWithUseObjectView() throws Exception {
    execute("CRUD.new");
    execute("Sections.change", "activeSection=2");
    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    execute("DeliveryDetail.saveFailing");
    assertNotExists("invoice.year");
  }

  public void testSearchUsesSearchView() throws Exception {
    execute("CRUD.new");
    execute("CRUD.search");
    assertDialog();
    assertNotExists("advice");
    assertNotExists("vehicle");

    setValue("description", "DELIVERY JUNIT 666");
    execute("Search.search");
    assertNoDialog();
    assertNoErrors();
    assertValue("description", "DELIVERY JUNIT 666");
  }

  public void testModifyEmptyReferenceNotMustShowTheDialog() throws Exception {
    execute("CRUD.new");
    assertValue("type.number", "");
    execute("Reference.modify", "model=DeliveryType,keyProperty=type.number");
    assertNoDialog();
    assertError("Impossible to modify an empty reference");
    assertTrue(!getHtml().contains("Modify - Delivery"));
  }

  public void testSecondLevelDialogReturningWithCancelButton() throws Exception {
    assertSecondLevelDialogReturning(false);
  }

  public void testSecondLevelDialogReturningWithCloseDialogButton() throws Exception {
    assertSecondLevelDialogReturning(true);
  }

  private void assertSecondLevelDialogReturning(boolean closeDialogButton) throws Exception {
    execute("CRUD.new");
    assertExists("vehicle"); // Only in Delivery, no dialog
    assertNotExists("customerDiscount"); // Only in Invoice, first dialog level
    assertNotExists("website"); // Only in Customer, second dialog level
    assertNoDialog();

    execute("Reference.createNew", "model=Invoice,keyProperty=invoice.number");
    assertNotExists("vehicle");
    assertExists("customerDiscount");
    assertNotExists("website");
    assertDialog();

    execute("Reference.createNew", "model=Customer,keyProperty=customer.number");
    assertNotExists("vehicle");
    assertNotExists("customerDiscount");
    assertExists("website");
    assertDialog();

    if (closeDialogButton) closeDialog();
    else execute("NewCreation.cancel");

    assertNotExists("vehicle");
    assertExists("customerDiscount");
    assertNotExists("website");
    assertDialog();

    if (closeDialogButton) closeDialog();
    else execute("NewCreation.cancel");

    assertExists("vehicle");
    assertNotExists("customerDiscount");
    assertNotExists("website");
    assertNoDialog();
  }

  public void testCreateEntityWithCollectionFromReference_secondLevelDialog() throws Exception {
    execute("CRUD.new");
    execute("Reference.createNew", "model=Invoice,keyProperty=xava.Delivery.invoice.number");
    assertDialog();

    setValue("year", "2002");
    setValue("number", "1");
    execute("Reference.search", "keyProperty=customer.number");
    execute("ReferenceSearch.choose", "row=1");
    assertValue("customer.name", "Juanillo");
    setValue("customer.number", "1");
    assertValue("customer.name", "Javi");
    execute("Sections.change", "activeSection=2");
    setValue("vatPercentage", "16");
    execute("NewCreation.saveNew");
    assertError("Impossible to create: an object with that key already exists");

    setValue("year", "2009");
    setValue("number", "66");
    execute("Sections.change", "activeSection=1");
    assertCollectionRowCount("details", 0);
    execute("Collection.new", "viewObject=xava_view_section1_details");
    setValue("quantity", "20");
    setValue("unitPrice", "1");
    setValue("product.number", "1");
    execute("Collection.save");
    assertNoErrors();
    assertMessage("Invoice detail created successfully");
    assertMessage("Invoice created successfully");
    assertNoErrors();
    assertCollectionRowCount("details", 1);
    execute("Sections.change", "activeSection=2");
    setValue("vatPercentage", "17");
    execute("NewCreation.saveNew");
    assertNoErrors();
    assertNoDialog();
    assertValue("invoice.year", "2009");
    assertValue("invoice.number", "66");

    changeModule("Invoice");
    execute("CRUD.new");
    setValue("year", "2009");
    setValue("number", "66");
    execute("CRUD.refresh");
    execute("Sections.change", "activeSection=2");
    assertValue("vatPercentage", "17");
    execute("CRUD.delete");
    assertMessage("Invoice deleted successfully");
  }

  public void testMinimunInCollection_overrideCollectionActions() throws Exception {
    // minimunCollection
    execute("CRUD.new");
    setValue("invoice.year", "2004");
    setValue("invoice.number", "2");
    setValue("type.number", "1");
    setValue("number", "666");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("description", "DELIVERY JUNIT 666");

    execute("Sections.change", "activeSection=2");
    assertCollectionRowCount("details", 3);

    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    setValue("number", "14");
    setValue("description", "JUNIT DETAIL 14");
    execute("DeliveryDetail.save");

    assertError("More than 3 items in Details of Delivery are not allowed");
    closeDialog();
    assertCollectionRowCount("details", 3);

    execute("List.orderBy", "property=number,collection=details");
    checkRowCollection("details", 2);
    execute("DeliveryDetail.removeSelected", "viewObject=xava_view_section2_details_details");
    assertNoErrors();
    assertMessage("Delivery detail deleted from database");
    assertMessage(
        "Delivery detail 13 deleted successfully"); // This message is by the override action for
    // removeSelected
    assertCollectionRowCount("details", 2);

    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    setValue("number", "13");
    setValue("description", "DETAIL 13");
    execute("DeliveryDetail.save");
    assertNoErrors();
    assertMessage("The action Save for delivery detail executed");
    assertCollectionRowCount("details", 3);

    execute("Collection.edit", "row=2,viewObject=xava_view_section2_details_details");
    execute("DeliveryDetail.save");
    assertNoErrors();

    // checkboxNotInCollectionWhenNotEditable, this test only work in a HTML UI
    /* Since v2.1.4 the check box is always present in all collections (because is implemented uses a Tab)
    assertTrue("Check box must be present", getHtml().indexOf("xava.Delivery.details.__SELECTED__") >= 0);
    execute("EditableOnOff.setOff");
    assertTrue("Check box must not be present", getHtml().indexOf("xava.Delivery.details.__SELECTED__") < 0);
    */
  }

  public void testMaxInCollectionWithSaveAndStay() throws Exception {
    assertListNotEmpty();
    execute("List.viewDetail", "row=0");
    execute("Sections.change", "activeSection=2");
    assertCollectionRowCount("details", 0);
    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    for (int x = 1; x < 5; x++) {
      setValue("number", String.valueOf(x));
      setValue("description", String.valueOf(x));
      execute("Collection.saveAndStay");
    }
    assertError("More than 3 items in Details of Delivery are not allowed");
    execute("DeliveryDetail.hideDetail");
    assertCollectionRowCount("details", 3);
    checkAllCollection("details");
    execute("DeliveryDetail.removeSelected", "viewObject=xava_view_section2_details_details");
    assertCollectionRowCount("details", 0);
  }

  public void testFocusWhenSectionsAndGroupsInHeader() throws Exception {
    execute("CRUD.new");
    assertFocusOn("invoice.year");

    setValue("shortcut", "DY");

    assertValue("remarks", "Delayed");
    assertFocusOn("remarks");
  }

  public void testZeroValueOnChange() throws Exception {
    createDeliveryType(0, "JUNIT DELIVERY TYPE 0");
    execute("CRUD.new");
    assertMessage("type=null");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    setValue("type.number", "0");
    assertMessage("type=0"); // Verifies zero as value for on change action
    deleteDeliveryType(0);
  }

  public void testNonExistentReferenceUsedAsKey() throws Exception {
    if (usesAnnotatedPOJO()) { // This case is not supported since 4m6, because Hibernate 3.6 does
      // not support it
      log.warn("testNonExistentReferenceUsedAsKey() case not supported in JPA version");
      return;
    }
    createDeliveryType(0, "JUNIT DELIVERY TYPE 0");
    execute("CRUD.new");
    assertMessage("type=null");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    setValue("type.number", "0");
    setValue("number", "66");
    setValue("description", "JUNIT");
    execute("CRUD.save");
    assertNoErrors();

    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "0");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("description", "JUNIT");

    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("description", "JUNIT");

    deleteDeliveryType(0);
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("description", "JUNIT");

    execute("CRUD.delete");
    assertMessage("Delivery deleted successfully");
  }

  private void createDeliveryType(int number, String description) {
    DeliveryType type = new DeliveryType();
    type.setNumber(number);
    type.setDescription(description);
    XPersistence.getManager().persist(type);
    XPersistence.commit();
  }

  private void deleteDeliveryType(int number) {
    DeliveryType type = XPersistence.getManager().find(DeliveryType.class, number);
    XPersistence.getManager().remove(type);
    XPersistence.commit();
  }

  public void testSearchingByAnyPropertyUsingRefresh() throws Exception {
    // One result
    execute("CRUD.new");
    assertValue("number", "");
    assertValue("description", "");
    setValue("description", "%SEARCHING");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("number", "777");
    assertValue("description", "FOR TEST SEARCHING BY DESCRIPTION");

    // There are more than one match, returns the first
    execute("CRUD.new");
    assertValue("number", "");
    assertValue("description", "");
    setValue("driverType", "");
    setValue("description", "DEL");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("description", "DELIVERY JUNIT 666");
  }

  public void testSearchingByAnyProperty() throws Exception {
    // One result
    execute("CRUD.new");
    assertValue("number", "");
    assertValue("description", "");
    execute("CRUD.search");
    setValue("description", "%SEARCHING");
    execute("Search.search");
    assertNoErrors();
    assertValue("number", "777");
    assertValue("description", "FOR TEST SEARCHING BY DESCRIPTION");

    // There are more than one match, returns the first
    execute("CRUD.new");
    assertValue("number", "");
    assertValue("description", "");
    execute("CRUD.search");
    setValue("description", "DEL");
    execute("Search.search");
    assertNoErrors();
    assertValue("description", "DELIVERY JUNIT 666");
  }

  public void testDateCalendarEditor() throws Exception {
    execute("CRUD.new");
    assertExists("invoice.date");
    String html = getHtml();
    assertFalse(html.contains("showCalendar('ox_OpenXavaTest_Delivery__invoice___date'"));
    assertTrue(html.contains("showCalendar('ox_OpenXavaTest_Delivery__date'"));
  }

  public void testAggregateInCollectionWithVisibleKeyDoesNotTryToSearchOnChangeKey()
      throws Exception {
    execute("CRUD.new");
    execute("Sections.change", "activeSection=2");
    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    setValue("number", "66");
    assertNoErrors();
  }

  public void testOnChangeActionOnlyOnce() throws Exception {
    execute("CRUD.new");
    assertValue("driverType", "X");
  }

  public void testAggregateInCollectionWithNotHiddenKey_setFocusInDialog() throws Exception {
    assertListNotEmpty();
    execute("Mode.detailAndFirst");
    execute("Sections.change", "activeSection=2");

    // The bucle is for choosing a delivery with less than 3 details
    while (getCollectionRowCount("details") >= 3) {
      execute("Navigation.next");
    }
    String number = getValue("number");
    executeClicking("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    assertMessage("The action New for delivery detail executed");
    assertValue("description", "DETAIL FOR DELIVERY " + number + "/" + number);
    assertFocusOn("description");
    setValue("number", "66");
    setValue("description", "JUNIT DELIVERY DETAIL");
    execute("DeliveryDetail.save");
    assertMessage("The action Save for delivery detail executed");
    assertNoErrors();

    execute("Collection.edit", "row=0,viewObject=xava_view_section2_details_details");
    assertValue("number", "66");
    execute("DeliveryDetail.hideDetail");
    assertMessage("The action Close for delivery detail executed");
    execute("Collection.edit", "row=0,viewObject=xava_view_section2_details_details");
    assertValue("number", "66");
    closeDialog();
    assertMessage("The action Close for delivery detail executed");
    execute("Collection.edit", "row=0,viewObject=xava_view_section2_details_details");
    assertValue("number", "66");
    execute("DeliveryDetail.remove");
    assertMessage("The action Remove for delivery detail executed");
    assertNoErrors();
  }

  public void testEntityWithCollectionOfAggregatesWithNotHiddenKey() throws Exception {
    execute("CRUD.new");

    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    setValue("type.number", "1");
    setValue("number", "66");
    setValue("description", "JUNIT");

    execute("Sections.change", "activeSection=2");
    assertCollectionRowCount("details", 0);
    execute("DeliveryDetail.new", "viewObject=xava_view_section2_details_details");
    setValue("number", "66");
    setValue("description", "JUNIT DELIVERY DETAIL");
    execute("DeliveryDetail.save");
    assertNoErrors();
    assertCollectionRowCount("details", 1);

    execute("CRUD.delete");
    assertNoErrors();
  }

  public void testReferenceAsDescriptionsListWithValidValuesInKey_validateViewPropertiesOnModify()
      throws Exception {
    execute("Mode.detailAndFirst");
    assertValue("shipment.KEY", "");
    Shipment shipment = (Shipment) Shipment.findAll().iterator().next();
    setValue("shipment.KEY", toKeyString(shipment));
    execute("CRUD.save");
    assertError("Value for Advice in Delivery is required");
    setValue("advice", "Modifying");
    execute("CRUD.save");
    assertNoErrors();
    execute("Mode.list");
    execute("Mode.detailAndFirst");
    assertValue("shipment.KEY", toKeyString(shipment));
    assertDescriptionValue("shipment.KEY", shipment.getDescription());
    // Restoring
    setValue("shipment.KEY", "");
    setValue("advice", "Restoring");
    execute("CRUD.save");
    assertNoErrors();
  }

  public void testWhenStereotypeWithoutFormatterUseTypeFormatter() throws Exception {
    // date: Without stereotype, use date formatter
    String date = getValueInList(0, "date");
    // dataAsLabel: With stereotype, but it has no formatter,
    // hence it must to use date formatter
    String dateAsLabel = getValueInList(0, "dateAsLabel");
    assertEquals(date, dateAsLabel);
  }

  public void testSecondLevelCalculatedPropertyAndDependenOf3LevelPropertyInList()
      throws Exception {
    int c = getListRowCount();
    boolean withoutDiscount = false;
    boolean withDiscount = true;
    for (int i = 0; i < c; i++) {
      String value = getValueInList(i, "invoice.sellerDiscount");
      if ("0.00".equals(value)) withoutDiscount = true;
      else if ("20.00".equals(value)) withDiscount = true;
      else fail("Only 0.00 or 20.00 are valid values for invoice.sellerDiscount");
    }
    assertTrue(
        "It's required deliveries with invoices with and without seller discount",
        withDiscount && withoutDiscount);
  }

  public void testUseListWithOtherModelAndReturnToModuleList() throws Exception {
    execute("CRUD.new");
    execute("Delivery.viewCurrentYearInvoices");
    assertNoErrors();
    execute("Return.return");
    assertNoErrors();
    execute("Mode.list");
  }

  public void testCreateObjectInvalidateDescriptionsCache() throws Exception {
    execute("CRUD.new");
    assertNoType("66");
    changeModule("DeliveryType");
    execute("CRUD.new");
    setValue("number", "66");
    setValue("description", "JUNIT TEST");
    execute("CRUD.save");
    assertNoErrors();
    changeModule("Delivery");
    assertType("66");
    changeModule("DeliveryType");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    execute("CRUD.delete");
    assertMessage("Delivery type deleted successfully");
    changeModule("Delivery");
    assertNoType("66");
  }

  public void testEntityValidatorWithKeyReference() throws Exception {
    assertListNotEmpty();
    execute("Mode.detailAndFirst");
    assertNoErrors();
    setValue("advice", "Validating");
    execute("CRUD.save");
    assertNoErrors();
  }

  public void testReadHiddenValuesFromServer() throws Exception {
    // Create one new
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    setValue("type.number", "1");
    setValue("number", "66");
    setValue("description", "JUNIT");
    setValue("remarks", "HIDDEN REMARK");
    execute("CRUD.save");
    assertNoErrors();
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("type.number", "");
    assertValue("number", "");
    assertValue("description", "");
    assertValue("remarks", "No remarks");

    // Hide remarks
    execute("Remarks.hideRemarks");
    assertNotExists("remarks");

    // Search the just created
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    assertValue("type.number", "1");
    assertValue("number", "66");
    assertValue("description", "JUNIT");
    assertNotExists("remarks");

    // Show remarks
    execute("Remarks.showRemarks");
    assertExists("remarks");
    assertValue("remarks", "HIDDEN REMARK");

    // Delete it
    execute("CRUD.delete");
    assertNoErrors();
    assertMessage("Delivery deleted successfully");
  }

  public void testNavigationActionCanReturnPreviousController() throws Exception {
    String[] initialActions = {
      "Navigation.previous",
      "Navigation.first",
      "Navigation.next",
      "CRUD.new",
      "CRUD.save",
      "CRUD.delete",
      "CRUD.search",
      "CRUD.refresh",
      "Mode.list",
      "Mode.split",
      "Reference.search",
      "Reference.createNew",
      "Reference.modify",
      "Sections.change",
      "Delivery.setDefaultInvoice",
      "Delivery.setDefaultType",
      "Delivery.generateNumber",
      "Delivery.generateNumber88",
      "Delivery.activateDeactivateSection",
      "Delivery.hideActions",
      "Delivery.viewCurrentYearInvoices",
      "Delivery.hideAdvice",
      "Delivery.hideShortcut",
      "EditableOnOff.setOn",
      "EditableOnOff.setOff",
      "Remarks.hideRemarks",
      "Remarks.showRemarks",
      "Remarks.setRemarks"
    };

    String[] minimumActions = {
      "CRUD.new",
      "CRUD.save",
      "CRUD.delete",
      "CRUD.search",
      "CRUD.refresh",
      "Mode.list",
      "Mode.split",
      "Reference.search",
      "Reference.createNew",
      "Reference.modify",
      "Sections.change",
      "Delivery.setDefaultInvoice",
      "Delivery.setDefaultType",
      "Delivery.generateNumber",
      "Delivery.generateNumber88",
    };

    String[] creatingNewActions = {"NewCreation.saveNew", "NewCreation.cancel"};

    execute("CRUD.new");
    assertActions(initialActions);

    execute("Delivery.hideActions");
    assertActions(minimumActions);

    execute("Reference.createNew", "model=DeliveryType,keyProperty=xava.Delivery.type.number");
    assertActions(creatingNewActions);

    execute("NewCreation.cancel");
    assertActions(minimumActions);
  }

  public void testPropertyAndReferenceActions() throws Exception {
    execute("Mode.detailAndFirst");
    assertNoErrors();
    assertNoAction("Delivery.generateNumber"); // of property
    assertNoAction("Delivery.setDefaultType"); // of reference as descriptions-list
    assertNoAction("Delivery.setDefaultInvoice"); // of reference
    execute("CRUD.new");
    assertAction("Delivery.generateNumber");
    assertAction("Delivery.setDefaultType");
    assertAction("Delivery.setDefaultInvoice");
    assertValue("number", "");
    assertValue("type.number", "");
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    execute("Delivery.generateNumber88", "xava.keyProperty=number");
    assertNoErrors();
    assertValue("number", "88");
    execute("Delivery.generateNumber", "xava.keyProperty=number");
    assertValue("number", "77");
    execute("Delivery.setDefaultType");
    assertValue("type.number", "1");
    execute("Delivery.setDefaultInvoice");
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
  }

  public void testActivateDeactivateSection() throws Exception {
    execute("CRUD.new");
    assertEditable("advice");
    assertEditable("remarks");
    execute("Delivery.activateDeactivateSection");
    assertNoEditable("advice");
    assertNoEditable("remarks");
    execute("Delivery.activateDeactivateSection");
    assertEditable("advice");
    assertEditable("remarks");
  }

  public void testCreateAndReadWithKeyReferences() throws Exception {
    // Create new one
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    setValue("type.number", "1");
    setValue("number", "66");
    setValue("description", "JUNIT");
    execute("CRUD.save");
    assertNoErrors();
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("type.number", "");
    assertValue("number", "");
    assertValue("description", "");
    // Searching the just created
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("invoice.date", "1/1/02");
    assertValue("type.number", "1");
    assertValue("number", "66");
    assertValue("description", "JUNIT");
    assertNoEditable("invoice.year");
    assertNoEditable("invoice.number");
    assertNoEditable("type");
    assertNoEditable("number");
    assertEditable("description");

    // Delete it
    execute("CRUD.delete");
    assertNoErrors();
    assertMessage("Delivery deleted successfully");
  }

  public void testConverterWithMetaSets() throws Exception {
    // Creating new
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    setValue("description", "JUNIT");
    setValue("distance", usesAnnotatedPOJO() ? "1" : "2"); // National, in database 'N'
    execute("CRUD.save");
    assertNoErrors();
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("type.number", "");
    assertValue("number", "");
    assertValue("description", "");
    assertValue("distance", usesAnnotatedPOJO() ? "" : "0");
    // Search just created
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("type.number", "1");
    assertValue("number", "66");
    assertValue("description", "JUNIT");
    assertValue("distance", usesAnnotatedPOJO() ? "1" : "2");
    assertNoErrors();

    // Verifying database value
    Query query =
        XPersistence.getManager()
            .createNativeQuery(
                "select d.distance from XAVATEST.Delivery as d where "
                    + "invoice_year=2002 and invoice_number=1 and type=1 and number=66");
    String distanceDB = (String) query.getSingleResult();
    assertEquals("distance in database incorrect", "N", distanceDB);

    // Delete
    execute("CRUD.delete");
    assertNoErrors();
    assertMessage("Delivery deleted successfully");
  }

  public void testDeleteSelectedOnesAndOrderBy() throws Exception {
    // Creating new
    execute("CRUD.new");
    setValue("invoice.year", "2009");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "1");
    setValue("description", "JUNIT");
    execute("CRUD.save");
    assertNoErrors();

    // To list mode and order
    execute("Mode.list");
    assertActions(listActions);
    execute("List.orderBy", "property=invoice.year"); // ascending
    execute("List.orderBy", "property=invoice.year"); // descending
    assertNoErrors();

    // Delete
    assertValueInList(0, "invoice.year", "2009");
    assertValueInList(0, "invoice.number", "1");
    assertValueInList(0, "type.number", "1");
    assertValueInList(0, "number", "1");

    checkRow(0);

    execute("CRUD.deleteSelected");
    assertNoErrors();
    assertRowUnchecked(0);

    // Verifying that it is deleted
    Query query =
        XPersistence.getManager()
            .createQuery(
                "from Delivery d where "
                    + "d.invoice.year=2009 and d.invoice.number=1 and d.type.number=1 and d.number=1");
    if (!query.getResultList().isEmpty()) {
      fail("Delivery would be deleted and it is not the case");
    }
  }

  public void testInEntityReferencesNoDefaultValues() throws Exception {
    execute("CRUD.new");
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("invoice.date", "");
    assertValue("invoice.yearDiscount", "");
    assertNoErrors();
  }

  public void testReferencesIfKeyNotExists() throws Exception {
    execute("CRUD.new");
    setValue("invoice.year", "2004"); // We supose that not exists
    setValue("invoice.number", "907"); // We supose that not exists
    assertError("Invoice with key {year=2004, number=907} not found");

    // The reference datas are deleted in screen
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("invoice.date", "");
    assertValue("invoice.yearDiscount", "");
  }

  public void testViewPropertyAndHideMembers() throws Exception {
    execute("CRUD.new");
    assertValue("deliveredBy", usesAnnotatedPOJO() ? "" : "0");
    assertNotExists("employee");
    assertNotExists("carrier.number");

    setValue("deliveredBy", usesAnnotatedPOJO() ? "0" : "1");
    assertExists("employee");
    assertNotExists("carrier.number");

    setValue("deliveredBy", usesAnnotatedPOJO() ? "1" : "2");
    assertNotExists("employee");
    assertExists("carrier.number");

    setValue("deliveredBy", usesAnnotatedPOJO() ? "" : "0");
    assertNotExists("employee");
    assertNotExists("carrier.number");

    setValue("deliveredBy", usesAnnotatedPOJO() ? "1" : "2");
    assertNotExists("employee");
    assertExists("carrier.number");

    execute("CRUD.new");
    assertValue("deliveredBy", usesAnnotatedPOJO() ? "" : "0");
    assertNotExists("employee");
    assertNotExists("carrier.number");
  }

  public void testEnvironmentVariablesModule() throws Exception {
    // Verifying if works the action search special for this module

    // Creating
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "61");
    setValue("description", "JUNIT WITHOUT DELIVEREDBY");
    execute("CRUD.save");
    assertNoErrors();

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "62");
    setValue("description", "JUNIT BY EMPLOYEE");
    setValue("deliveredBy", usesAnnotatedPOJO() ? "0" : "1");
    setValue("employee", "JUNIT EMPLOYEE");
    execute("CRUD.save");
    assertNoErrors();

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "63");
    setValue("description", "JUNIT BY CARRIER");
    setValue("deliveredBy", usesAnnotatedPOJO() ? "1" : "2");
    setValue("carrier.number", "1");
    execute("CRUD.save");
    assertNoErrors();

    // Reading and verifying
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "63");
    execute("CRUD.refresh");
    assertValue("description", "JUNIT BY CARRIER");
    assertExists("carrier.number");
    assertNotExists("employee");
    assertValue("carrier.number", "1");

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "62");
    execute("CRUD.refresh");
    assertValue("description", "JUNIT BY EMPLOYEE");
    assertNotExists("carrier.number");
    assertExists("employee");
    assertValue("employee", "JUNIT EMPLOYEE");

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "61");
    execute("CRUD.refresh");
    assertValue("description", "JUNIT WITHOUT DELIVEREDBY");
    assertNotExists("carrier.number");
    assertNotExists("employee");

    // Delete
    execute("CRUD.delete");
    assertMessage("Delivery deleted successfully");

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "62");
    execute("CRUD.refresh");
    execute("CRUD.delete");
    assertMessage("Delivery deleted successfully");

    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "63");
    execute("CRUD.refresh");
    execute("CRUD.delete");
    assertMessage("Delivery deleted successfully");
  }

  public void testMultipleMappingProperty() throws Exception {
    // Creating new
    execute("CRUD.new");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    setValue("date", "2/22/97");
    setValue("description", "JUNIT");
    execute("CRUD.save");
    assertNoErrors();
    assertValue("invoice.year", "");
    assertValue("invoice.number", "");
    assertValue("type.number", "");
    assertValue("number", "");
    assertValue("date", getCurrentDate());
    assertValue("description", "");
    // Search just created
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    setValue("type.number", "1");
    setValue("number", "66");
    execute("CRUD.refresh");
    assertNoErrors();
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("type.number", "1");
    assertValue("number", "66");
    assertValue("date", "2/22/97");
    assertValue("description", "JUNIT");
    assertNoErrors();

    // Verifying if date property is well in list
    // Only works if there are lest than 11 object (because see in first page)
    execute("Mode.list");
    assertActions(listActions);
    assertNoErrors();
    int quantity = getListRowCount();
    boolean found = false;
    int i = 0;
    for (i = 0; i < quantity; i++) {
      String number = getValueInList(i, "number");
      if ("66".equals(number)) {
        assertValueInList(i, "date", "2/22/97");
        found = true;
        break;
      }
    }
    if (!found) {
      fail("It is necessary that exists delivery 66 in list and there are al least 11 deliveries");
    }

    execute("List.viewDetail", "row=" + i);

    // Delete
    execute("CRUD.delete");
    assertNoErrors();
    assertMessage("Delivery deleted successfully");
  }

  public void
      testCalculatedValueDependentOnChangePropertyOnChangeAndPropertyOnChangeDepedentOnPropertyOnChange()
          throws Exception {
    execute("CRUD.new");
    assertValue("distance", usesAnnotatedPOJO() ? "" : "0");
    assertValue("vehicle", "");
    assertValue("transportMode", "");
    setValue("distance", usesAnnotatedPOJO() ? "0" : "1"); // Local
    assertValue("distance", usesAnnotatedPOJO() ? "0" : "1");
    assertValue("vehicle", "MOTORBIKE");
    assertValue("transportMode", "STREET/ROAD");
    assertValue("driverType", "ANY");
    setValue("distance", usesAnnotatedPOJO() ? "1" : "2"); // National
    assertValue("distance", usesAnnotatedPOJO() ? "1" : "2");
    assertValue("vehicle", "CAR");
    assertValue("transportMode", "HIGHWAY");
    assertValue("driverType", "DRIVER");
    setValue("distance", usesAnnotatedPOJO() ? "" : "0"); // Void
    assertValue("distance", usesAnnotatedPOJO() ? "" : "0");
    assertValue("vehicle", "");
    assertValue("transportMode", "");
    assertValue("driverType", "DRIVERX");
  }

  public void testOnChangeWithQualifiedProperty() throws Exception {
    execute("CRUD.new");
    // Left from field
    assertValue("remarks", "No remarks");
    setValue("remarks", "");
    setValue("invoice.year", "2004");
    setValue("invoice.number", "2");
    assertValue("remarks", "No remarks");
    setValue("remarks", "");
    setValue("invoice.year", "2002");
    setValue("invoice.number", "1");
    assertValue("remarks", "First invoice of year");
    setValue("remarks", "");
    setValue("invoice.number", "2");
    assertValue("remarks", "No remarks");

    // Searching with reference search button
    setValue("remarks", "");
    searchInvoiceWithList("2004", "2");
    assertValue("invoice.year", "2004");
    assertValue("invoice.number", "2");
    assertValue("remarks", "No remarks");
    setValue("remarks", "");

    searchInvoiceWithList("2002", "1");
    assertValue("invoice.year", "2002");
    assertValue("invoice.number", "1");
    assertValue("remarks", "First invoice of year");
    setValue("remarks", "");

    searchInvoiceWithList("2004", "2");
    assertValue("invoice.year", "2004");
    assertValue("invoice.number", "2");
    assertValue("remarks", "No remarks");
  }

  public void testOnChangeDescriptionsListKey_messagesInChangeAction() throws Exception {
    execute("CRUD.new");
    assertValue("remarks", "No remarks");
    setValue("deliveredBy", usesAnnotatedPOJO() ? "1" : "2");
    assertNoMessages();
    setValue("carrier.number", "3");
    assertMessagesCount(1);
    assertMessage("Carrier changed");
    assertValue("remarks", "The carrier is 3");
    setValue("carrier.number", "2");
    assertValue("remarks", "The carrier is 2");
  }

  public void testHideInSection() throws Exception {
    execute("CRUD.new");
    assertExists("remarks");
    execute("Remarks.hideRemarks");
    assertNotExists("remarks");
    execute("Remarks.showRemarks");
    assertExists("remarks");

    execute("Remarks.hideRemarks");
    assertNoErrors();
    assertNotExists("remarks");
    assertExists("advice");
    assertExists("shortcut");

    execute("Delivery.hideAdvice");
    assertNoErrors();
    assertNotExists("remarks");
    assertNotExists("advice");
    assertExists("shortcut");

    execute("Delivery.hideShortcut");
    assertNoErrors();
    assertNotExists("remarks");
    assertNotExists("advice");
    assertNotExists("shortcut");
    assertAction("Delivery.hideShortcut"); // Because when it failed there are no errors
    // but the sections and bottom actions are not displayed
  }

  public void testI18nOfValidValues_descriptionsListWithOrderAndNoCondition() throws Exception {
    // I18n of ValidValues
    execute("CRUD.new");
    String[][] distanceValues = {
      {usesAnnotatedPOJO() ? "" : "0", ""},
      {usesAnnotatedPOJO() ? "0" : "1", "Lokal"},
      {usesAnnotatedPOJO() ? "1" : "2", "Nachional"},
      {usesAnnotatedPOJO() ? "2" : "3", "Internachional"}
    };
    assertValidValues("distance", distanceValues);

    // DescriptionsList order
    String[] types = getKeysValidValues("type.number");
    int previous = Integer.MAX_VALUE;
    for (int i = 1; i < types.length; i++) { // 0 position is empty
      int current = Integer.parseInt(types[i]);
      assertTrue("delivery types must be in descending order by number", current < previous);
      previous = current;
    }
  }

  public void testViewPropertyInSectionDefaultCalcultarAndValidators() throws Exception {
    execute("CRUD.new");
    assertExists("advice");
    assertValue("advice", "IF YOU DRINK DO NOT DRIVE");
    setValue("advice", "");
    execute("CRUD.save");
    assertError("Value for Advice in Delivery is required");
  }

  public void testEditableAffectsSection() throws Exception {
    execute("Mode.detailAndFirst");
    assertEditable("description"); // out of section
    assertEditable("advice"); // in section
    execute("EditableOnOff.setOff");
    assertNoEditable("description"); // out of section
    assertNoEditable("advice"); // in section	
  }

  public void testValidValuesInList() throws Exception {
    int quantity = getListRowCount();
    assertTrue("For this test is needed at least one created delivery", quantity > 0);
    Collection values = new ArrayList();
    values.add("Lokal");
    values.add("Nachional");
    values.add("Internachional");
    boolean thereIsOne = false;
    for (int i = 0; i < quantity; i++) {
      String value = getValueInList(i, "distance");
      if (Is.emptyString(value)) continue;
      if (values.contains(value)) {
        thereIsOne = true;
        continue;
      }
      fail("Only the next values are valid: " + values);
    }
    assertTrue(
        "For this test is need at least one delivery with value in 'distance' property",
        thereIsOne);
  }

  public void testSetValueAgainstPropertiesOfSectionsHiddenAndShowed() throws Exception {
    execute("Remarks.hideRemarks");
    execute("CRUD.new");
    assertNotExists("remarks");
    execute("Remarks.showRemarks");
    assertExists("remarks");
    execute("Remarks.setRemarks");
    assertValue("remarks", "Hell in your eyes");
  }

  public void testGeneratePdf() throws Exception {
    execute("Print.generatePdf");
    assertContentTypeForPopup("application/pdf");
  }

  private String getCurrentDate() {
    DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
    return df.format(new java.util.Date());
  }

  private void searchInvoiceWithList(String year, String number) throws Exception {
    execute("Reference.search", "keyProperty=xava.Delivery.invoice.number");
    setConditionValues(new String[] {year, number, "", "true"});
    execute("List.filter");
    assertListRowCount(1);
    execute("ReferenceSearch.choose", "row=0");
  }

  private void assertNoType(String type) throws Exception {
    String[] types = getKeysValidValues("type.number");
    assertTrue(type + " not expected", !Arrays.asList(types).contains(type));
  }

  private void assertType(String type) throws Exception {
    String[] types = getKeysValidValues("type.number");
    assertTrue(type + " expected", Arrays.asList(types).contains(type));
  }

  public void testNewGoFirstSection() throws Exception {
    execute("CRUD.new");
    assertExists("advice");
    assertNotExists("incidents");
    execute("Sections.change", "activeSection=1");
    assertExists("incidents");
    assertNotExists("advice");
    execute("CRUD.new");
    assertExists("advice");
    assertNotExists("incidents");
  }

  public void testDescriptionsListHiddenAfterClearCondition() throws Exception {
    HtmlSelect select =
        getHtmlPage().getElementByName("ox_OpenXavaTest_Delivery__conditionValue___3");
    String s = select.getAttribute("style");
    assertFalse(s.contains("display: none") || s.contains("display:none"));
    clearCondition("ox_OpenXavaTest_Delivery__xava_clear_condition");
    select = getHtmlPage().getElementByName("ox_OpenXavaTest_Delivery__conditionValue___3");
    s = select.getAttribute("style");
    assertFalse(s.contains("display: none") || s.contains("display:none"));
  }
}