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