package at.gv.util.client.mis.simple; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.codec.binary.Base64; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.xpath.XPathAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import at.gv.util.DOMUtils; public class MISSimpleClient { private final static String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/"; private final static String MIS_NS = "http://reference.e-government.gv.at/namespace/mandates/mis/1.0/xsd"; private static Element NS_NODE = null; private static Logger log = LoggerFactory.getLogger(MISSimpleClient.class); static { try { NS_NODE = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().createElement("test"); NS_NODE.setAttribute("xmlns:soap", SOAP_NS); NS_NODE.setAttribute("xmlns:mis", MIS_NS); } catch (Exception e) { log.warn("Error initializing namespace node.", e); } } public static List sendGetMandatesRequest(String webServiceURL, String sessionId) throws MISSimpleClientException { if (webServiceURL == null) { throw new NullPointerException("Argument webServiceURL must not be null."); } if (sessionId == null) { throw new NullPointerException("Argument sessionId must not be null."); } try { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); Element sessionIdElement = doc.createElementNS(MIS_NS, "SessionID"); sessionIdElement.appendChild(doc.createTextNode(sessionId)); mirElement.appendChild(sessionIdElement); // send soap request Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); // check for error checkForError(mandateIssueResponseElement); // check for session id NodeList mandateElements = XPathAPI.selectNodeList(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Mandates/mis:Mandate", NS_NODE); if (mandateElements == null || mandateElements.getLength() == 0) { throw new MISSimpleClientException("No mandates found in response."); } ArrayList foundMandates = new ArrayList(); for (int i=0; i<mandateElements.getLength(); i++) { Element mandate = (Element) mandateElements.item(i); MISMandate misMandate = new MISMandate(); if ("true".equalsIgnoreCase(mandate.getAttribute("ProfessionalRepresentative"))) { misMandate.setProfRep(true); } misMandate.setMandate(Base64.decodeBase64(DOMUtils.getText(mandate))); foundMandates.add(misMandate); } return foundMandates; } catch (ParserConfigurationException e) { throw new MISSimpleClientException(e); } catch (DOMException e) { throw new MISSimpleClientException(e); } catch (TransformerException e) { throw new MISSimpleClientException(e); } } public static MISSessionId sendSessionIdRequest(String webServiceURL, byte[] idl, byte[] cert, String redirectURL, String refValue, String mandateIdentifier[]) throws MISSimpleClientException { if (webServiceURL == null) { throw new NullPointerException("Argument webServiceURL must not be null."); } if (idl == null) { throw new NullPointerException("Argument idl must not be null."); } if (redirectURL == null) { throw new NullPointerException("Argument redirectURL must not be null."); } if (refValue == null) { throw new NullPointerException("Argument refValue must not be null."); } try { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); Element idlElement = doc.createElementNS(MIS_NS, "IdentityLink"); idlElement.appendChild(doc.createTextNode(Base64.encodeBase64String(idl))); mirElement.appendChild(idlElement); if (cert != null && cert.length > 0) { Element certElement = doc.createElementNS(MIS_NS, "X509SignatureCertificate"); certElement.appendChild(doc.createTextNode(Base64.encodeBase64String(cert))); mirElement.appendChild(certElement); } Element redirectElement = doc.createElementNS(MIS_NS, "RedirectURL"); redirectElement.appendChild(doc.createTextNode(redirectURL)); mirElement.appendChild(redirectElement); Element refValElement = doc.createElementNS(MIS_NS, "ReferenceValue"); refValElement.appendChild(doc.createTextNode(refValue)); mirElement.appendChild(refValElement); if (mandateIdentifier != null && mandateIdentifier.length > 0) { Element filtersElement = doc.createElementNS(MIS_NS, "Filters"); Element mandateIdentifiersElement = doc.createElementNS(MIS_NS, "MandateIdentifiers"); for (int i=0; i<mandateIdentifier.length; i++) { Element mandateIdentifierElement = doc.createElementNS(MIS_NS, "MandateIdentifier"); mandateIdentifierElement.appendChild(doc.createTextNode(mandateIdentifier[i])); mandateIdentifiersElement.appendChild(mandateIdentifierElement); } filtersElement.appendChild(mandateIdentifiersElement); mirElement.appendChild(filtersElement); } // send soap request Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); // check for error checkForError(mandateIssueResponseElement); // check for session id Node sessionIdNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:SessionID/text()", NS_NODE)); if (sessionIdNode == null) { throw new MISSimpleClientException("SessionId not found in response."); } String sessionId = sessionIdNode.getNodeValue(); Node guiRedirectURLNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:GuiRedirectURL/text()", NS_NODE)); if (guiRedirectURLNode == null) { throw new MISSimpleClientException("GuiRedirectURL not found in response."); } String guiRedirectURL = guiRedirectURLNode.getNodeValue(); // create return object MISSessionId msid = new MISSessionId(); msid.setSessiondId(sessionId); msid.setRedirectURL(guiRedirectURL); return msid; } catch (ParserConfigurationException e) { throw new MISSimpleClientException(e); } catch (DOMException e) { throw new MISSimpleClientException(e); } catch (TransformerException e) { throw new MISSimpleClientException(e); } } private static void checkForError(Element mandateIssueResponseElement) throws MISSimpleClientException { if (mandateIssueResponseElement == null) { throw new NullPointerException("Argument mandateIssueResponseElement must not be null."); } try { Element errorElement = (Element) XPathAPI.selectSingleNode(mandateIssueResponseElement, "/mis:MandateIssueResponse/mis:Error", NS_NODE); if (errorElement != null) { String code = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "/mis:MandateIssueResponse/mis:Error/mis:Code/text()", NS_NODE)).getNodeValue(); String text = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "/mis:MandateIssueResponse/mis:Error/mis:Text/text()", NS_NODE)).getNodeValue(); throw new MISSimpleClientException("Fehler beim Abfragen des Online-Vollmachten Services: " + code + " / " + text); } } catch (TransformerException e) { throw new MISSimpleClientException(e); } } private static Element sendSOAPRequest(String webServiceURL, Element request) throws MISSimpleClientException { if (webServiceURL == null) { throw new NullPointerException("Argument webServiceURL must not be null."); } if (request == null) { throw new NullPointerException("Argument request must not be null."); } try { HttpClient httpclient = HttpClients.createDefault(); HttpPost post = new HttpPost(webServiceURL); StringEntity re = new StringEntity(DOMUtils.serializeNode(packIntoSOAP(request)),"text/xml"); post.setEntity(re); HttpResponse response = httpclient.execute(post); if (response.getStatusLine().getStatusCode() != 200) { throw new MISSimpleClientException("Invalid HTTP response code " + response.getStatusLine().getStatusCode()); } return unpackFromSOAP(DOMUtils.parseXmlNonValidating(post.getEntity().getContent())); } catch(IOException e) { throw new MISSimpleClientException(e); } catch (TransformerException e) { throw new MISSimpleClientException(e); } catch (ParserConfigurationException e) { throw new MISSimpleClientException(e); } catch (SAXException e) { throw new MISSimpleClientException(e); } } private static Element packIntoSOAP(Element element) throws MISSimpleClientException { try { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element soapEnvelope = doc.createElement("Envelope"); soapEnvelope.setAttribute("xmlns", SOAP_NS); Element soapBody = doc.createElement("Body"); soapEnvelope.appendChild(soapBody); soapBody.appendChild(doc.importNode(element, true)); return soapEnvelope; } catch(ParserConfigurationException e) { throw new MISSimpleClientException(e); } } private static Element unpackFromSOAP(Element element) throws MISSimpleClientException { try { return (Element) XPathAPI.selectSingleNode(element, "/soap:Envelope/soap:Body/child::*[position()=1]", NS_NODE); } catch(TransformerException e) { throw new MISSimpleClientException(e); } } }