KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mchange > v2 > naming > JavaBeanObjectFactory


1 /*
2  * Distributed as part of c3p0 v.0.9.1
3  *
4  * Copyright (C) 2005 Machinery For Change, Inc.
5  *
6  * Author: Steve Waldman <swaldman@mchange.com>
7  *
8  * This library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License version 2.1, as
10  * published by the Free Software Foundation.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this software; see the file LICENSE. If not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */

22
23
24 package com.mchange.v2.naming;
25
26 import java.beans.*;
27 import java.util.*;
28 import javax.naming.*;
29 import com.mchange.v2.log.*;
30 import java.lang.reflect.Method JavaDoc;
31 import javax.naming.spi.ObjectFactory JavaDoc;
32 import com.mchange.v2.beans.BeansUtils;
33 import com.mchange.v2.lang.Coerce;
34 import com.mchange.v2.ser.SerializableUtils;
35
36 public class JavaBeanObjectFactory implements ObjectFactory JavaDoc
37 {
38     private final static MLogger logger = MLog.getLogger( JavaBeanObjectFactory.class );
39
40     final static Object JavaDoc NULL_TOKEN = new Object JavaDoc();
41
42     public Object JavaDoc getObjectInstance(Object JavaDoc refObj, Name name, Context nameCtx, Hashtable env)
43     throws Exception JavaDoc
44     {
45     if (refObj instanceof Reference)
46         {
47         Reference ref = (Reference) refObj;
48         Map refAddrsMap = new HashMap();
49         for (Enumeration e = ref.getAll(); e.hasMoreElements(); )
50             {
51             RefAddr addr = (RefAddr) e.nextElement();
52             refAddrsMap.put( addr.getType(), addr );
53             }
54         Class JavaDoc beanClass = Class.forName( ref.getClassName() );
55         Set refProps = null;
56         RefAddr refPropsRefAddr = (BinaryRefAddr) refAddrsMap.remove( JavaBeanReferenceMaker.REF_PROPS_KEY );
57         if ( refPropsRefAddr != null )
58             refProps = (Set) SerializableUtils.fromByteArray( (byte[]) refPropsRefAddr.getContent() );
59         Map propMap = createPropertyMap( beanClass, refAddrsMap );
60         return findBean( beanClass, propMap, refProps );
61         }
62     else
63         return null;
64     }
65
66     private Map createPropertyMap( Class JavaDoc beanClass, Map refAddrsMap ) throws Exception JavaDoc
67     {
68     BeanInfo bi = Introspector.getBeanInfo( beanClass );
69     PropertyDescriptor[] pds = bi.getPropertyDescriptors();
70
71     Map out = new HashMap();
72     for (int i = 0, len = pds.length; i < len; ++i)
73         {
74         PropertyDescriptor pd = pds[i];
75         String JavaDoc propertyName = pd.getName();
76         Class JavaDoc propertyType = pd.getPropertyType();
77         Object JavaDoc addr = refAddrsMap.remove( propertyName );
78         if (addr != null)
79             {
80             if ( addr instanceof StringRefAddr )
81                 {
82                 String JavaDoc content = (String JavaDoc) ((StringRefAddr) addr).getContent();
83                 if ( Coerce.canCoerce( propertyType ) )
84                     out.put( propertyName, Coerce.toObject( content, propertyType ) );
85                 else
86                     {
87                     PropertyEditor pe = BeansUtils.findPropertyEditor( pd );
88                     pe.setAsText( content );
89                     out.put( propertyName, pe.getValue() );
90                     }
91                 }
92             else if ( addr instanceof BinaryRefAddr )
93                 {
94                 byte[] content = (byte[]) ((BinaryRefAddr) addr).getContent();
95                 if ( content.length == 0 )
96                     out.put( propertyName, NULL_TOKEN ); //we use an empty array to mean null
97
else
98                     out.put( propertyName, SerializableUtils.fromByteArray( content ) ); //this will handle "indirectly serialized" objects.
99
}
100             else
101                 {
102                 if (logger.isLoggable( MLevel.WARNING ))
103                     logger.warning(this.getClass().getName() + " -- unknown RefAddr subclass: " + addr.getClass().getName());
104                 }
105             }
106         }
107     for ( Iterator ii = refAddrsMap.keySet().iterator(); ii.hasNext(); )
108         {
109         String JavaDoc type = (String JavaDoc) ii.next();
110         if (logger.isLoggable( MLevel.WARNING ))
111             logger.warning(this.getClass().getName() + " -- RefAddr for unknown property: " + type);
112         }
113     return out;
114     }
115
116     protected Object JavaDoc createBlankInstance(Class JavaDoc beanClass) throws Exception JavaDoc
117     { return beanClass.newInstance(); }
118
119     protected Object JavaDoc findBean(Class JavaDoc beanClass, Map propertyMap, Set refProps ) throws Exception JavaDoc
120     {
121     Object JavaDoc bean = createBlankInstance( beanClass );
122     BeanInfo bi = Introspector.getBeanInfo( bean.getClass() );
123     PropertyDescriptor[] pds = bi.getPropertyDescriptors();
124     
125     for (int i = 0, len = pds.length; i < len; ++i)
126         {
127         PropertyDescriptor pd = pds[i];
128         String JavaDoc propertyName = pd.getName();
129         Object JavaDoc value = propertyMap.get( propertyName );
130         Method JavaDoc setter = pd.getWriteMethod();
131         if (value != null)
132             {
133             if (setter != null)
134                 setter.invoke( bean, new Object JavaDoc[] { (value == NULL_TOKEN ? null : value) } );
135             else
136                 {
137                 //System.err.println(this.getClass().getName() + ": Could not restore read-only property '" + propertyName + "'.");
138
if (logger.isLoggable( MLevel.WARNING ))
139                     logger.warning(this.getClass().getName() + ": Could not restore read-only property '" + propertyName + "'.");
140                 }
141             }
142         else
143             {
144             if (setter != null)
145                 {
146                 if (refProps == null || refProps.contains( propertyName ))
147                     {
148                     //System.err.println(this.getClass().getName() +
149
//": WARNING -- Expected writable property '" + propertyName + "' left at default value");
150
if (logger.isLoggable( MLevel.WARNING ))
151                         logger.warning(this.getClass().getName() + " -- Expected writable property ''" + propertyName + "'' left at default value");
152                     }
153                 }
154             }
155         }
156     
157     return bean;
158     }
159 }
160
Popular Tags