mp.platform.cyclone.webservices.utils.WebServiceHelper.java Source code

Java tutorial

Introduction

Here is the source code for mp.platform.cyclone.webservices.utils.WebServiceHelper.java

Source

/*
   This file is part of Cyclos.
    
   Cyclos is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
    
   Cyclos 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 General Public License for more details.
    
   You should have received a copy of the GNU General Public License
   along with Cyclos; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package mp.platform.cyclone.webservices.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;

import nl.strohalm.cyclos.dao.exceptions.EntityNotFoundException;
import nl.strohalm.cyclos.dao.exceptions.QueryParseException;
import nl.strohalm.cyclos.entities.Entity;
import nl.strohalm.cyclos.entities.access.User;
import nl.strohalm.cyclos.entities.accounts.pos.Pos;
import nl.strohalm.cyclos.entities.members.Element;
import nl.strohalm.cyclos.entities.services.ServiceClient;
import nl.strohalm.cyclos.services.access.exceptions.BlockedCredentialsException;
import nl.strohalm.cyclos.services.access.exceptions.InvalidCredentialsException;
import nl.strohalm.cyclos.services.accounts.pos.exceptions.InvalidPosPinException;
import nl.strohalm.cyclos.services.accounts.pos.exceptions.PosPinBlockedException;
import nl.strohalm.cyclos.utils.CurrentTransactionData;
import nl.strohalm.cyclos.utils.logging.LoggingHandler;
import nl.strohalm.cyclos.utils.validation.ValidationException;
import mp.platform.cyclone.webservices.WebServiceContext;
import mp.platform.cyclone.webservices.WebServiceFaultsEnum;
import mp.platform.cyclone.webservices.payments.WebServiceFault;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.binding.soap.SoapFault;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.service.model.MessageInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.transport.http.AbstractHTTPDestination;

/**
 * Contains helper methods for web services
 * @author luis
 */
public class WebServiceHelper {

    private static final String CODE_PREFIX = "cyclos";
    private static final Log logger = LogFactory.getLog(WebServiceHelper.class);

    /**
     * Returns a SOAP fault
     */
    public static SoapFault fault(final Throwable exception) {
        WebServiceFault fault;
        if ((exception instanceof ValidationException) || (exception instanceof IllegalArgumentException)) {
            fault = WebServiceFaultsEnum.INVALID_PARAMETERS;
        } else if (exception instanceof EntityNotFoundException) {
            final Class<? extends Entity> entityType = ((EntityNotFoundException) exception).getEntityType();
            if (Element.class.isAssignableFrom(entityType) || User.class.isAssignableFrom(entityType)) {
                fault = WebServiceFaultsEnum.MEMBER_NOT_FOUND;
            } else {
                fault = WebServiceFaultsEnum.INVALID_PARAMETERS;
            }
        } else if (exception instanceof QueryParseException) {
            fault = WebServiceFaultsEnum.QUERY_PARSE_ERROR;
        } else if (exception instanceof InvalidCredentialsException
                || exception instanceof InvalidPosPinException) {
            fault = WebServiceFaultsEnum.INVALID_CREDENTIALS;
        } else if (exception instanceof BlockedCredentialsException
                || exception instanceof PosPinBlockedException) {
            fault = WebServiceFaultsEnum.BLOCKED_CREDENTIALS;
        } else {
            fault = WebServiceFaultsEnum.UNEXPECTED_ERROR;
        }

        return fault(fault, exception);
    }

    public static SoapFault fault(final WebServiceFault fault) {
        return fault(fault.code(), null);
    }

    public static SoapFault fault(final WebServiceFault fault, final Throwable cause) {
        return fault(fault.code(), cause);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getParameter(final SoapMessage message) {
        final List params = message.getContent(java.util.List.class);
        if (CollectionUtils.isEmpty(params)) {
            return null;
        } else {
            if (params.size() > 1) {
                logger.warn("The operation '" + getWebServiceOperationName(message)
                        + "' has more than one parameter (" + params.size() + "). Returning only the first.");
            }
            return (T) params.get(0);
        }
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> getParameters(final SoapMessage message) {
        final MessageInfo messageInfo = message.get(MessageInfo.class);
        final List parameterValues = message.getContent(java.util.List.class);
        final Map<String, Object> result = new HashMap<String, Object>();

        if (parameterValues != null) {
            for (int i = 0; i < messageInfo.getMessageParts().size(); i++) {
                final String name = messageInfo.getMessagePart(i).getName().getLocalPart();
                if (!"credentials posPin fromMemberCredentials".contains(name)) {
                    result.put(name, parameterValues.get(i));
                }
            }
        } else {
            final Object param = message.getContent(Object.class);
            result.put("param", param);
        }

        return result;
    }

    public static String getWebServiceOperationName(final SoapMessage message) {
        final MessageInfo messageInfo = message.get(MessageInfo.class);
        final OperationInfo operation = messageInfo.getOperation();
        final QName operationQName = operation.getName();

        return operationQName.getLocalPart();
    }

    /**
     * Initialize the POS Web Service Context.
     */
    public static void initializeContext(final Pos pos, final SoapMessage message) {
        WebServiceContext.set(pos, servletContextOf(message), requestOf(message), message);
    }

    /**
     * Initialize the Web Service Context for all WS using Services Clients.
     */
    public static void initializeContext(final ServiceClient client, final SoapMessage message) {
        WebServiceContext.set(client, servletContextOf(message), requestOf(message), message);
    }

    /**
     * @return true if the specified client's id is equals to the restricted (used in this request) client's id
     */
    public static boolean isCurrentClient(final Long clientId) {
        if (WebServiceContext.isPosContext()) {
            return false;
        } else {
            return ObjectUtils.equals(WebServiceContext.getClient().getId(), clientId);
        }
    }

    /**
     * Checks whether the given fault was generated by Cyclos
     */
    public static boolean isFromCyclos(final Fault fault) {
        return CODE_PREFIX.equals(fault.getFaultCode().getNamespaceURI());
    }

    /**
     * Returns the HttpServletRequest instance for the given SOAP message
     */
    public static HttpServletRequest requestOf(final SoapMessage message) {
        return (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
    }

    /**
     * Returns the HttpServletRequest instance for the given SOAP message
     */
    public static ServletContext servletContextOf(final SoapMessage message) {
        return (ServletContext) message.get(AbstractHTTPDestination.HTTP_CONTEXT);
    }

    /**
     * Returns a SOAP fault
     */
    private static SoapFault fault(final String code, final Throwable th) throws SoapFault {
        SoapFault sf = new SoapFault("Server error: " + code, th, faultCode(code));
        if (th != null) {
            org.w3c.dom.Element el = sf.getOrCreateDetail();
            el.setTextContent(th.getMessage());
            sf.setDetail(el);
        }
        return sf;
    }

    /**
     * Returns a qualified name for a fault code
     */
    private static QName faultCode(final String code) {
        return new QName(CODE_PREFIX, code);
    }

    private LoggingHandler loggingHandler;

    public void error(final String error) {
        error(new Exception(error));
    }

    public void error(final Throwable th) {
        try {
            /* the context could not be initialized, for example, if there was an error in the unmarshalling phase */
            if (WebServiceContext.isInitialized()) {
                final String remoteAddr = WebServiceContext.getRequest().getRemoteAddr();
                final String methodName = WebServiceHelper
                        .getWebServiceOperationName(WebServiceContext.getSoapMessage());
                final Map<String, Object> params = WebServiceHelper
                        .getParameters(WebServiceContext.getSoapMessage());

                if (WebServiceContext.isPosContext()) {
                    loggingHandler.traceWebServiceError(remoteAddr, WebServiceContext.getPos(), methodName, params,
                            th);
                } else {
                    loggingHandler.traceWebServiceError(remoteAddr, WebServiceContext.getClient(), methodName,
                            params, th);
                }
            } else {
                loggingHandler.traceWebServiceError(th);
            }
        } finally {
            // in case of a Fault we are interested in the cause to be set as the error in the TxData
            if (th instanceof Fault && th.getCause() != null) {
                CurrentTransactionData.setError(th.getCause());
            } else {
                CurrentTransactionData.setError(th);
            }
        }
    }

    public void setLoggingHandler(final LoggingHandler loggingHandler) {
        this.loggingHandler = loggingHandler;
    }

    public void trace(final String message) {
        if (WebServiceContext.isPosContext()) {
            loggingHandler.traceWebService(WebServiceContext.getRequest().getRemoteAddr(),
                    WebServiceContext.getPos(), getWebServiceOperationName(WebServiceContext.getSoapMessage()),
                    message);
        } else {
            loggingHandler.traceWebService(WebServiceContext.getRequest().getRemoteAddr(),
                    WebServiceContext.getClient(), getWebServiceOperationName(WebServiceContext.getSoapMessage()),
                    message);
        }
    }
}