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