/** * */ package at.gv.egiz.pdfas.web.helper; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.framework.SignatorFactory; import at.gv.egiz.pdfas.framework.signator.Signator; import at.gv.egiz.pdfas.impl.output.ByteArrayDataSink; import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; import at.gv.egiz.pdfas.web.SignSessionInformation; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.framework.SignResult; import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; import at.knowcenter.wag.egov.egiz.web.PDFContainer; import at.knowcenter.wag.egov.egiz.web.servlets.ProvidePDFServlet; /** * @author wprinz * */ public class SignServletHelper { /** * The log. */ private static Log log = LogFactory.getLog(SignServletHelper.class); protected static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); RequestDispatcher disp = context.getRequestDispatcher(resource); disp.forward(request, response); } /** * Prepares the sign. * *
* This prepares the data for both being signed or being previewed. *
* * @param si * The SessionInformation to be prepared. * @throws PresentableException * f.e. */ public static void prepareSign(SignSessionInformation si) throws PresentableException { log.debug("prepareSign:"); //$NON-NLS-1$ PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); Signator signator = SignatorFactory.createSignator(algorithm); // tzefferer: modified // si.iui = signator.prepareSign(si.pdf, si.type, null, // ConnectorFactory.needsSIG_ID(si.connector)); si.si = signator.prepareSign(si.pdfDataSource, si.type, si.pos, ConnectorFactory.needsSIG_ID(si.connector)); // end modify log.debug("prepareSign finished."); //$NON-NLS-1$ } /** * Finishes the sign. * ** For non local connectors this concludes the sign process, signs the * document and returns the result. For local connectors this initializes the * local sign process and redirects to following servlets. *
* * @param si * The SessionInformation. * @param request * The servlet request for dispatching. * @param response * The servlet response for dispatching. * @param context * The servlet context for dispatching. * @throws PresentableException * f.e. * @throws IOException * f. e. * @throws ServletException * f. e. */ public static void finishSign(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws PresentableException, IOException, ServletException { log.debug("finishSign:"); //$NON-NLS-1$ log.debug("connector = " + si.connector); //$NON-NLS-1$ if (ConnectorFactory.isConnectorLocal(si.connector)) { log.debug("Connector is local -> dispatching to local processing."); //$NON-NLS-1$ String dispatch_to = LocalRequestHelper.processLocalSign(si, request, response); dispatch(request, response, dispatch_to, context); return; } log.debug("Connector is not local -> finishing the sign."); //$NON-NLS-1$ PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); Signator signator = SignatorFactory.createSignator(algorithm); log.debug("RequestURL = " + request.getRequestURL()); log.debug("ContextPath = " + request.getContextPath()); String host = request.getServerName(); // TODO TR: Web-Applikation verwendet in Loc-Ref-Variante ext. Referenz, um performanter zu sein; // nachfolend auskommentieren, wenn anstatt SwA-Connector LocRef-Connector verwendet wird URL signature_data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String signature_data_url = response.encodeURL(signature_data_URL.toString()); Connector c = ConnectorChooser.chooseWebConnectorForSign(si.connector, si.type, signature_data_url); SignSignatureObject signSignatureObject = c.doSign(si.si.getSignatureData()); si.si.setSignSignatureObject(signSignatureObject); si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); signator.finishSign(si.si, si.output); returnSignResponse(si, response); log.debug("finishSign finished."); //$NON-NLS-1$ } /** * Returns the data in the SignResult with proper content disposition. * * @param si * SessionInformation. * @param response * The servlet response. * @throws IOException * The IO Exception. */ public static void returnSignResponse(SignSessionInformation si, HttpServletResponse response) throws IOException { // SignResult sign_result = si.sign_result; String file_name = formatFileNameForSignResult(si.filename, si.output.getMimeType()); // tzefferer: added condition if (si.exappinf == null) { // The name parameter is actually deprecated in favour of // Content-Disposition filename // Unfortunately Acrobat reader does recognize neither of these parameters // with its inline save-as. It always takes the page name. response.setContentType(si.output.getMimeType() + "; name=\"" + file_name + "\""); if (si.download_inline) { response.addHeader("Content-Disposition", "inline; filename=\"" + file_name + "\""); } else { response.addHeader("Content-Disposition", "attachment; filename=\"" + file_name + "\""); } TempDirHelper.writeDataSinkToHttpResponse(si.output, response); //response.getOutputStream().write(sign_result.getData()); // tzefferer: added else-block } else { // TODO @tzefferer: what is this code? byte [] signed_pdf = null; if (si.output instanceof FileBasedDataSink) { FileBasedDataSink fbds = (FileBasedDataSink)si.output; signed_pdf = new byte [(int)fbds.getFile().length()]; FileInputStream fis = new FileInputStream(fbds.getFile()); fis.read(signed_pdf); fis.close(); } else { ByteArrayDataSink bads = (ByteArrayDataSink)si.output; signed_pdf = bads.getByteArray(); } PDFContainer entry = new PDFContainer(signed_pdf, si.exappinf.pdf_id); ProvidePDFServlet.signedDocuments.add(entry); // notify webapp... String invoke_url = si.exappinf.invoke_url; String providePDFServlet = "ProvidePDF"; String pdf_id = String.valueOf(si.exappinf.pdf_id); String session_id = si.exappinf.session_id; log.debug("External application has to be notified. Building url from callback url \"" + invoke_url + "\"."); // build URL int ind = invoke_url.indexOf("?"); // fixed by tknall: must not presume that invoke_url contains "?" String sep = "&"; if (ind == -1) { ind = invoke_url.length(); sep = "?"; } String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind) + sep + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length; log.debug("Notifying external application by redirecting to \"" + query + "\"."); response.sendRedirect(query); } } /** * Formats the file name according to the SignResult. * * @param file_name * The file name. * @param sign_result * The sign result. * @return Returns the formatted file name. */ public static String formatFileNameForSignResult(String file_name, String mimeType) { String output = file_name + "_signed"; if (mimeType.equals(DetachedSignator_1_0_0.MIME_TYPE)) { output += ".xml"; } else { output += ".pdf"; } return output; } }