Hi,

After some period I've returned to that problem and want to propose
the solution. Below you will find the diff for ScreenLoader.java
I have also diffs for PageLoader, NavigationLoader, LayoutLoader and
ActionLoader. I am ready to send them :)

Here is some brief history:
---------------------------

* The problem:
We want several separate applications to use one Turbine instance.
Then we meet the naming problem with loaders: since there is only one search path
indicated by module.package property we can not use for example two
different actions named "Login".

* The solution:
Give each application(package) unique name and indicate this names in
TR properties:
module.package.name=one_package
module.package.name=another_package

Then indicate module paths in TR properties as follows:
module.package.one_package=com.company.one.path.to.modules,...
module.package.another_package=com.compay.another.path.to.modules, ...

Also you may preserve the default path:
module.package = com.mycompany.path.to.modules, org.apache.turbine.modules

To access some module from the specific package, use package name as a
prefix to the module name. Example for action in url:
http://host:port/zone/Turbine/action/one_package.Login
http://host:port/zone/Turbine/action/another_package.Login

Solution implementation
-----------------------

All loaders are patched to store paths in hashtable.
The key is package name and the value is vector with paths.
Also there entry for the default path.

When some object name is passed to the loader the following algorithm is
used:

1. If prefix exists then first try to look in the specific paths using prefix
as a key for hashtable. Then look in the default path.
2. If there is no prefix - look in the default path.

Diff for ScreenLoader:


--- ScreenLoader.java.orig  Mon Sep 11 13:34:00 2000
+++ ScreenLoader.java Fri Sep 15 16:18:46 2000
@@ -78,8 +78,36 @@
     /** The single instance of this class. */
     private static ScreenLoader instance = null;
 
-    /** Packages to search for actions. */
-    private Vector packages;
+    /** 
+     * Stores named paths to search for modules.
+     * <p>
+     * You can have different packages using one Turbine instance and
+     * each package can have its own search path for his modules.
+     * <p>
+     * In order to do this, you should give each package his uniqe 
+     * name and store it in
+     * <code>module.package.name</code> property in 
+     * TurbineResources.properties file. Then store path
+     * for each package in
+     * <code>module.package.<i>&lt;package_name&gt;</i></code> property.
+     * Package names will become keys, and search paths will
+     * become values (as Vectors) in this hashtable.
+     * <p>
+     * Value from <code>module.package</code> property will be a default search path 
+for
+     * all pakages.
+     * <p>
+     * To access module from specific package use package name as
+     * a prefix before module name in format: 
+     * <code><i>&lt;package_name&gt;</i>.<i>&lt;module_name&gt;</i></code>
+     * Example for url: 
+<code>http://hostname:port/zone/Turbine/screen/package1.MyScreen/action/package1.MyAction</code>
+     * <p>
+     */
+    private Hashtable packages;
+
+    /** 
+     * Key for the default search path 
+     */
+    private static String DEFAULT_PATH_KEY = "turbine.default.modules.path";
 
     /**
      * These ctor's are private to force clients to use getInstance()
@@ -145,15 +173,26 @@
     /**
      * Pulls out an instance of the object by name.  Name is just the
      * single name of the object.
+     * <p>
+     * If name is in the form <code>prefix.name</code> then first
+     * we use <code>prefix</code> as a key to get search paths from 
+     * <code>packages</code> Hashtable. If object can not be found in this paths,
+     * then we search in default paths that are store under DEFAUL_PATH_KEY.
      *
      * @param name Name of object instance.
      * @return A Screen with the specified name, or null.
      * @exception Exception, a generic exception.
      */
-    public Screen getInstance (String name)
+    public Screen getInstance (String name) 
         throws Exception
     {
         Screen screen = null;
+
+        // prefix as a key in packages hashtable
+        // suffix as a class name
+        String prefix = null;
+        String suffix = null;
+
         try
         {
             if (  cache() && this.containsKey ( name ) )
@@ -162,30 +201,88 @@
             }
             else
             {
-                for (int i=0; i<instance.packages.size(); i++)
+                // determine prefix and suffix
+                int pos = name.indexOf('.');
+                if ( pos == -1 )
                 {
-                    String className = ((String) instance.packages.elementAt(i) +
-                                        ".screens." +
-                                        name);
-                    try
-                    {
-                        Class servClass = Class.forName( className );
-                        screen = ( Screen ) servClass.newInstance();
-                        addInstance ( name, screen );
-                        return screen;
-                    }
-                    catch (ClassNotFoundException cnfe)
-                    {
-                        // Do this so we loop through all the packages.
-                    }
-                    catch (NoClassDefFoundError ncdfe)
+                    prefix = DEFAULT_PATH_KEY;
+                    suffix = name;
+                } else {
+                    prefix = name.substring( 0, pos );
+                    suffix = name.substring( pos+1 );
+                }
+
+                if ( prefix==null || suffix==null ){
+                    prefix = DEFAULT_PATH_KEY;
+                    suffix = name;
+                }
+                    
+                // try to search in specified path
+                Vector paths = (Vector) instance.packages.get( prefix );
+                if ( paths!=null )
+                {
+                    for (int i=0; i<paths.size(); i++)
                     {
-                        // Do this so we loop through all the packages.
+                        // add suffix (class name) to the path
+                        String className = (String)paths.elementAt(i) + 
+                                            ".screens." + 
+                                            suffix;
+                        try
+                        {
+                            Class servClass = Class.forName( className );
+                            screen = ( Screen ) servClass.newInstance();
+                            addInstance ( name, screen );
+                            return screen;
+                        }
+                        catch (ClassNotFoundException cnfe)
+                        {
+                            // Do this so we loop through all the packages.
+                        }
+                        catch (NoClassDefFoundError ncdfe)
+                        {
+                            // Do this so we loop through all the packages.
+                        }
+                        catch (ClassCastException cce)
+                        {
+                            // Do this so we know what class is having problems.
+                            throw new ClassCastException( className );
+                        }
                     }
-                    catch (ClassCastException cce)
+                }
+                // Now search in default place if it was not already done.
+                // Use original name parameter.
+                if ( !prefix.equals(DEFAULT_PATH_KEY) )
+                {
+                    paths = (Vector) instance.packages.get ( DEFAULT_PATH_KEY );
+
+                    if ( paths!=null )
                     {
-                        // Do this so we know what class is having problems.
-                        throw new ClassCastException( className );
+                        for (int i=0; i<paths.size(); i++)
+                        {
+                            String className = (String)paths.elementAt(i) + 
+                                                ".screens." + 
+                                                name;
+                            try
+                            {
+                                Class servClass = Class.forName( className );
+                                screen = ( Screen ) servClass.newInstance();
+                                addInstance ( name, screen );
+                                return screen;
+                            }
+                            catch (ClassNotFoundException cnfe)
+                            {
+                                // Do this so we loop through all the packages.
+                            }
+                            catch (NoClassDefFoundError ncdfe)
+                            {
+                                // Do this so we loop through all the packages.
+                            }
+                            catch (ClassCastException cce)
+                            {
+                                // Do this so we know what class is having problems.
+                                throw new ClassCastException( className );
+                            }
+                        }
                     }
                 }
                 // If we got here the class is really not found.
@@ -194,10 +291,15 @@
         }
         catch ( ClassNotFoundException e )
         {
-            throw new Exception ( "\n\n\tRequested Screen not found: " +
-                                    name + "\n" +
-                                   "\tTurbine looked in the following 
modules.packages path: \n\t" +
-                                   instance.packages.toString() + "\n");
+            String errmsg =  "\n\n\tRequested Screen not found: " + 
+                             name + "\n" +
+                             "\tTurbine looked in the following modules.packages 
+path: \n\t" + 
+                             instance.packages.get( prefix ) + "\n";
+            if ( !prefix.equals( DEFAULT_PATH_KEY ) )
+            {
+                errmsg += instance.packages.get( DEFAULT_PATH_KEY ) + "\n";
+            }
+            throw new Exception ( errmsg );
         }
         return screen;
     }
@@ -217,8 +319,24 @@
                 {
                     int size = TurbineResources.getInt("screen.cache.size",50);
                     instance = new ScreenLoader(size);
-                    instance.packages = TurbineResources.getVector("module.packages");
-                    instance.packages.addElement( GenericLoader.getBasePackage() );
+                    instance.packages = new Hashtable();
+
+                    // loading all modules paths
+                    Enumeration e = 
+TurbineResources.getVector("module.package.name").elements();
+
+                    if ( e!=null)
+                    {
+                        while (e.hasMoreElements()) 
+                        {
+                            String moduleName = (String)e.nextElement();
+                            Vector modulePaths = 
+TurbineResources.getVector("module.package." + moduleName);
+                            instance.packages.put( moduleName, modulePaths );
+                        }
+                    }
+                    // storing default path
+                    Vector defaultPaths = 
+TurbineResources.getVector("module.packages");
+                    defaultPaths.addElement( GenericLoader.getBasePackage() );
+                    instance.packages.put( DEFAULT_PATH_KEY, defaultPaths );
                }
             }
         }




         
/ Shamil 




------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Search: <http://www.mail-archive.com/turbine%40list.working-dogs.com/>
Problems?:           [EMAIL PROTECTED]

Reply via email to