KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jca > Resource


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.jca;
31
32 import com.caucho.config.BuilderProgram;
33 import com.caucho.config.Config;
34 import com.caucho.config.ConfigException;
35 import com.caucho.config.types.InitProgram;
36 import com.caucho.jca.cfg.JavaMailConfig;
37 import com.caucho.jmx.IntrospectionMBean;
38 import com.caucho.jmx.Jmx;
39 import com.caucho.loader.ClassLoaderListener;
40 import com.caucho.loader.CloseListener;
41 import com.caucho.loader.Environment;
42 import com.caucho.loader.EnvironmentListener;
43 import com.caucho.loader.StartListener;
44 import com.caucho.naming.Jndi;
45 import com.caucho.util.CharBuffer;
46 import com.caucho.util.L10N;
47
48 import javax.annotation.PostConstruct;
49 import javax.management.Attribute JavaDoc;
50 import javax.management.MBeanAttributeInfo JavaDoc;
51 import javax.management.MBeanInfo JavaDoc;
52 import javax.management.MBeanServer JavaDoc;
53 import javax.management.NotificationFilter JavaDoc;
54 import javax.management.ObjectName JavaDoc;
55 import javax.naming.Context JavaDoc;
56 import javax.naming.InitialContext JavaDoc;
57 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
58 import javax.resource.spi.ResourceAdapter JavaDoc;
59 import java.lang.reflect.Constructor JavaDoc;
60 import java.lang.reflect.Method JavaDoc;
61 import java.util.ArrayList JavaDoc;
62 import java.util.logging.Level JavaDoc;
63 import java.util.logging.Logger JavaDoc;
64
65 /**
66  * Configuration for the init-param pattern.
67  */

68 public class Resource {
69   private static final Logger JavaDoc log
70     = Logger.getLogger(Resource.class.getName());
71   
72   private static L10N L = new L10N(Resource.class);
73
74   private Class JavaDoc _type;
75
76   private String JavaDoc _var;
77   private String JavaDoc _jndiName;
78   
79   private String JavaDoc _mbeanName;
80   
81   private Class JavaDoc _mbeanInterface;
82
83   // private ArrayList<BuilderProgram> _args = new ArrayList<BuilderProgram>();
84
private ArrayList JavaDoc<Object JavaDoc> _args = new ArrayList JavaDoc<Object JavaDoc>();
85
86   private boolean _isPreInit;
87   private boolean _localTransactionOptimization = true;
88   private boolean _shareable = true;
89
90   private Object JavaDoc _object;
91   private MBeanInfo JavaDoc _mbeanInfo;
92
93   /**
94    * Sets the config variable name.
95    */

96   public void setVar(String JavaDoc var)
97   {
98     _var = var;
99   }
100
101   /**
102    * Sets the JNDI name
103    */

104   public void setJndiName(String JavaDoc name)
105   {
106     _jndiName = name;
107   }
108
109   /**
110    * Gets the JNDI name
111    */

112   public String JavaDoc getJndiName()
113   {
114     return _jndiName;
115   }
116
117   /**
118    * Sets the mbean name
119    */

120   public void setMbeanName(String JavaDoc name)
121   {
122     _mbeanName = name;
123   }
124
125   /**
126    * Gets the mbean name
127    */

128   public String JavaDoc getMbeanName()
129   {
130     return _mbeanName;
131   }
132
133   /**
134    * Sets the class
135    */

136   public void setType(Class JavaDoc resourceClass)
137   {
138     if (resourceClass.getName().equals("javax.mail.Session"))
139       _type = JavaMailConfig.class;
140     else
141       _type = resourceClass;
142   }
143
144   /**
145    * Sets the class
146    */

147   public void setClass(Class JavaDoc resourceClass)
148   {
149     _type = resourceClass;
150   }
151
152   /**
153    * Gets the type;
154    */

155   public Class JavaDoc getType()
156   {
157     return _type;
158   }
159
160   /**
161    * Sets the class
162    */

163   public void setMBeanInterface(Class JavaDoc cl)
164   {
165     _mbeanInterface = cl;
166   }
167
168   /**
169    * Adds an argument.
170    */

171   /*
172   public void addArg(BuilderProgram builder)
173   {
174     _args.add(builder);
175   }
176   */

177   public void addArg(Object JavaDoc arg)
178   {
179     _args.add(arg);
180   }
181
182   /**
183    * Sets the local-transaction-optimization flag
184    */

185   public void setLocalTransactionOptimization(boolean enable)
186   {
187     _localTransactionOptimization = enable;
188   }
189
190   /**
191    * Sets the shareable
192    */

193   public void setShareable(boolean shareable)
194   {
195     _shareable = shareable;
196   }
197
198   /**
199    * Adds the init program
200    */

201   public void addInit(InitProgram init)
202     throws Throwable JavaDoc
203   {
204     preInit();
205
206     init.configure(_object);
207   }
208
209   /**
210    * Adds the listener program
211    */

212   public Object JavaDoc createListener()
213     throws Throwable JavaDoc
214   {
215     return createMbeanListener();
216   }
217
218   /**
219    * Adds the listener program
220    */

221   public Object JavaDoc createMbeanListener()
222     throws Throwable JavaDoc
223   {
224     preInit();
225
226     if (_mbeanName != null)
227       return new MBeanListener();
228     else
229       throw new ConfigException(L.l("<listener> needs a <resource> with an mbean-name."));
230   }
231
232   ObjectName JavaDoc getObjectName()
233     throws Throwable JavaDoc
234   {
235     preInit();
236
237     if (_mbeanName != null)
238       return Jmx.getObjectName(_mbeanName);
239     else
240       return null;
241   }
242
243   MBeanInfo JavaDoc getMBeanInfo()
244     throws Throwable JavaDoc
245   {
246     preInit();
247
248     return _mbeanInfo;
249   }
250
251   /**
252    * Initialize the resource.
253    */

254   private void preInit()
255     throws Throwable JavaDoc
256   {
257     if (_isPreInit)
258       return;
259     _isPreInit = true;
260
261     Object JavaDoc oldObject = null;
262
263     if (_jndiName != null) {
264       try {
265     String JavaDoc jndiName = Jndi.getFullName(_jndiName);
266
267     Context JavaDoc ic = new InitialContext JavaDoc();
268     oldObject = ic.lookup(_jndiName);
269       } catch (Exception JavaDoc e) {
270       }
271     }
272     
273     MBeanServer JavaDoc mbeanServer = Jmx.getMBeanServer();
274
275     ObjectName JavaDoc mbeanName = null;
276
277     if (_mbeanName != null)
278       mbeanName = Jmx.getObjectName(_mbeanName);
279
280     if (_type != null) {
281     }
282     else if (oldObject != null) {
283       _object = oldObject;
284       return;
285     }
286     else if (mbeanName != null &&
287          mbeanServer.getMBeanInfo(mbeanName) != null) {
288       return;
289     }
290     else
291       throw new ConfigException(L.l("<resource> configuration needs a <type>. The <type> is the class name of the resource bean."));
292
293     Constructor JavaDoc constructor = getConstructor(_args.size());
294
295     Class JavaDoc []params = constructor.getParameterTypes();
296       
297     Object JavaDoc []args = new Object JavaDoc[_args.size()];
298
299     /*
300     for (int i = 0; i < args.length; i++)
301       args[i] = _args.get(i).configure(params[i]);
302     */

303     for (int i = 0; i < args.length; i++)
304       args[i] = _args.get(i);
305
306     _object = constructor.newInstance(args);
307
308     if (mbeanName != null) {
309       Object JavaDoc mbean = _object;
310
311       if (_mbeanInterface != null)
312     mbean = new IntrospectionMBean(mbean, _mbeanInterface);
313       
314       Jmx.register(mbean, mbeanName);
315       _mbeanInfo = mbeanServer.getMBeanInfo(mbeanName);
316     }
317   }
318
319   /**
320    * Returns the constructor based on the length.
321    */

322   private Constructor JavaDoc getConstructor(int len)
323     throws Exception JavaDoc
324   {
325     Constructor JavaDoc []constructors = _type.getConstructors();
326
327     for (int i = 0; i < constructors.length; i++) {
328       if (constructors[i].getParameterTypes().length == len)
329     return constructors[i];
330     }
331
332     throw new ConfigException(L.l("`{0}' has no matching constructors.",
333                   _type.getName()));
334   }
335
336   /**
337    * Initialize the resource.
338    */

339   @PostConstruct
340   public void init()
341     throws Throwable JavaDoc
342   {
343     preInit();
344     
345     if (_type == null || _object == null)
346       return;
347     
348     Config.init(_object);
349     _object = Config.replaceObject(_object);
350
351     if (_object instanceof ClassLoaderListener) {
352       ClassLoaderListener listener = (ClassLoaderListener) _object;
353
354       Environment.addClassLoaderListener(listener);
355     }
356
357     if (_object instanceof EnvironmentListener) {
358       EnvironmentListener listener = (EnvironmentListener) _object;
359
360       Environment.addEnvironmentListener(listener);
361     }
362
363     Object JavaDoc jndiObject = _object;
364     boolean isStart = false;
365
366     if (_object instanceof ResourceAdapter JavaDoc) {
367       ResourceManagerImpl.addResource((ResourceAdapter JavaDoc) _object);
368       isStart = true;
369     }
370
371     if (_object instanceof ManagedConnectionFactory JavaDoc) {
372       ResourceManagerImpl rm = ResourceManagerImpl.createLocalManager();
373     
374       ManagedConnectionFactory JavaDoc mcf;
375       mcf = (ManagedConnectionFactory JavaDoc) _object;
376     
377       ConnectionPool cm = rm.createConnectionPool();
378
379       cm.setShareable(_shareable);
380       cm.setLocalTransactionOptimization(_localTransactionOptimization);
381       Object JavaDoc connectionFactory = cm.init(mcf);
382       cm.start();
383
384       jndiObject = connectionFactory;
385
386       isStart = true;
387     }
388
389     Method JavaDoc start = null;
390     try {
391       start = _object.getClass().getMethod("start", new Class JavaDoc[0]);
392     } catch (Throwable JavaDoc e) {
393     }
394
395     Method JavaDoc stop = null;
396     try {
397       stop = _object.getClass().getMethod("stop", new Class JavaDoc[0]);
398     } catch (Throwable JavaDoc e) {
399     }
400
401     if (_jndiName != null)
402       Jndi.bindDeepShort(_jndiName, jndiObject);
403
404     if (_var != null)
405       Config.setCurrentVar(_var, jndiObject);
406
407     if (isStart) {
408     }
409     else if (start != null || stop != null)
410       Environment.addEnvironmentListener(new StartListener(_object));
411     else if (CloseListener.getDestroyMethod(_object.getClass()) != null)
412       Environment.addClassLoaderListener(new CloseListener(_object));
413
414     if (log.isLoggable(Level.CONFIG))
415       logConfig();
416   }
417
418   private void logConfig()
419   {
420     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
421
422     if (_object instanceof ResourceAdapter JavaDoc)
423       sb.append("jca-resource");
424     else if (_object instanceof ManagedConnectionFactory JavaDoc)
425       sb.append("jca-resource");
426     else
427       sb.append("resource");
428
429     sb.append("[");
430     boolean hasValue = false;
431       
432     if (_jndiName != null) {
433       if (hasValue) sb.append(", ");
434       hasValue = true;
435       sb.append("jndi-name=" + _jndiName);
436     }
437     
438     if (_var != null) {
439       if (hasValue) sb.append(", ");
440       hasValue = true;
441       sb.append("var=" + _var);
442     }
443     
444     if (_mbeanName != null) {
445       if (hasValue) sb.append(", ");
446       hasValue = true;
447       sb.append("mbean-name=" + _mbeanName);
448     }
449       
450     if (_type != null) {
451       if (hasValue) sb.append(", ");
452       hasValue = true;
453       sb.append("type=" + _type);
454     }
455       
456     sb.append("]");
457
458     log.config(sb.toString() + " configured");
459   }
460
461   public String JavaDoc toString()
462   {
463     if (_mbeanName != null)
464       return "Resource[" + _mbeanName + "]";
465     else
466       return "Resource[" + _jndiName + "]";
467   }
468
469   public class MBeanInit {
470     public void setProperty(String JavaDoc attrName, BuilderProgram program)
471       throws Throwable JavaDoc
472     {
473       MBeanAttributeInfo JavaDoc attr = getAttribute(attrName);
474       if (attr == null)
475     throw new ConfigException(L.l("`{0}' is an unknown attribute for {1}",
476                       attrName, _mbeanName));
477
478       String JavaDoc typeName = attr.getType();
479       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
480       Class JavaDoc type = Class.forName(typeName, false, loader);
481
482       Object JavaDoc value = program.configure(type);
483       
484       MBeanServer JavaDoc server = Jmx.getMBeanServer();
485       
486       server.setAttribute(getObjectName(),
487               new Attribute JavaDoc(attr.getName(), value));
488     }
489
490     private MBeanAttributeInfo JavaDoc getAttribute(String JavaDoc key)
491       throws Throwable JavaDoc
492     {
493       MBeanInfo JavaDoc info = getMBeanInfo();
494
495       MBeanAttributeInfo JavaDoc []attrs = info.getAttributes();
496
497       if (attrs == null)
498     return null;
499
500       for (int i = 0; i < attrs.length; i++) {
501     if (attrs[i].getName().equals(key))
502       return attrs[i];
503       }
504
505       for (int i = 0; i < attrs.length; i++) {
506     if (convertName(attrs[i].getName()).equals(key))
507       return attrs[i];
508       }
509
510       return null;
511     }
512
513     private String JavaDoc convertName(String JavaDoc key)
514     {
515       CharBuffer cb = CharBuffer.allocate();
516
517       for (int i = 0; i < key.length(); i++) {
518     char ch = key.charAt(i);
519
520     if (! Character.isUpperCase(ch))
521       cb.append(ch);
522     else if (i == 0)
523       cb.append(Character.toLowerCase(ch));
524     else if (Character.isLowerCase(key.charAt(i - 1))) {
525       cb.append('-');
526       cb.append(Character.toLowerCase(ch));
527     }
528     else if (i + 1 != key.length() &&
529          Character.isLowerCase(key.charAt(i + 1))) {
530       cb.append('-');
531       cb.append(Character.toLowerCase(ch));
532     }
533     else
534       cb.append(Character.toLowerCase(ch));
535       }
536
537       return cb.close();
538     }
539   }
540
541   public class MBeanListener {
542     private String JavaDoc _mbeanName;
543     private Object JavaDoc _handback;
544     private NotificationFilter JavaDoc _filter;
545
546     public void setMBeanName(String JavaDoc name)
547     {
548       _mbeanName = name;
549     }
550
551     public String JavaDoc getMBeanName()
552     {
553       return _mbeanName;
554     }
555
556     public void setHandback(Object JavaDoc handback)
557     {
558       _handback = handback;
559     }
560
561     public Object JavaDoc getHandback()
562     {
563       return _handback;
564     }
565
566     @PostConstruct
567     public void init()
568       throws Throwable JavaDoc
569     {
570       if (_mbeanName != null) {
571     ObjectName JavaDoc mbeanName = Jmx.getObjectName(_mbeanName);
572
573     ObjectName JavaDoc listenerName = getObjectName();
574
575     MBeanServer JavaDoc server = Jmx.getMBeanServer();
576
577     server.addNotificationListener(mbeanName, listenerName,
578                        _filter, _handback);
579
580       }
581       else
582     throw new ConfigException(L.l("mbean name is required"));
583     }
584   }
585 }
586
587
Popular Tags