View Javadoc
1 /*** 2 * Copyright (c) 2002, CodeStreet LLC. All rights reserved. 3 * <p> 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * <p> 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. Redistributions in binary 9 * form must reproduce the above copyright notice, this list of conditions and 10 * the following disclaimer in the documentation and/or other materials provided 11 * with the distribution. Neither the name of CodeStreet LLC. nor the names of 12 * its contributors may be used to endorse or promote products derived from this 13 * software without specific prior written permission. 14 * <p> 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 * <p> 27 */ 28 package com.codestreet.messageforge; 29 30 import java.lang.reflect.Method; 31 import java.lang.reflect.Modifier; 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.Map; 35 import java.util.Iterator; 36 37 /*** 38 * @author jawaid.hakim 39 */ 40 public abstract class BeanFactory 41 { 42 /*** 43 * Create bean information using reflection. All public getter/setter pairs 44 * are identified. In addition, if <code>private</code> array support has 45 * been requested then all getter/setter pairs that operate on arrays are 46 * also identified. 47 * 48 * @param name 49 * Bean name. 50 * @param bean 51 * Bean class. 52 * @return Bean information. 53 * @see #setAccessPrivateArrays(boolean) 54 */ 55 public static RBeanInfo createBeanInfo(String name, Class bean) 56 { 57 try 58 { 59 RBeanInfo info = (RBeanInfo) beanInfo_.get(name); 60 if (info != null) 61 return info; 62 63 if (bean == null) 64 return null; 65 66 Map getters = EMPTY; 67 Map setters = EMPTY; 68 69 Class beanCls = bean; 70 Map allSetterMethods = new HashMap(); 71 Method[] allPublicMethods = beanCls.getMethods(); 72 for (int i = 0; i < allPublicMethods.length; ++i) 73 { 74 Method setterMethod = allPublicMethods[i]; 75 String setterName = setterMethod.getName(); 76 if (setterName.startsWith("set") 77 && !allSetterMethods.containsKey(setterName)) 78 { 79 allSetterMethods.put(setterName, setterMethod); 80 } 81 } 82 Method[] declMethods = beanCls.getDeclaredMethods(); 83 for (int i = 0; i < declMethods.length; ++i) 84 { 85 Method setterMethod = declMethods[i]; 86 String setterName = setterMethod.getName(); 87 if (setterName.startsWith("set") 88 && !allSetterMethods.containsKey(setterName)) 89 { 90 allSetterMethods.put(setterName, setterMethod); 91 } 92 } 93 94 for (Iterator iter = allSetterMethods.values().iterator(); iter 95 .hasNext();) 96 { 97 Method setterMethod = (Method) iter.next(); 98 String setterName = setterMethod.getName(); 99 if (setterName.startsWith("set")) 100 { 101 int modifiers = setterMethod.getModifiers(); 102 Class[] paramTypes = setterMethod.getParameterTypes(); 103 if (paramTypes.length == 1 && !Modifier.isNative(modifiers)) 104 { 105 boolean isPublic = Modifier.isPublic(modifiers); 106 boolean qualifies = isPublic; 107 if (!isPublic && processPrivateArrays) 108 { 109 qualifies = paramTypes[0].isArray(); 110 if (qualifies) 111 { 112 try 113 { 114 setterMethod.setAccessible(true); 115 } 116 catch (Exception ex) 117 { 118 continue; 119 } 120 } 121 } 122 if (qualifies) 123 { 124 String getterName = setterName.replaceFirst("set", 125 "get"); 126 Method getterMethod = null; 127 try 128 { 129 getterMethod = beanCls.getDeclaredMethod( 130 getterName, null); 131 } 132 catch (NoSuchMethodException ex) 133 { 134 try 135 { 136 getterMethod = beanCls.getMethod( 137 getterName, null); 138 } 139 catch (NoSuchMethodException ex2) 140 { 141 continue; 142 } 143 } 144 145 if (!isPublic) 146 { 147 try 148 { 149 getterMethod.setAccessible(true); 150 } 151 catch (Exception ex) 152 { 153 continue; 154 } 155 } 156 if (getters == EMPTY) 157 { 158 getters = new HashMap(); 159 setters = new HashMap(); 160 } 161 String propertyName = getterName.substring(3); 162 getters.put(propertyName, getterMethod); 163 setters.put(propertyName, setterMethod); 164 } 165 } 166 } 167 } 168 169 if (getters != EMPTY) 170 info = new RBeanInfo(name, 171 Collections.unmodifiableMap(getters), Collections 172 .unmodifiableMap(setters)); 173 else 174 info = new RBeanInfo(name, EMPTY, EMPTY); 175 176 beanInfo_.put(name, info); 177 178 return info; 179 } 180 catch (Exception e) 181 { 182 return new RBeanInfo(name, EMPTY, EMPTY); 183 } 184 } 185 186 /*** 187 * Set flag to indicate whether private array fields should be accessed. 188 * When this flag is set to <code>true</code> the bean factory identifies 189 * <code>private</code> getter/setter pais that operate on arrays. An 190 * attempt is made to set the accessibility for each identified pair to 191 * <code>true</code>. If the attempt to set the accessibility succeeds 192 * then the private getter/setter pair is added to the bean's information 193 * set. 194 * 195 * @param flag 196 * Flag to indicate whether private array fields should be 197 * accessed. Default is <code>true</code>. If this is set to 198 * <code>true</code> then <code>private</code> array fields 199 * will be accessed. 200 * @see #createBeanInfo(String, Class) 201 */ 202 public static void setAccessPrivateArrays(boolean flag) 203 { 204 processPrivateArrays = flag; 205 } 206 207 private static Map beanInfo_ = new HashMap(); 208 209 private static final Map EMPTY = Collections.unmodifiableMap(new HashMap()); 210 211 public static boolean processPrivateArrays = false; 212 }

This page was automatically generated by Maven