1 package org.xmlBlaster.client;
  2 
  3 import java.util.logging.Logger;
  4 import java.util.logging.Level;
  5 import org.xmlBlaster.util.Global;
  6 import org.xmlBlaster.util.def.ErrorCode;
  7 import org.xmlBlaster.util.XmlBlasterException;
  8 import org.xmlBlaster.authentication.plugins.I_ClientPlugin;
  9 import org.xmlBlaster.util.def.Constants;
 10 import org.xmlBlaster.util.plugin.PluginInfo;
 11 
 12 import java.util.Vector;
 13 import java.util.StringTokenizer;
 14 
 15 /**
 16  * <code>PluginLoader</code> is responsible for loading
 17  * and initialization of client secuirty plugins.
 18  *
 19  * Either the client application chooses an appropriate plugin, or the
 20  * <pre>xmlBlaster.properties</pre> file states, which plugin has to be used,
 21  * by using the <code>Security.Client.DefaultPlugin</code>-Option.
 22  *
 23  * Syntax:
 24  *   <code>Security.Client.DefaultPlugin=</code><i>PluginType</i>,<i>PluginVersion</i>
 25  *
 26  * Hint:
 27  *   Type and version must be the type and version of a valid and declared plugin.
 28  *
 29  * Example:
 30  *   <code>
 31  *     Security.Client.DefaultPlugin=gui,1.0
 32  *     Security.Client.Plugin[gui][1.0]=org.xmlBlaster.authentication.ClientSecurityHelper
 33  *   </code>
 34  *
 35  * If neither the application, nor the config enforce a specific plugin, the Dummy-Plugin
 36  * is used (old xmlBlaster behavior).
 37  */
 38 public class PluginLoader {
 39    private  static final String  ME = "SecurityPluginLoader";
 40    private final Global glob;
 41    private static Logger log = Logger.getLogger(PluginLoader.class.getName());
 42    private  String pluginMechanism = null;
 43    private  String pluginVersion = null;
 44    private  I_ClientPlugin plugin = null;
 45 
 46    public PluginLoader(Global glob)
 47    {
 48       this.glob = glob;
 49 
 50    }
 51 
 52    /**
 53     * Get the type of the currently used plugin
 54     *
 55     * @return String
 56     */
 57    public String getType()
 58    {
 59       return pluginMechanism;
 60    }
 61 
 62    /**
 63     * Get the Version of the currently used plugin
 64     *
 65     * @return String
 66     */
 67    public String getVersion()
 68    {
 69       return pluginVersion;
 70    }
 71 
 72    /**
 73     * Get the currently used plugin
 74     *
 75     * @return I_ClientPlugin
 76     */
 77    public I_ClientPlugin getCurrentClientPlugin() throws XmlBlasterException
 78    {
 79       if(plugin!=null) return plugin;
 80 
 81       return getClientPlugin(null, null);
 82    }
 83 
 84    /**
 85     * Load another plugin.
 86     * <p/>
 87     * @param String The type of the plugin, e.g. "ldap"
 88     * @param String The version of the plugin, e.g. "1.0"
 89     * @return I_ClientPlugin
 90     * @exception XmlBlasterException Thrown if the plugin wasn't loadable or initializable
 91     */
 92    public synchronized I_ClientPlugin getClientPlugin(String mechanism, String version) throws XmlBlasterException
 93    {
 94       if (log.isLoggable(Level.FINER)) log.finer("type=" + mechanism + " version=" + version);
 95       if((pluginMechanism!=null) && (pluginMechanism.equals(mechanism))) {
 96         if (((pluginVersion==null) && (version==null)) ||
 97             ((version!=null) && (version.equals(pluginVersion)))) {
 98                // ok, the used and the desired plugins are from the same type
 99                return plugin;
100          }
101       }
102 
103       plugin = loadPlugin(fetchClassnameAndParam(mechanism, version));
104 
105       return plugin;
106    }
107 
108    /**
109     * Handels the process of loading a plugin.
110     * <p/>
111     * @param String[] The first element of this array contains the class name. Following
112     *                 elements are arguments for the plugin. (Like in c/c++ the command-line arguments.)
113     * @return I_Manager
114     * @exception XmlBlasterException Thrown if loading or initializing failed.
115     */
116    private synchronized I_ClientPlugin loadPlugin(String[] param) throws XmlBlasterException
117    {
118       if(param==null) return null;
119       if(param[0]==null) return null;
120 
121       String[] p = new String[param.length-1];
122       I_ClientPlugin clntPlugin = null;
123 
124       try {
125          if (log.isLoggable(Level.FINE)) log.fine("Trying Class.forName('"+param[0]+"') ...");
126          Class cl = java.lang.Class.forName(param[0]);
127          clntPlugin = (I_ClientPlugin)cl.newInstance();
128          PluginInfo pluginInfo = new PluginInfo(glob, null, this.getType(), this.getVersion());
129          clntPlugin.init(glob, pluginInfo);
130          if (log.isLoggable(Level.FINE)) log.fine("Found I_ClientPlugin '"+param[0]+"'");
131       }
132       catch (IllegalAccessException e) {
133          if (log.isLoggable(Level.FINE)) log.fine("The plugin class '"+param[0]+"' is not accessible\n -> check the plugin name and/or the CLASSPATH");
134          throw new XmlBlasterException(glob, ErrorCode.RESOURCE_CONFIGURATION_PLUGINFAILED, ME, "The plugin class '"+param[0]+"' is not accessible\n -> check the plugin name and/or the CLASSPATH", e);
135       }
136       catch (SecurityException e) {
137          if (log.isLoggable(Level.FINE)) log.fine("Couldn't load security plugin '"+param[0]+"'. Access Denied");
138          throw new XmlBlasterException(glob, ErrorCode.RESOURCE_CONFIGURATION_PLUGINFAILED, ME, "The plugin class '"+param[0]+"' couldn't be loaded!", e);
139       }
140       catch (Throwable e) {
141          if (log.isLoggable(Level.FINE)) log.fine("The plugin class '"+param[0]+"'is invalid!" + e.toString());
142          throw new XmlBlasterException(glob, ErrorCode.RESOURCE_CONFIGURATION_PLUGINFAILED, ME, "The plugin class '"+param[0]+"'is invalid!", e);
143       }
144 
145       System.arraycopy(param,1,p,0,param.length-1);
146 
147       /*
148       if (clntPlugin!=null) {
149          try {
150             clntPlugin.init(p);
151             log.info(ME, "Plugin '"+param[0]+"' successfully initialized");
152          }
153          catch(Exception e) {
154             throw new XmlBlasterException(ME+".noInit", "Couldn't initialize plugin '"+param[0]+"'. Reaseon: "+e.toString());
155          }
156       }
157       */
158       if (log.isLoggable(Level.FINE)) log.fine("Plugin '"+param[0]+"' successfully initialized");
159 
160       return clntPlugin;
161    }
162 
163 
164    /**
165     * Resolve a class name of a plugin, specified by its type (mechanism) and version.
166     * <p />
167     * The plugin is read from xmlBlaster.properties if mechanism==version==null<br />
168     * If non is specified there, we return null
169     *
170     * @param String The type
171     * @param String The version
172     * @return String[] The name of the class and some parameters
173     */
174    private synchronized String[] fetchClassnameAndParam(String mechanism, String version) throws XmlBlasterException
175    {
176       String tmp = null;
177       Vector v   = new Vector();
178 
179       if((mechanism==null) || (mechanism.equals(""))) { // if the client application doesn't select the mechanism and version, we must check the configuartion
180          tmp = glob.getProperty().get("Security.Client.DefaultPlugin", Constants.DEFAULT_SECURITYPLUGIN_TYPE+","+Constants.DEFAULT_SECURITYPLUGIN_VERSION);
181          if (log.isLoggable(Level.FINE)) log.fine("Got Security.Client.DefaultPlugin=" + tmp);
182          if (tmp!=null) {
183             int i = tmp.indexOf(',');
184             if (i==-1) {  // version is optional
185                version = null;
186             }
187             else {
188                version = tmp.substring(i+1);
189             }
190             mechanism = tmp.substring(0,i);
191          }
192          else {
193             return (String[])null;
194          }
195       }
196       if(version==null) version="";
197 
198       String s = glob.getProperty().get("Security.Client.Plugin["+mechanism+"]["+version+"]", (String)null);
199       if(s==null) {
200          if (mechanism.equals("htpasswd")) // xmlBlaster should run without xmlBlaster.properties
201             s = "org.xmlBlaster.authentication.plugins.htpasswd.ClientPlugin";
202          else if (mechanism.equals("simple")) // xmlBlaster should run without xmlBlaster.properties
203             s = "org.xmlBlaster.authentication.plugins.simple.ClientPlugin";
204          else if (mechanism.equals("ldap")) // xmlBlaster should run without xmlBlaster.properties
205             s = "org.xmlBlaster.authentication.plugins.ldap.ClientPlugin";
206          else
207             throw new XmlBlasterException(glob, ErrorCode.RESOURCE_CONFIGURATION_PLUGINFAILED, ME, "Unknown Security.Client.Plugin["+mechanism+"]["+version+"] from ConnectQos is rejected.");
208       }
209 
210       StringTokenizer st = new StringTokenizer(s,",");
211       while(st.hasMoreTokens()) {
212          v.addElement(st.nextToken());
213       }
214 
215       String[] classnameAndParam = new String[v.size()];
216       v.copyInto(classnameAndParam); // For client side JDK 1.1 support (v.toArray(classnameAndParam); is since 1.2)
217 
218       this.pluginMechanism=mechanism;
219       this.pluginVersion=version;
220 
221       return classnameAndParam;
222    }
223 
224 }


syntax highlighted by Code2HTML, v. 0.9.1