View Javadoc

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  	// persistent variables
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 			// order
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 	 * Get XML output of this element
236 	 * 
237 	 * @param className
238 	 * @return String
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 }