package net.conselldemallorca.helium.integracio.plugins.portasignatures; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.activation.DataHandler; import javax.activation.DataSource; import net.conselldemallorca.helium.core.util.GlobalProperties; import net.conselldemallorca.helium.core.util.OpenOfficeUtils; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Annex; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Application; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.CWSSoapBindingStub; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.CwsProxy; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DeleteRequest; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DeleteRequestDocument; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DeleteResponse; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DocumentAttributes; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DownloadRequest; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DownloadRequestDocument; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.DownloadResponse; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.ImportanceEnum; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Sender; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.SignModeEnum; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Signer; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Step; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.Steps; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.UploadRequest; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.UploadRequestDocument; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.UploadResponse; import net.conselldemallorca.helium.integracio.plugins.portasignatures.wsdl.UploadStep; import org.apache.axis.attachments.AttachmentPart; /** * Implementació del plugin de portasignatures per la CAIB. * * @author Limit Tecnologies <limit@limit.es> */ public class PortasignaturesPluginCaib implements PortasignaturesPlugin { private OpenOfficeUtils openOfficeUtils; /** * Puja un document al Portasignatures. * * @param persona * @param documentDto * @param expedient * @param importancia * @param dataLimit * * @return Id del document al Portasignatures * * @throws Exception */ public Integer uploadDocument ( DocumentPortasignatures document, List<DocumentPortasignatures> annexos, boolean isSignarAnnexos, PasSignatura[] passesSignatura, String remitent, String importancia, Date dataLimit) throws PortasignaturesPluginException { CwsProxy factory = new CwsProxy(); factory.setEndpoint((String)GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.url")); CWSSoapBindingStub stub = (CWSSoapBindingStub)factory.getCws(); try { // Afegeix el document a signar (sempre és el primer document que s'adjunta) afegirAttachmentSoap( stub, document.getArxiuNom(), document.getArxiuContingut()); // Afegeix els annexos if (annexos != null) { for (DocumentPortasignatures annex: annexos) { afegirAttachmentSoap( stub, annex.getArxiuNom(), annex.getArxiuContingut()); } } UploadRequest request = new UploadRequest( getRequestApplication(), getRequestDocument( document, annexos, isSignarAnnexos, passesSignatura, remitent, importancia, dataLimit), null); UploadResponse response = stub.uploadDocument(request); if (response.getResult().getCode() == 0) { if (response.getDocument() != null) { return response.getDocument().getId(); } else { throw new PortasignaturesPluginException("Error al enviar el document al portasignatures: la resposta no ha retornat cap document"); } } else { throw new PortasignaturesPluginException("Error al enviar el document al portasignatures: " + response.getResult().getMessage()); } } catch (Exception ex) { throw new PortasignaturesPluginException("Error al enviar el document al portasignatures", ex); } } /** * elimina un document del Portasignatures. * * @param documents * * @throws Exception */ public void deleteDocuments ( List<Integer> documents) throws PortasignaturesPluginException { CwsProxy factory = new CwsProxy(); factory.setEndpoint((String)GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.url")); CWSSoapBindingStub stub = (CWSSoapBindingStub)factory.getCws(); try { DeleteRequest request = new DeleteRequest( getRequestApplication(), getDeleteRequestDocuments(documents), null, null); DeleteResponse response = stub.deleteDocuments(request); if (response.getResult().getCode() != 0) { throw new PortasignaturesPluginException("Error al eliminar el document del portasignatures: la resposta ha retornat l'error " + response.getResult().getMessage()); } } catch (Exception ex) { throw new PortasignaturesPluginException("Error al eliminar el document al portasignatures", ex); } } /** * Descarrega un document del Portasignatures * * @param documentId * * @return document * * @throws Exception */ @SuppressWarnings("rawtypes") public List<byte[]> obtenirSignaturesDocument( Integer documentId) throws PortasignaturesPluginException { DownloadRequest request = new DownloadRequest(); DownloadRequestDocument requestDocument = new DownloadRequestDocument(); requestDocument.setId(documentId); // Aplicació. Application application = new Application(); application.setUser(getUserName()); application.setPassword(getPassword()); request.setApplication(application); request.setDocument(requestDocument); request.setDownloadDocuments(Boolean.TRUE); request.setAdditionalInfo(Boolean.TRUE); request.setArchiveInfo(Boolean.TRUE); // Cream la connexió. CwsProxy factory = new CwsProxy(); factory.setEndpoint((String)GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.url")); CWSSoapBindingStub stub = (CWSSoapBindingStub)factory.getCws(); try { // Llançam la petició i obtenim la resposta. DownloadResponse response = stub.downloadDocument(request); if (response.getResult().getCode() == 0) { List<byte[]> resposta = new ArrayList<byte[]>(); Iterator attachs = stub._getCall().getMessageContext().getCurrentMessage().getAttachments(); if (attachs.hasNext()) { AttachmentPart attach = (AttachmentPart)attachs.next(); DataHandler dataHandler = attach.getActivationDataHandler(); if (dataHandler != null) { //attach.detachAttachmentFile(); byte[] bytes = new byte[dataHandler.getInputStream().available()]; dataHandler.getInputStream().read(bytes); if (bytes.length == 0) { throw new PortasignaturesPluginException("El contingut de la signatura es buit"); } resposta.add(bytes); } else { throw new PortasignaturesPluginException("El contingut de la signatura es null"); } attach.dispose(); } else { throw new PortasignaturesPluginException("La resposta no ha retornat cap signatura"); } return resposta; } else { throw new PortasignaturesPluginException("Error obtenint les signatures del portasignatures: " + response.getResult().getMessage()); } } catch (IOException ex) { throw new PortasignaturesPluginException("Error obtenint les signatures del portasignatures", ex); } } private boolean isCheckCert() { return "true".equals(GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.checkcerts")); } private String getUserName() { return GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.usuari"); } private String getPassword() { return GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.password"); } private Integer getSignaturaTipus() { String tipus = GlobalProperties.getInstance().getProperty("app.portasignatures.plugin.signatura.tipus"); if (tipus != null) return new Integer(tipus); else return new Integer(1); } private void afegirAttachmentSoap( CWSSoapBindingStub stub, String arxiuNom, byte[] arxiuContingut) throws Exception { DataSource ds = new ByteArrayDataSource( arxiuContingut, arxiuNom, getOpenOfficeUtils().getArxiuMimeType(arxiuNom)); DataHandler attachmentFile = new DataHandler(ds); stub.addAttachment(attachmentFile); } private Application getRequestApplication() { Application application = new Application(); application.setUser(getUserName()); application.setPassword(getPassword()); return application; } private DeleteRequestDocument[] getDeleteRequestDocuments( List<Integer> documents) { DeleteRequestDocument[] documentsRequest = new DeleteRequestDocument[documents.size()]; int i = 0; for (Integer document: documents) { DeleteRequestDocument documentRequest = new DeleteRequestDocument(document); documentsRequest[i++] = documentRequest; } return documentsRequest; } private UploadRequestDocument getRequestDocument( DocumentPortasignatures document, List<DocumentPortasignatures> annexos, boolean isSignarAnnexos, PasSignatura[] passesSignatura, String remitent, String importancia, Date dataLimit) { // Document. UploadRequestDocument documentRequest = new UploadRequestDocument(); DocumentAttributes attributes = new DocumentAttributes(); // Atributs obligatoris attributes.setTitle(limitarString(document.getTitol(), 100)); attributes.setExtension(getDocumentArxiuExtensio(document.getArxiuNom())); // Atributs opcionals attributes.setDescription(limitarString(document.getTitol(), 250)); //attributes.setSubject(arxiuDescripcio); if (document.getTipus() != null) attributes.setType(document.getTipus()); // Informació adicional del responsable del document Sender sender = new Sender(); sender.setName(limitarString(remitent, 50)); attributes.setSender(sender); // Importancia del document if (importancia != null) attributes.setImportance(ImportanceEnum.fromString(importancia)); else attributes.setImportance(ImportanceEnum.normal); if (dataLimit != null) { Calendar cal = Calendar.getInstance(); // Data d'enviament del document attributes.setDateNotice(cal); // Data límit per signar el document cal.setTime(dataLimit); attributes.setDateLimit(cal); } // 1 - PDF; 2 - P7/CMS/CADES; 3 - XADES; attributes.setTypeSign(getSignaturaTipus()); // Indica si el document ja està signat i es volen afegir més signatures. attributes.setIsFileSign(document.isSignat()); // Afegim els atributs al document. documentRequest.setAttributes(attributes); // Afegim els annexos if (annexos != null) { List<Annex> anxs = new ArrayList<Annex>(); for (DocumentPortasignatures annex: annexos) { Annex anx = new Annex(); anx.setDescription(limitarString(annex.getTitol(), 250)); anx.setExtension(getDocumentArxiuExtensio(annex.getArxiuNom())); anx.setReference(annex.getReference()); anxs.add(anx); Sender anxSender = new Sender(); anxSender.setName(remitent); anx.setSender(anxSender); } documentRequest.setAnnexes( anxs.toArray(new Annex[anxs.size()])); attributes.setNumberAnnexes(anxs.size()); } else { attributes.setNumberAnnexes(0); } attributes.setSignAnnexes(isSignarAnnexos); // Cream les etapes i especificam el tipus de firma. Steps steps = new Steps(); steps.setSignMode(SignModeEnum.attached); List<Step> stepList = new ArrayList<Step>(); for (PasSignatura pas: passesSignatura) { // Cream una etapa amb un firmant. UploadStep step = new UploadStep(); step.setMinimalSigners(pas.getMinSignataris()); List<Signer> signerList = new ArrayList<Signer>(); for (String signatari: pas.getSignataris()) { // És necessari que el DNI del certificat coincideixi amb el DNI de l'usuari logat a Portafirmas. Signer signer = new Signer(); signer.setId(signatari); signer.setCheckCert(new Boolean(isCheckCert())); signerList.add(signer); } step.setSigners( signerList.toArray( new Signer[pas.getSignataris().length])); stepList.add(step); } steps.setStep( stepList.toArray( new Step[passesSignatura.length])); // Afegim les etapes al document. documentRequest.setSteps(steps); return documentRequest; } private String getDocumentArxiuExtensio(String arxiuNom) { int index = arxiuNom.lastIndexOf("."); if (index != -1) { return arxiuNom.substring(index + 1); } else { return ""; } } private OpenOfficeUtils getOpenOfficeUtils() { if (openOfficeUtils == null) { openOfficeUtils = new OpenOfficeUtils(); } return openOfficeUtils; } private class ByteArrayDataSource implements DataSource { private byte[] dades; private String name; private String contentType; public ByteArrayDataSource(byte[] dades, String name, String contentType) { this.dades = dades; this.name = name; this.contentType = contentType; } public OutputStream getOutputStream() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(dades); return baos; } public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(dades); } public String getName() { return name; } public String getContentType() { return contentType; } } private String limitarString(String str, int maxChars) { String textFinal = "[...]"; if (str.length() > maxChars) { return str.substring(0, maxChars - textFinal.length()) + textFinal; } else { return str; } } }