1 package gov.bnl.gums.configuration;
2
3 import gov.bnl.gums.util.ClassUtils;
4 import gov.bnl.gums.util.StringUtil;
5
6 import java.lang.annotation.*;
7 import java.lang.ref.WeakReference;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Properties;
13 import java.lang.reflect.Method;
14
15 import javax.annotation.processing.*;
16
17 import javax.persistence.*;
18
19 @MappedSuperclass
20 @SupportedAnnotationTypes({"gov.bnl.gums.configuration.ConfigElement.PermanentField"})
21 public abstract class ConfigElement {
22 @Retention(RetentionPolicy.RUNTIME)
23 @Target({ElementType.METHOD})
24 public @interface ConfigFieldAnnotation {
25 String label();
26 String example() default "";
27 String help() default "";
28 int size() default 32;
29 String choices() default "";
30 int order() default -1;
31 boolean orderedList() default false;
32 boolean showInConciseView() default false;
33 }
34
35 public class ConfigField {
36 public String setterName;
37 public String getterName;
38 public String configFieldName;
39 public Class<?> type;
40 public ConfigFieldAnnotation configFieldAnnotation;
41 public Object value;
42 }
43
44 List<ConfigField> configurationFields;
45 protected WeakReference<Configuration> configurationRef = null;
46
47
48 protected String name;
49 protected String description;
50 protected String source;
51 private int id;
52
53 public ConfigElement() {
54 }
55
56 public ConfigElement(Configuration configuration, String name) {
57 configurationRef = new WeakReference<Configuration>(configuration);
58 setName(name);
59 configuration.addConfigElement(this);
60 }
61
62 public ConfigElement clone(Configuration configuration, boolean allowReplace) {
63 ConfigElement configElement = null;
64 try {
65 configElement = this.getClass().getConstructor().newInstance();
66 } catch (Exception e) {
67 throw new RuntimeException(e);
68 }
69 configElement.setConfiguration(configuration);
70 configElement.setName(name);
71 configuration.addConfigElement(this, allowReplace);
72
73 for (ConfigField field : getConfigFields()) {
74 try {
75 getClass().getMethod(field.setterName, String.class).invoke(configElement, field.value);
76 } catch (Exception e) {
77 throw new RuntimeException(e);
78 }
79 }
80 return configElement;
81 }
82
83 public boolean equals(Object obj) {
84 if (obj instanceof ConfigElement) {
85 ConfigElement ce = (ConfigElement) obj;
86 Iterator<ConfigField> it = getConfigFields().iterator();
87 while (it.hasNext()) {
88 ConfigField field = it.next();
89 Object value1 = null;
90 Object value2 = null;
91 try {
92 value1 = getClass().getMethod(field.getterName).invoke(this);
93 value2 = getClass().getMethod(field.getterName).invoke(ce);
94 } catch (Exception e) {
95 assert(false);
96 }
97 if ((value1 == null && value2 != null)
98 || (value1 != null && value2 == null)) {
99 return false;
100 }
101 if (value1 != null && value2 != null && !value1.equals(value2)) {
102 return false;
103 }
104 }
105 return true;
106 }
107 return false;
108 }
109
110 @ManyToOne
111 @JoinColumn(name = "configuration")
112 public Configuration getConfiguration() {
113 return configurationRef != null ? configurationRef.get() : null;
114 }
115
116 @Transient
117 public List<ConfigField> getConfigFields() {
118 if ((getConfiguration()!=null && !getConfiguration().isReadOnly()) || configurationFields==null) {
119 List<ConfigField> tempConfigurationFields = new ArrayList<ConfigField>();
120 Method[] methods = getClass().getMethods();
121 for (Method method : methods) {
122 ConfigField field = new ConfigField();
123 ConfigFieldAnnotation configFieldAnnotation = method.getAnnotation(ConfigFieldAnnotation.class);
124 if (configFieldAnnotation != null) {
125 field.configFieldAnnotation = configFieldAnnotation;
126 field.type = method.getParameterTypes()[0];
127 field.setterName = method.getName();
128 field.getterName = field.setterName.replace("set", "get");
129 try {
130 try {
131 field.value = getClass().getMethod(field.getterName, (Class<?>[])null).invoke(this, (Object[])null);
132 } catch (NoSuchMethodException e) {
133 field.getterName = field.setterName.replace("set", "is");
134 field.value = getClass().getMethod(field.getterName, (Class<?>[])null).invoke(this, (Object[])null);
135 }
136 String firstChar = field.setterName.substring(3, 4);
137 field.configFieldName = field.setterName.replace("set"+firstChar, firstChar.toLowerCase());
138 tempConfigurationFields.add(field);
139 }
140 catch (Exception e) {
141 throw new RuntimeException(e.getMessage());
142 }
143 }
144 }
145
146 configurationFields = new ArrayList<ConfigField>();
147 int max;
148 do {
149 max = -1;
150 int index = -1;
151 for (int i=0; i<tempConfigurationFields.size(); i++) {
152 ConfigField configField = tempConfigurationFields.get(i);
153 int order = configField.configFieldAnnotation.order();
154 if (order > max) {
155 max = order;
156 index = i;
157 }
158 }
159 if (index!=-1) {
160 configurationFields.add(0, tempConfigurationFields.get(index));
161 tempConfigurationFields.remove(index);
162 }
163 } while (max > -1);
164 for (int i=0; i<tempConfigurationFields.size(); i++)
165 configurationFields.add(tempConfigurationFields.get(i));
166 }
167 return configurationFields;
168 }
169
170 public String getDescription() {
171 return description;
172 }
173
174 public String getName() {
175 return name;
176 }
177
178 public String getSource() {
179 return source;
180 }
181
182 public int hashCode() {
183 return getName()==null ? 0 : getName().hashCode();
184 }
185
186 public void setConfiguration(Configuration configuration) {
187 configurationRef = new WeakReference<Configuration>(configuration);
188 }
189
190 @ConfigFieldAnnotation(label="Description", showInConciseView=true, order=2)
191 public void setDescription(String description) {
192 this.description = description;
193 }
194
195 @ConfigFieldAnnotation(label="Name", showInConciseView=true, order=1)
196 public void setName(String name) {
197 this.name = name;
198 }
199
200 @ConfigFieldAnnotation(label="Source", example="OSG", showInConciseView=true, order=3)
201 public void setSource(String source) {
202 this.source = source;
203 }
204
205 @SuppressWarnings("unchecked")
206 public String toString() {
207 StringBuffer sb = new StringBuffer();
208 sb.append(ClassUtils.getClassName(this.getClass()) + ": ");
209 Iterator<ConfigField> it = getConfigFields().iterator();
210 while (it.hasNext()) {
211 ConfigField field = it.next();
212 if (field.value instanceof String)
213 sb.append(field.configFieldName + "='" + field.value + "'");
214 else if (field.configFieldName.equals("properties")) {
215 Properties properties = (Properties)field.value;
216 for (Object property : properties.keySet())
217 sb.append(property + "='" + properties.get(property) + "'");
218 } else if (field.value instanceof Collection) {
219 sb.append(field.configFieldName + "='");
220 Iterator<String> it2 = ((Collection<String>) field.value).iterator();
221 while (it2.hasNext()) {
222 sb.append(it2.next());
223 if (it2.hasNext())
224 sb.append(", ");
225 }
226 sb.append("'");
227 }
228 if (it.hasNext())
229 sb.append(", ");
230 }
231 return sb.toString();
232 }
233
234
235
236
237
238
239
240 @SuppressWarnings("unchecked")
241 final public String toXML() {
242 List<ConfigField> fields = getConfigFields();
243 StringBuffer sb = new StringBuffer();
244 sb.append("\t\t<"
245 + classNameToXmlElement(ClassUtils.getClassName(this.getClass()))
246 + (fields.size() > 0 ? "\n" : ""));
247 Iterator<ConfigField> it = fields.iterator();
248 while (it.hasNext()) {
249 ConfigField field = it.next();
250 if (field.configFieldName.equals("properties")) {
251 Properties properties = (Properties) field.value;
252 for (Object property : properties.keySet()) {
253 Object value = properties.get(property);
254 sb.append("\t\t\t" + property + "='" + (value!=null?value:"") + "'");
255 }
256 }
257 else if (field.value instanceof Collection) {
258 sb.append("\t\t\t"+ field.configFieldName+ "='"+ StringUtil.toCommaSeparatedList((Collection<String>) field.value) + "'");
259 }
260 else {
261 sb.append("\t\t\t" + field.configFieldName + "='" + (field.value!=null?field.value.toString():"") + "'");
262 }
263 if (it.hasNext())
264 sb.append("\n");
265 }
266 sb.append("/>\n\n");
267 return sb.toString();
268 }
269
270 protected String classNameToXmlElement(String className) {
271 String retVal = className.substring(0, 1).toLowerCase() + className.substring(1);
272 retVal = retVal.replace("lDAP", "ldap");
273 retVal = retVal.replace("vOMS", "voms");
274 return retVal;
275 }
276
277 @Id
278 @GeneratedValue(strategy = GenerationType.AUTO)
279 @SuppressWarnings("unused")
280 private int getId() {
281 return id;
282 }
283
284 @SuppressWarnings("unused")
285 private void setId(int id) {
286 this.id = id;
287 }
288 }