Package org.openbel.framework.ws.core

Source Code of org.openbel.framework.ws.core.CustomizeSoapFaultExceptionResolver

/**
* Copyright (C) 2012-2013 Selventa, Inc.
*
* This file is part of the OpenBEL Framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The OpenBEL Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the OpenBEL Framework. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms under LGPL v3:
*
* This license does not authorize you and you are prohibited from using the
* name, trademarks, service marks, logos or similar indicia of Selventa, Inc.,
* or, in the discretion of other licensors or authors of the program, the
* name, trademarks, service marks, logos or similar indicia of such authors or
* licensors, in any marketing or advertising materials relating to your
* distribution of the program or any covered product. This restriction does
* not waive or limit your obligation to keep intact all copyright notices set
* forth in the program as delivered to you.
*
* If you distribute the program in whole or in part, or any modified version
* of the program, and you assume contractual liability to the recipient with
* respect to the program or modified version, then you will indemnify the
* authors and licensors of the program for any liabilities that these
* contractual assumptions directly impose on those licensors and authors.
*/
package org.openbel.framework.ws.core;

import static org.openbel.framework.common.BELUtilities.getFirstMessage;
import static org.openbel.framework.common.BELUtilities.hasLength;

import java.lang.reflect.Method;
import java.util.Locale;

import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointExceptionResolver;
import org.springframework.ws.server.endpoint.AbstractEndpointExceptionResolver;
import org.springframework.ws.server.endpoint.MethodEndpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.soap.SoapMessage;

/**
* {@link CustomizeSoapFaultExceptionResolver} is a custom implementation of an
* {@link EndpointExceptionResolver endpoint exception resolver} that prepends
* the webservice operation name to the endpoint's exception message.
*
* @author Anthony Bargnesi {@code <abargnesi@selventa.com>}
*/
public class CustomizeSoapFaultExceptionResolver extends
        AbstractEndpointExceptionResolver {

    /**
     * The suffix of the endpoint's request object - {@value}
     */
    private static final String ENDPOINT_REQUEST_SUFFIX = "Request";

    /**
     * The fault string format - {@value}
     */
    private static final String FAULT_STRING_FORMAT = "%s: %s";

    /**
     * {@inheritDoc} This implementation extracts the webservice operation name
     * from the {@link PayloadRoot payload root annotation} defines on the
     * {@link MethodEndpoint method endpoint}. The webservice operation name is
     * prepended to the soap fault's "faultstring".
     * <p>
     * If the webservice operation name cannot be determined the soap fault's
     * "faultstring" will just contain the {@link Exception exception}'s
     * message. This can occur when:
     * <ul>
     * <li>the endpoint, <tt>ep</tt>, is not an instance of
     * {@link MethodEndpoint method endpoint}</li>
     * <li>the {@link PayloadRoot} is <tt>null</tt></li>
     * <li>the "localPart" property of the {@link PayloadRoot payload root} does
     * not end with
     * {@link CustomizeSoapFaultExceptionResolver#ENDPOINT_REQUEST_SUFFIX}</li>
     * </p>
     */
    @Override
    protected boolean resolveExceptionInternal(
            MessageContext messageContext, Object ep, Exception ex) {
        // fail when the response is not a SoapMessage, because we would not be
        // able to attach fault to a soap response
        Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse(),
                "CustomizeSoapFaultExceptionResolver requires a SoapMessage");

        String exMsg = ex.getMessage();
        String firstMsg = getFirstMessage(ex);
        if (hasLength(firstMsg)) {
            if (!exMsg.equals(firstMsg) && !exMsg.contains(firstMsg)) {
                exMsg = exMsg.concat(" (caused by: " + firstMsg + ")");
            }
        }

        // if following conditions, soap fault with ex message
        if (!MethodEndpoint.class.isInstance(ep)) {
            return createFault(messageContext, null, exMsg);
        }

        // find payload root's localPart or return soap fault with ex message
        final Method emtd = ((MethodEndpoint) ep).getMethod();
        String localPart = null;
        PayloadRoot proot = emtd.getAnnotation(PayloadRoot.class);
        if (proot != null) {
            localPart = proot.localPart();
        } else {
            return createFault(messageContext, null, exMsg);
        }

        // return soap fault with ex message if localPart does not end with
        // 'Request'
        if (!localPart.endsWith(ENDPOINT_REQUEST_SUFFIX)) {
            return createFault(messageContext, null, exMsg);
        }

        // extract endpoint operation name
        localPart = localPart.substring(0,
                localPart.indexOf(ENDPOINT_REQUEST_SUFFIX));
        return createFault(messageContext, localPart, exMsg);
    }

    /**
     * Create the soap fault and attach to the {@link SoapBody} of the
     * {@link SoapMessage soap response}.
     *
     * @param msgctx {@link MessageContext}, the message context for this
     * webservice message
     * @param wsopName {@link String}, the webservice operation name, which can
     * be <tt>null</tt>
     * @param exMsg {@link String}, the endpoint {@link Exception exception}
     * message
     * @return
     */
    private boolean createFault(final MessageContext msgctx,
            final String wsopName, final String exMsg) {
        final String faultstring;
        if (wsopName == null) {
            logger.warn("Sending SOAP fault without endpoint identification for: "
                    + msgctx.getRequest());
            faultstring = exMsg;
        } else {
            faultstring = String.format(FAULT_STRING_FORMAT, wsopName, exMsg);
        }

        final SoapMessage response = (SoapMessage) msgctx.getResponse();
        final SoapBody body = response.getSoapBody();
        body.addServerOrReceiverFault(faultstring, Locale.ENGLISH);
        return true;
    }
}
TOP

Related Classes of org.openbel.framework.ws.core.CustomizeSoapFaultExceptionResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.