1 package com.tirsen.nanning.attribute; 2 3 import java.io.File ; 4 import java.io.FileOutputStream ; 5 import java.io.IOException ; 6 import java.io.OutputStream ; 7 import java.lang.reflect.Field ; 8 import java.lang.reflect.Method ; 9 import java.util.HashMap ; 10 import java.util.Iterator ; 11 import java.util.Map ; 12 import java.util.Properties ; 13 14 public class ClassPropertiesHelper { 15 16 private static Map methodSignatureCache = new HashMap (); 17 18 private static final String CLASS_PREFIX = "class"; 19 private static final String FIELD_PREFIX = "field"; 20 private static final String METHOD_PREFIX = "method"; 21 22 Properties properties; 23 private String className; 24 private String packageName; 25 private ClassAttributes targetClassAttributes; 26 private Class attributeClass; 27 28 public ClassPropertiesHelper() { 29 properties = new Properties (); 30 } 31 32 public ClassPropertiesHelper(ClassAttributes classAttributes) { 33 this(); 34 setTargetClassAttributes(classAttributes); 35 } 36 37 public String getClassName() { 38 return className; 39 } 40 41 public void setClassName(String className) { 42 this.className = className; 43 } 44 45 public void setTargetClassAttributes(ClassAttributes classAttributes) { 46 targetClassAttributes = classAttributes; 47 setAttributeClass(classAttributes.getAttributeClass()); 48 } 49 50 private void setAttributeClass(Class attributeClass) { 51 this.attributeClass = attributeClass; 52 if (attributeClass != null) { 53 className = className(attributeClass); 54 packageName = packageName(attributeClass); 55 } 56 } 57 58 void loadAttributes(Properties properties) { 59 assert targetClassAttributes != null; 60 61 this.properties = properties; 62 63 for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext();) { 64 Map.Entry entry = (Map.Entry ) iterator.next(); 65 String propertyName = (String ) entry.getKey(); 66 String attributeValue = (String ) entry.getValue(); 67 68 String [] parts = propertyName.split("\\."); 69 if (CLASS_PREFIX.equals(parts[0])) { 70 String attributeName = joinTail(parts, 1); 71 loadClassAttribute(attributeName, attributeValue); 72 } else if (FIELD_PREFIX.equals(parts[0])) { 73 String attributeName = joinTail(parts, 2); 74 String fieldName = parts[1]; 75 loadFieldAttribute(fieldName, attributeName, attributeValue); 76 } else if (METHOD_PREFIX.equals(parts[0])) { 77 String attributeName = joinTail(parts, 2); 78 String methodSignature = parts[1]; 79 loadMethodAttribute(methodSignature, attributeName, attributeValue); 80 } else { 81 throw new AttributeException("Invalid property " + propertyName); 82 } 83 } 84 } 85 86 void loadMethodAttribute(String methodSignature, String attributeName, String attributeValue) { 87 assert methodSignature.indexOf('(') != -1 && methodSignature.indexOf(')') != -1: 88 "method signature of wrong format: " + methodSignature; 89 if (targetClassAttributes != null) { 90 Method method = findMethod(methodSignature); 91 if (method == null) { 92 throw new AttributeException("Error while loading attributes, could not find method: " + 93 methodSignature + " for " + attributeClass); 94 } 95 96 targetClassAttributes.setMethodAttribute(method, attributeName, attributeValue); 97 } 98 properties.put(METHOD_PREFIX + "." + methodSignature + "." + attributeName, attributeValue); 99 } 100 101 void loadFieldAttribute(String fieldName, String attributeName, String attributeValue) { 102 if (targetClassAttributes != null) { 103 try { 104 Field field = attributeClass.getDeclaredField(fieldName); 105 targetClassAttributes.setFieldAttribute(field, attributeName, attributeValue); 106 } catch (Exception e) { 107 throw new AttributeException("Error while loading attributes, could not find field: " + 108 fieldName + " for " + attributeClass, e); 109 } 110 } 111 properties.put(FIELD_PREFIX + "." + fieldName + "." + attributeName, attributeValue); 112 } 113 114 void loadClassAttribute(String attributeName, String attributeValue) { 115 if (targetClassAttributes != null) { 116 if (attributeClass != null) { 117 targetClassAttributes.setClassAttribute(attributeName, attributeValue); 118 } 119 } 120 properties.put(CLASS_PREFIX + "." + attributeName, attributeValue); 121 } 122 123 private Method findMethod(String methodSignature) { 124 Method [] declaredMethods = attributeClass.getDeclaredMethods(); 125 for (int i = 0; i < declaredMethods.length; i++) { 126 Method method = declaredMethods[i]; 127 if (methodSignature(method).equals(methodSignature)) { 128 return method; 129 } 130 } 131 return null; 132 } 133 134 public static String joinTail(String [] parts, int firstIndex) { 135 StringBuffer result = new StringBuffer (); 136 for (int i = firstIndex; i < parts.length; i++) { 137 String part = parts[i]; 138 result.append(part); 139 if (i < parts.length - 1) { 140 result.append("."); 141 } 142 } 143 return result.toString(); 144 } 145 146 static String methodSignature(Method method) { 147 String signature = (String ) methodSignatureCache.get(method); 148 if (signature == null) { 149 StringBuffer stringBuffer = new StringBuffer (); 150 stringBuffer.append(method.getName()); 151 stringBuffer.append('('); 152 Class [] parameterTypes = method.getParameterTypes(); 153 for (int i = 0; i < parameterTypes.length; i++) { 154 Class parameterType = parameterTypes[i]; 155 if (parameterType.isArray()) { 156 parameterType = parameterType.getComponentType(); 157 } 158 String type = parameterType.getName(); 159 type = type.substring(type.lastIndexOf('.') + 1); 160 stringBuffer.append(type); 161 if (i + 1 < parameterTypes.length) { 162 stringBuffer.append(','); 163 } 164 } 165 stringBuffer.append(')'); 166 signature = stringBuffer.toString(); 167 methodSignatureCache.put(method, signature); 168 } 169 return signature; 170 } 171 172 public String getPackageName() { 173 return packageName; 174 } 175 176 public void setPackageName(String packageName) { 177 this.packageName = packageName; 178 } 179 180 static String className(Class klass) { 181 String className = klass.getName(); 182 return className.substring(className.lastIndexOf('.') + 1); 183 } 184 185 static String packageName(Class klass) { 186 String className = klass.getName(); 187 int lastDot = className.lastIndexOf('.'); 188 if (lastDot == -1) { 189 return ""; 190 } 191 return className.substring(0, lastDot); 192 } 193 194 public void transferAttributesToTarget() { 195 loadAttributes(properties); 196 } 197 198 public File getAttributeFile(File baseDir) { 199 return new File (baseDir, getPackageName().replace('.', File.separatorChar) + File.separator + getClassName() + 200 PropertyFileAttributeLoader.ATTRIBUTE_FILE_SUFFIX); 201 } 202 203 public void store(File dest) throws IOException { 204 OutputStream output = new FileOutputStream (getAttributeFile(dest)); 205 try { 206 properties.store(output, getPackageName() + "." + getClassName()); 207 } finally { 208 output.close(); 209 } 210 } 211 } 212
| Popular Tags
|