1 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 ; 31 import javax.naming.spi.ObjectFactory ; 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 37 { 38 private final static MLogger logger = MLog.getLogger( JavaBeanObjectFactory.class ); 39 40 final static Object NULL_TOKEN = new Object (); 41 42 public Object getObjectInstance(Object refObj, Name name, Context nameCtx, Hashtable env) 43 throws Exception 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 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 beanClass, Map refAddrsMap ) throws Exception 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 propertyName = pd.getName(); 76 Class propertyType = pd.getPropertyType(); 77 Object addr = refAddrsMap.remove( propertyName ); 78 if (addr != null) 79 { 80 if ( addr instanceof StringRefAddr ) 81 { 82 String content = (String ) ((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 ); else 98 out.put( propertyName, SerializableUtils.fromByteArray( content ) ); } 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 type = (String ) 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 createBlankInstance(Class beanClass) throws Exception 117 { return beanClass.newInstance(); } 118 119 protected Object findBean(Class beanClass, Map propertyMap, Set refProps ) throws Exception 120 { 121 Object 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 propertyName = pd.getName(); 129 Object value = propertyMap.get( propertyName ); 130 Method setter = pd.getWriteMethod(); 131 if (value != null) 132 { 133 if (setter != null) 134 setter.invoke( bean, new Object [] { (value == NULL_TOKEN ? null : value) } ); 135 else 136 { 137 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 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 |