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

Reply via email to