/**
*
*/
package at.knowcenter.wag.egov.egiz.sig.connectors.moa;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.PartSource;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import at.knowcenter.wag.egov.egiz.exceptions.WebException;
import at.knowcenter.wag.egov.egiz.sig.SignatureData;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* @author wprinz
*
*/
public final class MOASoapConnection
{
/**
* MOA siganture verification mode
*/
public static final String SERVICE_VERIFY = "SignatureVerification"; //$NON-NLS-1$
/**
* MOA siganture creation mode
*/
public static final String SERVICE_SIGN = "SignatureCreation"; //$NON-NLS-1$
/**
* The log.
*/
private static Log log = LogFactory.getLog(MOASoapConnection.class);
/**
* This method connects the moa server getting the requestString, the given
* serviseMode and the endpointUrl. The requestString is the envelope of the
* SOAP Message send and recieve by the AXIS module. The Response SOAP message
* of the MOA server is parsed by AXIS and the message envelope is send back
* to the calling method.
*
* @param requestString
* the request string (XML) to send.
* @param serviceMode
* the mode which connect to MOA
* @param endpointURL
* the URL which the MOA server is running
* @return the response string (XML) of the MOA server
* @throws WebException
*/
public static Properties connectMOA(String requestString, String serviceMode,
String endpointURL) throws WebException
{
try
{
if (log.isInfoEnabled())
{
log.info(serviceMode);
log.info(endpointURL);
}
// Parser/DOMBuilder instanzieren
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
// XML Datei in einen DOM-Baum umwandeln
ByteArrayInputStream bais = new ByteArrayInputStream(requestString.getBytes("UTF-8")); //$NON-NLS-1$
Document xmlRequest = builder.parse(bais);
// Call öffnen
Call call = null;
// Neues BodyElement anlegen und mit dem DOM-Baum füllen
SOAPBodyElement body = new SOAPBodyElement(xmlRequest.getDocumentElement());
SOAPBodyElement[] params = new SOAPBodyElement[] { body };
// AXIS-Server instanzieren
Service service = ServiceFactory.newInstance().createService(new QName(serviceMode));
call = service.createCall();
call.setTargetEndpointAddress(endpointURL);
// Call auslösen und die Antworten speichern
log.debug("Calling MOA: " + endpointURL); //$NON-NLS-1$
Vector responses = (Vector) call.invoke(params);
// Erstes Body Element auslesen
SOAPBodyElement response = (SOAPBodyElement) responses.get(0);
// Aus der Response den DOM-Baum lesen
Document root_response = response.getAsDocument();
log.debug("Return from MOA: " + serviceMode); //$NON-NLS-1$
// XML-Formatierung konfiguieren
OutputFormat format = new OutputFormat((Document) root_response);
format.setLineSeparator("\n"); //$NON-NLS-1$
format.setIndenting(false);
format.setPreserveSpace(true);
format.setOmitXMLDeclaration(false);
format.setEncoding("UTF-8"); //$NON-NLS-1$
// Ausgabe der Webservice-Antwort auf die Konsole
// XMLSerializer conSerializer = new XMLSerializer(System.out, format);
// conSerializer.serialize(root_response);
// Ausgabe der Webservice-Antwort in Datei
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLSerializer response_serializer = new XMLSerializer(baos, format);
response_serializer.serialize(root_response);
String response_string = baos.toString("UTF-8"); //$NON-NLS-1$
Properties response_properties = new Properties();
response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, response_string);
return response_properties;
}
catch (Exception e)
{
throw new WebException(e);
}
// serialize signature only
// if
// (root_response.getDocumentElement().getLocalName().equals("CreateXMLSignatureResponse"))
// {
// Element signature = (Element)
// root_response.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#",
// "Signature").item(0);
// String signatureFile = getProperty(mode + "Request").substring(0,
// getProperty(mode +
// "Request").lastIndexOf('.')) + ".Signature.xml";
// fileSerializer = new XMLSerializer(new FileOutputStream(signatureFile),
// format);
// fileSerializer.serialize(signature);
// }
}
public static Properties doPostRequestMultipart(String url, String serviceMode, String request,
final SignatureData data) throws HttpException, IOException
{
log.debug("doPostRequestMultipart:"); //$NON-NLS-1$
// Wrap XMLRequest into SOAP-Body
request = "" +
request.substring(request.indexOf("?>")+2)+ // do not forget to eliminate any additional XML-header
"";
StringPartMR xmlpart = new StringPartMR("test", request, "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$
xmlpart.setContentType("text/xml");
xmlpart.setContentID("");
// add file to be signed
final String filename = data.getMimeType().equals("application/pdf") ? "myfile.pdf" : "myfile.txt"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
PartSource ps = new PartSource() {
public InputStream createInputStream() throws IOException
{
return data.getDataSource().createInputStream();
}
public String getFileName()
{
return filename;
}
public long getLength()
{
return data.getDataSource().getLength();
}
};
//ByteArrayPartSource baps = new ByteArrayPartSource(filename, data.getData());
FilePartMR filepart = new FilePartMR("fileupload", ps); //$NON-NLS-1$
filepart.setContentType(data.getMimeType());
filepart.setContentID("");
// this is optional
// filepart.setCharSet(data.getCharacterEncoding());
Part[] parts = { xmlpart, filepart };
HttpMethodParams method_params = new HttpMethodParams();
method_params.setContentCharset("UTF-8"); //$NON-NLS-1$
PostMethod post_method = new PostMethod(url);
post_method.setParams(method_params);
post_method.addRequestHeader("SOAPAction",serviceMode);
// MultipartRequestEntity mprqe = new MultipartRequestEntity(parts, post_method.getParams());
MultipartRelatedEntity mprqe = new MultipartRelatedEntity(parts, post_method.getParams());
mprqe.setContentType("text/xml");
mprqe.setStartID("");
post_method.setRequestEntity(mprqe);
// post_method.setRequestHeader("Content-Type", "multipart/related; type=\"text/xml\"; boundary=\""+"\"");
HttpClient http_client = new HttpClient();
int method_response = http_client.executeMethod(post_method);
log.debug("method_response = " + method_response); //$NON-NLS-1$
Properties response_properties = new Properties();
if (log.isDebugEnabled())
{
Header[] response_headers = post_method.getResponseHeaders();
for (int i = 0; i < response_headers.length; i++)
{
log.debug(" response_header[" + i + "]: name = " + response_headers[i].getName() + ", value = " + response_headers[i].getValue()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
Header server_header = post_method.getResponseHeader("Server"); //$NON-NLS-1$
response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, server_header.getValue());
log.debug(post_method.getResponseCharSet());
if (!post_method.getResponseCharSet().equals("UTF-8")) //$NON-NLS-1$
{
log.warn("MOA response charset is not UTF-8!"); //$NON-NLS-1$
}
String response_string = post_method.getResponseBodyAsString();
response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, response_string);
log.debug("doPostRequestMultipart finished."); //$NON-NLS-1$
return response_properties;
}
}