
import java.util.Hashtable;

import oasis.names.tc.dss._1_0.core.wsdl.SOAPport;
import oasis.names.tc.dss._1_0.core.wsdl.digitalSignatureServiceClient;

import org.apache.xmlbeans.XmlAnyURI;
import org.apache.xmlbeans.XmlBase64Binary;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3.x2000.x09.xmldsig.KeyInfoType;
import org.w3.x2000.x09.xmldsig.X509DataType;

import x0CoreSchema.oasisNamesTcDss1.DocumentType;
import x0CoreSchema.oasisNamesTcDss1.InlineXMLType;
import x0CoreSchema.oasisNamesTcDss1.SignRequestDocument;
import x0CoreSchema.oasisNamesTcDss1.SignResponseDocument;
import x0CoreSchema.oasisNamesTcDss1.InputDocumentsDocument.InputDocuments;
import x0CoreSchema.oasisNamesTcDss1.KeySelectorDocument.KeySelector;
import x0CoreSchema.oasisNamesTcDss1.OptionalInputsDocument.OptionalInputs;
import x0CoreSchema.oasisNamesTcDss1.SignRequestDocument.SignRequest;


public class CreacioSignaturaXAdES_EPES {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {


		// Dades de prova
		// Certificat amb que es generarà la signatura o timestamp
		byte[] certificate = Utils.readBase64File("proves\\certificats\\certificate.dat");

		// XML a signar
		String xml = Utils.readXmlFile("proves\\data\\create-sig.xml");

		// Tipus de signatura disponibles
		// Signatura CAdES: 					http://uri.etsi.org/01733/v1.6.3#
		// Signatura CMS: 						urn:ietf:rfc:3852
		// Signatura XMLDsig: 					urn:ietf:rfc:3275
		// Signatura XAdES: 					http://uri.etsi.org/01903/v1.2.2#
		String type = "http://uri.etsi.org/01903/v1.2.2#";

		// Inicialització del client
		digitalSignatureServiceClient proxy = new digitalSignatureServiceClient();
		SOAPport port = proxy.getdssPortSoap("http://psis.catcert.net/psis/catcert/dss");

		// Composició del missatge

		// Definició dels namespaces correctes
		Hashtable prefixes = new Hashtable();
		prefixes.put("urn:oasis:names:tc:dss:1.0:core:schema","dss");
		prefixes.put("http://www.w3.org/2000/09/xmldsig#","ds");

		XmlOptions options= new XmlOptions();	
		options.setSaveSuggestedPrefixes(prefixes);

		// Creació del missatge DSS
		SignRequestDocument requestDocument = SignRequestDocument.Factory.newInstance(options);

		SignRequest request = requestDocument.addNewSignRequest();
		request.setProfile("urn:oasis:names:tc:dss:1.0:profiles:XSS");

		// Creació de l'element amb el document a signar (en format XML)
		DocumentType document = DocumentType.Factory.newInstance();

		InlineXMLType inline = document.addNewInlineXML();
		inline.set(XmlObject.Factory.parse(xml));

		InputDocuments inpDocuments = InputDocuments.Factory.newInstance();
		inpDocuments.setDocumentArray(new DocumentType[] { document });

		request.setInputDocuments(inpDocuments);

		// Creació de l'element amb els paràmetres opcionals necessaris
		OptionalInputs optional = request.addNewOptionalInputs();
		

		// Certificat del signatari
		KeySelector selector = optional.addNewKeySelector();
		KeyInfoType key = selector.addNewKeyInfo();
		X509DataType x509data = key.addNewX509Data();

		XmlBase64Binary b64certificate = x509data.addNewX509Certificate();
		b64certificate.setByteArrayValue(certificate);

		XmlAnyURI any = optional.addNewSignatureType();
		any.setStringValue(type);

		// Visualització de la petició
		System.out.println(requestDocument.xmlText(options));

		// Execució del servei
		SignResponseDocument responseDocument = port.sign(requestDocument);

		// visualització de la resposta
		System.out.println(responseDocument.xmlText(options));
	}
}