/** * */ 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.PdfDataSource; import at.gv.egiz.pdfas.framework.input.TextDataSource; import at.gv.egiz.pdfas.framework.output.DataSink; import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; 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.input.helper.DataSourceHelper; import at.gv.egiz.pdfas.impl.output.ByteArrayDataSink; 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. * *

* Reasonable means that the text is longer than a certain threshold. * Otherwise a short text is simply held in memory. *

* * @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 PdfDataSource placePdfIntoTempDir(InputStream pdfInput, String fileNameSuffix) throws IOException { log.debug("PERF: placing pdf into memory cache"); byte [] pdfData = DataSourceHelper.convertInputStreamToByteArray(pdfInput); PdfDataSource pdfDataSource = new ByteArrayPdfDataSourceImpl(pdfData); // 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) { // double check so that file name is always correct. fileNameSuffix = extractFileNameSuffix(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 DataSink createTempDataSink(String fileNameSuffix) throws IOException { log.debug("PERF: placing pdf into memory cache"); DataSink ds = new ByteArrayDataSink(); // String fileName = formatFileName(fileNameSuffix); // // File tmpFile = createTempFileInDir(fileName); // // FileBasedDataSink ds = new FileBasedDataSink(tmpFile); return ds; } public static void writeDataSinkToHttpResponse(DataSink ds, HttpServletResponse response) throws IOException { response.setContentType(ds.getMimeType()); response.setCharacterEncoding(ds.getCharacterEncoding()); OutputStream os = response.getOutputStream(); if (ds instanceof FileBasedDataSink) { FileBasedDataSink fbds = (FileBasedDataSink)ds; 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(); } else { ByteArrayDataSink bads = (ByteArrayDataSink)ds; os.write(bads.getByteArray()); } os.close(); } /** * Deletes the underlying file of the FileBased DataSource. * *

* If the DataSource is not FileBased, nothing is done. *

*

* This is usually used by the application to delete temporary files. *

* * @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); } } /** * Given a file (maybe with path), extracts the file name suffix. * @param file The file and maybe path. * @return Returns the file name. */ public static String extractFileNameSuffix (String file) { File f = new File(file); return f.getName(); } }