001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/enterprise/control/RPCFactory.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.enterprise.control;
037
038 import java.io.Reader;
039 import java.util.Date;
040
041 import org.deegree.framework.log.ILogger;
042 import org.deegree.framework.log.LoggerFactory;
043 import org.deegree.framework.util.TimeTools;
044 import org.deegree.framework.xml.ElementList;
045 import org.deegree.framework.xml.NamespaceContext;
046 import org.deegree.framework.xml.XMLTools;
047 import org.deegree.ogcbase.CommonNamespaces;
048 import org.w3c.dom.Document;
049 import org.w3c.dom.Element;
050
051 /**
052 * Factory for creating RPC methodCall and methodResponse objects from their XML representation.
053 *
054 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
055 * @author last edited by: $Author: mschneider $
056 *
057 * @version $Revision: 18195 $ $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
058 */
059 public class RPCFactory {
060
061 private static final ILogger LOG = LoggerFactory.getLogger( RPCFactory.class );
062
063 private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
064
065 /**
066 * Creates an instance of <code>RPCMethodCall</code> from an XML document that can be accessed through the passed
067 * <code>Reader</code>.
068 *
069 * @param reader
070 * reader to access an XML document
071 * @return an RPCMethodCall
072 * @throws RPCException
073 */
074 public static RPCMethodCall createRPCMethodCall( Reader reader )
075 throws RPCException {
076
077 Document doc = null;
078 try {
079 doc = XMLTools.parse( reader );
080 } catch ( Exception e ) {
081 LOG.logError( e.getMessage(), e );
082 throw new RPCException( e.toString() );
083 }
084
085 return createRPCMethodCall( doc );
086 }
087
088 /**
089 * Creates an instance of <code>RPCMethodCall</code> from the given XML document.
090 *
091 * @param doc
092 * XML document containing a RPC method call
093 * @return an RPCMethodCall
094 * @throws RPCException
095 */
096 public static RPCMethodCall createRPCMethodCall( Document doc )
097 throws RPCException {
098
099 RPCMethodCall mc = null;
100 try {
101 Element root = doc.getDocumentElement();
102 // get methode name - mandatory
103 String methodName = XMLTools.getRequiredStringValue( "methodName", null, root );
104
105 Element params = XMLTools.getChildElement( "params", null, root );
106
107 RPCParameter[] parameters = null;
108 if ( params != null ) {
109 ElementList el = XMLTools.getChildElements( params );
110 if ( el != null ) {
111 parameters = new RPCParameter[el.getLength()];
112 for ( int i = 0; i < el.getLength(); i++ ) {
113 parameters[i] = createRPCParam( el.item( i ) );
114 }
115 }
116 } else {
117 parameters = new RPCParameter[0];
118 }
119
120 mc = new RPCMethodCall( methodName, parameters );
121 } catch ( Exception e ) {
122 LOG.logError( e.getMessage(), e );
123 throw new RPCException( e.toString() );
124 }
125
126 return mc;
127 }
128
129 /**
130 * Creates an instance of <code>RPCMethodResponse</code> from an XML document that can be accessed through the
131 * passed <code>Reader</code>.
132 *
133 * @param reader
134 * reader to access an XML document
135 * @return created <code>RPCMethodResponse</code>
136 * @throws RPCException
137 */
138 public static RPCMethodResponse createRPCMethodResponse( Reader reader )
139 throws RPCException {
140
141 Document doc = null;
142 try {
143 doc = XMLTools.parse( reader );
144 } catch ( Exception e ) {
145 LOG.logError( e.getMessage(), e );
146 throw new RPCException( e.toString() );
147 }
148
149 return createRPCMethodResponse( doc );
150 }
151
152 /**
153 * Creates an instance of {@link RPCMethodResponse} from the given XML document.
154 *
155 * @param doc
156 * XML document containing a RPC method call
157 * @return created <code>RPCMethodResponse</code>
158 * @throws RPCException
159 */
160 public static RPCMethodResponse createRPCMethodResponse( Document doc )
161 throws RPCException {
162
163 RPCMethodResponse mc = null;
164 try {
165 Element root = doc.getDocumentElement();
166
167 Element params = XMLTools.getChildElement( "params", null, root );
168
169 if ( params != null ) {
170 ElementList el = XMLTools.getChildElements( params );
171 RPCParameter[] parameters = null;
172 if ( el != null ) {
173 parameters = new RPCParameter[el.getLength()];
174 for ( int i = 0; i < el.getLength(); i++ ) {
175 parameters[i] = createRPCParam( el.item( i ) );
176 }
177 }
178 mc = new RPCMethodResponse( parameters );
179 } else {
180 // a fault is contained instead of the expected result
181 Element fault = XMLTools.getChildElement( "fault", null, root );
182 RPCFault rpcFault = createRPCFault( fault );
183 mc = new RPCMethodResponse( rpcFault );
184 }
185
186 } catch ( Exception e ) {
187 LOG.logError( e.getMessage(), e );
188 throw new RPCException( e.toString() );
189 }
190
191 return mc;
192 }
193
194 /**
195 * Creates an {@link RPCMethodResponse} from the given parameters.
196 *
197 * @param par
198 * @return corresponding <code>RPCMethodResponse</code> object
199 */
200 public static RPCMethodResponse createRPCMethodResponse( RPCParameter[] par ) {
201 RPCMethodResponse mc = null;
202 if ( par != null ) {
203 RPCParameter[] params = par;
204 mc = new RPCMethodResponse( params );
205 } else {
206 LOG.logError( "Error in RPCFactory.createRPCMethodResponse(): par = null." );
207 }
208 return mc;
209 }
210
211 /**
212 * Creates an <code>RPCParameter</code> from its XML representation.
213 *
214 * @param param
215 * element containing an RPC parameter
216 * @return created <code>RPCParameter</code>
217 */
218 private static RPCParameter createRPCParam( Element param )
219 throws RPCException {
220
221 RPCParameter parameter = null;
222 try {
223 Element value = XMLTools.getChildElement( "value", null, param );
224 Element child = XMLTools.getFirstChildElement( value );
225 Object o = null;
226 Class cl = null;
227 if ( child.getNodeName().equals( "struct" ) ) {
228 o = createRPCStruct( child );
229 cl = RPCStruct.class;
230 } else if ( child.getNodeName().equals( "string" ) ) {
231 o = XMLTools.getRequiredStringValue( "string", null, value );
232 cl = String.class;
233 } else if ( child.getNodeName().equals( "int" ) ) {
234 double d = XMLTools.getRequiredNodeAsDouble( value, "./int", nsContext );
235 o = new Integer( (int) d );
236 cl = Integer.class;
237 } else if ( child.getNodeName().equals( "i4" ) ) {
238 double d = XMLTools.getRequiredNodeAsDouble( value, "./i4", nsContext );
239 o = new Integer( (int) d );
240 cl = Integer.class;
241 } else if ( child.getNodeName().equals( "double" ) ) {
242 double d = XMLTools.getRequiredNodeAsDouble( value, "./double", nsContext );
243 o = new Double( d );
244 cl = Double.class;
245 } else if ( child.getNodeName().equals( "boolean" ) ) {
246 o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
247 cl = Boolean.class;
248 } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
249 String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, value );
250 o = TimeTools.createCalendar( s ).getTime();
251 cl = Date.class;
252 } else if ( child.getNodeName().equals( "base64" ) ) {
253 } else if ( child.getNodeName().equals( "array" ) ) {
254 o = createArray( child );
255 cl = RPCParameter[].class;
256 }
257 parameter = new RPCParameter( cl, o );
258 } catch ( Exception e ) {
259 LOG.logError( e.getMessage(), e );
260 throw new RPCException( e.toString() );
261 }
262
263 return parameter;
264 }
265
266 /**
267 * Creates an RPC structure object from the passed <code>Element</code>.
268 *
269 * @param struct
270 * element containing an RPC struct
271 * @return created <code>RPCStruct</code>
272 */
273 private static RPCStruct createRPCStruct( Element struct )
274 throws RPCException {
275
276 RPCStruct structure = null;
277 try {
278 ElementList el = XMLTools.getChildElements( struct );
279 RPCMember[] members = null;
280 if ( el != null ) {
281 members = new RPCMember[el.getLength()];
282 for ( int i = 0; i < el.getLength(); i++ ) {
283 members[i] = createRPCMember( el.item( i ) );
284 }
285 }
286 structure = new RPCStruct( members );
287 } catch ( Exception e ) {
288 LOG.logError( e.getMessage(), e );
289 throw new RPCException( e.toString() );
290 }
291
292 return structure;
293 }
294
295 /**
296 * Creates an RPC structure member object from the passed <code>Element</code>.
297 *
298 * @param member
299 * element containing an RPC member
300 * @return created <code>RPCMember</code>
301 */
302 private static RPCMember createRPCMember( Element member )
303 throws RPCException {
304
305 RPCMember mem = null;
306 try {
307 String name = XMLTools.getRequiredStringValue( "name", null, member );
308 Element value = XMLTools.getChildElement( "value", null, member );
309 Element child = XMLTools.getFirstChildElement( value );
310 Object o = null;
311 Class<?> cl = null;
312 if ( child.getNodeName().equals( "struct" ) ) {
313 o = createRPCStruct( child );
314 cl = RPCStruct.class;
315 } else if ( child.getNodeName().equals( "string" ) ) {
316 o = XMLTools.getRequiredStringValue( "string", null, value );
317 cl = String.class;
318 } else if ( child.getNodeName().equals( "int" ) ) {
319 double d = XMLTools.getRequiredNodeAsDouble( value, "./int", nsContext );
320 o = new Integer( (int) d );
321 cl = Integer.class;
322 } else if ( child.getNodeName().equals( "i4" ) ) {
323 double d = XMLTools.getRequiredNodeAsDouble( value, "./i4", nsContext );
324 o = new Integer( (int) d );
325 cl = Integer.class;
326 } else if ( child.getNodeName().equals( "double" ) ) {
327 double d = XMLTools.getRequiredNodeAsDouble( value, "./double", nsContext );
328 o = new Double( d );
329 cl = Double.class;
330 } else if ( child.getNodeName().equals( "boolean" ) ) {
331 o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
332 cl = Boolean.class;
333 } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
334 String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, value );
335 o = TimeTools.createCalendar( s ).getTime();
336 cl = Date.class;
337 } else if ( child.getNodeName().equals( "base64" ) ) {
338 // TODO
339 } else if ( child.getNodeName().equals( "array" ) ) {
340 o = createArray( child );
341 cl = RPCParameter[].class;
342 }
343 mem = new RPCMember( cl, o, name );
344 } catch ( Exception e ) {
345 LOG.logError( e.getMessage(), e );
346 throw new RPCException( e.toString() );
347 }
348
349 return mem;
350 }
351
352 /**
353 * Creates an array of {@link RPCParameter} objects from the passed <code>Element</code>.
354 *
355 * @param array
356 * @return created array of <code>RPCParameter</code> objects
357 */
358 private static RPCParameter[] createArray( Element array )
359 throws RPCException {
360
361 RPCParameter[] param = null;
362 try {
363 Element data = XMLTools.getChildElement( "data", null, array );
364 ElementList el = XMLTools.getChildElements( data );
365 if ( el != null ) {
366 param = new RPCParameter[el.getLength()];
367 for ( int i = 0; i < el.getLength(); i++ ) {
368 Element child = XMLTools.getFirstChildElement( el.item( i ) );
369 Object o = null;
370 Class cl = null;
371 if ( child.getNodeName().equals( "struct" ) ) {
372 o = createRPCStruct( child );
373 cl = RPCStruct.class;
374 } else if ( child.getNodeName().equals( "string" ) ) {
375 o = XMLTools.getRequiredStringValue( "string", null, el.item( i ) );
376 cl = String.class;
377 } else if ( child.getNodeName().equals( "int" ) ) {
378 double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./int", nsContext );
379 o = new Integer( (int) d );
380 cl = Integer.class;
381 } else if ( child.getNodeName().equals( "i4" ) ) {
382 double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./i4", nsContext );
383 o = new Integer( (int) d );
384 cl = Integer.class;
385 } else if ( child.getNodeName().equals( "double" ) ) {
386 double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./double", nsContext );
387 o = new Double( d );
388 cl = Double.class;
389 } else if ( child.getNodeName().equals( "boolean" ) ) {
390 o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
391 cl = Boolean.class;
392 } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
393 String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, el.item( i ) );
394 o = TimeTools.createCalendar( s ).getTime();
395 cl = Date.class;
396 } else if ( child.getNodeName().equals( "base64" ) ) {
397 } else if ( child.getNodeName().equals( "array" ) ) {
398 o = createArray( child );
399 cl = RPCParameter[].class;
400 }
401 param[i] = new RPCParameter( cl, o );
402 }
403 }
404 } catch ( Exception e ) {
405 LOG.logError( e.getMessage(), e );
406 throw new RPCException( e.toString() );
407 }
408
409 return param;
410 }
411
412 /**
413 * Creates an {@link RPCFault} object from the passed <code>Element</code>.
414 *
415 * @param fault
416 * fault element
417 * @return created <code>RPCFault</code> object
418 */
419 private static RPCFault createRPCFault( Element fault )
420 throws RPCException {
421
422 RPCFault rpcFault = null;
423 try {
424 Element value = XMLTools.getChildElement( "value", null, fault );
425 Element child = XMLTools.getFirstChildElement( value );
426 RPCStruct struct = createRPCStruct( child );
427 String s1 = null;
428 String s2 = null;
429 Object o = struct.getMember( "faultCode" ).getValue();
430 if ( o != null ) {
431 s1 = o.toString();
432 }
433 o = struct.getMember( "faultString" ).getValue();
434 if ( o != null ) {
435 s2 = o.toString();
436 }
437 rpcFault = new RPCFault( s1, s2 );
438 } catch ( Exception e ) {
439 LOG.logError( e.getMessage(), e );
440 throw new RPCException( e.toString() );
441 }
442 return rpcFault;
443 }
444 }