1 19 20 package org.apache.cayenne.jpa.map; 21 22 import java.lang.reflect.Field ; 23 import java.lang.reflect.Member ; 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.Modifier ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.HashMap ; 29 import java.util.Map ; 30 import java.util.regex.Matcher ; 31 import java.util.regex.Pattern ; 32 33 import org.apache.cayenne.enhancer.EnhancementHelper; 34 35 41 public class JpaClassDescriptor { 42 43 private static final Pattern GETTER_PATTERN = Pattern 44 .compile("^(is|get)([A-Z])(.*)$"); 45 private static final Pattern SETTER_PATTERN = Pattern.compile("^set([A-Z])(.*)$"); 46 47 protected Collection <JpaPropertyDescriptor> fieldDescriptors; 48 protected Collection <JpaPropertyDescriptor> propertyDescriptors; 49 protected Class managedClass; 50 protected AccessType access; 51 52 public static String propertyNameForGetter(String getterName) { 53 Matcher getMatch = GETTER_PATTERN.matcher(getterName); 54 if (getMatch.matches()) { 55 return getMatch.group(2).toLowerCase() + getMatch.group(3); 56 } 57 58 return null; 59 } 60 61 public static String propertyNameForSetter(String setterName) { 62 Matcher setMatch = SETTER_PATTERN.matcher(setterName); 63 64 if (setMatch.matches()) { 65 return setMatch.group(1).toLowerCase() + setMatch.group(2); 66 } 67 68 return null; 69 } 70 71 public JpaClassDescriptor(Class managedClass) { 72 this.managedClass = managedClass; 73 } 74 75 public Class getManagedClass() { 76 return managedClass; 77 } 78 79 public AccessType getAccess() { 80 return access; 81 } 82 83 public void setAccess(AccessType access) { 84 this.access = access; 85 } 86 87 92 public JpaPropertyDescriptor getProperty(String name) { 93 if (getAccess() == AccessType.FIELD) { 94 for (JpaPropertyDescriptor d : getFieldDescriptors()) { 95 if (name.equals(d.getName())) { 96 return d; 97 } 98 } 99 } 100 else if (getAccess() == AccessType.PROPERTY) { 101 for (JpaPropertyDescriptor d : getPropertyDescriptors()) { 102 if (name.equals(d.getName())) { 103 return d; 104 } 105 } 106 } 107 108 return null; 109 } 110 111 116 public JpaPropertyDescriptor getPropertyForMember(Member classMember) { 117 if (classMember instanceof Field ) { 118 for (JpaPropertyDescriptor d : getFieldDescriptors()) { 119 if (d.getMember().equals(classMember)) { 120 return d; 121 } 122 } 123 } 124 else if (classMember instanceof Method ) { 125 for (JpaPropertyDescriptor d : getPropertyDescriptors()) { 126 if (d.getMember().equals(classMember)) { 127 return d; 128 } 129 } 130 } 131 132 return null; 133 } 134 135 public Collection <JpaPropertyDescriptor> getFieldDescriptors() { 136 if (fieldDescriptors == null) { 137 compileFields(); 138 } 139 140 return fieldDescriptors; 141 } 142 143 147 public Collection <JpaPropertyDescriptor> getPropertyDescriptors() { 148 if (propertyDescriptors == null) { 149 compileProperties(); 150 } 151 152 return propertyDescriptors; 153 } 154 155 protected void compileFields() { 156 157 Field [] fields = managedClass.getDeclaredFields(); 158 fieldDescriptors = new ArrayList <JpaPropertyDescriptor>(fields.length); 159 160 for (int i = 0; i < fields.length; i++) { 161 162 int modifiers = fields[i].getModifiers(); 163 if (Modifier.isTransient(modifiers)) { 165 continue; 166 } 167 168 if (Modifier.isStatic(modifiers)) { 170 continue; 171 } 172 173 if (EnhancementHelper.isGeneratedField(fields[i].getName())) { 175 continue; 176 } 177 178 fieldDescriptors.add(new JpaPropertyDescriptor(fields[i])); 179 } 180 } 181 182 protected void compileProperties() { 183 184 Map <String , PropertyTuple> properties = new HashMap <String , PropertyTuple>(); 185 186 191 193 200 Method [] methods = managedClass.getDeclaredMethods(); 201 for (int i = 0; i < methods.length; i++) { 202 203 int modifiers = methods[i].getModifiers(); 204 if (!Modifier.isProtected(modifiers) && !Modifier.isPublic(modifiers)) { 205 continue; 206 } 207 208 String name = methods[i].getName(); 209 Class [] parameters = methods[i].getParameterTypes(); 210 Class returnType = methods[i].getReturnType(); 211 boolean isVoid = Void.TYPE.equals(returnType); 212 213 if (!isVoid && parameters.length == 0) { 214 String propertyName = propertyNameForGetter(name); 215 216 if (propertyName != null) { 217 String key = propertyName + ":" + returnType.getName(); 218 PropertyTuple t = properties.get(key); 219 if (t == null) { 220 t = new PropertyTuple(); 221 properties.put(key, t); 222 } 223 224 t.getter = methods[i]; 225 t.name = propertyName; 226 continue; 227 } 228 } 229 230 if (isVoid && parameters.length == 1) { 231 String propertyName = propertyNameForSetter(name); 232 233 if (propertyName != null) { 234 235 String key = propertyName + ":" + parameters[0].getName(); 236 237 PropertyTuple t = properties.get(key); 238 if (t == null) { 239 t = new PropertyTuple(); 240 properties.put(key, t); 241 } 242 243 t.setter = methods[i]; 244 } 245 } 246 } 247 248 this.propertyDescriptors = new ArrayList <JpaPropertyDescriptor>(properties.size()); 249 250 for (PropertyTuple t : properties.values()) { 251 if (t.getter != null && t.setter != null) { 252 propertyDescriptors.add(new JpaPropertyDescriptor(t.getter, t.name)); 253 } 254 } 255 } 256 257 final class PropertyTuple { 258 259 String name; 260 Method getter; 261 Method setter; 262 } 263 } 264 | Popular Tags |