001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }