// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.plugin.http.eventcore; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Level; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import de.ugoe.cs.autoquest.plugin.http.HTTPUtils; import de.ugoe.cs.autoquest.plugin.http.logdata.Header; import de.ugoe.cs.autoquest.plugin.http.logdata.HttpExchange; import de.ugoe.cs.util.console.Console; /** *

* represents the specific HTTP event for a SOAP message exchange. It contains the SOAP request * and response envelopes and is more concrete when comparing object. E.g., it considers the * called SOAP operation on performing comparison. *

* * @author Patrick Harms */ public final class SOAPEventType extends HTTPEventType { /** */ private static final long serialVersionUID = 1L; /** *

* the SOAP request belonging to the event *

*/ transient private SOAPMessage soapRequest; /** *

* the SOAP response belonging to the event *

*/ transient private SOAPMessage soapResponse; /** *

* the SOAP method called in this request *

*/ private String calledMethod; /** *

* the human readable name of this event type *

*/ private String name; /** *

* initializes the event type with the represented HTTP exchange and the already extracted * SOAP request and response. *

* * @param exchange the represented HTTP exchange * @param soapRequest the already extracted SOAP request * @param soapResponse the already extracted SOAP response */ public SOAPEventType(HttpExchange exchange, SOAPMessage soapRequest, SOAPMessage soapResponse) { super(exchange); this.soapRequest = soapRequest; this.soapResponse = soapResponse; this.calledMethod = normalizeCalledMethod(determineCalledMethod(exchange, soapRequest)); String path = null; if ((exchange.getRequest() != null) && (exchange.getRequest().getUrl() != null)) { try { path = new URL(exchange.getRequest().getUrl()).getPath(); } catch (MalformedURLException e) { // ignore and continue } } StringBuffer nameBuffer = new StringBuffer("SOAPEvent"); boolean somethingAdded = false; if (path != null) { nameBuffer.append("("); nameBuffer.append(path); somethingAdded = true; } if (calledMethod != null) { nameBuffer.append(somethingAdded ? ", " : "("); nameBuffer.append(calledMethod); somethingAdded = true; } String senderStr = HTTPUtils.toString(exchange.getSender()); String receiverStr = HTTPUtils.toString(exchange.getReceiver()); if ((senderStr != null) && (receiverStr != null)) { nameBuffer.append(somethingAdded ? ", " : "("); nameBuffer.append(senderStr); nameBuffer.append(" --> "); nameBuffer.append(receiverStr); somethingAdded = true; } else if (senderStr != null) { nameBuffer.append(somethingAdded ? ", " : "("); nameBuffer.append(senderStr); somethingAdded = true; } else if (receiverStr != null) { nameBuffer.append(somethingAdded ? ", " : "("); nameBuffer.append(receiverStr); somethingAdded = true; } if (somethingAdded) { nameBuffer.append(")"); } this.name = nameBuffer.toString(); } /** *

* the SOAP method called in this request *

* * @return the SOAP method called in this request */ public String getCalledMethod() { return calledMethod; } /** * @return the soapRequest */ public SOAPMessage getSoapRequest() { return soapRequest; } /** * @return the soapResponse */ public SOAPMessage getSoapResponse() { return soapResponse; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName() */ @Override public String getName() { return name; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#toString() */ @Override public String toString() { return name; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj instanceof SOAPEventType) { if (!obj.getClass().isAssignableFrom(this.getClass())) { return false; } return super.equals(obj) && HTTPUtils.equals(calledMethod, ((SOAPEventType) obj).calledMethod); } else { return false; } } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#hashCode() */ @Override public int hashCode() { if (calledMethod != null) { return super.hashCode() + calledMethod.hashCode(); } else { return super.hashCode(); } } /** *

* determines the name of the method called in a SOAP request either through the HTTP header * or through the SOAP body *

*/ private String determineCalledMethod(HttpExchange exchange, SOAPMessage soapRequest) { // first check for a header containing the SOAP action if ((exchange.getRequest() != null) && (exchange.getRequest().getHeaders() != null) && (exchange.getRequest().getHeaders().getHeader() != null)) { for (Header header : exchange.getRequest().getHeaders().getHeader()) { if ("SOAPAction".equalsIgnoreCase(header.getKey())) { return header.getValue(); } } } // if there is none, use the root element of the body try { if ((soapRequest.getSOAPBody() != null) && (soapRequest.getSOAPBody().getChildNodes() != null) && (soapRequest.getSOAPBody().getChildNodes().getLength() > 0)) { return soapRequest.getSOAPBody().getChildNodes().item(0).getNodeName(); } } catch (SOAPException e) { Console.traceln(Level.WARNING, "could not process SOAP message correctly: " + e); Console.logException(e); } return null; } /** * removes unnecessary characters from the method name */ private String normalizeCalledMethod(String calledMethod) { if (calledMethod != null) { if (calledMethod.startsWith("\"") && calledMethod.endsWith("\"")) { calledMethod = calledMethod.substring(1, calledMethod.length() - 1); } if (calledMethod.startsWith("urn:")) { calledMethod = calledMethod.substring(4); } } return calledMethod; } }