001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/enterprise/control/RPCFactory.java $
002    package org.deegree.enterprise.control;
003    
004    import java.io.Reader;
005    import java.util.Date;
006    
007    import org.deegree.framework.log.ILogger;
008    import org.deegree.framework.log.LoggerFactory;
009    import org.deegree.framework.util.TimeTools;
010    import org.deegree.framework.xml.ElementList;
011    import org.deegree.framework.xml.NamespaceContext;
012    import org.deegree.framework.xml.XMLTools;
013    import org.deegree.ogcbase.CommonNamespaces;
014    import org.w3c.dom.Document;
015    import org.w3c.dom.Element;
016    
017    /**
018     * Factory class for creating RPC methodCall and methodResponse objects from their XML
019     * representation
020     * 
021     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
022     * @version $Revision: 6259 $ $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $
023     */
024    public class RPCFactory {
025        
026        private static final ILogger LOG = LoggerFactory.getLogger( RPCFactory.class );
027    
028        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
029    
030        /**
031         * creates an instance of <tt>RPCMethodCall</tt> from an XML document that can be accessed
032         * through the passed <tt>Reader</tt>
033         * 
034         * @param reader
035         *            reader to access an XML document
036         * @return an RPCMethodCall
037         */
038        public static RPCMethodCall createRPCMethodCall( Reader reader ) throws RPCException {
039            
040            Document doc = null;
041            try {
042                doc = XMLTools.parse( reader );
043            } catch (Exception e) {
044                LOG.logError( e.getMessage(), e );
045                throw new RPCException( e.toString() );
046            }
047    
048            return createRPCMethodCall( doc );
049        }
050    
051        /**
052         * creates an instance of <tt>RPCMethodCall</tt> from the XML document passed
053         * 
054         * @param doc
055         *            XML document containing a RPC method call
056         * @return an RPCMethodCall
057         */
058        public static RPCMethodCall createRPCMethodCall( Document doc ) throws RPCException {
059         
060            RPCMethodCall mc = null;
061            try {
062                Element root = doc.getDocumentElement();
063                // get methode name - mandatory
064                String methodName = XMLTools.getRequiredStringValue( "methodName", null, root );
065    
066                Element params = XMLTools.getChildElement( "params", null, root );
067    
068                RPCParameter[] parameters = null;
069                if ( params != null ) {
070                    ElementList el = XMLTools.getChildElements( params );
071                    if ( el != null ) {
072                        parameters = new RPCParameter[el.getLength()];
073                        for (int i = 0; i < el.getLength(); i++) {
074                            parameters[i] = createRPCParam( el.item( i ) );
075                        }
076                    }
077                } else {
078                    parameters = new RPCParameter[0];
079                }
080    
081                mc = new RPCMethodCall( methodName, parameters );
082            } catch (Exception e) {
083                LOG.logError( e.getMessage(), e );
084                throw new RPCException( e.toString() );
085            }
086    
087            return mc;
088        }
089    
090        /**
091         * creates an instance of <tt>RPCMethodResponse</tt> from an XML document that can be accessed
092         * through the passed <tt>Reader</tt>
093         * 
094         * @param reader
095         *            reader to access an XML document
096         * @return created <tt>RPCMethodResponse</tt>
097         */
098        public static RPCMethodResponse createRPCMethodResponse( Reader reader ) throws RPCException {
099         
100            Document doc = null;
101            try {
102                doc = XMLTools.parse( reader );
103            } catch (Exception e) {
104                LOG.logError( e.getMessage(), e );
105                throw new RPCException( e.toString() );
106            }
107    
108            return createRPCMethodResponse( doc );
109        }
110    
111        /**
112         * creates an instance of <tt>RPCMethodResponse</tt> from the XML document passed
113         * 
114         * @param doc
115         *            XML document containing a RPC method call
116         * @return created <tt>RPCMethodResponse</tt>
117         */
118        public static RPCMethodResponse createRPCMethodResponse( Document doc ) throws RPCException {
119            
120            RPCMethodResponse mc = null;
121            try {
122                Element root = doc.getDocumentElement();
123    
124                Element params = XMLTools.getChildElement( "params", null, root );
125    
126                if ( params != null ) {
127                    ElementList el = XMLTools.getChildElements( params );
128                    RPCParameter[] parameters = null;
129                    if ( el != null ) {
130                        parameters = new RPCParameter[el.getLength()];
131                        for (int i = 0; i < el.getLength(); i++) {
132                            parameters[i] = createRPCParam( el.item( i ) );
133                        }
134                    }
135                    mc = new RPCMethodResponse( parameters );
136                } else {
137                    // a fault is contained instead of the expected result
138                    Element fault = XMLTools.getChildElement( "fault", null, root );
139                    RPCFault rpcFault = createRPCFault( fault );
140                    mc = new RPCMethodResponse( rpcFault );
141                }
142    
143            } catch (Exception e) {
144                LOG.logError( e.getMessage(), e );
145                throw new RPCException( e.toString() );
146            }
147    
148            return mc;
149        }
150    
151        /**
152         * @param par
153         * @return
154         * @throws RPCException
155         */
156        public static RPCMethodResponse createRPCMethodResponse( RPCParameter[] par ) {
157            RPCMethodResponse mc = null;
158            if ( par != null ) {
159                RPCParameter[] params = par;
160                mc = new RPCMethodResponse( params );
161            } else {
162                LOG.logError( "Fehler createRPCMEthodResponse in RPSFactory" );
163            }
164            return mc;
165        }
166    
167        /**
168         * creates a <tt>RPCParameter</tt> from its XML representation
169         * 
170         * @param param
171         *            element containing a RPC param
172         * @return created <tt>RPCParameter</tt>
173         */
174        private static RPCParameter createRPCParam( Element param ) throws RPCException {
175            
176            RPCParameter parameter = null;
177            try {
178                Element value = XMLTools.getChildElement( "value", null, param );
179                Element child = XMLTools.getFirstChildElement( value );
180                Object o = null;
181                Class cl = null;
182                if ( child.getNodeName().equals( "struct" ) ) {
183                    o = createRPCStruct( child );
184                    cl = RPCStruct.class;
185                } else if ( child.getNodeName().equals( "string" ) ) {
186                    o = XMLTools.getRequiredStringValue( "string", null, value );
187                    cl = String.class;
188                } else if ( child.getNodeName().equals( "int" ) ) {
189                    double d = XMLTools.getRequiredNodeAsDouble( value, "./int", nsContext );
190                    o = new Integer( (int) d );
191                    cl = Integer.class;
192                } else if ( child.getNodeName().equals( "i4" ) ) {
193                    double d = XMLTools.getRequiredNodeAsDouble( value, "./i4", nsContext );
194                    o = new Integer( (int) d );
195                    cl = Integer.class;
196                } else if ( child.getNodeName().equals( "double" ) ) {
197                    double d = XMLTools.getRequiredNodeAsDouble( value, "./double", nsContext );
198                    o = new Double( d );
199                    cl = Double.class;
200                } else if ( child.getNodeName().equals( "boolean" ) ) {
201                    o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
202                    cl = Boolean.class;
203                } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
204                    String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, value );
205                    o = TimeTools.createCalendar( s ).getTime();
206                    cl = Date.class;
207                } else if ( child.getNodeName().equals( "base64" ) ) {
208                } else if ( child.getNodeName().equals( "array" ) ) {
209                    o = createArray( child );
210                    cl = RPCParameter[].class;
211                }
212                parameter = new RPCParameter( cl, o );
213            } catch (Exception e) {
214                LOG.logError( e.getMessage(), e );
215                throw new RPCException( e.toString() );
216            }
217    
218            return parameter;
219        }
220    
221        /**
222         * creates a RPC struture object from the passed <tt>Element</tt>
223         * 
224         * @param struct
225         *            element containing a RPC struct
226         * @return created <tt>RPCStruct</tt>
227         */
228        private static RPCStruct createRPCStruct( Element struct ) throws RPCException {
229    
230            RPCStruct structure = null;
231            try {
232                ElementList el = XMLTools.getChildElements( struct );
233                RPCMember[] members = null;
234                if ( el != null ) {
235                    members = new RPCMember[el.getLength()];
236                    for (int i = 0; i < el.getLength(); i++) {
237                        members[i] = createRPCMember( el.item( i ) );
238                    }
239                }
240                structure = new RPCStruct( members );
241            } catch (Exception e) {
242                LOG.logError( e.getMessage(), e );
243                throw new RPCException( e.toString() );
244            }
245    
246            return structure;
247        }
248    
249        /**
250         * creates a RPC struture member object from the passed <tt>Element</tt>
251         * 
252         * @param member
253         *            element containing a RPC member
254         * @return created <tt>RPCMember</tt>
255         */
256        private static RPCMember createRPCMember( Element member ) throws RPCException {
257    
258            RPCMember mem = null;        
259            try {
260                String name = XMLTools.getRequiredStringValue( "name", null, member );
261                Element value = XMLTools.getChildElement( "value", null, member );
262                Element child = XMLTools.getFirstChildElement( value );
263                Object o = null;
264                Class cl = null;
265                if ( child.getNodeName().equals( "struct" ) ) {
266                    o = createRPCStruct( child );
267                    cl = RPCStruct.class;
268                } else if ( child.getNodeName().equals( "string" ) ) {
269                    o = XMLTools.getRequiredStringValue( "string", null, value );
270                    cl = String.class;
271                } else if ( child.getNodeName().equals( "int" ) ) {
272                    double d = XMLTools.getRequiredNodeAsDouble( value, "./int", nsContext );
273                    o = new Integer( (int) d );
274                    cl = Integer.class;
275                } else if ( child.getNodeName().equals( "i4" ) ) {
276                    double d = XMLTools.getRequiredNodeAsDouble( value, "./i4", nsContext );
277                    o = new Integer( (int) d );
278                    cl = Integer.class;
279                } else if ( child.getNodeName().equals( "double" ) ) {
280                    double d = XMLTools.getRequiredNodeAsDouble( value, "./double", nsContext );
281                    o = new Double( d );
282                    cl = Double.class;
283                } else if ( child.getNodeName().equals( "boolean" ) ) {
284                    o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
285                    cl = Boolean.class;
286                } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
287                    String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, value );
288                    o = TimeTools.createCalendar( s ).getTime();
289                    cl = Date.class;
290                } else if ( child.getNodeName().equals( "base64" ) ) {
291                } else if ( child.getNodeName().equals( "array" ) ) {
292                    o = createArray( child );
293                    cl = RPCParameter[].class;
294                }        
295                mem = new RPCMember( cl, o, name );
296            } catch (Exception e) {
297                LOG.logError( e.getMessage(), e );
298                throw new RPCException( e.toString() );
299            } 
300    
301            return mem;
302        }
303    
304        /**
305         * creates an <tt>ArrayList</tt> object from the passed <tt>Element</tt>
306         * 
307         * @param array
308         * @return created <tt>ArrayList</tt>
309         */
310        private static RPCParameter[] createArray( Element array ) throws RPCException {
311    
312            RPCParameter[] param = null;
313            try {
314                Element data = XMLTools.getChildElement( "data", null, array );
315                ElementList el = XMLTools.getChildElements( data );
316                if ( el != null ) {
317                    param = new RPCParameter[el.getLength()];
318                    for (int i = 0; i < el.getLength(); i++) {
319                        Element child = XMLTools.getFirstChildElement( el.item( i ) );
320                        Object o = null;
321                        Class cl = null;
322                        if ( child.getNodeName().equals( "struct" ) ) {
323                            o = createRPCStruct( child );
324                            cl = RPCStruct.class;
325                        } else if ( child.getNodeName().equals( "string" ) ) {
326                            o = XMLTools.getRequiredStringValue( "string", null, el.item( i ) );
327                            cl = String.class;
328                        } else if ( child.getNodeName().equals( "int" ) ) {
329                            double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./int", nsContext );
330                            o = new Integer( (int) d );
331                            cl = Integer.class;
332                        } else if ( child.getNodeName().equals( "i4" ) ) {
333                            double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./i4", nsContext );
334                            o = new Integer( (int) d );
335                            cl = Integer.class;
336                        } else if ( child.getNodeName().equals( "double" ) ) {
337                            double d = XMLTools.getRequiredNodeAsDouble( el.item( i ), "./double",
338                                nsContext );
339                            o = new Double( d );
340                            cl = Double.class;
341                        } else if ( child.getNodeName().equals( "boolean" ) ) {
342                            o = Boolean.valueOf( child.getFirstChild().getNodeValue().equals( "1" ) );
343                            cl = Boolean.class;
344                        } else if ( child.getNodeName().equals( "dateTime.iso8601" ) ) {
345                            String s = XMLTools.getRequiredStringValue( "dateTime.iso8601", null, el
346                                .item( i ) );
347                            o = TimeTools.createCalendar( s ).getTime();
348                            cl = Date.class;
349                        } else if ( child.getNodeName().equals( "base64" ) ) {
350                        } else if ( child.getNodeName().equals( "array" ) ) {
351                            o = createArray( child );
352                            cl = RPCParameter[].class;
353                        }
354                        param[i] = new RPCParameter( cl, o );
355                    }
356                }
357            } catch (Exception e) {
358                LOG.logError( e.getMessage(), e );
359                throw new RPCException( e.toString() );
360            }
361    
362            return param;
363        }
364    
365        /**
366         * creates an <tt>RPCFault</tt> object from the passed <tt>Element</tt>
367         * 
368         * @param fault
369         *            fault element
370         * @return created <tt>RPCFault</tt>
371         */
372        private static RPCFault createRPCFault( Element fault ) throws RPCException {
373            
374            RPCFault rpcFault = null;
375            try {
376                Element value = XMLTools.getChildElement( "value", null, fault );
377                Element child = XMLTools.getFirstChildElement( value );
378                RPCStruct struct = createRPCStruct( child );
379                String s1 = null;
380                String s2 = null;
381                Object o = struct.getMember( "faultCode" ).getValue();
382                if ( o != null ) {
383                    s1 = o.toString();
384                }
385                o = struct.getMember( "faultString" ).getValue();
386                if ( o != null ) {
387                    s2 = o.toString();
388                }
389                rpcFault = new RPCFault( s1, s2 );
390            } catch (Exception e) {
391                LOG.logError( e.getMessage(), e );
392                throw new RPCException( e.toString() );
393            }
394    
395            return rpcFault;
396        }
397    
398    }
399    /* ********************************************************************
400    Changes to this class. What the people have been up to:
401    $Log$
402    Revision 1.13  2006/12/06 22:09:27  poth
403    *** empty log message ***
404    
405    Revision 1.12  2006/10/05 09:33:09  mays
406    remove a bug: now every RPCMethodCall contains RPCParameters, even though they might be empty.
407    
408    Revision 1.11  2006/07/29 08:49:25  poth
409    references to deprecated classes removed
410    
411    Revision 1.10  2006/07/12 14:46:17  poth
412    comment footer added
413    
414    ********************************************************************** */