aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/egiz/pdfas/web
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/egiz/pdfas/web')
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java87
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java140
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java195
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java48
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java229
-rw-r--r--src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java242
6 files changed, 941 insertions, 0 deletions
diff --git a/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java b/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java
new file mode 100644
index 0000000..83d214c
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java
@@ -0,0 +1,87 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web;
+
+import java.util.List;
+import java.util.Properties;
+
+import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
+import at.knowcenter.wag.egov.egiz.web.LocalRequest;
+
+/**
+ * Encapsulates a local operation.
+ *
+ * <p>
+ * A local operation is a sequence of successive local verifications.
+ * </p>
+ * <p>
+ * This is held on the VerifySessionInformation so that the DataURLServlet and RetrieveSignatureDataServlet
+ * can provide their data to the local service easily.
+ * </p>
+ *
+ * @author wprinz
+ */
+public class CurrentLocalOperation
+{
+
+ /**
+ * The signature holders to be verified in the current local operation.
+ */
+ public List holders_to_be_verified;
+
+
+ /**
+ * An array of local requests to be processed.
+ */
+ public LocalRequest[] requests = null;
+
+ /**
+ * An array of response strings of the local requests.
+ */
+ public Properties[] response_properties = null;
+
+ /**
+ * The index of the holder/request to be processed.
+ */
+ public int current_operation = 0;
+
+// /**
+// * Tells, if the current local request has been finished.
+// */
+// public boolean finished = false;
+
+ /**
+ * @see at.gv.egiz.pdfas.web.LocalOperation#isFinished()
+ */
+ public boolean isFinished()
+ {
+ return this.current_operation >= this.requests.length;
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentLocalRequest()
+ */
+ public LocalRequest getCurrentLocalRequest()
+ {
+ return this.requests[this.current_operation];
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentSignatureHolder()
+ */
+ public SignatureHolder getCurrentSignatureHolder()
+ {
+ return (SignatureHolder) this.holders_to_be_verified.get(this.current_operation);
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.web.LocalOperation#finishCurrentOperation(java.util.Properties)
+ */
+ public void finishCurrentOperation(Properties response_properties)
+ {
+ this.response_properties[this.current_operation] = response_properties;
+
+ this.current_operation++;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java b/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java
new file mode 100644
index 0000000..459a104
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java
@@ -0,0 +1,140 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl;
+import at.gv.egiz.pdfas.impl.output.FileBasedDataSink;
+import at.gv.egiz.pdfas.web.helper.TempDirHelper;
+import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.web.ExternAppInformation;
+import at.knowcenter.wag.egov.egiz.web.LocalRequest;
+
+/**
+ * @author wprinz
+ *
+ */
+public class SignSessionInformation implements HttpSessionBindingListener, Serializable
+{
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = 2739944460007369626L;
+
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(SignSessionInformation.class);
+
+ /**
+ * The connector.
+ */
+ public String connector = null;
+
+ /**
+ * For local requests, tells the application (sign, verify).
+ */
+ public String application = null;
+
+ /**
+ * Tells the operation mode (binary, textual).
+ */
+ public String mode = null;
+
+ /**
+ * The original, uploaded pdf.
+ */
+ public FileBasedPdfDataSourceImpl pdfDataSource = null;
+
+ /**
+ * The type/profile of the signature.
+ */
+ public String type = null;
+
+ /**
+ * The suggested filename.
+ */
+ public String filename;
+
+ /**
+ * Tells, if the file download should be done inline or as attachment.
+ */
+ public boolean download_inline;
+
+ /**
+ * Object containing information about the calling webapplication.
+ *
+ * @author: Thomas Zefferer
+ */
+ public ExternAppInformation exappinf;
+
+ /**
+ * Information about the signature position
+ *
+ * @author: Thomas Zefferer
+ */
+ public TablePos pos;
+
+ /**
+ * The SignatorInformation.
+ */
+ public SignatorInformation si = null;
+
+ /**
+ * The DataSink to write the output data to.
+ */
+ public FileBasedDataSink output = null;
+
+ /**
+ * The local request to be sent to the device.
+ */
+ public LocalRequest localRequest = null;
+
+ /**
+ * The response properties of the local request.
+ */
+ public Properties response_properties = null;
+
+ /**
+ * Tells if the sign request has been processed and the signed document is
+ * available in the DataSink.
+ */
+ public boolean outputAvailable = false;
+
+
+ /**
+ * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
+ */
+ public void valueBound(HttpSessionBindingEvent event)
+ {
+ log.debug("Bound SignSessionInformation to session.");
+ }
+
+ /**
+ * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
+ */
+ public void valueUnbound(HttpSessionBindingEvent event)
+ {
+ log.debug("Unbound SignSessionInformation from session.");
+
+ if (this.pdfDataSource != null)
+ {
+ TempDirHelper.deleteDataSourceIfFileBased(this.pdfDataSource);
+ }
+ if (this.output != null)
+ {
+ TempDirHelper.deleteDataSinkIfFileBased(this.output);
+ }
+ }
+}
diff --git a/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java b/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java
new file mode 100644
index 0000000..e998ded
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java
@@ -0,0 +1,195 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: SessionInformation.java,v 1.2 2006/08/25 17:06:11 wprinz Exp $
+ */
+package at.gv.egiz.pdfas.web;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.pdfas.framework.input.DataSource;
+import at.gv.egiz.pdfas.web.helper.TempDirHelper;
+import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.web.ExternAppInformation;
+
+/**
+ * This class is a collection of various session parameters that are passed
+ * between the servlets and jsps.
+ *
+ * <p>
+ * The SessionInformation class contains type safe references to the objects.
+ * </p>
+ *
+ * @author wprinz
+ */
+public class VerifySessionInformation implements HttpSessionBindingListener, Serializable
+{
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -7413884936584659150L;
+
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(VerifySessionInformation.class);
+
+ /**
+ * The connector.
+ */
+ public String connector = null;
+
+ /**
+ * For local requests, tells the application (sign, verify).
+ */
+ public String application = null;
+
+ /**
+ * Tells the operation mode (binary, textual).
+ */
+ public String mode = null;
+
+ /**
+ * The original, uploaded pdf.
+ */
+ //public FileBasedPdfDataSourceImpl pdfDataSource = null;
+ public DataSource inputDataSource = null;
+
+ /**
+ * The type/profile of the signature.
+ */
+ public String type = null;
+
+// /**
+// * The user name.
+// */
+// public String user_name = null;
+//
+// /**
+// * The password.
+// */
+// public String user_password = null;
+
+ /**
+ * All SignatureHolders extracted from the document.
+ */
+ public List signature_holders;
+
+ /**
+ * Keeps track of the currently running local operation.
+ *
+ * <p>
+ * Only valid during local verify.
+ * </p>
+ */
+ public CurrentLocalOperation currentLocalOperation = null;
+
+ /**
+ * This is used only for MOA loc-ref web verify.
+ */
+ public SignatureHolder moa_holder;
+
+
+// /**
+// * The incremental update information that has been extracted from the given
+// * PDF document.
+// */
+// public IncrementalUpdateInformation iui;
+
+// public SignatorInformation si = null;
+
+// public FileBasedDataSink output = null;
+
+
+// /**
+// * Copy of signature holders. It's needed by BKU when we try to verify single by single
+// * signature.
+// */
+// public List copy_of_signature_holders;
+
+// /**
+// * The suggested filename.
+// */
+// public String filename;
+//
+// /**
+// * Tells, if the file download should be done inline or as attachment.
+// */
+// public boolean download_inline;
+
+//// /**
+//// * The sign result to be passed back to the user.
+//// */
+//// public SignResult sign_result;
+//
+// public boolean isSignFinished = false;
+
+
+
+ /**
+ * Object containing information about the calling webapplication.
+ * @author: Thomas Zefferer
+ */
+ public ExternAppInformation exappinf;
+
+ /**
+ * Information about the signature position
+ * @author: Thomas Zefferer
+ */
+ public TablePos pos ;
+
+
+
+ /**
+ * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
+ */
+ public void valueBound(HttpSessionBindingEvent event)
+ {
+ log.debug("Bound SignSessionInformation to session.");
+ }
+
+ /**
+ * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
+ */
+ public void valueUnbound(HttpSessionBindingEvent event)
+ {
+ log.debug("Unbound SignSessionInformation from session.");
+
+ if (this.inputDataSource != null)
+ {
+ TempDirHelper.deleteDataSourceIfFileBased(this.inputDataSource);
+ }
+ if (this.signature_holders != null)
+ {
+ Iterator it = this.signature_holders.iterator();
+ while (it.hasNext())
+ {
+ SignatureHolder sh = (SignatureHolder) it.next();
+ TempDirHelper.deleteDataSourceIfFileBased(sh.getDataSource());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java
new file mode 100644
index 0000000..5752838
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java
@@ -0,0 +1,48 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web.helper;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.pdfas.exceptions.web.SessionExpiredException;
+import at.knowcenter.wag.egov.egiz.web.SessionAttributes;
+
+/**
+ * @author wprinz
+ *
+ */
+public class SessionHelper
+{
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(SessionHelper.class);
+
+ public static Object getSession(HttpServletRequest request) throws SessionExpiredException
+ {
+
+ HttpSession session = request.getSession(false);
+ if (session == null)
+ {
+ String msg = "There is no session associated with this request."; //$NON-NLS-1$
+ log.error(msg);
+ throw new SessionExpiredException(msg);
+ }
+
+ Object sessionObject = session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION);
+ if (sessionObject == null)
+ {
+ String msg = "The session is not found or no longer valid."; //$NON-NLS-1$
+ log.error(msg);
+ throw new SessionExpiredException(msg);
+ }
+
+ return sessionObject;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
new file mode 100644
index 0000000..55e0051
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
@@ -0,0 +1,229 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web.helper;
+
+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.web.SignSessionInformation;
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
+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;
+
+/**
+ * @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.
+ *
+ * <p>
+ * This prepares the data for both being signed or being previewed.
+ * </p>
+ *
+ * @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.
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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();
+ 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?
+ throw new RuntimeException("This has to be refactored.");
+// SignResult sr = si.sign_result;
+// byte[] signed_pdf = sr.getData();
+// 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;
+//
+// // build URL
+// int ind = invoke_url.indexOf("?");
+// String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind) + "&" + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID
+// + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length;
+//
+// 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;
+ }
+}
diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java
new file mode 100644
index 0000000..9f2b6fb
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java
@@ -0,0 +1,242 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.pdfas.framework.input.DataSource;
+import at.gv.egiz.pdfas.framework.input.TextDataSource;
+import at.gv.egiz.pdfas.framework.output.DataSink;
+import at.gv.egiz.pdfas.impl.input.FileBased;
+import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl;
+import at.gv.egiz.pdfas.impl.input.FileBasedTextDataSourceImpl;
+import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl;
+import at.gv.egiz.pdfas.impl.output.FileBasedDataSink;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
+import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder;
+
+/**
+ * @author wprinz
+ *
+ */
+public class TempDirHelper
+{
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(TempDirHelper.class);
+
+ protected static long runningIndex = 0;
+
+ public static void storeTextSignatureHoldersIfApplicable(List shs, String fileNameSuffix) throws IOException
+ {
+ Iterator it = shs.iterator();
+ while (it.hasNext())
+ {
+ SignatureHolder sh = (SignatureHolder) it.next();
+ if (sh instanceof TextualSignatureHolder)
+ {
+ TextualSignatureHolder tsh = (TextualSignatureHolder) sh;
+ if (!(tsh.getDataSource() instanceof FileBased))
+ {
+ TextDataSource tds = (TextDataSource) tsh.getDataSource();
+ if (isReasonableToStore(tds.getText().length()))
+ {
+ TextDataSource fbtds = placeTextIntoTempDir(tds.getText(), fileNameSuffix);
+ tsh.exchangeDataSource(fbtds);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Places the text into the temp dir if reasonable.
+ *
+ * <p>
+ * Reasonable means that the text is longer than a certain threshold.
+ * Otherwise a short text is simply held in memory.
+ * </p>
+ *
+ * @param text
+ * The text to be stored.
+ * @param fileNameSuffix
+ * A file name suffix so that the temp file gets a more "readable"
+ * name.
+ * @return Returns the TextDataSource.
+ * @throws IOException
+ * F.e.
+ */
+ public static TextDataSource placeTextIntoTempDir(String text, String fileNameSuffix) throws IOException
+ {
+ if (isReasonableToStore(text.length()))
+ {
+ String fileName = formatFileName(fileNameSuffix);
+
+ File tmpFile = createTempFileInDir(fileName);
+
+ FileOutputStream fos = new FileOutputStream(tmpFile);
+ OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+ osw.write(text);
+ osw.close();
+
+ FileBasedTextDataSourceImpl textDataSource = new FileBasedTextDataSourceImpl(tmpFile, "UTF-8");
+ return textDataSource;
+ }
+ else
+ {
+ return new TextDataSourceImpl(text);
+ }
+ }
+
+ /**
+ * Tells, if it is reasonable to store the text of the given length onto the
+ * disk.
+ *
+ * @param textLength
+ * The length of the text under question.
+ * @return Returns true if the text should be stored on the disk.
+ */
+ public static boolean isReasonableToStore(int textLength)
+ {
+ return textLength >= 10000;
+ }
+
+ public static FileBasedPdfDataSourceImpl placePdfIntoTempDir(InputStream pdfInput, String fileNameSuffix) throws IOException
+ {
+ File pdfFile = placeInputIntoTempDirFile(pdfInput, fileNameSuffix);
+
+ FileBasedPdfDataSourceImpl pdfDataSource = new FileBasedPdfDataSourceImpl(pdfFile, (int) pdfFile.length());
+ return pdfDataSource;
+ }
+
+ protected static File placeInputIntoTempDirFile(InputStream input, String fileNameSuffix) throws IOException
+ {
+ String fileName = formatFileName(fileNameSuffix);
+
+ File tmpFile = createTempFileInDir(fileName);
+
+ FileOutputStream fos = new FileOutputStream(tmpFile);
+
+ byte[] buffer = new byte[2048];
+ int read = -1;
+ while ((read = input.read(buffer)) > 0)
+ {
+ fos.write(buffer, 0, read);
+ }
+ fos.close();
+ input.close();
+
+ return tmpFile;
+ }
+
+ protected static String formatFileName(String fileNameSuffix)
+ {
+ String fileName = "tmp" + formatIndex(runningIndex) + "_" + fileNameSuffix;
+ runningIndex++;
+
+ return fileName;
+ }
+
+ protected static String formatIndex(long index)
+ {
+ NumberFormat nf = new DecimalFormat("00000000");
+
+ return nf.format(index);
+ }
+
+ protected static File createTempFileInDir(String fileName) throws IOException
+ {
+ File tempDir = new File(new File(SettingsReader.RESOURCES_PATH), "pdfastmp");
+
+ File tmpFile = new File(tempDir, fileName);
+
+ tmpFile.createNewFile();
+
+ tmpFile.deleteOnExit();
+
+ return tmpFile;
+ }
+
+ public static FileBasedDataSink createTempDataSink(String fileNameSuffix) throws IOException
+ {
+ String fileName = formatFileName(fileNameSuffix);
+
+ File tmpFile = createTempFileInDir(fileName);
+
+ FileBasedDataSink fbds = new FileBasedDataSink(tmpFile);
+
+ return fbds;
+ }
+
+ public static void writeDataSinkToHttpResponse(FileBasedDataSink fbds, HttpServletResponse response) throws IOException
+ {
+
+ response.setContentType(fbds.getMimeType());
+ response.setCharacterEncoding(fbds.getCharacterEncoding());
+
+ OutputStream os = response.getOutputStream();
+
+ byte[] buffer = new byte[2048];
+ FileInputStream fis = new FileInputStream(fbds.getFile());
+ int n = -1;
+ while ((n = fis.read(buffer)) > 0)
+ {
+ os.write(buffer, 0, n);
+ }
+ fis.close();
+ os.close();
+ }
+
+ /**
+ * Deletes the underlying file of the FileBased DataSource.
+ *
+ * <p>
+ * If the DataSource is not FileBased, nothing is done.
+ * </p>
+ * <p>
+ * This is usually used by the application to delete temporary files.
+ * </p>
+ *
+ * @param dataSource
+ */
+ public static void deleteDataSourceIfFileBased(DataSource dataSource)
+ {
+ if (dataSource instanceof FileBased)
+ {
+ FileBased fb = (FileBased) dataSource;
+ log.debug("Deleting temp file " + fb.getFile());
+ boolean deleted = fb.getFile().delete();
+ log.debug("deleted = " + deleted);
+ }
+ }
+
+ public static void deleteDataSinkIfFileBased(DataSink dataSink)
+ {
+ if (dataSink instanceof FileBased)
+ {
+ FileBased fb = (FileBased) dataSink;
+ log.debug("Deleting temp file " + fb.getFile());
+ boolean deleted = fb.getFile().delete();
+ log.debug("deleted = " + deleted);
+ }
+ }
+
+}