Update of /cvsroot/xdoclet/xdoclet/modules/jdo/src/xdoclet/modules/jdo In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2274/modules/jdo/src/xdoclet/modules/jdo
Modified Files: JdoXmlMetadataSubTask.java Added Files: JdoObjectIdGeneratorTagsHandler.java JdoObjectIdGeneratorSubTask.java Log Message: XDoclet finally supports the automatic creation of JDO objectid-classes! --- NEW FILE: JdoObjectIdGeneratorTagsHandler.java --- /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.modules.jdo; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Set; import org.apache.commons.logging.Log; import xjavadoc.XClass; import xjavadoc.XDoc; import xjavadoc.XField; import xdoclet.XDocletException; import xdoclet.XDocletTagSupport; import xdoclet.util.LogUtil; /** * @author Marco Schulze <[EMAIL PROTECTED]> * @created August 29, 2005 * @xdoclet.taghandler namespace="JdoObjectIdGenerator" */ public class JdoObjectIdGeneratorTagsHandler extends XDocletTagSupport { /** * This Comparator is used to sort the primary-key-fields by their name. */ protected static Comparator pkFieldComparator = new Comparator() { public int compare(Object obj0, Object obj1) { XField f0 = (XField) obj0; XField f1 = (XField) obj1; return f0.getName().compareTo(f1.getName()); } }; private static boolean lastPrimaryKeyField = false; private static XField currentPrimaryKeyField = null; /** * Used by [EMAIL PROTECTED] #isPrimitive(XClass)} to find out whether a class is primitive. Contains instances of [EMAIL PROTECTED] * java.lang.String} representing the primitive class names (e.g. "long"). */ private static Set primitiveClassNames = null; public static XField getCurrentPrimaryKeyField() { return currentPrimaryKeyField; } public static void setCurrentPrimaryKeyField(XField pkField) { currentPrimaryKeyField = pkField; } /** * For whatever reason, [EMAIL PROTECTED] XClass#isPrimitive()} doesn't work and always returns <tt>true</tt> . Hence, we check * it ourselves. This method returns true, if <tt>clazz</tt> is one of the following: * <ul> * <li> boolean</li> * <li> byte</li> * <li> char</li> * <li> double</li> * <li> float</li> * <li> int</li> * <li> long</li> * <li> short</li> * </ul> * * * @param clazz The XClass to check. * @return true, if the given clazz is primitive, false otherwise. */ protected static boolean isPrimitive(XClass clazz) { if (primitiveClassNames == null) { Set s = new HashSet(); s.add("boolean"); s.add("byte"); s.add("char"); s.add("double"); s.add("float"); s.add("int"); s.add("long"); s.add("short"); primitiveClassNames = s; } return primitiveClassNames.contains(clazz.getQualifiedName()); } public String getObjectIdPackage(Properties attributes) throws XDocletException { return getObjectIdClassOrPackage(true); } public String getObjectIdClass(Properties attributes) throws XDocletException { return getObjectIdClassOrPackage(false); } public String getCurrentPrimaryKeyFieldName(Properties attributes) throws XDocletException { XField pkf = getCurrentPrimaryKeyField(); if (pkf == null) throw new IllegalStateException("Cannot access current primary key field outside of forAllPrimaryKeyFields-loop!"); return pkf.getName(); } public String getCurrentPrimaryKeyFieldType(Properties attributes) throws XDocletException { XField pkf = getCurrentPrimaryKeyField(); if (pkf == null) throw new IllegalStateException("Cannot access current primary key field outside of forAllPrimaryKeyFields-loop!"); return pkf.getType().getQualifiedName(); } public void ifCurrentPrimaryKeyFieldIsPrimitive(String template, Properties attributes) throws XDocletException { XField pkf = getCurrentPrimaryKeyField(); if (pkf == null) throw new IllegalStateException("Cannot work with primary key fields outside of forAllPrimaryKeyFields-loop!"); if (isPrimitive(pkf.getType())) generate(template); } public void ifCurrentPrimaryKeyFieldIsNotPrimitive(String template, Properties attributes) throws XDocletException { XField pkf = getCurrentPrimaryKeyField(); if (pkf == null) throw new IllegalStateException("Cannot work with primary key fields outside of forAllPrimaryKeyFields-loop!"); if (!isPrimitive(pkf.getType())) generate(template); } public void ifNotLastPrimaryKeyField(String template, Properties attributes) throws XDocletException { XField pkf = getCurrentPrimaryKeyField(); if (pkf == null) throw new IllegalStateException("Cannot work with primary key fields outside of forAllPrimaryKeyFields-loop!"); if (lastPrimaryKeyField) generate(template); } /** * The <code>forAllPrimaryKeyFields</code> method iterates through all primary key fields in the current class. * * @param template a <code>String</code> value * @param attributes a <code>Properties</code> value * @exception XDocletException if an error occurs * @doc:tag type="block" */ public void forAllPrimaryKeyFields(String template, Properties attributes) throws XDocletException { Log log = LogUtil.getLog(this.getClass(), "forAllPrimaryKeyFields"); log.debug("enter method forAllPrimaryKeyFields..."); XClass clazz = getCurrentClass(); List pkFields = new ArrayList(); for (Iterator it = clazz.getFields().iterator(); it.hasNext(); ) { XField field = (XField) it.next(); XDoc fieldDoc = field.getDoc(); if (fieldDoc.hasTag("jdo.field")) { if ("true".equals(fieldDoc.getTag("jdo.field").getAttributeValue("primary-key"))) pkFields.add(field); } } // sort the pk-fields alphabetically by their name Collections.sort(pkFields, pkFieldComparator); // if there is a desired order specified, we respect it String fieldOrderStr = clazz.getDoc().getTagAttributeValue("jdo.create-objectid-class", "field-order"); if (fieldOrderStr != null && !"".equals(fieldOrderStr)) { String[] fieldOrder = fieldOrderStr.replaceAll(" ", "").split(","); int newIdx = 0; for (int i = 0; i < fieldOrder.length; ++i) { String field = fieldOrder[i]; int oldIdx = -1; for (int m = 0; m < pkFields.size(); ++m) { if (((XField) pkFields.get(m)).getName().equals(field)) { oldIdx = m; break; } } if (oldIdx >= 0) { XField f = (XField) pkFields.remove(oldIdx); pkFields.add(newIdx, f); ++newIdx; } else throw new XDocletException("Class \"" + clazz.getQualifiedName() + "\" has field \"" + field + "\" specified in '@jdo.create-objectid-class order-fields', but this field does not exist or is not tagged as primary-key-field!"); } } // if (fieldsOrderStr != null && !"".equals(fieldsOrderStr)) { if (log.isDebugEnabled()) log.debug("Iterating " + pkFields.size() + " primary-key fields..."); for (Iterator it = pkFields.iterator(); it.hasNext(); ) { XField pkField = (XField) it.next(); lastPrimaryKeyField = it.hasNext(); setCurrentPrimaryKeyField(pkField); generate(template); } setCurrentPrimaryKeyField(null); log.debug("exit method forAllPrimaryKeyFields."); } protected String getObjectIdClassOrPackage(boolean pakkage) { Log log = LogUtil.getLog(this.getClass(), "getObjectIdClassOrPackage"); XClass clazz = getCurrentClass(); XDoc classDoc = clazz.getDoc(); if (!classDoc.hasTag("jdo.create-objectid-class")) throw new IllegalStateException("No @jdo.create-objectid-class tag! This class should not be processed!"); String objectIDClassWithPackage = classDoc.getTag("jdo.persistence-capable").getAttributeValue("objectid-class"); if (objectIDClassWithPackage == null || "".equals(objectIDClassWithPackage)) throw new IllegalStateException("No objectid-class specified! This class should not be processed!"); // extend the package, if it is missing if (objectIDClassWithPackage.indexOf('.') < 0) { objectIDClassWithPackage = clazz.getContainingPackage().getName() + '.' + objectIDClassWithPackage; if (log.isDebugEnabled()) log.debug("Class " + clazz.getQualifiedName() + " specifies its objectid-class without package. Have extended it to \"" + objectIDClassWithPackage + "\"!"); } String objectIDPackage = objectIDClassWithPackage.substring(0, objectIDClassWithPackage.lastIndexOf('.')); if (pakkage) return objectIDPackage; String objectIDClass = objectIDClassWithPackage.substring(objectIDPackage.length() + 1); return objectIDClass; } } --- NEW FILE: JdoObjectIdGeneratorSubTask.java --- /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.modules.jdo; import java.io.File; import org.apache.commons.logging.Log; import xjavadoc.XClass; import xjavadoc.XDoc; import xdoclet.TemplateSubTask; import xdoclet.XDocletException; import xdoclet.util.LogUtil; /** * @author Marco Schulze ([EMAIL PROTECTED]) * @created August 29, 2005 * @version $Revision: 1.1 $ * @ant.element display-name="JDO ObjectId Generator" name="jdoobjectidgenerator" * parent="xdoclet.modules.jdo.JdoDocletTask" */ public class JdoObjectIdGeneratorSubTask extends TemplateSubTask { protected final static String DEFAULT_TEMPLATE_FILE = "resources/java_objectid.xdt"; public JdoObjectIdGeneratorSubTask() { Log log = LogUtil.getLog(this.getClass(), "constructor"); log.debug("New instance of JdoObjectIdGeneratorSubTask created."); setTemplateURL(getClass().getResource(DEFAULT_TEMPLATE_FILE)); setDestinationFile("{0}.java"); // will be ignored in getGeneratedFileName addOfType("java.lang.Object"); setPackageSubstitutionInheritanceSupported(false); } protected String getGeneratedFileName(XClass clazz) throws XDocletException { Log log = LogUtil.getLog(this.getClass(), "getGeneratedFileName"); XDoc classDoc = clazz.getDoc(); // ignore all classes that do not have the tag @jdo.create-objectid-class if (!classDoc.hasTag("jdo.create-objectid-class")) throw new IllegalStateException("No @jdo.create-objectid-class tag! This should be checked by matchesGenerationRules(...)!"); // find out what's the objectid-class String objectIDClassWithPackage = classDoc.getTag("jdo.persistence-capable").getAttributeValue("objectid-class"); if (objectIDClassWithPackage == null || "".equals(objectIDClassWithPackage)) throw new IllegalStateException("No objectid-class specified! This should be checked by matchesGenerationRules(...)!"); String res = objectIDClassWithPackage.replace('.', File.separatorChar) + ".java"; if (log.isDebugEnabled()) log.debug("result=" + res); return res; } protected boolean matchesGenerationRules(XClass clazz) throws XDocletException { Log log = LogUtil.getLog(this.getClass(), "matchesGenerationRules"); XDoc classDoc = clazz.getDoc(); // ignore all classes that do not have the tag @jdo.create-objectid-class if (!classDoc.hasTag("jdo.create-objectid-class")) { if (log.isDebugEnabled()) log.debug("Class " + clazz.getQualifiedName() + " does not have tag @jdo.create-objectid-class - won't create an object-id-class."); return false; } // find out what's the objectid-class String objectIDClassWithPackage = classDoc.getTag("jdo.persistence-capable").getAttributeValue("objectid-class"); if (objectIDClassWithPackage == null || "".equals(objectIDClassWithPackage)) { log.warn("Though the class " + clazz.getQualifiedName() + " has the tag @jdo.create-objectid-class present, it does not have an objectid-class specified. Cannot create the class!"); return false; } return true; } } Index: JdoXmlMetadataSubTask.java =================================================================== RCS file: /cvsroot/xdoclet/xdoclet/modules/jdo/src/xdoclet/modules/jdo/JdoXmlMetadataSubTask.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** JdoXmlMetadataSubTask.java 20 Jul 2005 14:43:48 -0000 1.14 --- JdoXmlMetadataSubTask.java 29 Aug 2005 20:28:50 -0000 1.15 *************** *** 12,16 **** import org.apache.commons.logging.Log; ! import xjavadoc.*; import xdoclet.XDocletException; import xdoclet.XDocletMessages; --- 12,18 ---- import org.apache.commons.logging.Log; ! import xjavadoc.XPackage; ! ! import xdoclet.DocletContext; import xdoclet.XDocletException; import xdoclet.XDocletMessages; *************** *** 28,31 **** --- 30,34 ---- * @author Ludovic Claude ([EMAIL PROTECTED]) * @author David Jencks ([EMAIL PROTECTED]) + * @author Marco Schulze ([EMAIL PROTECTED]) * @created June 11, 20012 * @version $Revision$ *************** *** 54,58 **** private static String JDOXML_DTD_FILE_NAME_2_0 = "resources/jdo_2_0.dtd"; - private String jdoSpec = null; private String generation = "class"; private boolean forceGenerationPerPackage; --- 57,60 ---- *************** *** 68,86 **** } - /** - * Gets the Jdospec attribute of the JdoXmlSubTask object - * - * @return The Jdospec value - */ - public String getJdoSpec() - { - if (jdoSpec != null) - return jdoSpec; - - // TODO Why the hell doesn't it copy the parameters from JdoDocletTask to JdoXmlMetadataSubTask??? - // Fortunately, the correct value can be found in getContext().getConfigParam(...): - return (String) getContext().getConfigParam("jdospec"); - } - public String getGeneration() { --- 70,73 ---- *************** *** 104,121 **** /** - * Sets the Jdospec attribute of the JdoXmlSubTask object - * - * @param jdoSpec The new Jdospec value - */ - public void setJdoSpec(JdoSpecVersion jdoSpec) - { - // TODO Why is this method never called? see getJdoSpec()! - Log log = LogUtil.getLog(JdoXmlMetadataSubTask.class, "setJdoSpec"); - - log.info("new jdoSpec: " + jdoSpec.getValue()); - this.jdoSpec = jdoSpec.getValue(); - } - - /** * Called to validate configuration parameters. * --- 91,94 ---- *************** *** 136,142 **** public void execute() throws XDocletException { - String jdoSpec = getJdoSpec(); Log log = LogUtil.getLog(JdoXmlMetadataSubTask.class, "execute"); log.info("Using jdoSpec \"" + jdoSpec + "\"."); --- 109,122 ---- public void execute() throws XDocletException { Log log = LogUtil.getLog(JdoXmlMetadataSubTask.class, "execute"); + DocletContext context = getContext(); + + if (context == null) + throw new NullPointerException("Have no DocletContext!"); + + // String jdoSpec = getJdoSpec(); + String jdoSpec = (String) context.getConfigParam("jdospec"); + log.info("Using jdoSpec \"" + jdoSpec + "\"."); ------------------------------------------------------- SF.Net email is Sponsored by the Better Software Conference & EXPO September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf _______________________________________________ xdoclet-devel mailing list xdoclet-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/xdoclet-devel