001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/owswatch/ServicesConfigurationFactory.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    
037    package org.deegree.portal.owswatch;
038    
039    import java.io.File;
040    import java.io.FileInputStream;
041    import java.io.IOException;
042    import java.io.Serializable;
043    import java.util.ArrayList;
044    import java.util.List;
045    import java.util.Properties;
046    
047    import javax.xml.parsers.DocumentBuilder;
048    import javax.xml.parsers.DocumentBuilderFactory;
049    import javax.xml.parsers.ParserConfigurationException;
050    
051    import org.deegree.framework.util.StringTools;
052    import org.deegree.framework.xml.NamespaceContext;
053    import org.deegree.framework.xml.XMLFragment;
054    import org.deegree.framework.xml.XMLParsingException;
055    import org.deegree.framework.xml.XMLTools;
056    import org.w3c.dom.Document;
057    import org.w3c.dom.Element;
058    import org.w3c.dom.Node;
059    import org.w3c.dom.NodeList;
060    
061    /**
062     * This class is used to parse the services as services.xml. This xml file includes all services to be tested
063     *
064     * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
065     * @author last edited by: $Author: jmays $
066     *
067     * @version $Revision: 20271 $, $Date: 2009-10-21 13:07:15 +0200 (Mi, 21 Okt 2009) $
068     */
069    public class ServicesConfigurationFactory implements Serializable {
070    
071        /**
072         *
073         */
074        private static final long serialVersionUID = -4433307342023097237L;
075    
076        private String prefix = null;
077    
078        private static NamespaceContext cnxt = CommonNamepspaces.getNameSpaceContext();
079    
080        /**
081         * Parses a list of ServiceConfiguration from the given xml file
082         *
083         * @param url
084         * @return List of ServiceMonitor. These are the parsed services
085         * @throws XMLParsingException
086         * @throws IOException
087         */
088        public List<ServiceConfiguration> parseServices( String url )
089                                throws XMLParsingException, IOException {
090    
091            List<ServiceConfiguration> services = new ArrayList<ServiceConfiguration>();
092            try {
093                File file = new File( url );
094                FileInputStream stream = new FileInputStream( file );
095                Document doc = instantiateParser().parse( stream, XMLFragment.DEFAULT_URL );
096    
097                int idSequence = Integer.parseInt( XMLTools.getAttrValue( doc.getDocumentElement(), null,
098                                                                          "service_id_sequence", "0" ) );
099                ServiceConfiguration.setServiceCounter( idSequence );
100                prefix = doc.lookupPrefix( CommonNamepspaces.DEEGREEWSNS.toASCIIString() );
101                String dotPrefix = null;
102                if ( prefix == null ) {
103                    throw new XMLParsingException( "The Services xml must contain the namespace: "
104                                                   + CommonNamepspaces.DEEGREEWSNS.toASCIIString() );
105                }
106                dotPrefix = prefix + ":";
107                cnxt.addNamespace( prefix, CommonNamepspaces.DEEGREEWSNS );
108                List<Element> list = XMLTools.getElements( doc.getDocumentElement(),
109                                                           StringTools.concat( 150, "./", dotPrefix,
110                                                                               Constants.SERVICE_MONITOR ), cnxt );
111                for ( Element elem : list ) {
112                    services.add( parseService( elem, prefix ) );
113                }
114            } catch ( IOException e ) {
115                throw new IOException( "The given path was not found: " + url );
116            } catch ( Exception e ) {
117                throw new XMLParsingException( e.getLocalizedMessage() );
118            }
119            return services;
120        }
121    
122        /**
123         * Creates a new instance of DocumentBuilder
124         *
125         * @return DocumentBuilder
126         * @throws IOException
127         */
128        private DocumentBuilder instantiateParser()
129                                throws IOException {
130    
131            DocumentBuilder parser = null;
132    
133            try {
134                DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
135                fac.setNamespaceAware( true );
136                fac.setValidating( false );
137                fac.setIgnoringElementContentWhitespace( false );
138                parser = fac.newDocumentBuilder();
139                return parser;
140            } catch ( ParserConfigurationException e ) {
141                throw new IOException( "Unable to initialize DocumentBuilder: " + e.getMessage() );
142            }
143        }
144    
145        /**
146         * Takes in a service Node and parses it.
147         *
148         * @param serviceNode
149         *            xml node as an example refer to services.xml
150         * @param prefix
151         * @return ServiceConfiguration
152         * @throws XMLParsingException
153         * @throws ConfigurationsException
154         */
155        public ServiceConfiguration parseService( Node serviceNode, String prefix )
156                                throws XMLParsingException, ConfigurationsException {
157    
158            String dotPrefix = null;
159            if ( prefix == null ) {
160                throw new XMLParsingException( Messages.getMessage( "ERROR_NULL_OBJ", "Prefix" ) );
161            }
162            dotPrefix = prefix + ":";
163            int id = Integer.parseInt( XMLTools.getRequiredAttrValue( "id", null, serviceNode ) );
164            String onlineResource = XMLTools.getRequiredNodeAsString( serviceNode,
165                                                                      StringTools.concat( 100, "./", dotPrefix,
166                                                                                          Constants.ONLINE_RESOURCE ), cnxt );
167            String serviceName = XMLTools.getRequiredNodeAsString( serviceNode,
168                                                                   StringTools.concat( 100, "./", dotPrefix,
169                                                                                       Constants.SERVICE_NAME ), cnxt );
170            int interval = XMLTools.getRequiredNodeAsInt( serviceNode, StringTools.concat( 100, "./", dotPrefix,
171                                                                                           Constants.INTERVAL ), cnxt );
172            int timeout = XMLTools.getRequiredNodeAsInt( serviceNode, StringTools.concat( 100, "./", dotPrefix,
173                                                                                          Constants.TIMEOUT_KEY ), cnxt );
174            boolean active = XMLTools.getRequiredNodeAsBoolean( serviceNode, StringTools.concat( 100, "./", dotPrefix,
175                                                                                                 Constants.ACTIVE ), cnxt );
176    
177            Element httpElem = XMLTools.getElement( serviceNode, StringTools.concat( 100, "./", dotPrefix,
178                                                                                     Constants.HTTP_METHOD ), cnxt );
179            String httpMethod = XMLTools.getAttrValue( httpElem, null, "type", null );
180    
181            Properties props = null;
182            if ( "GET".equals( httpMethod ) ) {
183                props = parseHttpRequestGet( httpElem );
184            } else if ( "POST".equals( httpMethod ) ) {
185                props = parseHttpRequestPOST( httpElem, prefix );
186            } else {
187                throw new ConfigurationsException( "The Http method has to be either GET or POST" );
188            }
189            return new ServiceConfiguration( id, serviceName, httpMethod, onlineResource, active, interval, timeout, props );
190        }
191    
192        /**
193         * Parses a GET Request
194         *
195         * @param httpElem
196         * @return Properties contains key value pairs of the request
197         * @throws XMLParsingException
198         */
199        private Properties parseHttpRequestGet( Node httpElem )
200                                throws XMLParsingException {
201            Properties props = new Properties();
202    
203            NodeList list = httpElem.getChildNodes();
204            for ( int i = 0; i < list.getLength(); i++ ) {
205                Node node = list.item( i );
206                if ( node.getNodeType() != Node.TEXT_NODE ) {
207                    props.setProperty( node.getLocalName(), node.getTextContent() );
208    
209                }
210            }
211            return props;
212        }
213    
214        /**
215         * Parses a POST xml request
216         *
217         * @param httpElem
218         *            that contains the element XMLREQUEST to parse
219         * @return Properties contains, service type,request type, version and the xml request
220         * @throws XMLParsingException
221         */
222        private Properties parseHttpRequestPOST( Node httpElem, String prefix )
223                                throws XMLParsingException {
224            Properties props = new Properties();
225            String dotPrefix = prefix + ":";
226            String serviceType = XMLTools.getRequiredNodeAsString( httpElem, StringTools.concat( 100, "./", dotPrefix,
227                                                                                                 Constants.SERVICE_TYPE ),
228                                                                   cnxt );
229            props.put( Constants.SERVICE_TYPE, serviceType );
230            String requestType = XMLTools.getRequiredNodeAsString( httpElem, StringTools.concat( 100, "./", dotPrefix,
231                                                                                                 Constants.REQUEST_TYPE ),
232                                                                   cnxt );
233            props.put( Constants.REQUEST_TYPE, requestType );
234            props.put( Constants.VERSION, XMLTools.getRequiredNodeAsString( httpElem,
235                                                                            StringTools.concat( 100, "./", dotPrefix,
236                                                                                                Constants.VERSION ), cnxt ) );
237            String xmlContent = XMLTools.getElement( httpElem,
238                                                     StringTools.concat( 100, "./", dotPrefix, Constants.XML_REQUEST ),
239                                                     cnxt ).getTextContent();
240    
241            props.put( Constants.XML_REQUEST, xmlContent != null ? xmlContent : "" );
242            return props;
243        }
244    
245        /**
246         * @return deegree NameSpacecontext plus the cnxt of the ServiceConfiguration
247         */
248        public static NamespaceContext getCnxt() {
249            return cnxt;
250        }
251    
252        /**
253         * @return Prefix of the Serviceconfiguration xml file
254         */
255        public String getPrefix() {
256            return prefix;
257        }
258    }