/** * 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.HashMap; import java.util.Map; import java.util.StringTokenizer; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPFault; import javax.xml.transform.dom.DOMSource; import javax.xml.ws.LogicalMessage; import javax.xml.ws.ProtocolException; import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.soap.SOAPFaultException; import javax.xml.xpath.XPathConstants; import org.w3c.dom.Node; import org.apache.cxf.binding.soap.Soap11; import org.apache.cxf.binding.soap.saaj.SAAJUtils; import org.apache.cxf.common.util.PackageUtils; import org.apache.cxf.helpers.XPathUtils; import org.apache.handler_test.PingException; import org.apache.handler_test.types.Ping; import org.apache.handler_test.types.PingResponse; import org.apache.handler_test.types.PingWithArgs; public class TestHandler<T extends LogicalMessageContext> extends TestHandlerBase implements LogicalHandler<T> { private final JAXBContext jaxbCtx; public TestHandler() { this(true); } public TestHandler(boolean serverSide) { super(serverSide); try { jaxbCtx = JAXBContext.newInstance(PackageUtils.getPackageName(Ping.class)); } catch (JAXBException e) { throw new RuntimeException(e); } } public String getHandlerId() { return "handler" + getId(); } public boolean handleMessage(T ctx) { methodCalled("handleMessage"); printHandlerInfo("handleMessage", isOutbound(ctx)); boolean outbound = (Boolean)ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); boolean ret = getHandleMessageRet(); if (!isServerSideHandler()) { return true; } try { verifyJAXWSProperties(ctx); } catch (PingException e) { e.printStackTrace(); throw new ProtocolException(e); } Object obj = ctx.getMessage().getPayload(jaxbCtx); if (obj instanceof Ping || obj instanceof PingResponse) { ret = handlePingMessage(outbound, ctx); } else if (obj instanceof PingWithArgs) { ret = handlePingWithArgsMessage(outbound, ctx); } return ret; } private boolean handlePingWithArgsMessage(boolean outbound, T ctx) { LogicalMessage msg = ctx.getMessage(); Object payload = msg.getPayload(jaxbCtx); addHandlerId(ctx.getMessage(), ctx, outbound); boolean ret = true; if (payload instanceof PingWithArgs) { String arg = ((PingWithArgs)payload).getHandlersCommand(); 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)) { PingResponse resp = new PingResponse(); resp.getHandlersInfo().addAll(getHandlerInfoList(ctx)); msg.setPayload(resp, jaxbCtx); 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 (exceptionType != null && outbound && "outbound".equals(direction)) { if ("RuntimeException".equals(exceptionType)) { throw new RuntimeException(exceptionText); } else if ("ProtocolException".equals(exceptionType)) { throw new ProtocolException(exceptionText); } } } } return ret; } private boolean checkServerOutBindStopHandler(boolean outbound, T ctx) { if (outbound) { LogicalMessage msg = ctx.getMessage(); Object obj = msg.getPayload(jaxbCtx); if (obj instanceof PingResponse) { // only check if we need call for the server response handler false PingResponse origResp = (PingResponse)obj; for (String handler : origResp.getHandlersInfo()) { if (handler.indexOf("server") == 0 && handler.indexOf(getHandlerId()) > 0 && handler.indexOf("stop") > 0) { return true; } } } } return false; } private boolean handlePingMessage(boolean outbound, T ctx) { LogicalMessage msg = ctx.getMessage(); addHandlerId(msg, ctx, outbound); if (checkServerOutBindStopHandler(outbound, ctx)) { return false; } else { return getHandleMessageRet(); } } private void addHandlerId(LogicalMessage msg, T ctx, boolean outbound) { Object obj = msg.getPayload(jaxbCtx); if (obj instanceof PingResponse) { PingResponse origResp = (PingResponse)obj; PingResponse newResp = new PingResponse(); newResp.getHandlersInfo().addAll(origResp.getHandlersInfo()); newResp.getHandlersInfo().add(getHandlerId()); msg.setPayload(newResp, jaxbCtx); } else if (obj instanceof Ping || obj instanceof PingWithArgs) { getHandlerInfoList(ctx).add(getHandlerId()); } } public boolean handleFault(T ctx) { methodCalled("handleFault"); printHandlerInfo("handleFault", isOutbound(ctx)); if (isServerSideHandler()) { if (!"handler2".equals(getHandlerId())) { return true; } DOMSource source = (DOMSource)ctx.getMessage().getPayload(); Node node = source.getNode(); Map<String, String> ns = new HashMap<>(); ns.put("s", Soap11.SOAP_NAMESPACE); XPathUtils xu = new XPathUtils(ns); String exceptionText = (String)xu.getValue("//s:Fault/faultstring/text()", node, XPathConstants.STRING); //XMLUtils.writeTo(node, System.out); if ("handler2HandleFaultThrowsRunException".equals(exceptionText)) { throw new RuntimeException("handler2 HandleFault throws RuntimeException"); } else if ("handler2HandleFaultThrowsSOAPFaultException".equals(exceptionText)) { throw createSOAPFaultException("handler2 HandleFault " + "throws SOAPFaultException"); } } return true; } private SOAPFaultException createSOAPFaultException(String faultString) { try { SOAPFault fault = SOAPFactory.newInstance().createFault(); fault.setFaultString(faultString); SAAJUtils.setFaultCode(fault, new QName("http://cxf.apache.org/faultcode", "Server")); return new SOAPFaultException(fault); } catch (SOAPException e) { // do nothing } return null; } public void close(MessageContext arg0) { methodCalled("close"); } public void destroy() { methodCalled("destroy"); } public String toString() { return getHandlerId(); } }