1 package org.codehaus.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 }
This page was automatically generated by Maven