You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/07/21 09:55:22 UTC
svn commit: r424221 -
/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/
Author: arminw
Date: Fri Jul 21 00:55:21 2006
New Revision: 424221
URL: http://svn.apache.org/viewvc?rev=424221&view=rev
Log:
Initial check in of forward engineering tool by Tom Antony, see OJB-112
port (support for JDK1.3 needed) source to OJB 1.0.x.
There are issues when generating JavaBeans and torque-xml file:
- Bean Generation: No support for package structure
- Bean Generation: No support for inner classes
- SQL Gneration: Duplicated FK definitions. Seems caused by "extent-class" settings (defined sub-classes))
- SQL Gneration: Duplicated columns and missing columns in m:n indirection tables
Added:
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanDescriptor.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanGenerator.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/ForwardRepositoryTask.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/RepositoryXmlProcessor.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/SQLStructures.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/TorqueSchemaGenerator.java
db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/Utils.java
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanDescriptor.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanDescriptor.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanDescriptor.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanDescriptor.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,85 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+
+/**
+ * Descriptor for a Java bean.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+public class BeanDescriptor
+{
+ private String packageName;
+ private String className;
+ private String baseClass;
+ private String [] interfaces;
+ private ArrayList attributes;
+ private ArrayList types;
+
+ /**
+ * Create a new BeanDescriptor object.
+ *
+ * @param packageName the package name of the bean
+ * @param className the class name of the bean
+ * @param baseClass the parent class of the bean
+ * @param interfaces array of interface names implemented by the bean
+ * @param attributes the bean attributes
+ * @param types types for bean attributes, should match attributes in order
+ */
+ public BeanDescriptor(String packageName, String className, String baseClass,
+ String [] interfaces, ArrayList attributes, ArrayList types)
+ {
+ this.packageName = packageName;
+ this.className = className;
+ this.baseClass = baseClass;
+ this.interfaces = interfaces;
+ this.attributes = attributes;
+ this.types = types;
+ }
+
+ public String packageName()
+ {
+ return packageName;
+ }
+
+ public String className()
+ {
+ return className;
+ }
+
+ public String baseClass()
+ {
+ return baseClass;
+ }
+
+ public String[] interfaces()
+ {
+ return interfaces;
+ }
+
+ public ArrayList attributes()
+ {
+ return attributes;
+ }
+
+ public ArrayList types()
+ {
+ return types;
+ }
+}
\ No newline at end of file
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanGenerator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanGenerator.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanGenerator.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/BeanGenerator.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,187 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+
+/**
+ * Generator for Java bean source.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+public class BeanGenerator
+{
+ // output directory into which bean source code is generated.
+ private String outputDirectory;
+
+ /**
+ * Creates a new instance of the bean generator for the specified output directory.
+ *
+ * @param outputDirectory the output directory into which bean source code is generated.
+ */
+ public BeanGenerator(String outputDirectory)
+ {
+ this.outputDirectory = outputDirectory;
+ }
+
+ private static String capitalizeMemberField(String str)
+ {
+ String s = str.substring(0, 1);
+ s = s.toUpperCase();
+ s += str.substring(1);
+ return s;
+ }
+
+ private static String generateTypeDeclaration(String attribute, String type)
+ {
+ StringBuffer buf = new StringBuffer(100);
+
+ buf.append("\n\tprivate ");
+ buf.append(type);
+ buf.append(" ");
+ buf.append(attribute);
+ buf.append(";");
+
+ return buf.toString();
+ }
+
+ private static String generateGetMethod(String attribute, String type)
+ {
+ StringBuffer buf = new StringBuffer(100);
+
+ buf.append("\n\tpublic ");
+ buf.append(type);
+ buf.append(" get");
+ buf.append(capitalizeMemberField(attribute));
+ buf.append("()");
+ buf.append(" { return ");
+ buf.append(attribute);
+ buf.append("; }");
+
+ return buf.toString();
+ }
+
+ private static String generateSetMethod(String attribute, String type)
+ {
+ StringBuffer buf = new StringBuffer(100);
+
+ buf.append("\n\tpublic ");
+ buf.append("void ");
+ buf.append(" set");
+ buf.append(capitalizeMemberField(attribute));
+ buf.append("(");
+ buf.append(type);
+ buf.append(" ");
+ buf.append(attribute);
+ buf.append(")");
+ buf.append(" { this.");
+ buf.append(attribute);
+ buf.append(" = ");
+ buf.append(attribute);
+ buf.append("; }");
+
+ return buf.toString();
+ }
+
+ /**
+ * Generate the source for the Java bean.
+ *
+ * @param beanDescription the bean descriptor.
+ */
+ public void generate(BeanDescriptor beanDescription) throws Exception
+ {
+ StringBuffer buf = new StringBuffer(100);
+
+ if(beanDescription.packageName() != null && beanDescription.packageName().trim().length() > 0)
+ {
+ buf.append("package ");
+ buf.append(beanDescription.packageName());
+ buf.append(";\n");
+ }
+
+ buf.append("\n");
+ buf.append("public class ");
+ buf.append(beanDescription.className());
+
+ if(beanDescription.baseClass() != null)
+ buf.append(" extends ").append(beanDescription.baseClass());
+
+ if(beanDescription.interfaces() != null)
+ {
+ buf.append(" implements ");
+ for(int i = 0; i < beanDescription.interfaces().length; i++)
+ {
+ buf.append(beanDescription.interfaces()[i]);
+ if(i < beanDescription.interfaces().length - 1) buf.append(" , ");
+ }
+ }
+
+ buf.append("\n");
+
+ buf.append("{");
+
+ for(int i = 0; i < beanDescription.attributes().size(); i++)
+ {
+ String attribute = (String) beanDescription.attributes().get(i);
+ String type = (String) beanDescription.types().get(i);
+ buf.append(generateTypeDeclaration(attribute, type));
+ }
+
+ buf.append("\n");
+
+ for(int i = 0; i < beanDescription.attributes().size(); i++)
+ {
+ String attribute = (String) beanDescription.attributes().get(i);
+ String type = (String) beanDescription.types().get(i);
+
+ buf.append(generateSetMethod(attribute, type));
+ buf.append(generateGetMethod(attribute, type));
+
+ buf.append("\n");
+ }
+
+ buf.append("\n");
+
+ buf.append("}");
+
+ FileWriter fwr = new FileWriter(new File(outputDirectory, beanDescription.className() + ".java"));
+ fwr.write(buf.toString());
+ fwr.close();
+ }
+
+ public static void main(String args[]) throws Exception
+ {
+ BeanGenerator gen = new BeanGenerator(null);
+
+ ArrayList attributes = new ArrayList();
+ ArrayList types = new ArrayList();
+
+ attributes.add("name");
+ types.add("String");
+
+ attributes.add("age");
+ types.add("int");
+
+ BeanDescriptor description = new BeanDescriptor(null, "Customer", "Person",
+ new String []{"XYZ", "ABC"},
+ attributes, types
+ );
+ gen.generate(description);
+ }
+}
\ No newline at end of file
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/ForwardRepositoryTask.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/ForwardRepositoryTask.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/ForwardRepositoryTask.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/ForwardRepositoryTask.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,87 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.commons.lang.exception.ExceptionUtils;
+
+/**
+ * Ant task for {@link RepositoryXmlProcessor}.
+ *
+ * @version $Id: $
+ */
+public class ForwardRepositoryTask extends Task
+{
+ private String input;
+ private String beanOutput;
+ private String torqueOutput;
+
+ public ForwardRepositoryTask()
+ {
+ }
+
+ public void execute() throws BuildException
+ {
+ super.execute();
+ getProject().log("Start OJB Forward Engineering");
+ getProject().log("Input: " + getInput());
+ getProject().log("Bean output: " + getBeanOutput());
+ getProject().log("Torque output: " + getTorqueOutput());
+
+ try
+ {
+ RepositoryXmlProcessor processor = new RepositoryXmlProcessor(getInput(), getBeanOutput(), getTorqueOutput());
+ processor.generateSQL();
+ processor.generateJavaCode();
+ }
+ catch(Exception e)
+ {
+ getProject().log("Forward Engineering failed: " + ExceptionUtils.getFullStackTrace(e));
+ throw new BuildException("Can't finish forward engineering", e);
+ }
+ }
+
+ public String getInput()
+ {
+ return input;
+ }
+
+ public void setInput(String input)
+ {
+ this.input = input;
+ }
+
+ public String getBeanOutput()
+ {
+ return beanOutput;
+ }
+
+ public void setBeanOutput(String beanOutput)
+ {
+ this.beanOutput = beanOutput;
+ }
+
+ public String getTorqueOutput()
+ {
+ return torqueOutput;
+ }
+
+ public void setTorqueOutput(String torqueOutput)
+ {
+ this.torqueOutput = torqueOutput;
+ }
+}
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/RepositoryXmlProcessor.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/RepositoryXmlProcessor.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/RepositoryXmlProcessor.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/RepositoryXmlProcessor.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,651 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+
+import java.util.Set;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.apache.commons.lang.StringUtils;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/**
+ * Utility to process OJB's repository.xml file and generate Java bean source code and
+ * SQL schema in Torque XML format.
+ *
+ * Auto generated indirection tables
+ * ---------------------------------
+ *
+ * If there are no explicit mappings for an indirection table, the utility generates the SQL
+ * schema for it including referential constraints.
+ *
+ * An indirection table associates two tables. So it will contain two referential constraints,
+ * one for each of the associated table. The primary key will be a combination of the foreign
+ * keys for both of the associated tables.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+public class RepositoryXmlProcessor
+{
+ // the output Torque xml file name.
+ private String torqueXmlFile = "ojb-torque.xml";
+
+ // the output directory for generated torque xml.
+ private String torqueOutputDirectory;
+
+ // the output directory for generated java beans.
+ private String beanOutputDirectory;
+
+ // the DOM document holding OJB mappings.
+ private Document doc;
+
+ // auto generated indirection tables.
+ private Map indirectionTables = new HashMap();
+
+ // tables which need merging of multiple mapping definitions.
+ private Map deferredTables = new HashMap();
+
+ // mapping between JDBC/SQL and Java types.
+ private static HashMap typeMap = new HashMap();
+
+ // http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html
+ static
+ {
+ typeMap.put("BIT", "boolean");
+
+ typeMap.put("SMALLINT", "short");
+ typeMap.put("INTEGER", "int");
+ typeMap.put("BIGINT", "long");
+
+ typeMap.put("FLOAT", "float");
+ typeMap.put("DOUBLE", "double");
+ typeMap.put("REAL", "float");
+ typeMap.put("NUMERIC", "java.math.BigDecimal");
+ typeMap.put("DECIMAL", "java.math.BigDecimal");
+
+ typeMap.put("CHAR", "String");
+ typeMap.put("VARCHAR", "String");
+ typeMap.put("LONGVARCHAR", "String");
+
+ typeMap.put("CLOB", "java.sql.Clob");
+ typeMap.put("BLOB", "java.sql.Blob");
+ typeMap.put("ARRAY", "java.sql.Array");
+ typeMap.put("STRUCT", "java.sql.Struct");
+ typeMap.put("REF", "java.sql.Ref");
+
+ typeMap.put("BINARY", "byte []");
+ typeMap.put("VARBINARY", "byte []");
+ typeMap.put("LONGVARBINARY", "byte []");
+
+ typeMap.put("DATE", "java.sql.Date");
+ typeMap.put("TIME", "java.sql.Time");
+ typeMap.put("TIMESTAMP", "java.sql.Timestamp");
+ }
+
+ /**
+ * Creates a new instance of the repository xml processor.
+ *
+ * @param repositoryXml the path of the repository.xml to be processed.
+ * @param torqueOutputDirectory the output directory into which java beans and Torque xml are
+ * generated, specify null for current directory.
+ * @param beanOutputDirectory the name of the Torque xml file, specify null for the default
+ * which is is 'ojb-torque.xml'.
+ */
+ public RepositoryXmlProcessor(String repositoryXml, String torqueOutputDirectory, String beanOutputDirectory) throws Exception
+ {
+ if(torqueOutputDirectory != null)
+ this.torqueOutputDirectory = torqueOutputDirectory;
+ if(beanOutputDirectory != null)
+ this.beanOutputDirectory = beanOutputDirectory;
+
+ // create output directory if it does not exist.
+ if(!new File(torqueOutputDirectory).exists())
+ new File(torqueOutputDirectory).mkdir();
+
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ doc = builder.parse(new File(repositoryXml));
+ }
+
+ /*
+ * Convinience method.
+ */
+ private Table getTableInfo(Element clsDescElem)
+ {
+ return getTableInfo(clsDescElem, true);
+ }
+
+ /*
+ * Get the table description associated with a <class-descriptor> element.
+ * If recurse is true, explore <reference-descriptor> elements, else return after
+ * filling in the columns.
+ */
+ private Table getTableInfo(Element clsDescElem, boolean recurse)
+ {
+ Table table = new Table();
+
+ table.name = clsDescElem.getAttribute("table");
+
+ Map fieldColumnMap = new HashMap();
+
+ NodeList fldDescList = clsDescElem.getElementsByTagName("field-descriptor");
+ for(int i = 0; i < fldDescList.getLength(); i++)
+ {
+ Element fldDescElem = (Element) fldDescList.item(i);
+
+ String fieldName = fldDescElem.getAttribute("name");
+ String columnName = fldDescElem.getAttribute("column");
+ String jdbcType = fldDescElem.getAttribute("jdbc-type");
+ String primaryKey = fldDescElem.getAttribute("primarykey");
+ String nullable = fldDescElem.getAttribute("nullable");
+ String autoincriment = fldDescElem.getAttribute("autoincrement");
+ String length = fldDescElem.getAttribute("length");
+
+ Column column = new Column();
+ table.columns.add(column);
+
+ column.name = columnName;
+ column.jdbcType = jdbcType;
+ column.length = length;
+
+ if(primaryKey != null && primaryKey.equals("true"))
+ column.isPrimaryKey = true;
+ if(nullable != null && nullable.equals("false"))
+ column.isNullable = false;
+ if(autoincriment != null && autoincriment.equals("true"))
+ column.isAutoIncriment = true;
+
+ fieldColumnMap.put(fieldName, columnName);
+ }
+
+ // If recurse is false, we are calling just to get parent table's primary keys, so return.
+ if(!recurse)
+ return table;
+
+ // Generate foreignkey definitions.
+ NodeList refDescList = clsDescElem.getElementsByTagName("reference-descriptor");
+ for(int i = 0; i < refDescList.getLength(); i++)
+ {
+ Element refDescElem = (Element) refDescList.item(i);
+ String refClassName = refDescElem.getAttribute("class-ref");
+
+ // First, figure out the foreign table.
+ Element clsDescElemForeignTable = findFirstMappedClass(doc, refClassName);
+ Table foreignTable = getTableInfo(clsDescElemForeignTable, false);
+ ForeignKey foreignKey = new ForeignKey();
+ table.foreignKeys.add(foreignKey);
+ foreignKey.foreignTable = foreignTable.name;
+
+ // Iterate through foreignkeys defined in the current reference description
+ NodeList fkList = refDescElem.getElementsByTagName("foreignkey");
+ for(int j = 0; j < fkList.getLength(); j++)
+ {
+ Element fkElem = (Element) fkList.item(j);
+ String fkFieldName = fkElem.getAttribute("field-ref");
+ String fkColumn = (String) fieldColumnMap.get(fkFieldName);
+
+ foreignKey.localColumns.add(fkColumn);
+ }
+
+ // Add primary keys of the foreign table, in order.
+ for(int j = 0; j < foreignTable.columns.size(); j++)
+ {
+ Column foreignColumn = (Column) foreignTable.columns.get(j);
+ if(foreignColumn.isPrimaryKey)
+ foreignKey.foreignColumns.add(foreignColumn.name);
+ }
+ }
+
+ // read-in index definitions
+ NodeList indexDescList = clsDescElem.getElementsByTagName("index-descriptor");
+ for(int i = 0; i < indexDescList.getLength(); i++)
+ {
+ Element indexDescElem = (Element) indexDescList.item(i);
+ String name = indexDescElem.getAttribute("name");
+ String unique = indexDescElem.getAttribute("unique");
+ Index index = new Index();
+ table.indexes.add(index);
+ index.name = name;
+ if(unique != null && unique.equals("true"))
+ index.isUnique = true;
+
+ NodeList indexColumnList = indexDescElem.getElementsByTagName("index-column");
+ for(int j = 0; j < indexColumnList.getLength(); j++)
+ {
+ Element indexColumnElem = (Element) indexColumnList.item(j);
+ String indexColumnName = indexColumnElem.getAttribute("name");
+ index.columns.add(indexColumnName);
+ }
+ }
+
+ return table;
+ }
+
+ /*
+ * Returns set of all table names.
+ */
+ private Set allTables(Document doc)
+ {
+ Set tableNames = new HashSet();
+ NodeList clsDescList = doc.getElementsByTagName("class-descriptor");
+ for(int i = 0; i < clsDescList.getLength(); i++)
+ {
+ Element clsDescElem = (Element) clsDescList.item(i);
+ String tableName = clsDescElem.getAttribute("table");
+ tableNames.add(tableName);
+ }
+ return tableNames;
+ }
+
+ /*
+ * Returns set of names of tables mapped to multiple classes.
+ */
+ private Set duplicateTables(Document doc)
+ {
+ Set workingSet = new HashSet();
+ Set duplicateSet = new HashSet();
+
+ NodeList clsDescList = doc.getElementsByTagName("class-descriptor");
+ for(int i = 0; i < clsDescList.getLength(); i++)
+ {
+ Element clsDescElem = (Element) clsDescList.item(i);
+ String tableName = clsDescElem.getAttribute("table");
+ if(workingSet.contains(tableName))
+ duplicateSet.add(tableName);
+ else
+ workingSet.add(tableName);
+ }
+ return duplicateSet;
+ }
+
+ /*
+ * Merge the src table into the target.
+ */
+ private void mergeTables(Table target, Table src)
+ {
+ // merge columns
+ for(int i = 0; i < src.columns.size(); i++)
+ {
+ Column srcColumn = (Column) src.columns.get(i);
+ if(!target.columns.contains(srcColumn))
+ {
+ target.columns.add(srcColumn);
+ }
+ }
+
+ // merge foreign keys
+ for(int i = 0; i < src.foreignKeys.size(); i++)
+ {
+ ForeignKey srcForeignKey = (ForeignKey) src.foreignKeys.get(i);
+ if(!target.foreignKeys.contains(srcForeignKey))
+ {
+ target.foreignKeys.add(srcForeignKey);
+ }
+ }
+
+ // merge indexes.
+ for(int i = 0; i < src.indexes.size(); i++)
+ {
+ Index srcIndex = (Index) src.indexes.get(i);
+ if(!target.indexes.contains(srcIndex))
+ {
+ target.indexes.add(srcIndex);
+ }
+ }
+ }
+
+ /** Generate the Torque format SQL schema definitions. */
+ public void generateSQL() throws Exception
+ {
+ Set allTables = allTables(doc);
+ Set duplicateTables = duplicateTables(doc);
+
+ NodeList clsDescList = doc.getElementsByTagName("class-descriptor");
+
+ File out = new File(torqueOutputDirectory);
+ out.mkdirs();
+ FileWriter fwr = new FileWriter(new File(torqueOutputDirectory, torqueXmlFile));
+ fwr.write(TorqueSchemaGenerator.torquePrefix());
+
+ for(int i = 0; i < clsDescList.getLength(); i++)
+ {
+ Element clsDescElem = (Element) clsDescList.item(i);
+ Table currentTable = getTableInfo(clsDescElem);
+ String tableName = currentTable.name;
+ if(StringUtils.isNotBlank(tableName))
+ {
+ try
+ {
+ /*
+ * If table has multiple class mappings, keep the table structure in the deferred
+ * list and keep merging later definitions we encounter.
+ */
+ if(duplicateTables.contains(tableName))
+ {
+ Table existingTable = (Table) deferredTables.get(tableName);
+ if(existingTable == null)
+ deferredTables.put(tableName, currentTable);
+ else
+ mergeTables(existingTable, currentTable);
+ }
+ else
+ {
+ String tableStr = TorqueSchemaGenerator.generateTorqueSchema(currentTable);
+ fwr.write(tableStr);
+ }
+
+ // Auto generate table definition for indirection tables if any.
+ NodeList colDescList = clsDescElem.getElementsByTagName("collection-descriptor");
+
+ for(int j = 0; j < colDescList.getLength(); j++)
+ {
+ Element colDescElem = (Element) colDescList.item(j);
+ String indirectionTableName = colDescElem.getAttribute("indirection-table");
+
+ if(indirectionTableName != null && indirectionTableName.trim().length() > 0)
+ {
+ Table indirectionTable = (Table) indirectionTables.get(indirectionTableName);
+
+ if(indirectionTable == null)
+ {
+ indirectionTable = new Table();
+ indirectionTable.name = indirectionTableName;
+
+ indirectionTables.put(indirectionTableName, indirectionTable);
+ }
+
+ // Generate one foreign key constraint for the current table.
+ ForeignKey foreignKey = new ForeignKey();
+
+ indirectionTable.foreignKeys.add(foreignKey);
+
+ foreignKey.foreignTable = currentTable.name;
+
+ NodeList fkSelfList = colDescElem.getElementsByTagName("fk-pointing-to-this-class");
+ for(int k = 0; k < fkSelfList.getLength(); k++)
+ {
+ Element fkSelfElem = (Element) fkSelfList.item(k);
+ String columnName = fkSelfElem.getAttribute("column");
+
+ Column column = new Column();
+ indirectionTable.columns.add(column);
+
+ column.name = columnName;
+ foreignKey.localColumns.add(columnName);
+
+ /*
+ * Foreign keys pointing to current table in the <collection-descriptor>
+ * element should match primary keys of current table in the same sequence.
+ * Match attributes for indirection columns with corresponding primary key columns.
+ */
+ String foreignColumnName = null;
+ String foreignColumnType = null;
+ String foreignColumnLength = null;
+
+ int primaryKeyCounter = 0;
+ for(int q = 0; q < currentTable.columns.size(); q++)
+ {
+ Column currentTableColumn = (Column) currentTable.columns.get(q);
+ if(currentTableColumn.isPrimaryKey)
+ {
+ if(primaryKeyCounter == k)
+ {
+ foreignColumnName = currentTableColumn.name;
+ foreignColumnType = currentTableColumn.jdbcType;
+ foreignColumnLength = currentTableColumn.length;
+ break;
+ }
+ else
+ primaryKeyCounter++;
+ }
+ }
+
+ column.jdbcType = foreignColumnType;
+ column.length = foreignColumnLength;
+ foreignKey.foreignColumns.add(foreignColumnName);
+
+ // All indirection columns become part of primary key for indirection table.
+ column.isPrimaryKey = true;
+ column.isNullable = false;
+ }
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ throw new ForwardException("Error while performing table: " + currentTable, e);
+ }
+ }
+ }
+
+ // Generate deferred tables at the end.
+
+ Set defKeySet = deferredTables.keySet();
+ Iterator defKeysItr = defKeySet.iterator();
+ while(defKeysItr.hasNext())
+ {
+ String tableName = (String) defKeysItr.next();
+ Table defferedTable = (Table) deferredTables.get(tableName);
+
+ String tableStr = TorqueSchemaGenerator.generateTorqueSchema(defferedTable);
+ fwr.write(tableStr);
+ }
+
+ /*
+ * Generate tables for indirection tables at the end. Table structure for an
+ * indirection table gets filled up after processing both of the association tables.
+ */
+
+ Set indKeySet = indirectionTables.keySet();
+ Iterator indKeysItr = indKeySet.iterator();
+ while(indKeysItr.hasNext())
+ {
+ String tableName = (String) indKeysItr.next();
+
+ /*
+ * Sometimes there can be explicit mappings for indirection tables. In such cases
+ * skip the auto generation of indirection table.
+ */
+ if(allTables.contains(tableName))
+ continue;
+
+ Table indirectionTable = (Table) indirectionTables.get(tableName);
+
+ String tableStr = TorqueSchemaGenerator.generateTorqueSchema(indirectionTable);
+ fwr.write(tableStr);
+ }
+
+ fwr.write(TorqueSchemaGenerator.torqueSuffix());
+ fwr.close();
+ }
+
+ /** Generate the source for Java beans mapped to tables. */
+ public void generateJavaCode() throws Exception
+ {
+ NodeList clsDescList = doc.getElementsByTagName("class-descriptor");
+ for(int i = 0; i < clsDescList.getLength(); i++)
+ {
+ Element clsDescElem = (Element) clsDescList.item(i);
+
+ String clsName = clsDescElem.getAttribute("class");
+
+ String packageName = null;
+ String className;
+ int indexDot = clsName.lastIndexOf(".");
+ if(indexDot == -1)
+ className = clsName;
+ else
+ {
+ packageName = clsName.substring(0, indexDot);
+ className = clsName.substring(indexDot + 1);
+ }
+
+ String baseClass = null;
+ ArrayList attributes = new ArrayList();
+ ArrayList types = new ArrayList();
+
+ NodeList refDescList = clsDescElem.getElementsByTagName("reference-descriptor");
+ for(int j = 0; j < refDescList.getLength(); j++)
+ {
+ Element refDescElem = (Element) refDescList.item(j);
+
+ String fieldName = refDescElem.getAttribute("name");
+ String classRef = refDescElem.getAttribute("class-ref");
+
+ // handle super references
+ if(fieldName.equals("super"))
+ {
+ baseClass = classRef;
+ }
+ else
+ {
+ attributes.add(fieldName);
+ types.add(classRef);
+ }
+ }
+
+ NodeList fldDescList = clsDescElem.getElementsByTagName("field-descriptor");
+ for(int j = 0; j < fldDescList.getLength(); j++)
+ {
+ Element fldDescElem = (Element) fldDescList.item(j);
+
+ String fieldName = fldDescElem.getAttribute("name");
+ String jdbcType = fldDescElem.getAttribute("jdbc-type");
+ String primaryKey = fldDescElem.getAttribute("primarykey");
+ boolean isPrimaryKey = primaryKey != null && primaryKey.equals("true");
+ String type = (String) typeMap.get(jdbcType);
+
+ /*
+ * If baseClass is set using the 'super' reference then primary key
+ * fields are being repeated only for join purpose.
+ */
+ if(baseClass == null || !isPrimaryKey)
+ {
+ attributes.add(fieldName);
+ types.add(type);
+ }
+ }
+
+ NodeList colDescList = clsDescElem.getElementsByTagName("collection-descriptor");
+ for(int j = 0; j < colDescList.getLength(); j++)
+ {
+ Element colDescElem = (Element) colDescList.item(j);
+
+ String fieldName = colDescElem.getAttribute("name");
+ String type = "java.util.List";
+
+ attributes.add(fieldName);
+ types.add(type);
+ }
+
+ BeanDescriptor descriptor = new BeanDescriptor(packageName, className, baseClass, null,
+ attributes, types);
+ BeanGenerator generator = new BeanGenerator(beanOutputDirectory);
+ generator.generate(descriptor);
+ }
+ }
+
+ Element findClass(Document doc, String name)
+ {
+ NodeList clsDescList = doc.getElementsByTagName("class-descriptor");
+ for(int j = 0; j < clsDescList.getLength(); j++)
+ {
+ Element elem = (Element) clsDescList.item(j);
+ String clsName = elem.getAttribute("class");
+ if(clsName != null && clsName.equals(name))
+ {
+ return elem;
+ }
+ }
+ return null;
+ }
+
+ Element findFirstMappedClass(Document doc, String name)
+ {
+ Element result = findClass(doc, name);
+ String tablename = result.getAttribute("table");
+ if(StringUtils.isEmpty(tablename))
+ {
+ String[] subClasses = findDeclaredExtendClasses(result);
+ for(int i = 0; i < subClasses.length; i++)
+ {
+ String className = subClasses[i];
+ result = findFirstMappedClass(doc, className);
+ }
+ }
+ return result;
+ }
+
+ String[] findDeclaredExtendClasses(Element classNode)
+ {
+ List result = new ArrayList();
+ NodeList list = classNode.getElementsByTagName("extent-class");
+ for(int i = 0; i < list.getLength(); i++)
+ {
+ Element e = (Element) list.item(i);
+ String refClass = e.getAttribute("class-ref");
+ if(refClass != null)
+ {
+ result.add(refClass);
+ }
+ }
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ class ForwardException extends RuntimeException
+ {
+ public ForwardException()
+ {
+ }
+
+ public ForwardException(String message)
+ {
+ super(message);
+ }
+
+ public ForwardException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public ForwardException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+ }
+
+ public static void main(String [] args) throws Exception
+ {
+ RepositoryXmlProcessor processor = new RepositoryXmlProcessor
+ ("repository.xml", "target/test", "target/test");
+// RepositoryXmlProcessor processor = new RepositoryXmlProcessor
+// ("repository.xml", "target/test", "target/test");
+ processor.generateSQL();
+ processor.generateJavaCode();
+ }
+}
\ No newline at end of file
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/SQLStructures.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/SQLStructures.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/SQLStructures.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/SQLStructures.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,154 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+/*
+ * Classes for representing SQL schema structures. The representation maps to OJB's
+ * repository.xml format whereever there is a mismatch between OJB format and the Torque
+ * format. For example in repository.xml, uniqueness of columns can be represented only
+ * by using a 'unique' attribute of the index descriptor, whereas in the Torque schema
+ * these are seperate aspects. The transformation will be handled in the TorqueSchemaGenerator.
+ */
+
+/**
+ * Structure representing a Table.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+class Table
+{
+ String name;
+
+ ArrayList columns = new ArrayList();
+ ArrayList foreignKeys = new ArrayList();
+ ArrayList indexes = new ArrayList();
+
+ public boolean equals(Object o)
+ {
+ if(o == null || !(o instanceof Table))
+ return false;
+
+ Table other = (Table) o;
+ return other.name != null && other.name.equals(name);
+ }
+
+ public String toString()
+ {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
+
+/**
+ * Structure representing a column.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+class Column
+{
+ String name;
+
+ boolean isPrimaryKey;
+ boolean isNullable = true; // OJB default.
+ boolean isAutoIncriment;
+
+ String jdbcType;
+ String length;
+
+ public boolean equals(Object o)
+ {
+ if(o == null || !(o instanceof Column))
+ return false;
+
+ Column other = (Column) o;
+ return other.name != null && other.name.equals(name);
+ }
+
+ public String toString()
+ {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
+
+/**
+ * Structure representing a foreign key.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+class ForeignKey
+{
+ String foreignTable;
+ ArrayList localColumns = new ArrayList();
+ ArrayList foreignColumns = new ArrayList();
+
+ public boolean equals(Object o)
+ {
+ if(o == null || !(o instanceof ForeignKey))
+ return false;
+
+ ForeignKey other = (ForeignKey) o;
+
+ if(foreignTable.equals(other.foreignTable))
+ {
+ if(Utils.compareLists(localColumns, other.localColumns))
+ return Utils.compareLists(foreignColumns, other.foreignColumns);
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+
+ public String toString()
+ {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
+
+/**
+ * Structure representing an index.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+class Index
+{
+ String name;
+ boolean isUnique;
+ ArrayList columns = new ArrayList();
+
+ public boolean equals(Object o)
+ {
+ if(o == null || !(o instanceof Index))
+ return false;
+
+ Index other = (Index) o;
+
+ return Utils.compareLists(columns, other.columns);
+ }
+
+ public String toString()
+ {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/TorqueSchemaGenerator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/TorqueSchemaGenerator.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/TorqueSchemaGenerator.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/TorqueSchemaGenerator.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,207 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Generator for Torque format database schema definitions.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+public class TorqueSchemaGenerator
+{
+ private static String SPACE = " ";
+ private static String TAB = "\t";
+ private static String NEWLINE = System.getProperty("line.separator");
+
+ /**
+ * The prefix string for Torque xml.
+ *
+ * @return the prefix string
+ */
+ public static String torquePrefix()
+ {
+ StringBuffer buf = new StringBuffer(150);
+
+ buf.append("<?xml version=\"1.0\"?>");
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append("<!DOCTYPE database SYSTEM \"http://db.apache.org/torque/dtd/database.dtd\">");
+ buf.append(whitespace(NEWLINE, 2));
+ buf.append("<database name=\"ojb-auto-gen\">");
+
+ return buf.toString();
+ }
+
+ /**
+ * The suffix string for Torque xml.
+ *
+ * @return the suffix string
+ */
+ public static String torqueSuffix()
+ {
+ return whitespace(NEWLINE, 2) + "</database>";
+ }
+
+ private static String whitespace(String ch, int num)
+ {
+ String str = "";
+ for(int i = 0; i < num; i++)
+ str += ch;
+ return str;
+ }
+
+ /*
+ * Generate the <table> xml block corresponding to the Table structure.
+ *
+ * @param table the Table structure
+ * @return the Torque xml table definition.
+ */
+ public static String generateTorqueSchema(Table table)
+ {
+ StringBuffer buf = new StringBuffer(100);
+
+ buf.append(whitespace(NEWLINE, 2));
+ buf.append(whitespace(TAB, 1));
+
+ buf.append("<table name=\"").append(table.name).append("\">");
+
+ // generate column definitions.
+ for(int i = 0; i < table.columns.size(); i++)
+ {
+ Column column = (Column) table.columns.get(i);
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+
+ buf.append("<column ");
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("name=\"").append(column.name).append("\"");
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("type=\"").append(column.jdbcType).append("\"");
+
+ if(column.length != null && column.length.trim().length() > 0)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("size=\"").append(column.length).append("\"");
+ }
+ if(column.isPrimaryKey)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("primaryKey=\"true\"");
+ }
+ if(!column.isNullable)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("required=\"true\"");
+ }
+ if(column.isAutoIncriment)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append(whitespace(SPACE, 3));
+ buf.append("autoIncrement=\"true\"");
+ }
+
+ buf.append("/>");
+ }
+
+ // generate foreign key definitions.
+ for(int i = 0; i < table.foreignKeys.size(); i++)
+ {
+ ForeignKey foreignKey = (ForeignKey) table.foreignKeys.get(i);
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("<foreign-key foreignTable=\"").append(foreignKey.foreignTable).append("\">");
+
+ for(int j = 0; j < foreignKey.localColumns.size(); j++)
+ {
+ String localColumn = (String) foreignKey.localColumns.get(j);
+ String foreignColumn = (String) foreignKey.foreignColumns.get(j);
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 3));
+ buf.append("<reference local=\"")
+ .append(localColumn).append("\" foreign=\"").append(foreignColumn).append("\"/>");
+ }
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("</foreign-key>");
+ }
+
+ // generate index definitions.
+ for(int i = 0; i < table.indexes.size(); i++)
+ {
+ Index index = (Index) table.indexes.get(i);
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("<index name=\"").append(index.name).append("\">");
+
+ for(int j = 0; j < index.columns.size(); j++)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 3));
+ buf.append("<index-column name=\"").append(index.columns.get(j)).append("\"/>");
+ }
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("</index>");
+ }
+
+ // generate unique constraint definitions.
+ for(int i = 0; i < table.indexes.size(); i++)
+ {
+ Index index = (Index) table.indexes.get(i);
+
+ if(index.isUnique)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("<unique>");
+ for(int j = 0; j < index.columns.size(); j++)
+ {
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 3));
+ buf.append("<unique-column name=\"").append(index.columns.get(j)).append("\"/>");
+ }
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 2));
+ buf.append("</unique>");
+ }
+ }
+
+ buf.append(whitespace(NEWLINE, 1));
+ buf.append(whitespace(TAB, 1));
+ buf.append("</table>");
+
+ return buf.toString();
+ }
+}
\ No newline at end of file
Added: db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/Utils.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/Utils.java?rev=424221&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/Utils.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/tools/org/apache/ojb/tools/mapping/forward/Utils.java Fri Jul 21 00:55:21 2006
@@ -0,0 +1,62 @@
+package org.apache.ojb.tools.mapping.forward;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.List;
+
+/**
+ * Utility functions.
+ *
+ * @author Tom Antony
+ * @version 1.0, 03-MAY-2006.
+ */
+public class Utils
+{
+ /*
+ * Compare two lists in an order independent manner.
+ *
+ * Note : the contains() method of the Collections interface will use the equals() method
+ * of Object class to determine equalness. So elements in source and target should have
+ * equals() method properly defined.
+ *
+ * @param src the source list
+ * @param target the target list
+ * @return true if lists contain the same set of elements, else false.
+ */
+ public static boolean compareLists(List src, List target)
+ {
+ if(src == null && target == null) return true;
+ if((src != null && target == null) || (src == null && target != null)) return false;
+ if(src.size() != target.size()) return false;
+
+ // Each item in source should be present in target.
+ for(int k = 0; k < src.size(); k++)
+ {
+ Object item = src.get(k);
+ if(!target.contains(item)) return false;
+ }
+
+ // Each item in target should be present in source.
+ for(int k = 0; k < target.size(); k++)
+ {
+ Object item = target.get(k);
+ if(!src.contains(item)) return false;
+ }
+
+ return true;
+ }
+
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org