KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > j2ee > appclient > AppClient


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * Caucho Technology permits modification and use of this file in
5  * source and binary form ("the Software") subject to the Caucho
6  * Developer Source License 1.1 ("the License") which accompanies
7  * this file. The License is also available at
8  * http://www.caucho.com/download/cdsl1-1.xtp
9  *
10  * In addition to the terms of the License, the following conditions
11  * must be met:
12  *
13  * 1. Each copy or derived work of the Software must preserve the copyright
14  * notice and this notice unmodified.
15  *
16  * 2. Each copy of the Software in source or binary form must include
17  * an unmodified copy of the License in a plain ASCII text file named
18  * LICENSE.
19  *
20  * 3. Caucho reserves all rights to its names, trademarks and logos.
21  * In particular, the names "Resin" and "Caucho" are trademarks of
22  * Caucho and may not be used to endorse products derived from
23  * this software. "Resin" and "Caucho" may not appear in the names
24  * of products derived from this software.
25  *
26  * This Software is provided "AS IS," without a warranty of any kind.
27  * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
28  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
29  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
30  *
31  * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
32  * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR
33  * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE
34  * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
35  * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
36  * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
37  * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY
38  * OF SUCH DAMAGES.
39  *
40  * @author Scott Ferguson
41  */

42
43 package com.caucho.j2ee.appclient;
44
45 import com.caucho.config.BuilderProgram;
46 import com.caucho.config.Config;
47 import com.caucho.config.ConfigException;
48 import com.caucho.config.j2ee.InjectIntrospector;
49 import com.caucho.j2ee.J2EEVersion;
50 import com.caucho.java.WorkDir;
51 import com.caucho.lifecycle.Lifecycle;
52 import com.caucho.loader.EnvironmentBean;
53 import com.caucho.loader.EnvironmentClassLoader;
54 import com.caucho.loader.EnvironmentLocal;
55 import com.caucho.soa.client.WebServiceClient;
56 import com.caucho.util.L10N;
57 import com.caucho.vfs.JarPath;
58 import com.caucho.vfs.Path;
59 import com.caucho.vfs.Vfs;
60
61 import org.w3c.dom.Element JavaDoc;
62 import org.w3c.dom.Node JavaDoc;
63
64 import javax.naming.Context JavaDoc;
65 import javax.naming.InitialContext JavaDoc;
66 import javax.security.auth.callback.Callback JavaDoc;
67 import javax.security.auth.callback.CallbackHandler JavaDoc;
68 import javax.security.auth.callback.NameCallback JavaDoc;
69 import javax.security.auth.callback.PasswordCallback JavaDoc;
70 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
71 import java.io.IOException JavaDoc;
72 import java.lang.reflect.Method JavaDoc;
73 import java.util.ArrayList JavaDoc;
74 import java.util.Hashtable JavaDoc;
75 import java.util.logging.Level JavaDoc;
76 import java.util.logging.Logger JavaDoc;
77
78 public class AppClient implements EnvironmentBean
79 {
80   private static L10N L = new L10N(AppClient.class);
81   private static Logger JavaDoc log = Logger.getLogger(AppClient.class.getName());
82
83   private static final EnvironmentLocal<AppClient> _local
84     = new EnvironmentLocal<AppClient>();
85
86   private final EnvironmentClassLoader _loader;
87
88   private J2EEVersion _j2eeVersion = J2EEVersion.RESIN;
89
90   private Path _rootDirectory;
91   private Path _workDirectory;
92   private String JavaDoc _mainClassName;
93   private Path _clientJar;
94
95   private Lifecycle _lifecycle = new Lifecycle(log);
96   private Method JavaDoc _mainMethod;
97   private String JavaDoc[] _mainArgs = new String JavaDoc[] {};
98
99   private Hashtable JavaDoc _ejbEnv = new Hashtable JavaDoc();
100   private Context JavaDoc _ejbContext;
101
102   private AppClient()
103   {
104     _loader = new EnvironmentClassLoader();
105     _local.set(this, _loader);
106   }
107
108   public ClassLoader JavaDoc getClassLoader()
109   {
110     return _loader;
111   }
112
113   public static AppClient getLocal()
114   {
115     return _local.get();
116   }
117
118   /**
119    * Used to distinguish the version of the configuration file.
120    */

121   public void setConfigNode(Node JavaDoc node)
122   {
123     _j2eeVersion = J2EEVersion.getJ2EEVersion((Element JavaDoc) node);
124   }
125
126   public J2EEVersion getJ2EEVersion()
127   {
128     return _j2eeVersion;
129   }
130
131   public void setRootDirectory(Path rootDirectory)
132   {
133     _rootDirectory = rootDirectory;
134     Vfs.setPwd(_rootDirectory);
135   }
136
137   public void setWorkDirectory(Path workDirectory)
138   {
139     _workDirectory = workDirectory;
140   }
141
142   public void setId(String JavaDoc id)
143   {
144   }
145
146   public void setDescription(String JavaDoc value)
147   {
148   }
149
150   public void setIcon(com.caucho.config.types.Icon icon)
151   {
152   }
153
154   /**
155    * Adds a web service client.
156    */

157   public WebServiceClient createWebServiceClient()
158   {
159     return new WebServiceClient();
160   }
161
162   private void addConfig(Path path)
163     throws Exception JavaDoc
164   {
165     new Config().configureBean(this, path);
166   }
167
168   public void setClientJar(Path clientJar)
169   {
170     _clientJar = clientJar;
171   }
172
173   public void setMainClass(String JavaDoc mainClassName)
174   {
175     _mainClassName = mainClassName;
176   }
177
178   public void setMainArgs(String JavaDoc[] mainArgs)
179   {
180     _mainArgs = mainArgs;
181   }
182
183   public void setSchemaLocation(String JavaDoc schemaLocation)
184   {
185     // not needed
186
}
187
188
189   public void setVersion(String JavaDoc version)
190   {
191     // not needed
192
}
193
194   public void setDisplayName(String JavaDoc displayName)
195   {
196     // not needed
197
}
198
199   public void setCallbackHandler(Class JavaDoc<CallbackHandler JavaDoc> callbackHandler)
200     throws Exception JavaDoc
201   {
202     CallbackManager callback = new CallbackManager();
203
204     CallbackHandler JavaDoc handler = callbackHandler.newInstance();
205
206     callback.handle(handler);
207
208     System.setProperty(Context.SECURITY_PRINCIPAL, callback.getName());
209     System.setProperty(Context.SECURITY_CREDENTIALS, callback.getPassword());
210   }
211
212   public ClientEjbRef createEjbRef()
213   {
214     return new ClientEjbRef(_ejbContext);
215   }
216
217   public void init()
218     throws Exception JavaDoc
219   {
220     if (!_lifecycle.toInitializing())
221       return;
222
223     if (_clientJar == null)
224       throw new ConfigException(L.l("'client-jar' is required"));
225
226     // corba needs for RMI(?)
227

228     //EnvironmentClassLoader.initializeEnvironment();
229
//System.setSecurityManager(new SecurityManager());
230

231     if (_rootDirectory == null) {
232       String JavaDoc name = _clientJar.getTail();
233
234       int lastDot = name.lastIndexOf(".");
235
236       if (lastDot > -1)
237         name = name.substring(0, lastDot);
238
239       _rootDirectory = WorkDir.getLocalWorkDir(_loader).lookup("_appclient").lookup("_" + name);
240     }
241
242     if (_workDirectory == null)
243       _workDirectory = _rootDirectory.lookup("META-INF/work");
244
245     WorkDir.setLocalWorkDir(_workDirectory, _loader);
246
247     _loader.setId(toString());
248     _loader.addJar(_clientJar);
249
250     Thread JavaDoc thread = Thread.currentThread();
251     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
252
253     try {
254       thread.setContextClassLoader(_loader);
255
256       if (log.isLoggable(Level.FINE))
257         log.log(Level.FINE, L.l("root-directory is {0}", _rootDirectory));
258
259       if (log.isLoggable(Level.FINER))
260         log.log(Level.FINER, L.l("work-directory is {0}", WorkDir.getLocalWorkDir()));
261
262       _ejbContext = new InitialContext JavaDoc(_ejbEnv);
263
264       JarPath jarPath = JarPath.create(_clientJar);
265
266       configureFrom(jarPath.lookup("META-INF/application-client.xml"), true, true);
267       configureFrom(jarPath.lookup("META-INF/resin-application-client.xml"), true, false);
268
269       if (_mainClassName == null)
270         throw new ConfigException(L.l("'main-class' is required"));
271
272       Class JavaDoc<?> mainClass = Class.forName(_mainClassName, false, _loader);
273
274       ArrayList JavaDoc<BuilderProgram> programList
275         = InjectIntrospector.introspectStatic(mainClass);
276
277       for (BuilderProgram program : programList) {
278         if (log.isLoggable(Level.FINER))
279           log.log(Level.FINER, "configure: " + program);
280
281         program.configure((Object JavaDoc) null);
282       }
283
284       _mainMethod = mainClass.getMethod("main", String JavaDoc[].class);
285
286       _lifecycle.setName(toString());
287       _lifecycle.toInit();
288     } finally {
289       thread.setContextClassLoader(oldLoader);
290     }
291   }
292
293   private void configureFrom(Path xml, boolean optional, boolean validate)
294     throws Exception JavaDoc
295   {
296     if (xml.canRead()) {
297       if (log.isLoggable(Level.FINE))
298         log.log(Level.FINE, L.l("reading configuration file {0}", xml));
299
300       if (validate)
301         new Config().configureBean(this, xml, "com/caucho/server/e_app/app-client.rnc");
302       else
303         new Config().configureBean(this, xml);
304     }
305     else {
306       if (!optional)
307         throw new ConfigException(L.l("missing required configuration file {0}", xml));
308
309       if (log.isLoggable(Level.FINEST))
310         log.log(Level.FINEST, L.l("no configuration file {0}", xml));
311     }
312   }
313
314   public void run()
315     throws Exception JavaDoc
316   {
317     init();
318
319     Thread JavaDoc thread = Thread.currentThread();
320     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
321
322     try {
323       thread.setContextClassLoader(_loader);
324
325       _mainMethod.invoke(null, new Object JavaDoc[] { _mainArgs });
326     } finally {
327       thread.setContextClassLoader(oldLoader);
328     }
329   }
330
331   public String JavaDoc toString()
332   {
333     return "AppClient[" + _clientJar + "," + _mainClassName + "]";
334   }
335
336   public static void main(String JavaDoc []args)
337     throws Throwable JavaDoc
338   {
339     String JavaDoc clientJar = null;
340     String JavaDoc main = null;
341     String JavaDoc conf = null;
342     String JavaDoc workDir = null;
343     String JavaDoc []mainArgs = null;
344
345     EnvironmentClassLoader.initializeEnvironment();
346
347     for (int i = 0; i < args.length; i++) {
348       String JavaDoc arg = args[i];
349
350       if (arg.startsWith("-")) {
351         String JavaDoc option = arg.substring((arg.startsWith("--")) ? 2 : 1);
352
353         if (option.equals("conf")) {
354           conf = args[++i];
355           continue;
356         }
357         else if (option.equals("client-jar")) {
358           clientJar = args[++i];
359           continue;
360         }
361         else if (option.equals("work-dir")) {
362           workDir = args[++i];
363           continue;
364         }
365         else if (option.equals("main")) {
366           main = args[++i];
367
368           mainArgs = new String JavaDoc[args.length - i - 1];
369           System.arraycopy(args, i + 1, mainArgs, 0, mainArgs.length);
370           break;
371         }
372       }
373
374       throw new ConfigException(L.l("unknown arg '{0}'", args[i]));
375     }
376
377     AppClient appClient = new AppClient();
378
379     if (workDir != null)
380       appClient.setWorkDirectory(Vfs.lookup(workDir));
381
382     if (clientJar != null)
383       appClient.setClientJar(Vfs.lookup(clientJar));
384
385     if (conf != null)
386       appClient.addConfig(Vfs.lookup(conf));
387
388     if (main != null)
389       appClient.setMainClass(main);
390
391     if (mainArgs != null)
392       appClient.setMainArgs(mainArgs);
393
394     appClient.run();
395   }
396
397   public class CallbackManager
398   {
399     private final NameCallback JavaDoc _nameCallback;
400     private final PasswordCallback JavaDoc _passwordCallback;
401
402     public CallbackManager()
403     {
404       _nameCallback = new NameCallback JavaDoc(L.l("Name"));
405       _passwordCallback = new PasswordCallback JavaDoc(L.l("Password"), false);
406
407     }
408
409     public void handle(CallbackHandler JavaDoc handler)
410       throws IOException JavaDoc, UnsupportedCallbackException JavaDoc
411     {
412       Callback JavaDoc[] callbacks = new Callback JavaDoc[]{
413         _nameCallback,
414         _passwordCallback
415       };
416
417       handler.handle(callbacks);
418     }
419
420     public String JavaDoc getName()
421     {
422       return _nameCallback.getName();
423     }
424
425     public String JavaDoc getPassword()
426     {
427       return new String JavaDoc(_passwordCallback.getPassword());
428     }
429   }
430 }
431
432
Popular Tags