001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.server.e_app;
031:
032: import com.caucho.config.Config;
033: import com.caucho.config.ConfigException;
034: import com.caucho.config.types.EjbRef;
035: import com.caucho.ejb.AbstractStubLoader;
036: import com.caucho.ejb.EJBClientInterface;
037: import com.caucho.java.WorkDir;
038: import com.caucho.lifecycle.Lifecycle;
039: import com.caucho.loader.Environment;
040: import com.caucho.loader.EnvironmentBean;
041: import com.caucho.loader.EnvironmentClassLoader;
042: import com.caucho.log.Log;
043: import com.caucho.naming.Jndi;
044: import com.caucho.server.deploy.DeployInstance;
045: import com.caucho.util.Alarm;
046: import com.caucho.util.L10N;
047: import com.caucho.vfs.Depend;
048: import com.caucho.vfs.JarPath;
049: import com.caucho.vfs.Path;
050: import com.caucho.vfs.Vfs;
051:
052: import javax.annotation.PostConstruct;
053: import javax.naming.InitialContext;
054: import javax.rmi.PortableRemoteObject;
055: import java.lang.reflect.Method;
056: import java.util.ArrayList;
057: import java.util.HashMap;
058: import java.util.Hashtable;
059: import java.util.jar.Manifest;
060: import java.util.logging.Level;
061: import java.util.logging.Logger;
062:
063: /**
064: * An enterprise application (ear)
065: */
066: public class EntAppClient implements DeployInstance, EnvironmentBean {
067: /* implements EnvironmentBean, EnvironmentListener, AlarmListener */
068:
069: static final L10N L = new L10N(EntAppClient.class);
070: static final Logger log = Log.open(EntAppClient.class);
071:
072: private EnvironmentClassLoader _loader;
073:
074: private String _name;
075:
076: private Path _rootDir;
077:
078: private Path _archivePath;
079:
080: private String _mainClass;
081:
082: private String _prefix = "";
083:
084: private AppClientDeployController _entry;
085:
086: private AbstractStubLoader _stubLoader;
087:
088: private ApplicationConfig _config;
089:
090: private JarPath _clientJar;
091:
092: private EJBClientInterface _ejbClient;
093:
094: private AppClientConfig _appClientConfig;
095:
096: private ArrayList<EjbLink> _links = new ArrayList<EjbLink>();
097:
098: private HashMap<String, EjbRef> _ejbRefMap = new HashMap<String, EjbRef>();
099:
100: private Throwable _configException;
101:
102: private Alarm _alarm;
103: private final Lifecycle _lifecycle;
104:
105: private static void log(String message) {
106: System.out.println(EntAppClient.class.getSimpleName() + ": "
107: + message);
108: }
109:
110: /**
111: * Creates the application.
112: */
113: EntAppClient(AppClientDeployController entry, String name) {
114: _entry = entry;
115: _name = name;
116:
117: ClassLoader parentLoader = Thread.currentThread()
118: .getContextClassLoader();
119:
120: _loader = new EnvironmentClassLoader(parentLoader);
121: //_loader.setOwner(this);
122: _loader.setId("EntAppClient[" + name + "]");
123:
124: _lifecycle = new Lifecycle(log, toString(), Level.INFO);
125:
126: if (entry.getArchivePath() != null)
127: Environment.addDependency(
128: new Depend(entry.getArchivePath()), _loader);
129:
130: // _alarm = new Alarm(this);
131: }
132:
133: /**
134: * Sets the name.
135: */
136: public void setName(String name) {
137: _name = name;
138: _loader.setId("EntAppClient[" + name + "]");
139: }
140:
141: /**
142: * Gets the name.
143: */
144: public String getName() {
145: return _name;
146: }
147:
148: /**
149: * Returns the ejb client.
150: */
151: public EJBClientInterface getEJBClient()
152: throws ClassNotFoundException, InstantiationException,
153: IllegalAccessException {
154: if (_ejbClient == null) {
155: Class cl = Class.forName("com.caucho.iiop.IiopClient");
156: _ejbClient = (EJBClientInterface) cl.newInstance();
157: }
158:
159: return _ejbClient;
160: }
161:
162: /**
163: * Sets the root directory.
164: */
165: public void setRootDirectory(Path rootDir) {
166: _rootDir = rootDir;
167: }
168:
169: /**
170: * Sets the root directory.
171: */
172: public Path getRootDirectory() {
173: return _rootDir;
174: }
175:
176: /**
177: * Sets the archive path
178: */
179: public void setArchivePath(Path archivePath) {
180: _archivePath = archivePath;
181: }
182:
183: /**
184: * Sets the description.
185: */
186: public void setDescription(String description) {
187: }
188:
189: /**
190: * Sets the display-name.
191: */
192: public void setDisplayName(String displayName) {
193: }
194:
195: /**
196: * Adds a module.
197: */
198: public Module createModule() {
199: return new Module();
200: }
201:
202: /**
203: * Adds an ejb-reference.
204: */
205: public void addEjbRef(EjbRef ejbRef) {
206: _ejbRefMap.put(ejbRef.getEjbRefName(), ejbRef);
207:
208: addIiopStub(ejbRef.getHome());
209: addIiopStub(ejbRef.getRemote());
210: }
211:
212: private void addIiopStub(Class stubClass) {
213: if (stubClass == null)
214: return;
215:
216: try {
217: if (_stubLoader == null) {
218: Class iiopClass = Class
219: .forName("com.caucho.iiop.IiopStubLoader");
220: _stubLoader = (AbstractStubLoader) iiopClass
221: .newInstance();
222: _stubLoader.setPath(WorkDir.getLocalWorkDir());
223: _loader.addLoader(_stubLoader);
224: }
225:
226: _stubLoader.addStubClass(stubClass.getName());
227: } catch (Throwable e) {
228: e.printStackTrace();
229:
230: log.info(e.toString());
231: }
232: }
233:
234: /**
235: * Gets an ejb home.
236: */
237: Class getEjbHome(String ejbName) throws ConfigException {
238: EjbRef ref = _ejbRefMap.get(ejbName);
239:
240: if (ref != null)
241: return ref.getHome();
242: else
243: return null;
244: }
245:
246: /**
247: * Sets the main class.
248: */
249: public void setMainClass(String mainClass) {
250: _mainClass = mainClass;
251: }
252:
253: /**
254: * Returns the class loader.
255: */
256: public EnvironmentClassLoader getClassLoader() {
257: return _loader;
258: }
259:
260: /**
261: * Sets the class loader.
262: */
263: public void setEnvironmentClassLoader(EnvironmentClassLoader loader) {
264: _loader = loader;
265: }
266:
267: /**
268: * Sets the config exception.
269: */
270: public void setConfigException(Throwable e) {
271: _configException = e;
272: }
273:
274: /**
275: * Gets the config exception.
276: */
277: public Throwable getConfigException() {
278: return _configException;
279: }
280:
281: /**
282: * Adds an EjbLink.
283: */
284: public EjbLink createEjbLink() {
285: EjbLink link = new EjbLink();
286:
287: _links.add(link);
288:
289: return link;
290: }
291:
292: /**
293: * Adds an EjbLink.
294: */
295: public SecurityRole createSecurityRole() {
296: return new SecurityRole();
297: }
298:
299: /**
300: * Stub for the xsi:schemaLocation tag.
301: */
302: public void setSchemaLocation(String s) {
303: }
304:
305: /**
306: * Stub for the version tag.
307: */
308: public void setVersion(String s) {
309: }
310:
311: /**
312: * Initialize the client.
313: */
314: @PostConstruct
315: public void init() {
316: log("INIT: " + _links);
317: if (!_lifecycle.toInit())
318: return;
319:
320: Thread thread = Thread.currentThread();
321: ClassLoader oldLoader = thread.getContextClassLoader();
322:
323: try {
324: thread.setContextClassLoader(_loader);
325:
326: Path rootDir = getRootDirectory();
327: Vfs.setPwd(rootDir);
328:
329: Path workDir = getRootDirectory().lookup("META-INF/work");
330: _loader.addJar(workDir);
331:
332: WorkDir.setLocalWorkDir(workDir);
333:
334: for (EjbLink link : _links) {
335: link.deploy();
336: }
337:
338: // configApplication();
339: } catch (Throwable e) {
340: e.printStackTrace();
341: log.log(Level.WARNING, e.toString(), e);
342:
343: _configException = e;
344: } finally {
345: thread.setContextClassLoader(oldLoader);
346: }
347: }
348:
349: private void configResinBinding() throws Exception {
350: Path rootDir = getRootDirectory();
351:
352: Path xml = rootDir.lookup("META-INF/resin-client.xml");
353:
354: if (!xml.canRead())
355: return;
356:
357: // AppClientBinding binding = new AppClientBinding(this);
358:
359: // builder.setCompactSchema("com/caucho/server/e_app/app-client.rnc");
360:
361: new Config().configure(this , xml);
362: }
363:
364: /**
365: * Return true for modified.
366: */
367: public boolean isModified() {
368: return false;
369: }
370:
371: /**
372: * Return true for modified.
373: */
374: public boolean isModifiedNow() {
375: return false;
376: }
377:
378: /**
379: * Log the reason for modification.
380: */
381: public boolean logModified(Logger log) {
382: return false;
383: }
384:
385: /**
386: * Return true is the deployment had an error.
387: */
388: public boolean isDeployError() {
389: return _configException != null;
390: }
391:
392: /**
393: * Return true is the deployment is idle
394: */
395: public boolean isDeployIdle() {
396: return false;
397: }
398:
399: /**
400: * Start the client.
401: */
402: public void start() {
403: init();
404:
405: if (!_lifecycle.toActive())
406: return;
407: }
408:
409: /**
410: * Execute the main class.
411: */
412: public void main(String[] args) throws Throwable {
413: if (_mainClass == null)
414: throw new IllegalStateException(L
415: .l("main() method require a main class"));
416:
417: main(_mainClass, args);
418: }
419:
420: /**
421: * Execute the main class.
422: */
423: public void main(String mainClassName, String[] args)
424: throws Throwable {
425: start();
426:
427: log("MAIN: " + mainClassName);
428: log("C: " + System.getProperty("java.class.path"));
429:
430: if (_configException != null)
431: throw _configException;
432:
433: if (!_lifecycle.isActive())
434: throw new IllegalStateException(L.l("{0} is not active.",
435: this ));
436:
437: Thread thread = Thread.currentThread();
438: ClassLoader oldLoader = thread.getContextClassLoader();
439:
440: try {
441: thread.setContextClassLoader(_loader);
442:
443: Class mainClass = Class.forName(mainClassName, false,
444: _loader);
445:
446: log("MAIN:");
447: Method main = mainClass.getMethod("main",
448: new Class[] { String[].class });
449:
450: try {
451: Class cl = Class
452: .forName(
453: "com.sun.ts.lib.implementation.sun.common.SunRIURL",
454: false, _loader);
455: log("CL: " + cl);
456: } catch (Throwable e) {
457: e.printStackTrace();
458: }
459:
460: main.invoke(null, new Object[] { args });
461: } finally {
462: thread.setContextClassLoader(oldLoader);
463: }
464: }
465:
466: /**
467: * Destroys the client.
468: */
469: public void destroy() {
470: if (!_lifecycle.toDestroy())
471: return;
472: }
473:
474: public String toString() {
475: return "EntAppClient[" + getName() + "]";
476: }
477:
478: public class EjbLink {
479: private String _ejbName;
480: private String _jndiName;
481: private Class _api;
482:
483: public void setEjbName(String ejbName) throws ConfigException {
484: _ejbName = ejbName;
485: }
486:
487: public void setJndiName(String jndiName) {
488: _jndiName = jndiName;
489: }
490:
491: public void deploy() throws Exception {
492: log("LINK: " + _jndiName + " " + _ejbName);
493: String orbHost = System
494: .getProperty("org.omg.CORBA.ORBInitialHost");
495: String orbPort = System
496: .getProperty("org.omg.CORBA.ORBInitialPort");
497:
498: Hashtable env = new Hashtable();
499: env.put("java.naming.factory.initial",
500: "com.sun.jndi.cosnaming.CNCtxFactory");
501: env.put("java.naming.provider.url", "iiop://" + orbHost
502: + ":" + orbPort);
503: javax.naming.Context ic = new InitialContext(env);
504:
505: Object ior = ic.lookup(_jndiName);
506:
507: _api = getEjbHome(_ejbName);
508:
509: if (_api == null)
510: throw new ConfigException(L.l(
511: "'{0}' is an unknown ejb name.", _ejbName));
512:
513: Object value = PortableRemoteObject.narrow(ior, _api);
514:
515: log("VALUE: " + value + " " + value.getClass() + " " + _api);
516: Jndi.rebindDeepShort(_ejbName, value);
517: }
518: }
519:
520: public class SecurityRole {
521: public void setId(String id) {
522: }
523:
524: public void addDescription(String description) {
525: }
526:
527: public void setRoleName(String roleName) {
528: }
529:
530: public void setRoleLink(String roleLink) {
531: }
532: }
533:
534: public class Module {
535: /**
536: * Sets the module id.
537: */
538: public void setId(String id) {
539: }
540:
541: /**
542: * Creates a new web module.
543: */
544: public void addWeb(WebModule web) throws Exception {
545: }
546:
547: /**
548: * Adds a new ejb module.
549: */
550: public void addEjb(Path path) throws Exception {
551: getClassLoader().addJar(path);
552:
553: getEJBClient().addEJBJar(path);
554:
555: getEJBClient().initEJBs();
556: }
557:
558: /**
559: * Adds a new java module.
560: */
561: public void addJava(Path path) throws Exception {
562: if (!path.canRead())
563: throw new ConfigException(L
564: .l("<java> module {0} must be a valid path.",
565: path));
566:
567: getClassLoader().addJar(path);
568:
569: _clientJar = JarPath.create(path);
570:
571: Manifest manifest = _clientJar.getManifest();
572: String mainClass = manifest.getMainAttributes().getValue(
573: "Main-Class");
574:
575: setMainClass(mainClass);
576:
577: Path appClient = _clientJar
578: .lookup("META-INF/application-client.xml");
579:
580: if (appClient.canRead())
581: new Config()
582: .configureBean(EntAppClient.this , appClient);
583: }
584:
585: /**
586: * Adds a new connector
587: */
588: public void addConnector(String path) {
589: }
590:
591: /**
592: * Adds a new alt-dd module.
593: */
594: public void addAltDD(String path) {
595: }
596: }
597: }
|