/** @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")); } }
/** @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(); } }
/** @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) {} }
/** @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")); } }