001 /*----------------------------------------------------------------------------
002 This file is part of deegree, http://deegree.org/
003 Copyright (C) 2001-2009 by:
004 Department of Geography, University of Bonn
005 and
006 lat/lon GmbH
007
008 This library is free software; you can redistribute it and/or modify it under
009 the terms of the GNU Lesser General Public License as published by the Free
010 Software Foundation; either version 2.1 of the License, or (at your option)
011 any later version.
012 This library is distributed in the hope that it will be useful, but WITHOUT
013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
014 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
015 details.
016 You should have received a copy of the GNU Lesser General Public License
017 along with this library; if not, write to the Free Software Foundation, Inc.,
018 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019
020 Contact information:
021
022 lat/lon GmbH
023 Aennchenstr. 19, 53177 Bonn
024 Germany
025 http://lat-lon.de/
026
027 Department of Geography, University of Bonn
028 Prof. Dr. Klaus Greve
029 Postfach 1147, 53001 Bonn
030 Germany
031 http://www.geographie.uni-bonn.de/deegree/
032
033 e-mail: info@deegree.org
034 ----------------------------------------------------------------------------*/
035 package org.deegree.ogcwebservices.csw.iso_profile.ebrim;
036
037 import java.net.MalformedURLException;
038 import java.security.InvalidParameterException;
039 import java.util.List;
040
041 import org.deegree.framework.log.ILogger;
042 import org.deegree.framework.log.LoggerFactory;
043 import org.deegree.framework.xml.XMLFragment;
044 import org.deegree.framework.xml.XMLParsingException;
045 import org.deegree.framework.xml.XMLTools;
046 import org.deegree.ogcbase.CommonNamespaces;
047 import org.deegree.ogcwebservices.OGCWebServiceException;
048 import org.deegree.ogcwebservices.csw.CSWExceptionCode;
049 import org.w3c.dom.Document;
050 import org.w3c.dom.Element;
051 import org.w3c.dom.Node;
052
053 /**
054 * The <code>CSWSOAPFilter</code> class parses an incoming soap - (post)request which (if the root element is bound to
055 * the soap name space "http://www.w3.org/2003/05/soap-envelope") will copy the csw:Operation inside the envelope. Sets
056 * the user name and passwords inside the root element of the csw:reqquest and sends it to the chain.
057 *
058 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
059 *
060 * @author last edited by: $Author: bezema $
061 *
062 * @version $Revision: 1.4 $, $Date: 2007-06-21 13:53:49 $
063 *
064 */
065
066 public class CSWSOAPHandler {
067 private static ILogger LOG = LoggerFactory.getLogger( CSWSOAPHandler.class );
068
069 private XMLFragment incomingRequest;
070
071 private boolean isSOAPRequest;
072
073 private String userName = "anonymous";
074
075 private String password = "";
076
077 /**
078 * Create an empty CSWSoapHandler with username set to anonymous and password to "". No xml-data is set.
079 */
080 public CSWSOAPHandler() {
081 incomingRequest = null;
082 isSOAPRequest = false;
083 }
084
085 /**
086 * Simple constructor buffering the request.
087 *
088 * @param incomingRequest
089 */
090 public CSWSOAPHandler( XMLFragment incomingRequest ) {
091 if ( incomingRequest == null ) {
092 throw new InvalidParameterException( "The incomingRequest parameter may not be null" );
093 }
094 this.incomingRequest = incomingRequest;
095 String ns = incomingRequest.getRootElement().getNamespaceURI();
096 LOG.logDebug( " The namespace of the rootelement = " + ns );
097 isSOAPRequest = CommonNamespaces.W3SOAP_ENVELOPE.toASCIIString().equals( ns );
098 }
099
100 /**
101 * @return true if the namespace of the root element is 'http://www.w3.org/2003/05/soap-envelope' false otherwise.
102 */
103 public boolean isSOAPRequest() {
104 return isSOAPRequest;
105 }
106
107 /**
108 * Finds a user and a password from a given soap request, and inserts them as attributes into the rootelement of the
109 * csw:request inside the body of the soap. This request is returned.
110 *
111 * @return the XMLTree inside the soap:body or <code>null</code> if the element has no localname of Envelope, or
112 * the data (aka as doc) was not set.
113 * @throws OGCWebServiceException
114 * if some required elements are not set.
115 */
116 public XMLFragment createCSWRequestFromSOAP()
117 throws OGCWebServiceException {
118 if ( !isSOAPRequest ) {
119 LOG.logDebug( " not a soaprequest, so returning the unparsed xmlfragment." );
120 return this.incomingRequest;
121 }
122 if ( incomingRequest == null ) {
123 LOG.logDebug( " no data was set, so returning null." );
124 return null;
125 }
126
127 Element rootElement = this.incomingRequest.getRootElement();
128
129 String localName = rootElement.getLocalName();
130 if ( localName == null || !"Envelope".equals( localName ) ) {
131 LOG.logDebug( " The localname of the root element is not: 'Envelope', so not parsing the SOAP request. " );
132 throw new OGCWebServiceException(
133 "A SOAP-Request must contain the root element with a localname of 'Envelope', you supplied: "
134 + localName, CSWExceptionCode.WRS_INVALIDREQUEST );
135 }
136 Element header = null;
137 Element cswRequest = null;
138 try {
139 header = XMLTools.getRequiredElement( rootElement, CommonNamespaces.W3SOAP_ENVELOPE_PREFIX + ":Header",
140 CommonNamespaces.getNamespaceContext() );
141 Element body = XMLTools.getRequiredElement( rootElement, CommonNamespaces.W3SOAP_ENVELOPE_PREFIX + ":Body",
142 CommonNamespaces.getNamespaceContext() );
143 List<Element> cswRequests = XMLTools.getElements( body, "*", CommonNamespaces.getNamespaceContext() );
144 if ( cswRequests.size() != 1 ) {
145 StringBuffer sb = new StringBuffer();
146 for ( int i = 0; i < cswRequests.size(); ++i ) {
147 sb.append( cswRequests.get( i ).getLocalName() + ( ( ( i + 1 ) < cswRequests.size() ) ? ", " : "" ) );
148 }
149 LOG.logDebug( " Not enough csw requests found in the body of the soap envelope, found: "
150 + sb.toString() );
151 throw new OGCWebServiceException(
152 "You have not supplied exactly one csw requests in the body of the soap envelope (you supplied: "
153 + sb.toString()
154 + "), only one request per soap envelope is allowed.",
155 CSWExceptionCode.WRS_INVALIDREQUEST );
156 }
157 cswRequest = cswRequests.get( 0 );
158 LOG.logDebug( " found csw request: " + cswRequest.getLocalName() );
159
160 } catch ( XMLParsingException e ) {
161 LOG.logDebug( " No soap:header or soap:body found: " + e.getMessage() );
162 throw new OGCWebServiceException(
163 "While parsing your soap request, a required element (soap:Header or soap:Body) wasn't found, the exact error message is: "
164 + e.getMessage(),
165 CSWExceptionCode.WRS_INVALIDREQUEST );
166
167 }
168
169 try {
170 userName = XMLTools.getNodeAsString( header, CommonNamespaces.DGSEC_PREFIX + ":user",
171 CommonNamespaces.getNamespaceContext(), "default" );
172 password = XMLTools.getNodeAsString( header, CommonNamespaces.DGSEC_PREFIX + ":password",
173 CommonNamespaces.getNamespaceContext(), "default" );
174 } catch ( XMLParsingException e ) {
175 LOG.logDebug( " No deegreesec:user/deegreesec:password found: " + e.getMessage() );
176 throw new OGCWebServiceException(
177 "While parsing your soap request, a required element (deegreesec:user/deegreesec:password) wasn't found, the exact error message is: "
178 + e.getMessage(),
179 CSWExceptionCode.WRS_INVALIDREQUEST );
180 }
181
182 LOG.logDebug( " found user: " + userName );
183 LOG.logDebug( " found password: " + password );
184
185 String ns = cswRequest.getNamespaceURI();
186 if ( !CommonNamespaces.CSWNS.toASCIIString().equals( ns ) ) {
187 LOG.logDebug( " The namespace of the enveloped request-root element is not: " + CommonNamespaces.CSWNS
188 + " so not using the SOAP servlet filter. " );
189 throw new OGCWebServiceException( "The namespace of the enveloped request-root element is not: "
190 + CommonNamespaces.CSWNS, CSWExceptionCode.WRS_INVALIDREQUEST );
191 }
192
193 Document newRequestDoc = XMLTools.create();
194 Node a = newRequestDoc.importNode( cswRequest, true );
195 if ( a.getNodeType() != Node.ELEMENT_NODE ) {
196 throw new OGCWebServiceException( "The copied request is not of type w3c.ELEMENT_NODE, this cannot be.",
197 CSWExceptionCode.WRS_INVALIDREQUEST );
198 }
199 Element insertedRequest = (Element) newRequestDoc.appendChild( a );
200 insertedRequest.setAttribute( "user", userName );
201 insertedRequest.setAttribute( "password", password );
202
203 XMLFragment frag = null;
204 try {
205 frag = new XMLFragment( newRequestDoc, XMLFragment.DEFAULT_URL );
206 XMLTools.appendNSBinding( frag.getRootElement(), "rim", CommonNamespaces.OASIS_EBRIMNS );
207 if ( LOG.isDebug() ) {
208 LOG.logDebug( " the resulting request:\n " + frag.getAsPrettyString() );
209 }
210 } catch ( MalformedURLException e ) {
211 // never happens because using default url
212 }
213 return frag;
214 }
215
216 /**
217 * @return the password.
218 */
219 public String getPassword() {
220 return password;
221 }
222
223 /**
224 * @return the userName.
225 */
226 public String getUserName() {
227 return userName;
228 }
229
230 /**
231 * @param doc
232 * sets the incomingRequest to doc.
233 */
234 public void setIncomingRequest( XMLFragment doc ) {
235 if ( doc == null ) {
236 throw new InvalidParameterException( "The incomingRequest parameter may not be null" );
237 }
238 incomingRequest = doc;
239 String ns = incomingRequest.getRootElement().getNamespaceURI();
240 LOG.logDebug( " The namespace of the rootelement = " + ns );
241 isSOAPRequest = CommonNamespaces.W3SOAP_ENVELOPE.toASCIIString().equals( ns );
242
243 }
244
245 }