Update of /cvsroot/xdoclet/xdoclet2/src/java/xdoclet
In directory sc8-pr-cvs1:/tmp/cvs-serv22426/src/java/xdoclet
Modified Files:
package.html PluginFactory.java XDoclet.java
Added Files:
BeanContextSupportEx.java
Log Message:
-Improved JavaBeans support (which is the metadata layer for XDoclet configuration)
-Made tests able to run in unforked mode
--- NEW FILE: BeanContextSupportEx.java ---
package xdoclet;
import java.beans.beancontext.BeanContextSupport;
/**
* A BeanContext that is aware of its parent.
*
* @author <a href="mailto:aslak.hellesoy at bekk.no">Aslak Hellesøy</a>
* @version $Revision: 1.1 $
*/
public class BeanContextSupportEx extends BeanContextSupport {
private BeanContextSupportEx _parent;
public boolean add( Object o ) {
System.out.println("Adding " + o + " to " + this);
if( o instanceof BeanContextSupportEx ) {
BeanContextSupportEx child = (BeanContextSupportEx) o;
child.setParent( this );
}
return super.add( o );
}
private void setParent( BeanContextSupportEx parent ) {
_parent = parent;
}
public BeanContextSupportEx getParent() {
return _parent;
}
}
Index: package.html
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet2/src/java/xdoclet/package.html,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** package.html 27 Feb 2003 00:13:00 -0000 1.1.1.1
--- package.html 12 Mar 2003 23:41:03 -0000 1.2
***************
*** 1,23 ****
<body>
! XDoclet core classes. It's important to understand the relationships between
XDoclet, Plugin and Generator.
! One XDoclet has many Plugins. One Plugin has many Generators. In order to make it
easy to write XDoclet extensions,
! the class hierarchy is as shown under. That means that if you plan to generate only
one kind of file, you
! just subclass a Generator, and you have the Plugin and the XDoclet for free!
<pre>
! +-------------+
! | XDoclet |----+
! +-------------+ |
! /|\ |
! | |
! +-------------+ |
! +----| Plugin |<-*-+
! | +-------------+
! | /|\
! | |
! | +-------------+
! +-*->| Generator |
! +-------------+
!
</pre>
--- 1,9 ----
<body>
! XDoclet core classes.
<pre>
! +-------------+ +-------------+
! | XDoclet |---*->| Plugin |
! +-------------+ +-------------+
</pre>
Index: PluginFactory.java
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet2/src/java/xdoclet/PluginFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** PluginFactory.java 8 Mar 2003 14:21:09 -0000 1.5
--- PluginFactory.java 12 Mar 2003 23:41:03 -0000 1.6
***************
*** 17,21 ****
import java.util.*;
! import java.beans.Beans;
/**
--- 17,22 ----
import java.util.*;
! import java.beans.*;
! import java.lang.reflect.Method;
/**
***************
*** 55,58 ****
--- 56,153 ----
// Register plugins from classpath
registerDynamicPlugins();
+
+ // Update BeanInfo for all XDoclet classes
+ for( Iterator i = _pluginClassNameToXDocletClassNameMap.values().iterator();
i.hasNext(); ) {
+ String xdocletClassName = (String) i.next();
+ try {
+ Class xdocletClass =
_classpathManager.getClassLoader().loadClass(xdocletClassName);
+ updateBeanInfo(xdocletClass);
+ } catch (ClassNotFoundException e) {
+ // Should never happen
+ LogFactory.getLog(PluginFactory.class).error("Couldn't load class",
e);;
+ }
+ }
+
+ }
+
+ /**
+ * Updates the MethodDescriptor of XDoclet's createPlugin method with an
+ * attribute indicating what plugins are allowed.
+ *
+ * @param xdocletClass
+ */
+ private void updateBeanInfo(Class xdocletClass) {
+ try {
+ // Get all allowed plugins
+ Collection allowedPluginNames = getAllowedPluginNames( xdocletClass );
+
+ BeanInfo beanInfo = Introspector.getBeanInfo(xdocletClass);
+ MethodDescriptor[] md = beanInfo.getMethodDescriptors();
+ Method createPlugin = xdocletClass.getMethod("createPlugin", new Class[]
{String.class});
+ boolean didUpdate = false;
+ for( int i = 0; i < md.length; i++ ) {
+ if( md[i].getMethod().equals( createPlugin ) ) {
+ md[i].setValue("pluginNames", allowedPluginNames);
+ didUpdate = true;
+ break;
+ }
+ }
+ if( !didUpdate ) {
+ throw new IllegalStateException("BeanInfo was not properly updated.
Couldn't find createPlugin method in " + xdocletClass.getName());
+ }
+ } catch (IntrospectionException e) {
+ LogFactory.getLog(XDoclet.class).error("Couldn't update BeanInfo", e);
+ throw new IllegalStateException(e.getMessage());
+ } catch (NoSuchMethodException e) {
+ LogFactory.getLog(XDoclet.class).error("Couldn't update BeanInfo", e);
+ throw new IllegalStateException(e.getMessage());
+ } catch (SecurityException e) {
+ LogFactory.getLog(XDoclet.class).error("Couldn't update BeanInfo", e);
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+ /**
+ * Checks whether a particular plugin class is allowed under a particular XDoclet
+ * @param pluginName name of the plugin to check for.
+ * @param xdocletClass the XDoclet class to check for.
+ * @return true if the plugin can be used with the XDoclet instance.
+ */
+ private boolean allowsPlugin(String pluginName, Class xdocletClass) {
+ try {
+ // plugin names are case insensitive
+ pluginName = pluginName.toLowerCase(Locale.US);
+
+ // Look up the plugin class.
+ Class pluginClass = getPluginClass(pluginName);
+
+ // Look up the allowed parent class
+ Class parentClass = getContainerClass(pluginClass.getName());
+
+ // Verify that the passed xdoclet is allowed to contain the plugin.
+ return parentClass.isAssignableFrom(xdocletClass);
+ } catch (XDocletException e) {
+ LogFactory.getLog(PluginFactory.class).error("Error in allowsPlugin", e);
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+
+ /**
+ * Returns a Collection of all known plugin names. This can be used to create
plugins.
+ * @see <a
href="XDoclet.html#createPlugin(java.lang.String)">XDoclet.createPlugin</a>.
+ * @return a Collection of [EMAIL PROTECTED] String}.
+ */
+ public Collection getAllowedPluginNames(Class xdocletClass) {
+ ArrayList allowedPluginNames = new ArrayList();
+
+ for( Iterator i = _nameToPluginClassNameMap.keySet().iterator();
i.hasNext(); ) {
+ String pluginName = (String) i.next();
+ if( allowsPlugin(pluginName, xdocletClass) ) {
+ allowedPluginNames.add( pluginName );
+ }
+ }
+ Collections.sort( allowedPluginNames );
+ return allowedPluginNames;
}
***************
*** 82,86 ****
// Verify that the passed xdoclet is allowed to contain the plugin.
! if (!parentClass.isAssignableFrom(xdoclet.getClass())) {
throw new XDocletException("Not allowed to have " +
pluginClass.getName() + " in "
+ xdoclet.getClass().getName() + ". The enclosing XDoclet must be a
subclass of "
--- 177,181 ----
// Verify that the passed xdoclet is allowed to contain the plugin.
! if (!allowsPlugin(pluginName, xdoclet.getClass())) {
throw new XDocletException("Not allowed to have " +
pluginClass.getName() + " in "
+ xdoclet.getClass().getName() + ". The enclosing XDoclet must be a
subclass of "
***************
*** 92,99 ****
+ pluginClass.getName() + ", parentClass=" + parentClass.getName());
! // Instantiate, initialise and add the plugin
! // Plugin plugin = (Plugin) pluginClass.newInstance();
! System.out.println("Instantiating bean with " +
_classpathManager.getClassLoader());
! Plugin plugin = (Plugin)
Beans.instantiate(_classpathManager.getClassLoader(), pluginClass.getName(),
xdoclet.getPlugins());
LogFactory.getLog(getClass()).debug("Creating plugin " +
pluginClass.getName());
--- 187,193 ----
+ pluginClass.getName() + ", parentClass=" + parentClass.getName());
! // Instantiate the plugin. The instantiated
! // plugin will be added to the XDoclet's BeanContext by
Beans.instantiate.
! Plugin plugin = (Plugin)
Beans.instantiate(_classpathManager.getClassLoader(), pluginClass.getName(), xdoclet);
LogFactory.getLog(getClass()).debug("Creating plugin " +
pluginClass.getName());
***************
*** 101,105 ****
plugin.setName(pluginName);
plugin.setXDoclet(xdoclet);
- xdoclet.addPlugin(plugin);
return plugin;
--- 195,198 ----
Index: XDoclet.java
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet2/src/java/xdoclet/XDoclet.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** XDoclet.java 8 Mar 2003 14:21:09 -0000 1.7
--- XDoclet.java 12 Mar 2003 23:41:03 -0000 1.8
***************
*** 10,21 ****
import java.util.*;
- import java.io.Serializable;
- import java.beans.beancontext.BeanContext;
- import java.beans.beancontext.BeanContextSupport;
/**
! * Serves as an entry-point for starting XDoclet. Adapter classes for particular
environments such
! * as various IDEs and Ant should be maintained separately. It's important to keep
XDoclet's
! * core environment agnostic.
*
* @bean.class locale="en"
--- 10,24 ----
import java.util.*;
/**
! * <p>This class as an entry-point for starting XDoclet. Adapter classes for
! * particular environments such as various IDEs and Ant should be maintained
! * separately. It's important to keep XDoclet's core environment agnostic.</p>
! *
! * <p>This class also extends [EMAIL PROTECTED]
java.beans.beancontext.BeanContextSupport},
! * and thereby this is actually a Collection, so we can store the plugins
! * "in ourself". The main reason for extending BeanContextSupport is to
! * be a ble to provide IDE integration in a convenient way. See the
! * <a href="../swing/package.html"></a>xdoclet.swing</p> package.
*
* @bean.class locale="en"
***************
*** 30,34 ****
* @version $Revision$
*/
! public class XDoclet implements Serializable {
/**
* The ClasspathManager finds directories and jars/zips on the classpath.
--- 33,37 ----
* @version $Revision$
*/
! public class XDoclet extends BeanContextSupportEx {
/**
* The ClasspathManager finds directories and jars/zips on the classpath.
***************
*** 36,56 ****
* when/if setClasspath is called.
*/
! private static ClasspathManager _classpathManager = new
ClasspathManager(System.getProperty("java.class.path"));
/** The PluginFactory registers and creates plugins found on the classpath. */
private static PluginFactory _pluginFactory;
- /** Collection of all configured plugins. */
- private final BeanContext _plugins = new BeanContextSupport();
-
/** Provides us with metadata. */
private transient MetadataProvider _metadataProvider;
! // A cache of the collection created by _metadataProvider. */
private transient Collection _collection;
- /** The name. */
- private String _name;
-
/**
* To work around the fact that org.apache.commons.jelly.tags.ant.AntTag
--- 39,53 ----
* when/if setClasspath is called.
*/
! private static ClasspathManager _classpathManager;
/** The PluginFactory registers and creates plugins found on the classpath. */
private static PluginFactory _pluginFactory;
/** Provides us with metadata. */
private transient MetadataProvider _metadataProvider;
! /** A cache of the collection created by _metadataProvider. */
private transient Collection _collection;
/**
* To work around the fact that org.apache.commons.jelly.tags.ant.AntTag
***************
*** 60,69 ****
private transient Throwable _failure;
/**
* Creates a new XDoclet.
*/
public XDoclet() {
- // We'll use our own name as default
- setName(getClass().getName());
}
--- 57,68 ----
private transient Throwable _failure;
+ static {
+ setClasspath(System.getProperty("java.class.path"));
+ }
+
/**
* Creates a new XDoclet.
*/
public XDoclet() {
}
***************
*** 77,102 ****
/**
- * Gets the name of the xdoclet.
- * @return the name of the plugin.
- * @bean.ignore
- */
- public final String getName() {
- return _name;
- }
-
- /**
- * Sets the name of the xdoclet.
- * @param name the name of the plugin.
- * @bean.ignore
- */
- public final void setName(String name) {
- _name = name;
- }
-
- public final BeanContext getPlugins() {
- return _plugins;
- }
-
- /**
* Sets the classpath under which XDoclet is run.
* @param classpath the classpath under which XDoclet is run
--- 76,79 ----
***************
*** 164,168 ****
* Executes all the plugins.
*
! * @exception XDocletException
*/
public void execute() throws XDocletException {
--- 141,148 ----
* Executes all the plugins.
*
! * @bean.method name="Run"
! * shortDescription="Run"
! * displayName="Run XDoclet"
! * @throws XDocletException if execution fails.
*/
public void execute() throws XDocletException {
***************
*** 171,175 ****
failIfFailureSet();
! if (_plugins.isEmpty()) {
throw new XDocletException("At least one plugin must be specified.");
}
--- 151,155 ----
failIfFailureSet();
! if (isEmpty()) {
throw new XDocletException("At least one plugin must be specified.");
}
***************
*** 177,181 ****
long start = System.currentTimeMillis();
! for (Iterator i = getPlugins().iterator(); i.hasNext();) {
Plugin plugin = (Plugin) i.next();
--- 157,161 ----
long start = System.currentTimeMillis();
! for (Iterator i = iterator(); i.hasNext();) {
Plugin plugin = (Plugin) i.next();
***************
*** 188,191 ****
--- 168,186 ----
}
+ /**
+ * Called by [EMAIL PROTECTED] xdoclet.ant.AntProxy#createDynamicElement} when a
dynamic element is added
+ * to the XDoclet task. This method will route the call to [EMAIL PROTECTED]
#createPlugin}.
+ *
+ * @param name the name of the plugin to create.
+ * @return a [EMAIL PROTECTED] Plugin} object mapped to name.
+ * @throws XDocletException
+ */
+ public Object createElement(String name)
+ throws XDocletException {
+ LogFactory.getLog(XDoclet.class).debug("createElement(" + name + ")");
+
+ return createPlugin(name);
+ }
+
private static final void printVersion() {
// This should really be a System.out.print[ln], as we want this to be
printed
***************
*** 210,215 ****
}
! private void failIfFailureSet()
! throws XDocletException {
if (_failure != null) {
if (_failure instanceof XDocletException) {
--- 205,209 ----
}
! private void failIfFailureSet() throws XDocletException {
if (_failure != null) {
if (_failure instanceof XDocletException) {
***************
*** 222,260 ****
/**
! * Instantiates a new Plugin.
*
! * @param name the logical name for the plugin
* @return a Plugin instance
* @throws XDocletException plugin creation fails
*/
! public Plugin createPlugin(String name)
! throws XDocletException {
return _pluginFactory.createPlugin(name,this);
- }
-
- /**
- * Called by [EMAIL PROTECTED] xdoclet.ant.AntProxy#createDynamicElement} when a
dynamic element is added
- * to the XDoclet task. This method will route the call to [EMAIL PROTECTED]
#createPlugin}.
- *
- * @param name
- * @return a [EMAIL PROTECTED] Plugin} object mapped to name.
- * @throws XDocletException
- */
- public Object createElement(String name)
- throws XDocletException {
- LogFactory.getLog(XDoclet.class).debug("createElement(" + name + ")");
-
- return createPlugin(name);
- }
-
- /**
- * Callback method called by [EMAIL PROTECTED]
PluginFactory#createPlugin(java.lang.String,xdoclet.XDoclet)}
- * upon call to [EMAIL PROTECTED] #createPlugin(String)}.
- *
- * @param plugin
- */
- public void addPlugin(Plugin plugin) {
- plugin.setXDoclet(this);
- _plugins.add(plugin);
}
}
--- 216,229 ----
/**
! * Adds a new Plugin.
*
! * @bean.method shortDescription="Add a new plugin"
! * displayName="New Plugin"
! * @param name Plugin name
* @return a Plugin instance
* @throws XDocletException plugin creation fails
*/
! public Plugin createPlugin(String name) throws XDocletException {
return _pluginFactory.createPlugin(name,this);
}
}
-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open!
Get cracking and register here for some mind boggling fun and
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en
_______________________________________________
xdoclet-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/xdoclet-devel