/** * */ 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. * *

* 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 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. * *

* 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); } } }