/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.cxf.systest.handlers; import java.util.Set; import java.util.StringTokenizer; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.xml.namespace.QName; import javax.xml.soap.Detail; import javax.xml.soap.DetailEntry; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPConstants; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPFault; import javax.xml.soap.SOAPMessage; import javax.xml.ws.ProtocolException; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import javax.xml.ws.soap.SOAPFaultException; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.apache.cxf.Bus; import org.apache.cxf.binding.soap.saaj.SAAJUtils; /** * Describe class TestSOAPHandler here. */ public class TestSOAPHandler extends TestHandlerBase implements SOAPHandler<SOAPMessageContext> { @Resource Bus bus; @Resource(name = "org.apache.cxf.wsdl.WSDLManager") org.apache.cxf.wsdl.WSDLManager manager; public TestSOAPHandler() { this(true); } public TestSOAPHandler(boolean serverSide) { super(serverSide); } @PostConstruct public void initPost() { if (bus == null) { throw new RuntimeException("No BUS"); } if (manager == null) { throw new RuntimeException("No WSDL Manager"); } } // Implementation of javax.xml.ws.handler.soap.SOAPHandler public final Set<QName> getHeaders() { return null; } public String getHandlerId() { return "soapHandler" + getId(); } public boolean handleMessage(SOAPMessageContext ctx) { boolean continueProcessing = true; if (!isValidWsdlDescription(ctx.get(MessageContext.WSDL_DESCRIPTION))) { throw new RuntimeException("can't find WsdlDescription throws RuntimeException"); } try { methodCalled("handleMessage"); printHandlerInfo("handleMessage", isOutbound(ctx)); Object b = ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); boolean outbound = (Boolean)b; SOAPMessage msg = ctx.getMessage(); if (isServerSideHandler()) { if (outbound) { continueProcessing = getReturnValue(outbound, ctx); } else { continueProcessing = getReturnValue(outbound, ctx); if (!continueProcessing) { outbound = true; } } if (outbound) { try { // append handler id to SOAP response message SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); Node resp = body.getFirstChild(); if (resp.getNodeName().contains("pingResponse")) { Node child = resp.getFirstChild(); Document doc = resp.getOwnerDocument(); Node info = doc.createElementNS(child.getNamespaceURI(), child.getLocalName()); info.setPrefix("ns4"); info.appendChild(doc.createTextNode(getHandlerId())); resp.appendChild(info); msg.saveChanges(); } } catch (DOMException e) { e.printStackTrace(); } } else { getHandlerInfoList(ctx).add(getHandlerId()); } } } catch (SOAPException e) { e.printStackTrace(); } return continueProcessing; } public boolean handleFault(SOAPMessageContext ctx) { methodCalled("handleFault"); printHandlerInfo("handleFault", isOutbound(ctx)); if (isServerSideHandler()) { if (!"soapHandler4".equals(getHandlerId())) { return true; } try { SOAPMessage msg = ctx.getMessage(); String fs = msg.getSOAPPart().getEnvelope().getBody().getFault().getFaultString(); if ("soapHandler4HandleFaultThrowsRunException".equals(fs)) { throw new RuntimeException("soapHandler4 HandleFault throws RuntimeException"); } else if ("soapHandler4HandleFaultThrowsSOAPFaultException".equals(fs)) { throw createSOAPFaultException("soapHandler4 HandleFault throws SOAPFaultException"); } } catch (SOAPException e) { // do nothing } } return true; } public final void destroy() { methodCalled("destroy"); } public final void close(MessageContext messageContext) { methodCalled("close"); } private boolean getReturnValue(boolean outbound, SOAPMessageContext ctx) { boolean ret = true; try { SOAPMessage msg = ctx.getMessage(); SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); if (body.getFirstChild().getFirstChild() == null) { return true; } Node commandNode = body.getFirstChild().getFirstChild().getFirstChild(); String arg = commandNode.getNodeValue(); String namespace = body.getFirstChild().getFirstChild().getNamespaceURI(); StringTokenizer strtok = new StringTokenizer(arg, " "); String hid = ""; String direction = ""; String command = ""; if (strtok.countTokens() >= 3) { hid = strtok.nextToken(); direction = strtok.nextToken(); command = strtok.nextToken(); } if (!getHandlerId().equals(hid)) { return true; } if ("stop".equals(command)) { if (!outbound && "inbound".equals(direction)) { // remove the incoming request body. Document doc = body.getOwnerDocument(); // build the SOAP response for this message // Node wrapper = doc.createElementNS(namespace, "pingResponse"); wrapper.setPrefix("ns4"); body.removeChild(body.getFirstChild()); body.appendChild(wrapper); for (String info : getHandlerInfoList(ctx)) { // copy the previously invoked handler list into the response. // Ignore this handler's information as it will be added again later. // if (!info.contains(getHandlerId())) { Node newEl = doc.createElementNS(namespace, "HandlersInfo"); newEl.setPrefix("ns4"); newEl.appendChild(doc.createTextNode(info)); wrapper.appendChild(newEl); } } ret = false; } else if (outbound && "outbound".equals(direction)) { ret = false; } } else if ("throw".equals(command)) { String exceptionType = null; String exceptionText = "HandleMessage throws exception"; if (strtok.hasMoreTokens()) { exceptionType = strtok.nextToken(); } if (strtok.hasMoreTokens()) { exceptionText = strtok.nextToken(); } if (exceptionType != null && !outbound && "inbound".equals(direction)) { if ("RuntimeException".equals(exceptionType)) { throw new RuntimeException(exceptionText); } else if ("ProtocolException".equals(exceptionType)) { throw new ProtocolException(exceptionText); } else if ("SOAPFaultException".equals(exceptionType)) { throw createSOAPFaultException(exceptionText); } else if ("SOAPFaultExceptionWDetail".equals(exceptionType)) { throw createSOAPFaultExceptionWithDetail(exceptionText); } } else if (exceptionType != null && outbound && "outbound".equals(direction)) { if ("RuntimeException".equals(exceptionType)) { throw new RuntimeException(exceptionText); } else if ("ProtocolException".equals(exceptionType)) { throw new ProtocolException(exceptionText); } else if ("SOAPFaultException".equals(exceptionType)) { throw createSOAPFaultException(exceptionText); } else if ("SOAPFaultExceptionWDetail".equals(exceptionType)) { throw createSOAPFaultExceptionWithDetail(exceptionText); } } } } catch (SOAPException e) { e.printStackTrace(); } return ret; } private SOAPFaultException createSOAPFaultException(String faultString) throws SOAPException { SOAPFault fault = SOAPFactory.newInstance().createFault(); fault.setFaultString(faultString); SAAJUtils.setFaultCode(fault, new QName("http://cxf.apache.org/faultcode", "Server")); return new SOAPFaultException(fault); } private SOAPFaultException createSOAPFaultExceptionWithDetail(String faultString) throws SOAPException { SOAPFault fault = SOAPFactory.newInstance().createFault(); QName faultName = new QName(SOAPConstants.URI_NS_SOAP_ENVELOPE, "Server"); SAAJUtils.setFaultCode(fault, faultName); fault.setFaultActor("http://gizmos.com/orders"); fault.setFaultString(faultString); Detail detail = fault.addDetail(); QName entryName = new QName("http://gizmos.com/orders/", "order", "PO"); DetailEntry entry = detail.addDetailEntry(entryName); entry.addTextNode("Quantity element does not have a value"); QName entryName2 = new QName("http://gizmos.com/orders/", "order", "PO"); DetailEntry entry2 = detail.addDetailEntry(entryName2); entry2.addTextNode("Incomplete address: no zip code"); return new SOAPFaultException(fault); } public String toString() { return getHandlerId(); } private boolean isValidWsdlDescription(Object wsdlDescription) { return (wsdlDescription != null) && ((wsdlDescription instanceof java.net.URI) || (wsdlDescription instanceof java.net.URL)); } }