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
[email protected]
https://lists.sourceforge.net/lists/listinfo/xdoclet-devel