public class IdentitySchema { private static final String IDENTITY_TABLE_PREFIX = "JBPM_ID_"; Configuration configuration = null; Properties properties = null; Dialect dialect = null; Mapping mapping = null; String[] createSql = null; String[] dropSql = null; String[] cleanSql = null; ConnectionProvider connectionProvider = null; Connection connection = null; Statement statement = null; public IdentitySchema(Configuration configuration) { this.configuration = configuration; this.properties = configuration.getProperties(); this.dialect = Dialect.getDialect(properties); try { // get the mapping field via reflection :-( Field mappingField = Configuration.class.getDeclaredField("mapping"); mappingField.setAccessible(true); this.mapping = (Mapping) mappingField.get(configuration); } catch (Exception e) { throw new RuntimeException("couldn't get the hibernate mapping", e); } } // scripts lazy initializations ///////////////////////////////////////////// public String[] getCreateSql() { if (createSql == null) { createSql = configuration.generateSchemaCreationScript(dialect); } return createSql; } public String[] getDropSql() { if (dropSql == null) { dropSql = configuration.generateDropSchemaScript(dialect); } return dropSql; } public String[] getCleanSql() { if (cleanSql == null) { // loop over all foreign key constraints List dropForeignKeysSql = new ArrayList(); List createForeignKeysSql = new ArrayList(); Iterator iter = configuration.getTableMappings(); while (iter.hasNext()) { Table table = (Table) iter.next(); if (table.isPhysicalTable()) { Iterator subIter = table.getForeignKeyIterator(); while (subIter.hasNext()) { ForeignKey fk = (ForeignKey) subIter.next(); if (fk.isPhysicalConstraint()) { // collect the drop key constraint dropForeignKeysSql.add( fk.sqlDropString( dialect, properties.getProperty(Environment.DEFAULT_CATALOG), properties.getProperty(Environment.DEFAULT_SCHEMA))); createForeignKeysSql.add( fk.sqlCreateString( dialect, mapping, properties.getProperty(Environment.DEFAULT_CATALOG), properties.getProperty(Environment.DEFAULT_SCHEMA))); } } } } List deleteSql = new ArrayList(); iter = configuration.getTableMappings(); while (iter.hasNext()) { Table table = (Table) iter.next(); deleteSql.add("delete from " + table.getName()); } List cleanSqlList = new ArrayList(); cleanSqlList.addAll(dropForeignKeysSql); cleanSqlList.addAll(deleteSql); cleanSqlList.addAll(createForeignKeysSql); cleanSql = (String[]) cleanSqlList.toArray(new String[cleanSqlList.size()]); } return cleanSql; } // runtime table detection ////////////////////////////////////////////////// public boolean hasIdentityTables() { return (getIdentityTables().size() > 0); } public List getIdentityTables() { // delete all the data in the jbpm tables List jbpmTableNames = new ArrayList(); try { createConnection(); ResultSet resultSet = connection.getMetaData().getTables("", "", null, null); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); if ((tableName != null) && (tableName.length() > 5) && (IDENTITY_TABLE_PREFIX.equalsIgnoreCase(tableName.substring(0, 5)))) { jbpmTableNames.add(tableName); } } } catch (SQLException e) { throw new RuntimeException("couldn't get the jbpm table names"); } finally { closeConnection(); } return jbpmTableNames; } // script execution methods ///////////////////////////////////////////////// public void dropSchema() { execute(getDropSql()); } public void createSchema() { execute(getCreateSql()); } public void cleanSchema() { execute(getCleanSql()); } public void saveSqlScripts(String dir, String prefix) { try { new File(dir).mkdirs(); saveSqlScript(dir + "/" + prefix + ".drop.sql", getDropSql()); saveSqlScript(dir + "/" + prefix + ".create.sql", getCreateSql()); saveSqlScript(dir + "/" + prefix + ".clean.sql", getCleanSql()); new SchemaExport(configuration) .setDelimiter(getSqlDelimiter()) .setOutputFile(dir + "/" + prefix + ".drop.create.sql") .create(true, false); } catch (Exception e) { throw new RuntimeException("couldn't generate scripts", e); } } // main ///////////////////////////////////////////////////////////////////// public static void main(String[] args) { try { if ((args != null) && (args.length == 1) && ("create".equalsIgnoreCase(args[0]))) { new IdentitySchema(IdentitySessionFactory.createConfiguration()).createSchema(); } else if ((args != null) && (args.length == 1) && ("drop".equalsIgnoreCase(args[0]))) { new IdentitySchema(IdentitySessionFactory.createConfiguration()).dropSchema(); } else if ((args != null) && (args.length == 1) && ("clean".equalsIgnoreCase(args[0]))) { new IdentitySchema(IdentitySessionFactory.createConfiguration()).cleanSchema(); } else if ((args != null) && (args.length == 3) && ("scripts".equalsIgnoreCase(args[0]))) { new IdentitySchema(IdentitySessionFactory.createConfiguration()) .saveSqlScripts(args[1], args[2]); } else { System.err.println("syntax: JbpmSchema create"); System.err.println("syntax: JbpmSchema drop"); System.err.println("syntax: JbpmSchema clean"); System.err.println("syntax: JbpmSchema scripts <dir> <prefix>"); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } private void saveSqlScript(String fileName, String[] sql) throws FileNotFoundException { FileOutputStream fileOutputStream = new FileOutputStream(fileName); PrintStream printStream = new PrintStream(fileOutputStream); for (int i = 0; i < sql.length; i++) { printStream.println(sql[i] + getSqlDelimiter()); } } // sql script execution ///////////////////////////////////////////////////// public void execute(String[] sqls) { String sql = null; String showSqlText = properties.getProperty("hibernate.show_sql"); boolean showSql = ("true".equalsIgnoreCase(showSqlText)); try { createConnection(); statement = connection.createStatement(); for (int i = 0; i < sqls.length; i++) { sql = sqls[i]; String delimitedSql = sql + getSqlDelimiter(); if (showSql) log.debug(delimitedSql); statement.executeUpdate(delimitedSql); } } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("couldn't execute sql '" + sql + "'", e); } finally { closeConnection(); } } private void closeConnection() { try { if (statement != null) statement.close(); if (connection != null) { JDBCExceptionReporter.logWarnings(connection.getWarnings()); connection.clearWarnings(); connectionProvider.closeConnection(connection); connectionProvider.close(); } } catch (Exception e) { System.err.println("Could not close connection"); e.printStackTrace(); } } private void createConnection() throws SQLException { connectionProvider = ConnectionProviderFactory.newConnectionProvider(properties); connection = connectionProvider.getConnection(); if (!connection.getAutoCommit()) { connection.commit(); connection.setAutoCommit(true); } } public Properties getProperties() { return properties; } // sql delimiter //////////////////////////////////////////////////////////// private static String sqlDelimiter = null; private synchronized String getSqlDelimiter() { if (sqlDelimiter == null) { sqlDelimiter = properties.getProperty("jbpm.sql.delimiter", ";"); } return sqlDelimiter; } // logger /////////////////////////////////////////////////////////////////// private static final Log log = LogFactory.getLog(IdentitySchema.class); }
/** @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; } } }
/** * 領域マスタデータアクセスクラス。 ID RCSfile="$RCSfile: MasterRyouikiInfoDao.java,v $" Revision="$Revision: 1.1 $" * Date="$Date: 2007/06/28 02:06:50 $" */ public class MasterRyouikiInfoDao { // --------------------------------------------------------------------- // Static data // --------------------------------------------------------------------- /** ログ */ protected static final Log log = LogFactory.getLog(MasterRyouikiInfoDao.class); // --------------------------------------------------------------------- // Instance data // --------------------------------------------------------------------- /** 実行するユーザ情報 */ private UserInfo userInfo = null; // --------------------------------------------------------------------- // Constructors // --------------------------------------------------------------------- /** * コンストラクタ。 * * @param userInfo 実行するユーザ情報 */ public MasterRyouikiInfoDao(UserInfo userInfo) { this.userInfo = userInfo; } // --------------------------------------------------------------------- // Public Methods // --------------------------------------------------------------------- /** * 領域の一覧(コンポボックス用)を取得する。 * * @param connection コネクション * @return 事業情報 * @throws ApplicationException */ public static List selectRyouikiKubunInfoList(Connection connection) throws ApplicationException, NoDataFoundException { // ----------------------- // SQL文の作成 // ----------------------- String select = "SELECT" + " A.RYOIKI_NO" + ",A.RYOIKI_RYAKU" + " FROM MASTER_RYOIKI A" + " ORDER BY RYOIKI_NO"; StringBuffer query = new StringBuffer(select); if (log.isDebugEnabled()) { log.debug("query:" + query); } // ----------------------- // リスト取得 // ----------------------- try { return SelectUtil.select(connection, query.toString()); } catch (DataAccessException e) { throw new ApplicationException("領域情報検索中にDBエラーが発生しました。", new ErrorInfo("errors.4004"), e); } catch (NoDataFoundException e) { throw new NoDataFoundException("領域マスタに1件もデータがありません。", e); } } /** * 領域マスタの1レコードをMap形式で返す。 引数には主キー値を渡す。 * * @param connection * @param labelKubun * @param value * @return * @throws NoDataFoundException * @throws DataAccessException */ public static Map selectRecord(Connection connection, String ryouikiNo) throws NoDataFoundException, DataAccessException { // ----------------------- // SQL文の作成 // ----------------------- String select = "SELECT" + " A.RYOIKI_NO" + ",A.RYOIKI_RYAKU" + ",A.KOMOKU_NO" // 2006/06/26 苗 修正ここから + ",A.SETTEI_KIKAN" // 設定期間 + ",A.SETTEI_KIKAN_KAISHI" // 設定期間(開始年度) + ",A.SETTEI_KIKAN_SHURYO" // 設定期間(終了年度) // 2006/06/26 苗 修正ここまで + ",A.BIKO" + " FROM MASTER_RYOIKI A" + " WHERE RYOIKI_NO = ? "; if (log.isDebugEnabled()) { log.debug("query:" + select); } // ----------------------- // レコード取得 // ----------------------- List result = SelectUtil.select(connection, select, new String[] {ryouikiNo}); if (result.isEmpty()) { throw new NoDataFoundException("当該レコードは存在しません。領域No=" + ryouikiNo); } return (Map) result.get(0); } /** * 領域マスタの1レコードをMap形式で返す。 引数には主キー値を渡す。 * * @param connection * @param labelKubun * @param value * @return * @throws NoDataFoundException * @throws DataAccessException */ public static Map selectRecord(Connection connection, RyouikiInfoPk pkInfo) throws NoDataFoundException, DataAccessException { return selectRecord(connection, pkInfo, "0"); } /** * 領域マスタの1レコードをMap形式で返す。 引数には主キー値を渡す。 * * @param connection * @param labelKubun * @param value * @return * @throws NoDataFoundException * @throws DataAccessException */ public static Map selectRecord(Connection connection, RyouikiInfoPk pkInfo, String ryoikiKbn) throws NoDataFoundException, DataAccessException { // ----------------------- // SQL文の作成 // ----------------------- String select = "SELECT" + " A.RYOIKI_NO" + ",A.RYOIKI_RYAKU" + ",A.KOMOKU_NO" // 2006/07/04 苗 修正ここから + ",A.SETTEI_KIKAN" // 設定期間 + ",A.SETTEI_KIKAN_KAISHI" // 設定期間(開始年度) + ",A.SETTEI_KIKAN_SHURYO" // 設定期間(終了年度) // 2006/07/04 苗 修正ここまで + " FROM MASTER_RYOIKI A" + " WHERE RYOIKI_NO = ? " + " AND KOMOKU_NO = ? "; // 計画研究の場合 if ("1".equals(ryoikiKbn)) { select = select + " AND KEIKAKU_FLG = '1'"; } // 公募研究の場合 else if ("2".equals(ryoikiKbn)) { select = select + " AND KOUBO_FLG = '1'"; } if (log.isDebugEnabled()) { log.debug("query:" + select); } // ----------------------- // レコード取得 // ----------------------- List result = SelectUtil.select( connection, select, new String[] {pkInfo.getRyoikiNo(), pkInfo.getKomokuNo()}); if (result.isEmpty()) { throw new NoDataFoundException("当該レコードは存在しません。"); } return (Map) result.get(0); } /** * 領域情報を登録する。 * * @param connection コネクション * @param addInfo 登録するキーワード情報 * @throws DataAccessException 登録中に例外が発生した場合。 * @throws DuplicateKeyException キーに一致するデータが既に存在する場合。 */ public void insertRyoikiInfo(Connection connection, RyouikiInfo addInfo) throws DataAccessException, DuplicateKeyException { // 重複チェック try { selectRecord(connection, addInfo); // NG throw new DuplicateKeyException("'" + addInfo + "'は既に登録されています。"); } catch (NoDataFoundException e) { // OK } String query = "INSERT INTO MASTER_RYOIKI " + "(" + " RYOIKI_NO" // 領域番号 + ",RYOIKI_RYAKU" // 領域略称名 + ",KOMOKU_NO" // 研究項目番号 + ",KOUBO_FLG" // 公募フラグ + ",KEIKAKU_FLG" // 計画研究フラグ // add start liuyi 2006/06/30 + ",ZENNENDO_OUBO_FLG" // 前年度応募フラグ + ",SETTEI_KIKAN_KAISHI" // 設定期間(開始年度) + ",SETTEI_KIKAN_SHURYO" // 設定期間(終了年度) + ",SETTEI_KIKAN" // 設定期間 // add end liuyi 2006/06/30 + ",BIKO" // 備考 + ")" + "VALUES " + "(?,?,?,?,?,?,?,?,?,?)"; PreparedStatement preparedStatement = null; try { // 登録 preparedStatement = connection.prepareStatement(query); int i = 1; DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getRyoikiNo()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getRyoikiName()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getKomokuNo()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getKobou()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getKeikaku()); // add start liuyi 2006/06/30 DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getZennendoOuboFlg()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getSettelKikanKaishi()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getSettelKikanShuryo()); DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getSettelKikan()); // add end liuyi 2006/06/30 DatabaseUtil.setParameter(preparedStatement, i++, addInfo.getBiko()); DatabaseUtil.executeUpdate(preparedStatement); } catch (SQLException ex) { log.error("領域マスタ情報登録中に例外が発生しました。 ", ex); throw new DataAccessException("領域マスタ情報登録中に例外が発生しました。 ", ex); } finally { DatabaseUtil.closeResource(null, preparedStatement); } } /** * コード一覧作成用メソッド。<br> * 領域番号と領域名称の一覧を取得する。 領域番号順にソートする。 * * @param connection コネクション * @return * @throws ApplicationException */ public static List selectRyoikiInfoList(Connection connection, String kubun) throws ApplicationException { // ----------------------- // SQL文の作成 // ----------------------- String select = "SELECT" + " RYOIKI_NO," // 領域番号 + " RYOIKI_RYAKU" // 領域名称 + " FROM MASTER_RYOIKI"; if ("1".equals(kubun)) { select = select + " WHERE KEIKAKU_FLG = '1'"; } else { select = select + " WHERE KOUBO_FLG = '1'"; } select = select + " GROUP BY RYOIKI_NO, RYOIKI_RYAKU" + " ORDER BY RYOIKI_NO"; if (log.isDebugEnabled()) { log.debug("query:" + select); } // ----------------------- // リスト取得 // ----------------------- try { return SelectUtil.select(connection, select); } catch (DataAccessException e) { throw new ApplicationException("領域情報検索中にDBエラーが発生しました。", new ErrorInfo("errors.4004"), e); } catch (NoDataFoundException e) { throw new SystemException("領域マスタに1件もデータがありません。", e); } } // 2006/06/26 苗 追加ここから /** * 領域番号の件数を取得する。 領域番号順にソートする。 * * @param connection コネクション * @param ryoikoNo 領域番号 * @return * @throws ApplicationException * @throws DataAccessException */ public String selectRyoikiNoCount(Connection connection, String ryoikoNo) throws ApplicationException, DataAccessException { String strCount = null; ResultSet recordSet = null; PreparedStatement preparedStatement = null; // ----------------------- // SQL文の作成 // ----------------------- StringBuffer select = new StringBuffer(); select.append("SELECT COUNT(RYOIKI_NO) "); select.append(ISystemServise.STR_COUNT); select.append(" FROM"); select.append(" (SELECT MR.RYOIKI_NO FROM MASTER_RYOIKI MR WHERE MR.ZENNENDO_OUBO_FLG = '1' "); select.append(" AND MR.RYOIKI_NO = '"); select.append(EscapeUtil.toSqlString(ryoikoNo)); select.append("')"); if (log.isDebugEnabled()) { log.debug("query:" + select.toString()); } try { preparedStatement = connection.prepareStatement(select.toString()); recordSet = preparedStatement.executeQuery(); if (recordSet.next()) { strCount = recordSet.getString(ISystemServise.STR_COUNT); } else { throw new NoDataFoundException("領域マスタデータテーブルに該当するデータが見つかりません。"); } } catch (SQLException ex) { throw new DataAccessException("領域マスタデータテーブルの検索中に例外が発生しました。", ex); } catch (NoDataFoundException ex) { throw new NoDataFoundException("該当する領域番号が存在しません。", ex); } return strCount; } // 2006/06/26 苗 追加ここまで // 2006/07/24 苗 追加ここから /** * コード一覧(新規領域)作成用メソッド。<br> * 領域番号と領域名称の一覧を取得する。 領域番号順にソートする。 * * @param connection コネクション * @return List * @throws ApplicationException */ public static List selectRyoikiSinnkiInfoList(Connection connection) throws ApplicationException { // ----------------------- // SQL文の作成 // ----------------------- StringBuffer select = new StringBuffer(); select.append("SELECT DISTINCT"); select.append(" RYOIKI_NO,"); // 領域番号 select.append(" RYOIKI_RYAKU,"); // 領域名称 select.append(" SETTEI_KIKAN"); // 設定期間 select.append(" FROM MASTER_RYOIKI"); select.append(" WHERE ZENNENDO_OUBO_FLG = '1'"); select.append(" ORDER BY RYOIKI_NO"); if (log.isDebugEnabled()) { log.debug("query:" + select); } // ----------------------- // リスト取得 // ----------------------- try { return SelectUtil.select(connection, select.toString()); } catch (DataAccessException e) { throw new ApplicationException("領域情報検索中にDBエラーが発生しました。", new ErrorInfo("errors.4004"), e); } catch (NoDataFoundException e) { throw new SystemException("領域マスタに1件もデータがありません。", e); } } // 2006/07/24 苗 追加ここまで }