KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.*;
28 import java.util.*;
29 import javax.naming.*;
30 import com.mchange.v2.log.*;
31 import java.lang.reflect.Method JavaDoc;
32 import com.mchange.v2.lang.Coerce;
33 import com.mchange.v2.beans.BeansUtils;
34 import com.mchange.v2.ser.SerializableUtils;
35 import com.mchange.v2.ser.IndirectPolicy;
36
37 public class JavaBeanReferenceMaker implements ReferenceMaker
38 {
39     private final static MLogger logger = MLog.getLogger( JavaBeanReferenceMaker.class );
40
41     final static String JavaDoc REF_PROPS_KEY = "com.mchange.v2.naming.JavaBeanReferenceMaker.REF_PROPS_KEY";
42
43     final static Object JavaDoc[] EMPTY_ARGS = new Object JavaDoc[0];
44
45     final static byte[] NULL_TOKEN_BYTES = new byte[0];
46
47     String JavaDoc factoryClassName = "com.mchange.v2.naming.JavaBeanObjectFactory";
48     String JavaDoc defaultFactoryClassLocation = null;
49
50     Set referenceProperties = new HashSet();
51
52     ReferenceIndirector indirector = new ReferenceIndirector();
53
54     public Hashtable getEnvironmentProperties()
55     { return indirector.getEnvironmentProperties(); }
56
57     public void setEnvironmentProperties( Hashtable environmentProperties )
58     { indirector.setEnvironmentProperties( environmentProperties ); }
59
60     public void setFactoryClassName(String JavaDoc factoryClassName)
61     { this.factoryClassName = factoryClassName; }
62
63     public String JavaDoc getFactoryClassName()
64     { return factoryClassName; }
65
66     public String JavaDoc getDefaultFactoryClassLocation()
67     { return defaultFactoryClassLocation; }
68
69     public void setDefaultFactoryClassLocation( String JavaDoc defaultFactoryClassLocation )
70     { this.defaultFactoryClassLocation = defaultFactoryClassLocation; }
71
72     public void addReferenceProperty( String JavaDoc propName )
73     { referenceProperties.add( propName ); }
74
75     public void removeReferenceProperty( String JavaDoc propName )
76     { referenceProperties.remove( propName ); }
77
78     public Reference createReference( Object JavaDoc bean )
79     throws NamingException
80     {
81     try
82         {
83         BeanInfo bi = Introspector.getBeanInfo( bean.getClass() );
84         PropertyDescriptor[] pds = bi.getPropertyDescriptors();
85         List refAddrs = new ArrayList();
86         String JavaDoc factoryClassLocation = defaultFactoryClassLocation;
87
88         boolean using_ref_props = referenceProperties.size() > 0;
89
90         // we only include this so that on dereference we are not surprised to find some properties missing
91
if (using_ref_props)
92             refAddrs.add( new BinaryRefAddr( REF_PROPS_KEY, SerializableUtils.toByteArray( referenceProperties ) ) );
93
94         for (int i = 0, len = pds.length; i < len; ++i)
95             {
96             PropertyDescriptor pd = pds[i];
97             String JavaDoc propertyName = pd.getName();
98             //System.err.println("Making Reference: " + propertyName);
99

100             if (using_ref_props && ! referenceProperties.contains( propertyName ))
101                 {
102                 //System.err.println("Not a ref_prop -- continuing.");
103
continue;
104                 }
105
106             Class JavaDoc propertyType = pd.getPropertyType();
107             Method JavaDoc getter = pd.getReadMethod();
108             Method JavaDoc setter = pd.getWriteMethod();
109             if (getter != null && setter != null) //only use properties that are both readable and writable
110
{
111                 Object JavaDoc val = getter.invoke( bean, EMPTY_ARGS );
112                 //System.err.println( "val: " + val );
113
if (propertyName.equals("factoryClassLocation"))
114                     {
115                     if (String JavaDoc.class != propertyType)
116                         throw new NamingException(this.getClass().getName() + " requires a factoryClassLocation property to be a string, " +
117                                       propertyType.getName() + " is not valid.");
118                     factoryClassLocation = (String JavaDoc) val;
119                     }
120
121                 if (val == null)
122                     {
123                     RefAddr addMe = new BinaryRefAddr( propertyName, NULL_TOKEN_BYTES );
124                     refAddrs.add( addMe );
125                     }
126                 else if ( Coerce.canCoerce( propertyType ) )
127                     {
128                     RefAddr addMe = new StringRefAddr( propertyName, String.valueOf( val ) );
129                     refAddrs.add( addMe );
130                     }
131                 else //other Object properties
132
{
133                     RefAddr addMe = null;
134                     PropertyEditor pe = BeansUtils.findPropertyEditor( pd );
135                     if (pe != null)
136                         {
137                         pe.setValue( val );
138                         String JavaDoc textValue = pe.getAsText();
139                         if (textValue != null)
140                             addMe = new StringRefAddr( propertyName, textValue );
141                         }
142                     if (addMe == null) //property editor approach failed
143
addMe = new BinaryRefAddr( propertyName, SerializableUtils.toByteArray( val,
144                                                             indirector,
145                                                             IndirectPolicy.INDIRECT_ON_EXCEPTION ) );
146                     refAddrs.add( addMe );
147                     }
148                 }
149             else
150                 {
151 // System.err.println(this.getClass().getName() +
152
// ": Skipping " + propertyName + " because it is " + (setter == null ? "read-only." : "write-only."));
153

154                 if ( logger.isLoggable( MLevel.WARNING ) )
155                     logger.warning(this.getClass().getName() + ": Skipping " + propertyName +
156                            " because it is " + (setter == null ? "read-only." : "write-only."));
157                 }
158
159             }
160         Reference out = new Reference( bean.getClass().getName(), factoryClassName, factoryClassLocation );
161         for (Iterator ii = refAddrs.iterator(); ii.hasNext(); )
162             out.add( (RefAddr) ii.next() );
163         return out;
164         }
165     catch ( Exception JavaDoc e )
166         {
167         //e.printStackTrace();
168
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ) )
169             logger.log( MLevel.FINE, "Exception trying to create Reference.", e);
170
171         throw new NamingException("Could not create reference from bean: " + e.toString() );
172         }
173     }
174
175 }
176
177
Popular Tags