org.libreplan.importers.TimSoapClient.java Source code

Java tutorial

Introduction

Here is the source code for org.libreplan.importers.TimSoapClient.java

Source

/*
 * This file is part of LibrePlan
 *
 * Copyright (C) 2013 St. Antoniusziekenhuis
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.libreplan.importers;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.common.util.Base64Utility;
import org.libreplan.importers.tim.RosterResponseDTO;

/**
 * Client to interact with Tim SOAP server.
 *
 * This client creates SOAP message, makes connection to the SOAP server and sends the request.
 * It is also the task of this client to convert the response(xml document) to java objects.
 *
 * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
 */
public class TimSoapClient {

    private static final Log LOG = LogFactory.getLog(TimSoapClient.class);

    /**
     * Creates request message to be send to the SOAP server
     *
     * @param clazz
     *            object to be marshaled
     * @param userName
     *            the user name
     * @param password
     *            the password
     * @return the created soap message
     * @throws SOAPException
     *             if unable to create message or envelope
     * @throws JAXBException
     *             if unable to marshal the clazz
     */
    private static <T> SOAPMessage createRequest(T clazz, String userName, String password)
            throws SOAPException, JAXBException {

        SOAPMessage message = createMessage();

        addAuthorization(message, userName, password);

        SOAPEnvelope soapEnvelope = createEnvelope(message.getSOAPPart());

        SOAPBody soapBody = soapEnvelope.getBody();
        marshal(clazz, soapBody);

        message.saveChanges();

        return message;
    }

    /**
     * Creates SOAP message to be send to the SOAP server
     *
     * @return the created SOAP message
     * @throws SOAPException
     *             if unable to create soap message
     */
    private static SOAPMessage createMessage() throws SOAPException {
        MessageFactory messageFactory = MessageFactory.newInstance();

        return messageFactory.createMessage();
    }

    /**
     * Adds authorization to the specified parameter <code>message</code>
     *
     * @param message
     *            the message
     * @param username
     *            the user name
     * @param password
     *            the password
     */
    private static void addAuthorization(SOAPMessage message, String username, String password) {
        String encodeUserInfo = username + ":" + password;
        encodeUserInfo = Base64Utility.encode(encodeUserInfo.getBytes());
        message.getMimeHeaders().setHeader("Authorization", "Basic " + encodeUserInfo);
    }

    /**
     * Creates SOAP envelope and adds namespace declaration and sets encoding
     * style
     *
     * @param soapPart
     *            the message part
     * @return the SOAP envelope
     * @throws SOAPException
     */
    private static SOAPEnvelope createEnvelope(SOAPPart soapPart) throws SOAPException {
        SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
        addNamespaceDeclaration(soapEnvelope);
        setEncodingStyle(soapEnvelope);

        return soapEnvelope;
    }

    /**
     * Adds namespace declaration to the specified parameter
     * <code>soapEnvelop</code>
     *
     * @param soapEnvelope
     *            the SOAP envelope
     * @throws SOAPException
     */
    private static void addNamespaceDeclaration(SOAPEnvelope soapEnvelope) throws SOAPException {
        soapEnvelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
        soapEnvelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        soapEnvelope.addNamespaceDeclaration("enc", "http://schemas.xmlsoap.org/soap/encoding/");
        soapEnvelope.addNamespaceDeclaration("env", "http://schemas.xmlsoap.org/soap/envelop/");

    }

    /**
     * Sets the encoding style to the specified parameter
     * <code>soapEnvelop</code>
     *
     * @param soapEnvelope
     *            the SOAP envelope
     * @throws SOAPException
     */
    private static void setEncodingStyle(SOAPEnvelope soapEnvelope) throws SOAPException {
        soapEnvelope.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");
    }

    /**
     * Marshals the specified parameter <code>clazz</code> to the specified
     * <code>soapBody</code>
     *
     * @param clazz
     *            the object to be marshaled
     * @param soapBody
     *            the SOAP body, result of marshal
     * @throws JAXBException
     *             if marshaling failed
     */
    private static <T> void marshal(T clazz, SOAPBody soapBody) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(clazz.getClass());
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.marshal(clazz, soapBody);
    }

    /**
     * Unmarshals the specified paramter <code>soapBody</code> to the specified
     * <code>clazz</code>
     *
     * @param clazz
     *            object to hold unmarashal result
     * @param soapBody
     *            the soap body to be unmarshalled
     * @return the unmarashalled object
     * @throws JAXBException
     *             if unmarshal failed
     */
    @SuppressWarnings("unchecked")
    private static <T> T unmarshal(Class<T> clazz, SOAPBody soapBody) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(clazz);

        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        Node bindElement = (Node) soapBody.getFirstChild();

        while (bindElement.getNodeType() != Node.ELEMENT_NODE) {
            bindElement = (Node) bindElement.getNextSibling();
        }

        return unmarshaller.unmarshal(bindElement, clazz).getValue();
    }

    /**
     * Sends the SOAP message request to the SOAP server
     *
     * @param url
     *            the endpoint of the web service
     * @param message
     *            the SOAP message to be send
     * @return the response, SOAP message
     * @throws SOAPException
     *             if unable to send request
     */
    private static SOAPMessage sendRequest(String url, SOAPMessage message) throws SOAPException {
        SOAPConnection connection = null;
        SOAPMessage response = null;
        try {
            connection = createConnection();
            response = connection.call(message, url);
        } finally {
            if (connection != null) {
                closeConnection(connection);
            }
        }
        return response;
    }

    /**
     * Creates a SOAP connection to the SOAP server
     *
     * @return the SOAPconnection object
     * @throws SOAPException
     *             if unable to create connection
     */
    private static SOAPConnection createConnection() throws SOAPException {
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();

        return soapConnectionFactory.createConnection();
    }

    /**
     * Closes the SOAP connection
     *
     * @param connection
     *            the SOAP connection
     * @throws SOAPException
     *             if unable to close connection
     */
    private static void closeConnection(SOAPConnection connection) throws SOAPException {
        connection.close();
    }

    /**
     * Sends soap request to the SOAP server. Receives and unmarshals the
     * response
     *
     * @param url
     *            the SOAP server url(endpoint)
     * @param userName
     *            the user
     * @param password
     *            the password
     * @param request
     *            the request object
     * @param response
     *            the response class
     * @return the expected object or null
     */
    public static <T, U> T sendRequestReceiveResponse(String url, String userName, String password, U request,
            Class<T> response) {

        try {
            SOAPMessage requestMsg = createRequest(request, userName, password);
            SOAPMessage responseMsg = sendRequest(url, requestMsg);

            return unmarshal(response, responseMsg.getSOAPBody());
        } catch (SOAPException soapExp) {
            LOG.error("SOAPException: ", soapExp);
        } catch (JAXBException jaxbExp) {
            LOG.error("JAXBException: ", jaxbExp);
        }

        return null;
    }

    /**
     * Checks authorization for the specified <code>username</code> and
     * <code>password</code>
     *
     * @param url
     *            webservices url
     * @param username
     *            the user
     * @param password
     *            the password
     * @return true if user is authorized otherwise false
     */
    public static boolean checkAuthorization(String url, String username, String password) {
        try {
            SOAPMessage message = createMessage();
            addAuthorization(message, username, password);
            sendRequest(url, message);

            return true;
        } catch (SOAPException e) {
            LOG.error("SOAP Exception: ", e);
        }
        return false;
    }

    /**
     * simulates roster response, to be used for example by unit test
     *
     * unmarshals the roster xml from the specified <code>file</code> and
     * returns {@link RosterResponseDTO}
     *
     * @param file
     *            file with xml contents
     * @return exportRosterDTO if unmarshal succeeded otherwise null
     */
    public static RosterResponseDTO unmarshalRosterFromFile(File file) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(RosterResponseDTO.class);

            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            return (RosterResponseDTO) unmarshaller.unmarshal(file);
        } catch (JAXBException e) {
            LOG.error("Error processing response: ", e);
        }
        return null;
    }
}