001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2004 TOPP - www.openplans.org
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.validation;
018:
019: import java.beans.BeanDescriptor;
020: import java.beans.BeanInfo;
021: import java.beans.Introspector;
022: import java.beans.PropertyDescriptor;
023: import java.lang.reflect.Constructor;
024: import java.lang.reflect.InvocationTargetException;
025: import java.util.HashMap;
026: import java.util.Iterator;
027: import java.util.Map;
028:
029: import org.geotools.validation.dto.ArgumentDTO;
030: import org.geotools.validation.xml.ValidationException;
031:
032: /**
033: * Contains the information required for Validation creation.
034: *
035: * <p>
036: * Currently just used for configuration, may need to be public for dynamic
037: * configuration.
038: * </p>
039: *
040: * @see <a http://vwfs.refractions.net/docs/Validating_Web_Feature_Server.pdf>A
041: * PDF on Validating Web Feature Servers</a>
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/validation/src/main/java/org/geotools/validation/PlugIn.java $
043: */
044: public class PlugIn {
045: Map defaults;
046: String plugInName;
047: String plugInDescription;
048: BeanInfo beanInfo;
049: Map propertyMap;
050:
051: PlugIn(Map config) throws ValidationException {
052: this (get(config, "name"),
053: get(config, "bean", Validation.class), get(config,
054: "description"), config);
055: }
056:
057: public PlugIn(String name, Class type, String description,
058: Map config) throws ValidationException {
059: if ((type == null)
060: || (!Validation.class.isAssignableFrom(type) && type
061: .isInterface())) {
062: throw new ValidationException("Not a validation test '"
063: + name + "' plugIn:" + type);
064: }
065:
066: try {
067: beanInfo = Introspector.getBeanInfo(type);
068: } catch (Exception e) {
069: e.printStackTrace();
070: throw new ValidationException("Could not use the '" + name
071: + "' plugIn:" + type.getName());
072: }
073:
074: if (config != null) {
075: defaults = transArgs(config);
076: }
077:
078: plugInName = name;
079: plugInDescription = description;
080:
081: propertyMap = propertyMap(beanInfo);
082: }
083:
084: private Map transArgs(Map config) {
085: Map defaults = new HashMap();
086: Iterator i = config.keySet().iterator();
087:
088: while (i.hasNext()) {
089: String key = (String) i.next();
090: Object o = config.get(key);
091:
092: if (o instanceof ArgumentDTO) {
093: defaults.put(key, ((ArgumentDTO) o).getValue());
094: } else {
095: defaults.put(key, o);
096: }
097: }
098:
099: return defaults;
100: }
101:
102: protected PropertyDescriptor propertyInfo(String name) {
103: return (PropertyDescriptor) propertyMap.get(name);
104: }
105:
106: protected static Map propertyMap(BeanInfo info) {
107: PropertyDescriptor[] properties = info.getPropertyDescriptors();
108: Map lookup = new HashMap(properties.length);
109:
110: for (int i = 0; i < properties.length; i++) {
111: lookup.put(properties[i].getName(), properties[i]);
112: }
113:
114: return lookup;
115: }
116:
117: /**
118: * Create a Validation based on provided <code>test</code> definition.
119: *
120: * <p>
121: * Creates the required Java Bean and configures according to the provided
122: * test definition, using this plugIn's defaults.
123: * </p>
124: *
125: * @param name Map defining User's test.
126: * @param description DOCUMENT ME!
127: * @param args DOCUMENT ME!
128: *
129: * @return Validation ready for use by the ValidationProcessor
130: *
131: * @throws ValidationException when an error occurs
132: */
133: public Validation createValidation(String name, String description,
134: Map args) throws ValidationException {
135: BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
136: Class type = beanDescriptor.getBeanClass();
137:
138: Constructor create;
139:
140: try {
141: create = type.getConstructor(new Class[0]);
142: } catch (SecurityException e) {
143: throw new ValidationException("Could not create '"
144: + plugInName + "' as " + type.getName(), e);
145: } catch (NoSuchMethodException e) {
146: throw new ValidationException("Could not create '"
147: + plugInName + "' as " + type.getName(), e);
148: } catch (IllegalArgumentException e) {
149: throw new ValidationException("Could not create '"
150: + plugInName + "' as " + type.getName(), e);
151: }
152:
153: Validation validate;
154:
155: try {
156: validate = (Validation) create.newInstance(new Object[0]);
157: } catch (InstantiationException e) {
158: throw new ValidationException("Could not create '" + name
159: + "' as plugIn " + plugInName, e);
160: } catch (IllegalAccessException e) {
161: throw new ValidationException("Could not create '" + name
162: + "' as plugIn " + plugInName, e);
163: } catch (InvocationTargetException e) {
164: throw new ValidationException("Could not create '" + name
165: + "' as plugIn " + plugInName, e);
166: }
167:
168: validate.setName(name);
169: validate.setDescription(description);
170: configure(validate, defaults);
171: configure(validate, transArgs(args));
172:
173: return validate;
174: }
175:
176: protected void configure(Object bean, Map config)
177: throws ValidationException {
178: if ((config == null) || (config.size() == 0)) {
179: return;
180: }
181:
182: PropertyDescriptor property;
183:
184: for (Iterator i = config.entrySet().iterator(); i.hasNext();) {
185: Map.Entry entry = (Map.Entry) i.next();
186: property = propertyInfo((String) entry.getKey());
187:
188: if (property == null) {
189: // error here
190: continue;
191: }
192:
193: try {
194: property.getWriteMethod().invoke(bean,
195: new Object[] { entry.getValue() });
196: } catch (IllegalArgumentException e) {
197: String val = entry.getValue() == null ? entry
198: .getValue().toString() : "null";
199: throw new ValidationException(
200: "test failed to configure " + plugInName + " "
201: + entry.getKey() + " " + val, e);
202: } catch (IllegalAccessException e) {
203: String val = entry.getValue() == null ? entry
204: .getValue().toString() : "null";
205: throw new ValidationException(
206: "test failed to configure " + plugInName + " "
207: + entry.getKey() + " " + val, e);
208: } catch (InvocationTargetException e) {
209: String val = entry.getValue() == null ? entry
210: .getValue().toString() : "null";
211: throw new ValidationException(
212: "test failed to configure " + plugInName + " "
213: + entry.getKey() + " " + val, e);
214: }
215: }
216: }
217:
218: /**
219: * get purpose.
220: *
221: * <p>
222: * Gets a String from a map of Strings
223: * </p>
224: *
225: * @param map Map the map to extract the string from
226: * @param key String the key for the map.
227: *
228: * @return String the value in the map.
229: *
230: * @see Map
231: */
232: private static String get(Map map, String key) {
233: if (map.containsKey(key)) {
234: return (String) map.get(key);
235: }
236:
237: return null;
238: }
239:
240: /**
241: * get purpose.
242: *
243: * <p>
244: * Gets a Class from a map given the specified key. If the Class is not
245: * found the default Class is returned.
246: * </p>
247: *
248: * @param map Map the map to extract the file from
249: * @param key String the key to extract the value for
250: * @param defaultType The default value should the key not exist.
251: *
252: * @return Class an boolean as described above.
253: */
254: private static Class get(Map map, String key, Class defaultType) {
255: if (!map.containsKey(key)) {
256: return defaultType;
257: }
258:
259: Object value = map.get(key);
260:
261: if (value instanceof Class) {
262: return (Class) value;
263: }
264:
265: if (value instanceof String) {
266: try {
267: return Class.forName((String) value);
268: } catch (ClassNotFoundException e) {
269: // error
270: }
271: }
272:
273: return defaultType;
274: }
275:
276: public Map getPropertyMap() {
277: return propertyMap;
278: }
279: }
|