KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > EjbServerManager


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.ejb;
31
32 import com.caucho.amber.entity.AmberEntityHome;
33 import com.caucho.amber.manager.AmberContainer;
34 import com.caucho.amber.manager.AmberPersistenceUnit;
35 import com.caucho.bytecode.ByteCodeClassMatcher;
36 import com.caucho.bytecode.ByteCodeClassScanner;
37 import com.caucho.bytecode.JClassLoader;
38 import com.caucho.config.ConfigException;
39 import com.caucho.config.types.FileSetType;
40 import com.caucho.ejb.admin.EJBAdmin;
41 import com.caucho.ejb.cfg.EjbConfig;
42 import com.caucho.ejb.entity.EntityKey;
43 import com.caucho.ejb.entity.EntityServer;
44 import com.caucho.ejb.entity.QEntityContext;
45 import com.caucho.ejb.metadata.Bean;
46 import com.caucho.ejb.protocol.EjbProtocolManager;
47 import com.caucho.ejb.xa.EjbTransactionManager;
48 import com.caucho.lifecycle.Lifecycle;
49 import com.caucho.loader.EnvironmentClassLoader;
50 import com.caucho.loader.EnvironmentListener;
51 import com.caucho.management.j2ee.EJBModule;
52 import com.caucho.management.j2ee.J2EEManagedObject;
53 import com.caucho.util.CharBuffer;
54 import com.caucho.util.L10N;
55 import com.caucho.vfs.JarPath;
56 import com.caucho.vfs.Path;
57 import com.caucho.vfs.TempBuffer;
58
59 import javax.jms.ConnectionFactory JavaDoc;
60 import javax.sql.DataSource JavaDoc;
61 import java.io.ByteArrayOutputStream JavaDoc;
62 import java.io.IOException JavaDoc;
63 import java.io.InputStream JavaDoc;
64 import java.util.ArrayList JavaDoc;
65 import java.util.Comparator JavaDoc;
66 import java.util.LinkedHashMap JavaDoc;
67 import java.util.Map JavaDoc;
68 import java.util.logging.Level JavaDoc;
69 import java.util.logging.Logger JavaDoc;
70 import java.util.zip.ZipEntry JavaDoc;
71 import java.util.zip.ZipInputStream JavaDoc;
72
73 /**
74  * Manages the EJBs.
75  */

76 public class EjbServerManager
77   implements EJBServerInterface, EnvironmentListener
78 {
79   private static final L10N L = new L10N(EjbServerManager.class);
80   protected static final Logger JavaDoc log = Logger.getLogger(EjbServerManager.class.getName());
81
82   private EnvironmentClassLoader _classLoader;
83
84   private EnvServerManager _envServerManager;
85
86   private boolean _autoCompile = true;
87
88   private boolean _entityLoadLazyOnTransaction = true;
89
90   protected boolean _allowJVMCall = true;
91   protected boolean _allowReferenceCall = true;
92
93   protected boolean _createDatabaseSchema;
94   protected boolean _validateDatabaseSchema;
95
96   private boolean _hasInitJdbc;
97   private ConfigException _initException;
98
99   private EjbConfig _ejbConfig;
100   
101   private AmberContainer _amberContainer;
102   private AmberPersistenceUnit _amberPersistenceUnit;
103
104   protected ConnectionFactory JavaDoc _jmsConnectionFactory;
105   private int _messageConsumerMax = 5;
106
107   private EntityKey _entityKey = new EntityKey();
108
109   private final Lifecycle _lifecycle = new Lifecycle(log, "ejb-manager");
110
111   private Map JavaDoc<String JavaDoc, J2EEManagedObject> _ejbModuleManagedObjectMap
112     = new LinkedHashMap JavaDoc<String JavaDoc, J2EEManagedObject>();
113
114   /**
115    * Create a server with the given prefix name.
116    */

117   EjbServerManager()
118   {
119     try {
120       _amberContainer = AmberContainer.getLocalContainer();
121
122       _amberPersistenceUnit = AmberContainer.getLocalContainer().createPersistenceUnit("resin-ejb");
123       _amberPersistenceUnit.setBytecodeGenerator(false);
124
125       _envServerManager = new EnvServerManager(_amberPersistenceUnit);
126
127       _ejbConfig = new EjbConfig(this);
128
129       _envServerManager.addEjbConfig(_ejbConfig);
130     } catch (RuntimeException JavaDoc e) {
131       throw e;
132     } catch (Exception JavaDoc e) {
133       throw new RuntimeException JavaDoc(e);
134     }
135   }
136
137   /**
138    * Returns the loader.
139    */

140   public EnvironmentClassLoader getClassLoader()
141   {
142     return _envServerManager.getClassLoader();
143   }
144
145   /**
146    * Returns the environment server manager.
147    */

148   public EnvServerManager getEnvServerManager()
149   {
150     return _envServerManager;
151   }
152
153   /**
154    * Returns the protocol manager.
155    */

156   public EjbProtocolManager getProtocolManager()
157   {
158     return _envServerManager.getProtocolManager();
159   }
160
161   /**
162    * Returns the transaction manager.
163    */

164   public EjbTransactionManager getTransactionManager()
165   {
166     return _envServerManager.getTransactionManager();
167   }
168
169   public AmberContainer getAmberContainer()
170   {
171     return _amberContainer;
172   }
173
174   public void setLocalJndiPrefix(String JavaDoc localJndiPrefix)
175   {
176     getProtocolManager().setLocalJndiPrefix(localJndiPrefix);
177   }
178
179   public String JavaDoc getLocalJndiPrefix()
180   {
181     return getProtocolManager().getLocalJndiPrefix();
182   }
183
184   public void setRemoteJndiPrefix(String JavaDoc remoteJndiPrefix)
185   {
186     getProtocolManager().setRemoteJndiPrefix(remoteJndiPrefix);
187   }
188
189   public String JavaDoc getRemoteJndiPrefix()
190   {
191     return getProtocolManager().getRemoteJndiPrefix();
192   }
193
194   /**
195    * Sets the data source for the container.
196    */

197   public void setDataSource(DataSource JavaDoc dataSource)
198   {
199     _amberContainer.setDataSource(dataSource);
200     _amberPersistenceUnit.setDataSource(dataSource);
201   }
202
203   /**
204    * Sets the data source for the container.
205    */

206   public DataSource JavaDoc getDataSource()
207   {
208     return _amberContainer.getDataSource();
209   }
210
211   /**
212    * The read-only data source for the container.
213    */

214   public void setReadDataSource(DataSource JavaDoc dataSource)
215   {
216     _amberContainer.setReadDataSource(dataSource);
217   }
218
219   /**
220    * The read-only data source for the container.
221    */

222   public DataSource JavaDoc getReadDataSource()
223   {
224     return _amberContainer.getReadDataSource();
225   }
226
227   /**
228    * The xa data source for the container.
229    */

230   public void setXADataSource(DataSource JavaDoc dataSource)
231   {
232     _amberContainer.setXADataSource(dataSource);
233   }
234
235   /**
236    * The read-only data source for the container.
237    */

238   public DataSource JavaDoc getXADataSource()
239   {
240     return _amberContainer.getXADataSource();
241   }
242
243   /**
244    * Sets the Resin isolation.
245    */

246   public void setResinIsolation(int resinIsolation)
247   {
248     getTransactionManager().setResinIsolation(resinIsolation);
249   }
250
251   /**
252    * Sets the Resin isolation for the container.
253    */

254   public int getResinIsolation()
255   {
256     return getTransactionManager().getResinIsolation();
257   }
258
259   /**
260    * Sets the JDBC isolation.
261    */

262   public void setJDBCIsolation(int jdbcIsolation)
263   {
264     getTransactionManager().setJDBCIsolation(jdbcIsolation);
265   }
266
267   /**
268    * Gets the JDBC isolation level.
269    */

270   public int getJDBCIsolation()
271   {
272     return getTransactionManager().getJDBCIsolation();
273   }
274
275   /**
276    * Gets the transaction timeout
277    */

278   public long getTransactionTimeout()
279   {
280     return getTransactionManager().getTransactionTimeout();
281   }
282
283   /**
284    * Sets the transaction timout.
285    */

286   public void setTransactionTimeout(long transactionTimeout)
287   {
288     getTransactionManager().setTransactionTimeout(transactionTimeout);
289   }
290
291   /**
292    * Gets the lazy-load on transaction
293    */

294   public boolean isEntityLoadLazyOnTransaction()
295   {
296     return _entityLoadLazyOnTransaction;
297   }
298
299   /**
300    * Sets the lazy-load on transaction
301    */

302   public void setEntityLoadLazyOnTransaction(boolean isLazy)
303   {
304     _entityLoadLazyOnTransaction = isLazy;
305   }
306
307   /**
308    * Sets the queue connection factory for the container.
309    */

310   public void setJMSConnectionFactory(ConnectionFactory JavaDoc factory)
311   {
312     _jmsConnectionFactory = factory;
313   }
314
315   /**
316    * Sets the consumer maximum for the container.
317    */

318   public void setMessageConsumerMax(int consumerMax)
319   {
320     _messageConsumerMax = consumerMax;
321   }
322
323   /**
324    * Sets the consumer maximum for the container.
325    */

326   public int getMessageConsumerMax()
327   {
328     return _messageConsumerMax;
329   }
330
331   /**
332    * Gets the queue connection factory for the container.
333    */

334   public ConnectionFactory JavaDoc getConnectionFactory()
335   {
336     return _jmsConnectionFactory;
337   }
338
339   /**
340    * Returns the work path.
341    */

342   public Path getWorkPath()
343   {
344     return _envServerManager.getWorkPath();
345   }
346
347   /**
348    * Sets the work path.
349    */

350   public void setWorkPath(Path workPath)
351   {
352     _envServerManager.setWorkPath(workPath);
353     // _workPath = workPath;
354
}
355
356   /**
357    * Returns true if the server should auto-compile.
358    */

359   public boolean isAutoCompile()
360   {
361     return _autoCompile;
362   }
363
364   /**
365    * Sets true if should auto-compile
366    */

367   public void setAutoCompile(boolean autoCompile)
368   {
369     _autoCompile = autoCompile;
370   }
371
372   /**
373    * Returns true if the server should allow POJO beans.
374    */

375   public boolean isAllowPOJO()
376   {
377     return _ejbConfig.isAllowPOJO();
378   }
379
380   /**
381    * Sets true if should allow POJO beans
382    */

383   public void setAllowPOJO(boolean allowPOJO)
384   {
385     _ejbConfig.setAllowPOJO(allowPOJO);
386   }
387
388   /**
389    * Sets whether clients in the same JVM can use a fast in-memory call.
390    */

391   public void setAllowJVMCall(boolean allowJVMCall)
392   {
393     _allowJVMCall = allowJVMCall;
394   }
395
396   /**
397    * Sets whether clients in the same class loader call can pass arguments
398    * by reference.
399    */

400   public void setAllowReferenceCall(boolean allowReferenceCall)
401   {
402     _allowReferenceCall = allowReferenceCall;
403   }
404
405   /**
406    * Sets true if database schema should be generated automatically.
407    */

408   public void setCreateDatabaseSchema(boolean create)
409   {
410     _createDatabaseSchema = create;
411
412     _amberPersistenceUnit.setCreateDatabaseTables(create);
413   }
414
415   /**
416    * True if database schema should be generated automatically.
417    */

418   public boolean getCreateDatabaseSchema()
419   {
420     return _createDatabaseSchema;
421   }
422
423   /**
424    * Sets true if database schema should be generated automatically.
425    */

426   public void setValidateDatabaseSchema(boolean validate)
427   {
428     _validateDatabaseSchema = validate;
429     
430     _amberPersistenceUnit.setValidateDatabaseTables(validate);
431   }
432
433   /**
434    * True if database schema should be generated automatically.
435    */

436   public boolean getValidateDatabaseSchema()
437   {
438     return _validateDatabaseSchema;
439   }
440
441   /**
442    * Gets the cache timeout.
443    */

444   public long getCacheTimeout()
445   {
446     return _envServerManager.getCacheTimeout();
447   }
448
449   /**
450    * Sets the cache timeout.
451    */

452   public void setCacheTimeout(long cacheTimeout)
453   {
454     _envServerManager.setCacheTimeout(cacheTimeout);
455   }
456
457   /**
458    * Gets the cache size.
459    */

460   public int getCacheSize()
461   {
462     return _envServerManager.getCacheSize();
463   }
464
465   /**
466    * Sets the cache size.
467    */

468   public void setCacheSize(int cacheSize)
469   {
470     _envServerManager.setCacheSize(cacheSize);
471   }
472
473   /**
474    * Returns the admin class.
475    */

476   public EJBAdmin getAdmin()
477   {
478     return _envServerManager.getAdmin();
479   }
480
481   /**
482    * Returns the ejb config.
483    */

484   public EjbConfig getConfig()
485   {
486     return _ejbConfig;
487   }
488
489   /**
490    * Adds a file-set.
491    */

492   public void addConfigFiles(FileSetType fileSet)
493   {
494     _ejbConfig.addFileSet(fileSet);
495   }
496       
497   /**
498    * Adds an EJB jar.
499    */

500   public void addEJBJar(Path path)
501     throws Exception JavaDoc
502   {
503     JarPath jar;
504
505     if (path instanceof JarPath)
506       jar = (JarPath) path;
507     else
508       jar = JarPath.create(path);
509
510     introspectJar(jar.getContainer());
511
512     Path descriptorPath = jar.lookup("META-INF/ejb-jar.xml");
513
514     if (descriptorPath.exists()) {
515       addEJBPath(path, descriptorPath);
516     }
517     
518     descriptorPath = jar.lookup("META-INF/resin-ejb-jar.xml");
519
520     if (descriptorPath.exists()) {
521       addEJBPath(path, descriptorPath);
522     }
523
524     Path metaInf = jar.lookup("META-INF");
525     if (metaInf.isDirectory()) {
526       String JavaDoc []metaList = metaInf.list();
527       for (int j = 0; j < metaList.length; j++) {
528     String JavaDoc metaName = metaList[j];
529     if (metaName.endsWith(".ejb")) {
530       Path metaPath = metaInf.lookup(metaName);
531     
532       addEJBPath(path, metaPath);
533     }
534       }
535     }
536   }
537
538   private void introspectJar(Path path)
539   {
540     try {
541       InputStream JavaDoc is = path.openRead();
542       
543       try {
544     ZipInputStream JavaDoc zipIs = new ZipInputStream JavaDoc(is);
545
546     ZipEntry JavaDoc entry;
547     TempBuffer tbuf = TempBuffer.allocate();
548     byte []buffer = tbuf.getBuffer();
549     
550     while ((entry = zipIs.getNextEntry()) != null) {
551       String JavaDoc classFileName = entry.getName();
552       
553       if (! classFileName.endsWith(".class"))
554         continue;
555
556       String JavaDoc className
557         = classFileName.substring(0, classFileName.length() - 6);
558       className = className.replace('/', '.');
559
560       ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
561
562       int size = 0;
563       int sublen;
564
565       while ((sublen = zipIs.read(buffer, 0, buffer.length)) > 0) {
566         bos.write(buffer, 0, sublen);
567
568         size += size;
569       }
570
571       bos.close();
572
573       byte []classBytes = bos.toByteArray();
574       ByteCodeClassMatcher matcher = new EjbClassMatcher();
575       ByteCodeClassScanner scanner
576         = new ByteCodeClassScanner(className,
577                        classBytes, 0, classBytes.length,
578                        matcher);
579
580       if (scanner.scan()) {
581         try {
582           Bean bean = new Bean(this);
583
584           bean.setType(className);
585
586           bean.init();
587         } catch (ConfigException e) {
588           throw e;
589         } catch (Exception JavaDoc e) {
590           throw new ConfigException(e);
591         }
592       }
593     }
594
595     zipIs.close();
596       } finally {
597     is.close();
598       }
599     } catch (IOException JavaDoc e) {
600       log.log(Level.FINE, e.toString(), e);
601     }
602   }
603
604   // callback
605
public void addEJBModule(String JavaDoc ejbModuleName)
606   {
607     J2EEManagedObject ejbModuleManagedObject = _ejbModuleManagedObjectMap.get(ejbModuleName);
608
609     if (ejbModuleManagedObject == null) {
610       ejbModuleManagedObject = J2EEManagedObject.register(new EJBModule(ejbModuleName));
611       _ejbModuleManagedObjectMap.put(ejbModuleName, ejbModuleManagedObject);
612     }
613   }
614
615   /**
616    * Adds an EJB configuration file.
617    */

618   public void addEJBPath(Path ejbModulePath, Path path)
619     throws ConfigException
620   {
621     _ejbConfig.addEJBPath(ejbModulePath, path);
622   }
623
624   /**
625    * interface callback.
626    */

627   public void initEJBs()
628     throws Exception JavaDoc
629   {
630     init();
631   }
632
633   /**
634    * interface callback.
635    */

636   public void init()
637     throws Exception JavaDoc
638   {
639     _envServerManager.init();
640
641     build();
642   }
643   
644   /**
645    * Initialize the manager after all the configuration files have been read.
646    */

647   public void build()
648     throws ConfigException
649   {
650     try {
651       _amberPersistenceUnit.init();
652
653       _ejbConfig.configure();
654
655       // initJdbc();
656
} catch (ConfigException e) {
657       throw e;
658     } catch (Exception JavaDoc e) {
659       throw new ConfigException(e);
660     }
661   }
662
663   public void start()
664     throws Exception JavaDoc
665   {
666     _envServerManager.start();
667   }
668
669   /**
670    * Return the jndi name for an ejb.
671    *
672    * @param path the archive-path or expand-path of a module
673    */

674   public AbstractServer getServer(Path path, String JavaDoc ejbName)
675   {
676     return _envServerManager.getServer(path, ejbName);
677   }
678
679   public AmberEntityHome getAmberEntityHome(String JavaDoc name)
680   {
681     return _amberPersistenceUnit.getEntityHome(name);
682   }
683
684   public AmberPersistenceUnit getAmberManager()
685   {
686     return _amberPersistenceUnit;
687   }
688
689   public JClassLoader getJClassLoader()
690   {
691     return getAmberManager().getJClassLoader();
692   }
693
694   /**
695    * Invalidates the caches for all the beans.
696    */

697   public void invalidateCache()
698   {
699   }
700
701   /**
702    * Adds a server.
703    */

704   public void addServer(AbstractServer server)
705   {
706     _envServerManager.addServer(server);
707   }
708
709   /**
710    * Adds a new entity.
711    */

712   public QEntityContext getEntity(EntityServer server, Object JavaDoc key)
713   {
714     return _envServerManager.getEntity(server, key);
715   }
716
717   /**
718    * Adds a new entity.
719    */

720   public QEntityContext putEntityIfNew(EntityServer server, Object JavaDoc key,
721                        QEntityContext context)
722   {
723     return _envServerManager.putEntityIfNew(server, key, context);
724   }
725
726   /**
727    * Adds a new entity.
728    */

729   public void removeEntity(EntityServer server, Object JavaDoc key)
730   {
731     _envServerManager.removeEntity(server, key);
732   }
733
734   /**
735    * Adds a new entity.
736    */

737   public void removeBeans(ArrayList JavaDoc<QEntityContext> beans, EntityServer server)
738   {
739     EnvServerManager manager = _envServerManager;
740
741     if (manager != null)
742       manager.removeBeans(beans, server);
743   }
744
745   /**
746    * Handles the case where the environment is starting (after init).
747    */

748   public void environmentStart(EnvironmentClassLoader loader)
749     throws Throwable JavaDoc
750   {
751     start();
752   }
753   
754   /**
755    * Handles the case where the environment is stopping
756    */

757   public void environmentStop(EnvironmentClassLoader loader)
758   {
759   }
760
761   /**
762    * Closes the container.
763    */

764   public void destroy()
765   {
766     if (! _lifecycle.toDestroy())
767       return;
768
769     ArrayList JavaDoc<J2EEManagedObject> ejbModuleManagedObjects;
770     EnvServerManager envServerManager;
771     
772     // ejbModuleManagedObjects does not need destroy
773
_ejbModuleManagedObjectMap.clear();
774
775     envServerManager = _envServerManager;
776     // ejb/0200
777
//_envServerManager = null;
778

779     // ejbConfig does not need destroy
780
_ejbConfig = null;
781
782     try {
783       envServerManager.destroy();
784     } catch (Throwable JavaDoc e) {
785       log.log(Level.WARNING, e.toString(), e);
786     }
787   }
788
789   class EjbClassMatcher implements ByteCodeClassMatcher {
790     public boolean isClassMatch(String JavaDoc className)
791     {
792       return false;
793     }
794
795     public boolean isMatch(CharBuffer annotationName)
796     {
797       if (annotationName.matches("javax.ejb.Stateless"))
798         return true;
799       else if (annotationName.matches("javax.ejb.Stateful"))
800         return true;
801       else if (annotationName.matches("javax.ejb.Session"))
802         return true;
803       else
804         return false;
805     }
806   }
807
808   /**
809    * Sorts the servers so they can be destroyed in a consistent order.
810    * (To make QA sane.)
811    */

812   static class ServerCmp implements Comparator JavaDoc<AbstractServer> {
813     public int compare(AbstractServer a, AbstractServer b)
814     {
815       return a.getEJBName().compareTo(b.getEJBName());
816     }
817   }
818 }
819
820
Popular Tags