Author: jgbutler Date: Tue Mar 11 10:20:37 2008 New Revision: 636016 URL: http://svn.apache.org/viewvc?rev=636016&view=rev Log: Abator: enhancement so that Abator will not override members in a rootClass if there is an exact match
Added: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/ClassloaderUtility.java Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/build.xml ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/javaModelGenerator.html ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/table.html ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/PropertyRegistry.java ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/db/ConnectionFactory.java ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/abatorConfig.xml ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/execute/miscellaneous/BaseClass.java Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/build.xml URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/build.xml?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/build.xml (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/build.xml Tue Mar 11 10:20:37 2008 @@ -41,8 +41,8 @@ <property name="reports.junit" value="${reports.dir}/junit" /> <target name="clean" unless="${TSTAMP}"> - <tstamp/> - <available classname="java.lang.annotation.Annotation" property="usingJava5"/> + <tstamp/> + <available classname="java.lang.annotation.Annotation" property="usingJava5"/> <delete dir="${work.dir}" /> <delete dir="${deploy.dir}" /> <delete dir="${reports.dir}" /> @@ -204,8 +204,6 @@ </target> <target name="test.generate.test.code.java5" depends="test.prepare" if="usingJava5"> - <echo message="Expect three warnings from Abator (BLOBSONLY, NonExistantTable, FRED)" /> - <!-- note that the class does not exist until the build runs. Validating Ant editors will complain that the task cannot be found, but it's not really an error. --> @@ -215,20 +213,33 @@ <pathelement location="${deploy.files}/abator.jar"/> </classpath> </taskdef> + + <!-- compile the base class so Abator can load it --> + <javac destdir="${generated.bin.dir.java5}" + deprecation="true" + debug="true" + source="1.5" + target="1.5"> + <src path="${basedir}/../testJava5"/> + <include name="abatortest/execute/miscellaneous/BaseClass.java" /> + </javac> - <abator configfile="${basedir}/../testJava5/abatortest/abatorConfig.xml" > - <propertyset> - <propertyref name="generated.source.dir.java5"/> - </propertyset> - </abator> + <echo message="Expect three warnings from Abator (BLOBSONLY, NonExistantTable, FRED)" /> + + <abator configfile="${basedir}/../testJava5/abatortest/abatorConfig.xml" > + <propertyset> + <propertyref name="generated.source.dir.java5"/> + <propertyref name="generated.bin.dir.java5"/> + </propertyset> + </abator> </target> <target name="test.compile.test.code.java2" depends="test.generate.test.code.java2"> <javac destdir="${generated.bin.dir.java2}" - deprecation="true" - debug="true" - source="1.4" - target="1.4"> + deprecation="true" + debug="true" + source="1.4" + target="1.4"> <src path="${generated.source.dir.java2}"/> <src path="${basedir}/../testJava2"/> </javac> Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties Tue Mar 11 10:20:37 2008 @@ -1,4 +1,4 @@ #Abator build version info -#Mon Feb 25 15:55:41 CST 2008 +#Tue Mar 11 11:44:54 CDT 2008 version=1.1.0 -buildNum=413 +buildNum=421 Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt Tue Mar 11 10:20:37 2008 @@ -47,6 +47,8 @@ 20. Allowed specifying a type (pre or post) for the generatedKey element. 21. Added a comment generator interface +22. Abator will not generate model properties that would override + properties in a rootClass. ------------------------------------------------------------------------------- Version 1.0.0: Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/javaModelGenerator.html URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/javaModelGenerator.html?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/javaModelGenerator.html (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/javaModelGenerator.html Tue Mar 11 10:20:37 2008 @@ -103,11 +103,31 @@ of the primary key object, if the table has a primary key, or the record object otherwise. This value may be overridden by specifying the <code>rootClass</code> property on a Table configuration. - <p><b>Important:</b> Abator does not verify that the class exists, or is a - valid Java class. The generated classes may override elements in this - class without warning.</p> + <p><b>Important:</b> If Abator is able to load the root class, Abator + will not override a property in the root class that exactly matches a + property that Abator would normally generate. + An exact match of a property is defined as follows</p> + <ul> + <li>Property name matches exactly</li> + <li>Property is of the same type</li> + <li>Property has a "getter" method</li> + <li>Property has a "setter" method</li> + </ul> + <p>You may use the "rootClasspath" property + to add entries to the rootClass lookup classpath if necessary.</p> <p>If specified, the value of this property should be a fully qualified class name (like com.mycompany.MyRootClass).</p></td> + </tr> + <tr> + <td valign="top">rootClasspath</td> + <td>This property can be used to specify a class path for the "rootClass" + specified here for or on the <table> element. Abator will check + in the rootClass and will not generate a property if the property exists + in the rootClass. If not specified, Abator will attempt to load the rootClass + through the current thread context classloader. + <p>This property is a semi-colon (;) delimited string + of classpath entries.</p> + </td> </tr> <tr> <td valign="top">trimStrings</td> Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/table.html URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/table.html?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/table.html (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/configreference/table.html Tue Mar 11 10:20:37 2008 @@ -294,9 +294,19 @@ record object otherwise. The value specified in this property will override the <code>rootClass</code> property set on the Java Model Generator configuration if any is set. - <p><b>Important:</b> Abator does not verify that the class exists, or is a - valid Java class. The generated classes may override elements in this - class without warning.</p> + <p><b>Important:</b> If Abator is able to load the root class, Abator + will not override a property in the root class that exactly matches a + property that Abator would normally generate. + An exact match of a property is defined as follows</p> + <ul> + <li>Property name matches exactly</li> + <li>Property is of the same type</li> + <li>Property has a "getter" method</li> + <li>Property has a "setter" method</li> + </ul> + <p>You may use the "rootClasspath" property of the + <a href="javaModelGenerator.html"><javaModelGenerator></a> + element to add entries to the rootClass lookup classpath if necessary.</p> <p>If specified, the value of this property should be a fully qualified class name (like com.mycompany.MyRootClass).</p></td> </tr> Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html Tue Mar 11 10:20:37 2008 @@ -90,14 +90,14 @@ about how to extend these classes. See the <a href="generatedobjects/extendingExampleClass.html">Extending the Example Classes</a> reference page for more information.</li> - <li>Made the legacy DAOs extendable</li> + <li>Made the legacy DAOs extendable.</li> <li>Added the ability to provide a renaming rule for columns. This is for the use case where columns have a common prefix that should be removed before calculating the property name. See the <a href="configreference/columnRenamingRule.html"><columnRenamingRule></a> - reference page for more information</li> + reference page for more information.</li> <li>Added support for persisting a configuration to XML - this to enable - a graphical editor in the future</li> + a graphical editor in the future.</li> <li>Add afterXXXGenerationHook() methods in all generators to enable adding extra Java code or XML elements to any generated object. This will make it easier to create customized generators.</li> @@ -112,9 +112,15 @@ <li><code>rootClass</code> and <code>rootInterface</code> may now be specified for each table. See the <a href="configreference/table.html"><table></a> reference page for more information.</li> + <li>If a <code>rootClass</code> is specified for any table, Abator will now check in the + rootClass to see if a generated property already exists in the root class. If it does, + Abator will not generate the property. The <javaModelGenerator> element now + accepts a property to specify the classpath of the <code>rootClass</code>. See the + <a href="configreference/javaModelGenerator.html"><javaModelGenerator></a> + reference page for more information.</li> <li>Allowed specifying a type (pre or post) for the generated key element. See the <a href="configreference/generatedKey.html"><generatedKey></a> - reference page for more information</li> + reference page for more information.</li> <li>Added a comment generator interface to enable generation of custom comments. See the <a href="configreference/commentGenerator.html"><commentGenerator></a> reference page for more information.</li> Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/PropertyRegistry.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/PropertyRegistry.java?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/PropertyRegistry.java (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/PropertyRegistry.java Tue Mar 11 10:20:37 2008 @@ -53,6 +53,7 @@ public static final String TYPE_RESOLVER_FORCE_BIG_DECIMALS = "forceBigDecimals"; //$NON-NLS-1$ public static final String MODEL_GENERATOR_TRIM_STRINGS = "trimStrings"; //$NON-NLS-1$ + public static final String MODEL_GENERATOR_ROOT_CLASSPATH = "rootClasspath"; //$NON-NLS-1$ public static final String COMMENT_GENERATOR_SUPPRESS_DATE = "suppressDate"; //$NON-NLS-1$ } Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/db/ConnectionFactory.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/db/ConnectionFactory.java?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/db/ConnectionFactory.java (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/db/ConnectionFactory.java Tue Mar 11 10:20:37 2008 @@ -15,20 +15,15 @@ */ package org.apache.ibatis.abator.internal.db; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.sql.Connection; import java.sql.Driver; import java.sql.SQLException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.Properties; import org.apache.ibatis.abator.config.JDBCConnectionConfiguration; +import org.apache.ibatis.abator.internal.util.ClassloaderUtility; import org.apache.ibatis.abator.internal.util.StringUtility; import org.apache.ibatis.abator.internal.util.messages.Messages; @@ -85,11 +80,13 @@ JDBCConnectionConfiguration connectionInformation) { String driverClass = connectionInformation.getDriverClass(); Driver driver = (Driver) drivers.get(driverClass); - + if (driver == null) { + ClassLoader classLoader = + ClassloaderUtility.getCustomClassloader(connectionInformation); + try { - Class clazz = getCustomClassloader(connectionInformation) - .loadClass(driverClass); + Class clazz = classLoader.loadClass(driverClass); driver = (Driver) clazz.newInstance(); drivers.put(driverClass, driver); } catch (Exception e) { @@ -99,35 +96,5 @@ } return driver; - } - - private ClassLoader getCustomClassloader( - JDBCConnectionConfiguration connectionInformation) { - ArrayList urls = new ArrayList(); - File file; - - Iterator iter = connectionInformation.getClassPathEntries().iterator(); - while (iter.hasNext()) { - String classPathEntry = (String) iter.next(); - file = new File(classPathEntry); - if (!file.exists()) { - throw new RuntimeException( - Messages.getString("RuntimeError.9", classPathEntry)); //$NON-NLS-1$ - } - - try { - urls.add(file.toURL()); - } catch (MalformedURLException e) { - // this shouldn't happen, but just in case... - throw new RuntimeException( - Messages.getString("RuntimeError.9", classPathEntry)); //$NON-NLS-1$ - } - } - - ClassLoader parent = Thread.currentThread().getContextClassLoader(); - URLClassLoader ucl = new URLClassLoader((URL[]) urls - .toArray(new URL[urls.size()]), parent); - - return ucl; } } Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java Tue Mar 11 10:20:37 2008 @@ -15,6 +15,10 @@ */ package org.apache.ibatis.abator.internal.java.model; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -40,6 +44,7 @@ import org.apache.ibatis.abator.config.PropertyRegistry; import org.apache.ibatis.abator.internal.db.ColumnDefinition; import org.apache.ibatis.abator.internal.rules.AbatorRules; +import org.apache.ibatis.abator.internal.util.ClassloaderUtility; import org.apache.ibatis.abator.internal.util.JavaBeansUtil; import org.apache.ibatis.abator.internal.util.StringUtility; import org.apache.ibatis.abator.internal.util.messages.Messages; @@ -93,10 +98,15 @@ private Map tableValueMaps; + private Map propertyDescriptorMap; + + private ClassLoader rootClassLoader; + public JavaModelGeneratorJava2Impl() { super(); tableValueMaps = new HashMap(); properties = new Properties(); + propertyDescriptorMap = new HashMap(); } public void addConfigurationProperties(Properties properties) { @@ -137,7 +147,8 @@ * the generated fields and methods will be added to this object */ protected void generateClassParts(FullyQualifiedTable table, - Iterator columnDefinitions, TopLevelClass topLevelClass) { + Iterator columnDefinitions, TopLevelClass topLevelClass, + String rootClass) { boolean trimStrings = "true".equalsIgnoreCase(properties //$NON-NLS-1$ .getProperty(PropertyRegistry.MODEL_GENERATOR_TRIM_STRINGS)); @@ -150,6 +161,10 @@ while (columnDefinitions.hasNext()) { ColumnDefinition cd = (ColumnDefinition) columnDefinitions.next(); + if (propertyExistsInRootClass(cd, rootClass)) { + continue; + } + FullyQualifiedJavaType fqjt = cd.getResolvedJavaType() .getFullyQualifiedJavaType(); @@ -250,7 +265,8 @@ answer.addImportedType(answer.getSuperClass()); } - generateClassParts(table, introspectedTable.getPrimaryKeyColumns(), answer); + generateClassParts(table, introspectedTable.getPrimaryKeyColumns(), answer, + getRootClass(introspectedTable)); return answer; } @@ -279,14 +295,17 @@ if (!introspectedTable.getRules().generatePrimaryKeyClass() && introspectedTable.hasPrimaryKeyColumns()) { - generateClassParts(table, introspectedTable.getPrimaryKeyColumns(), answer); + generateClassParts(table, introspectedTable.getPrimaryKeyColumns(), answer, + getRootClass(introspectedTable)); } - generateClassParts(table, introspectedTable.getBaseColumns(), answer); + generateClassParts(table, introspectedTable.getBaseColumns(), answer, + getRootClass(introspectedTable)); if (!introspectedTable.getRules().generateRecordWithBLOBsClass() && introspectedTable.hasBLOBColumns()) { - generateClassParts(table, introspectedTable.getBLOBColumns(), answer); + generateClassParts(table, introspectedTable.getBLOBColumns(), answer, + getRootClass(introspectedTable)); } return answer; @@ -310,7 +329,8 @@ answer.setSuperClass(getPrimaryKeyType(table)); } - generateClassParts(table, introspectedTable.getBLOBColumns(), answer); + generateClassParts(table, introspectedTable.getBLOBColumns(), answer, + getRootClass(introspectedTable)); return answer; } @@ -1493,5 +1513,110 @@ } return rootClass; + } + + // Ashok's enhancement for checking parent classes... + protected Class loadRootClass(IntrospectedTable introspectedTable) { + Class clazz = null; + + String rootClass = getRootClass(introspectedTable); + + if (rootClass != null) { + try { + clazz = Class.forName(rootClass); + } catch (Exception e) { + warnings.add(Messages.getString("Warning.20", rootClass)); //$NON-NLS-1$ + } + } + + return clazz; + } + + protected PropertyDescriptor[] getRootClassPropertyDescriptors(String rootClass) { + if (rootClass == null) { + return null; + } + + if (propertyDescriptorMap.containsKey(rootClass)) { + return (PropertyDescriptor[]) propertyDescriptorMap.get(rootClass); + } + + // new class not in map already + + Class clazz = null; + try { + clazz = getRootclassloader().loadClass(rootClass); + } catch (Exception e) { + propertyDescriptorMap.put(rootClass, null); + warnings.add(Messages.getString("Warning.20", rootClass)); //$NON-NLS-1$ + return null; + } + + BeanInfo bi; + try { + bi = Introspector.getBeanInfo(clazz); + } catch (IntrospectionException e) { + propertyDescriptorMap.put(rootClass, null); + warnings.add(Messages.getString("Warning.20", rootClass)); //$NON-NLS-1$ + return null; + } + + PropertyDescriptor[] pd = bi.getPropertyDescriptors(); + propertyDescriptorMap.put(rootClass, pd); + return pd; + } + + protected boolean propertyExistsInRootClass(ColumnDefinition columnDefinition, String rootClass) { + PropertyDescriptor[] rootClassProperties = getRootClassPropertyDescriptors(rootClass); + if (rootClassProperties == null) { + return false; + } + + boolean found = false; + String propertyName = columnDefinition.getJavaProperty(); + String propertyType = columnDefinition.getResolvedJavaType().getFullyQualifiedJavaType().getFullyQualifiedName(); + + // get method names from class and check against this column definition. + // better yet, have a map of method Names. check against it. + for (int i = 0; i < rootClassProperties.length; i++) { + if (rootClassProperties[i].getName().equals(propertyName)) { + // property is in the rootClass... + + // Is it the proper type? + if (!rootClassProperties[i].getPropertyType().getName().equals(propertyType)) { + warnings.add(Messages.getString("Warning.21", + propertyName, rootClass, propertyType)); + break; + } + + // Does it have a getter? + if (rootClassProperties[i].getReadMethod() == null) { + warnings.add(Messages.getString("Warning.22", + propertyName, rootClass)); + break; + } + + // Does it have a setter? + if (rootClassProperties[i].getWriteMethod() == null) { + warnings.add(Messages.getString("Warning.23", + propertyName, rootClass)); + break; + } + + found = true; + break; + } + } + + return found; + } + + private ClassLoader getRootclassloader() { + if (rootClassLoader == null) { + rootClassLoader = ClassloaderUtility.getCustomClassloader( + properties.getProperty(PropertyRegistry.MODEL_GENERATOR_ROOT_CLASSPATH)); + } + + return rootClassLoader; } } Added: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/ClassloaderUtility.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/ClassloaderUtility.java?rev=636016&view=auto ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/ClassloaderUtility.java (added) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/ClassloaderUtility.java Tue Mar 11 10:20:37 2008 @@ -0,0 +1,102 @@ +/* + * Copyright 2008 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. + */ + +package org.apache.ibatis.abator.internal.util; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.ibatis.abator.config.JDBCConnectionConfiguration; +import org.apache.ibatis.abator.internal.util.messages.Messages; + +/** + * This class holds methods useful for constructing custom + * classloaders in Abator. + * + * @author Jeff Butler + * + */ +public class ClassloaderUtility { + + /** + * Utility Class - No Instances + */ + private ClassloaderUtility() { + } + + /** + * Builds a classloader and adds the specified entries to the + * classpath. + * + * @param entries a semicolon delimited string of class path entries + * @return + */ + public static ClassLoader getCustomClassloader(String entries) { + if (entries == null) { + return getCustomClassloader((List) null); + } + + List entryList = new ArrayList(); + StringTokenizer st = new StringTokenizer(entries, ";"); + while (st.hasMoreTokens()) { + entryList.add(st.nextToken()); + } + + return getCustomClassloader(entryList); + } + + public static ClassLoader getCustomClassloader( + JDBCConnectionConfiguration connectionInformation) { + return getCustomClassloader(connectionInformation.getClassPathEntries()); + } + + public static ClassLoader getCustomClassloader(List entries) { + ArrayList urls = new ArrayList(); + File file; + + if (entries != null) { + Iterator iter = entries.iterator(); + while (iter.hasNext()) { + String classPathEntry = (String) iter.next(); + file = new File(classPathEntry); + if (!file.exists()) { + throw new RuntimeException( + Messages.getString("RuntimeError.9", classPathEntry)); //$NON-NLS-1$ + } + + try { + urls.add(file.toURL()); + } catch (MalformedURLException e) { + // this shouldn't happen, but just in case... + throw new RuntimeException( + Messages.getString("RuntimeError.9", classPathEntry)); //$NON-NLS-1$ + } + } + } + + ClassLoader parent = Thread.currentThread().getContextClassLoader(); + URLClassLoader ucl = new URLClassLoader((URL[]) urls + .toArray(new URL[urls.size()]), parent); + + return ucl; + } +} Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties Tue Mar 11 10:20:37 2008 @@ -24,7 +24,7 @@ RuntimeError.6=Cannot instantiate object of type {0} RuntimeError.7=Cannot connect to database (possibly bad driver/URL combination) RuntimeError.8=Exception getting JDBC Driver -RuntimeError.9=Cannot resolve classpath entry {0} +RuntimeError.9=Cannot resolve classpath entry: {0} RuntimeError.11=Enumerations do not have super classes RuntimeError.12=Internal Error - Cannot calculate record type for selectByExample method RuntimeError.13=Invalid model type: {0} @@ -56,7 +56,11 @@ Warning.16=Invalid value for exampleMethodVisibility specified ({0}), defaulting to public Warning.17=Cannot instantiate DAO method name calculator of type {0}, using default calculator Warning.18=Table {0} contains only LOB fields, this table will be ignored -Warning.19=Table configuration with catalog {0}, schema {1}, and table {2} did not resolve to any tables +Warning.19=Table configuration with catalog {0}, schema {1}, and table {2} did not resolve to any tables +Warning.20=Root class {0} cannot be loaded, checking for member overrides is disabled for this class +Warning.21=Property {0} exists in root class {1}, but is not of type {2}. Abator will generate the property. +Warning.22=Property {0} exists in root class {1}, but does not have a getter. Abator will generate the property. +Warning.23=Property {0} exists in root class {1}, but does not have a setter. Abator will generate the property. Progress.0=Connecting to the Database Progress.1=Introspecting table {0} @@ -72,26 +76,25 @@ Progress.12=Generating SQL Map for table {0} Progress.13=Found SQL Statement: {0} -Usage.Lines=20 +Usage.Lines=19 Usage.0=Abator code generator for iBATIS. Usage: -Usage.1=\ java -jar abator.jar -configfile file_name -Usage.2=\ [-overwrite] -Usage.3=\ [-contextids ids] -Usage.4=\ [-tables tableName] -Usage.5= -Usage.6=Where: -Usage.7=\ -configfile: Specifies the name of the abator XML configuration file (required) -Usage.8= -Usage.9=\ -overwrite: If specified then exsting Java files will be overwritten. -Usage.10=\ If not specified, then Abator will not overwrite existing -Usage.11=\ Java files (will save results in uniqely named files) -Usage.12= -Usage.13=\ -contextids: Used to specify a comma delimited list of contexts to use in this -Usage.14=\ run of Abator. If not specified, all contexts will be used. -Usage.15= -Usage.16=\ -tables: Used to specify a comma delimited list of tables to use in this -Usage.17=\ run of Abator. If not specified, all tables will be used. Table -Usage.18=\ names must be fully qualified (e.g. schema.tablename). Table names -Usage.19=\ must exactly match the case specified in the configuration file. +Usage.1=\ java -jar abator.jar -configfile file_name [-overwrite] +Usage.2=\ [-contextids ids] [-tables tableName] +Usage.3= +Usage.4=Where: +Usage.5=\ -configfile: Specifies the the Abator XML configuration file (required) +Usage.6= +Usage.7=\ -overwrite: If specified then exsting Java files will be overwritten. +Usage.8=\ If not specified, then Abator will not overwrite existing +Usage.9=\ Java files (will save results in uniqely named files) +Usage.10= +Usage.11=\ -contextids: Used to specify a comma delimited list of contexts to use in +Usage.12=\ this run of Abator. If not specified, all contexts will be +Usage.13=\ used. +Usage.14= +Usage.15=\ -tables: Used to specify a comma delimited list of tables to use in this +Usage.16=\ run of Abator. If not specified, all tables will be used. Table +Usage.17=\ names must be fully qualified (e.g. schema.tablename). Table names +Usage.18=\ must exactly match the case specified in the configuration file. Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/abatorConfig.xml URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/abatorConfig.xml?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/abatorConfig.xml (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/abatorConfig.xml Tue Mar 11 10:20:37 2008 @@ -364,6 +364,7 @@ <javaModelGenerator targetPackage="abatortest.generated.miscellaneous.model" targetProject="${generated.source.dir.java5}"> <property name="trimStrings" value="true" /> <property name="rootClass" value="abatortest.execute.miscellaneous.BaseClass" /> + <property name="rootClasspath" value="${generated.bin.dir.java5}"/> </javaModelGenerator> <sqlMapGenerator targetPackage="abatortest.generated.miscellaneous.xml" targetProject="${generated.source.dir.java5}"> Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/execute/miscellaneous/BaseClass.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/execute/miscellaneous/BaseClass.java?rev=636016&r1=636015&r2=636016&view=diff ============================================================================== --- ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/execute/miscellaneous/BaseClass.java (original) +++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/testJava5/abatortest/execute/miscellaneous/BaseClass.java Tue Mar 11 10:20:37 2008 @@ -19,10 +19,24 @@ * @author Jeff Butler */ public class BaseClass { + private String lastname; + /** * */ public BaseClass() { super(); + } + + // these methods are final so that an error will be generated + // if the extended class tries to overwrite them. This + // will break the build as the generator should + // see a duplicate property. + public final String getLastname() { + return lastname; + } + + public final void setLastname(String lastname) { + this.lastname = lastname; } }