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&oslash;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

Reply via email to