001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.ows;
006:
007: import org.geoserver.ows.util.OwsUtils;
008: import org.geotools.util.Converters;
009:
010: import java.lang.reflect.Method;
011: import java.util.Iterator;
012: import java.util.Map;
013: import java.util.logging.Logger;
014:
015: /**
016: * Creates a request bean from a kvp set.
017: * <p>
018: * A request bean is an object which captures the parameters of an operation
019: * being requested to a service.
020: * </p>
021: * <p>
022: * This class is intended to be subclassed in cases when the creation
023: * and initilization of a request bean cannot be created reflectivley.
024: * </p>
025: * <p>
026: * The type of the request bean must be declared by the class.
027: * See {@link #getRequestBean()}.
028: * </p>
029: * <p>
030: * Instances need to be declared in a spring context like the following:
031: * <pre>
032: * <code>
033: * <bean id="myKvpRequestReader" class="org.geoserver.ows.KvpRequestReader">
034: * <constructor-arg value="com.xyz.MyRequestBean"/>
035: * </bean>
036: * </code>
037: * </pre>
038: * Where <code>com.xyz.MyRequestBean</code> is a simple java bean such as:
039: * <pre>
040: * <code>
041: * public class MyRequestBean {
042: *
043: * public void setX( Object x ) {
044: * ...
045: * }
046: *
047: * public Object getX() {
048: * ...
049: * }
050: * }
051: * </code>
052: * </pre>
053: * </p>
054: *
055: * @author Justin Deoliveira, The Open Planning Project
056: *
057: */
058: public class KvpRequestReader {
059: /**
060: * logging instance
061: */
062: protected static Logger LOGGER = org.geotools.util.logging.Logging
063: .getLogger("org.geoserver.ows");
064:
065: /**
066: * The class of the request bean
067: */
068: private Class requestBean;
069:
070: /**
071: * Creats the new kvp request reader.
072: *
073: * @param requestBean The type of the request read, not <code>null</code>
074: */
075: public KvpRequestReader(Class requestBean) {
076: if (requestBean == null) {
077: throw new NullPointerException();
078: }
079:
080: this .requestBean = requestBean;
081: }
082:
083: /**
084: * @return The class of the request bean.
085: */
086: public final Class getRequestBean() {
087: return requestBean;
088: }
089:
090: /**
091: * Creats a new instance of the request object.
092: * <p>
093: * Subclasses may with to override this method. The default implementation
094: * attempts to reflectivley create an instance of the request bean.
095: * </p>
096: * @return A new instance of the request.
097: */
098: public Object createRequest() throws Exception {
099: return getRequestBean().newInstance();
100: }
101:
102: /**
103: * Reads the request from the set of kvp parameters.
104: * <p>
105: * Subclasses may wish to override this method. The default implementation
106: * uses java bean reflection to populate the request bean with parameters
107: * taken from the kvp map.
108: * </p>
109: * <p>
110: * The "raw" (unparsed) kvp map is also made available.
111: * </p>
112: * <p>
113: * This method may return a new instance of the request object, or the original
114: * passed in.
115: * </p>
116: * @param request The request instance.
117: * @param kvp The kvp set, map of String,Object.
118: * @param rawKvp The raw kvp set (unparsed), map of String,String
119: *
120: * @return A new request object, or the ori
121: */
122: public Object read(Object request, Map kvp, Map rawKvp)
123: throws Exception {
124: for (Iterator e = kvp.entrySet().iterator(); e.hasNext();) {
125: Map.Entry entry = (Map.Entry) e.next();
126: String property = (String) entry.getKey();
127: Object value = entry.getValue();
128:
129: if (value == null) {
130: continue;
131: }
132:
133: Method setter = OwsUtils.setter(request.getClass(),
134: property, value.getClass());
135:
136: if (setter == null) {
137: //no setter matching the object of teh type, try to convert
138: setter = OwsUtils.setter(request.getClass(), property,
139: null);
140: if (setter != null) {
141: //convert
142: Class target = setter.getParameterTypes()[0];
143: Object converted = Converters
144: .convert(value, target);
145: if (converted != null) {
146: value = converted;
147: } else {
148: setter = null;
149: }
150: }
151: }
152:
153: if (setter != null) {
154: setter.invoke(request, new Object[] { value });
155: }
156: }
157:
158: return request;
159: }
160:
161: /**
162: * Equals override, equality is based on {@link #getRequestBean()}
163: */
164: public final boolean equals(Object obj) {
165: if (obj instanceof KvpRequestReader) {
166: KvpRequestReader other = (KvpRequestReader) obj;
167:
168: return requestBean == other.requestBean;
169: }
170:
171: return false;
172: }
173:
174: public final int hashCode() {
175: return requestBean.hashCode();
176: }
177: }
|