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