/** * */ package at.gv.egiz.pdfas.utils; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Iterator; import java.util.List; 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.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.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; /** * Assembles the File of the temporary directory without checking if it really * exists. */ public static File assembleTemporaryDirectoryFile() { File temp_dir = new File(SettingsReader.TMP_PATH); return temp_dir; } /** * Returns the directory where temporary files should be stored. * *

* If the directory doesn't exist, it is created. *

* * @return Returns the directory where temporary files should be stored. */ public static File getTemporaryDirectory() { File temp_dir = assembleTemporaryDirectoryFile(); if (!temp_dir.exists()) { temp_dir.mkdirs(); } return temp_dir; } /** * Deletes all files in the temporary directory, if it exists. * *

* This should be used to clear temporary files when the application shuts * down. *

*/ public static void clearTemporaryDirectory() { File temp_dir = assembleTemporaryDirectoryFile(); log.debug("Clearing temporary directory: " + temp_dir); if (!temp_dir.exists()) { return; } File[] files = temp_dir.listFiles(); for (int i = 0; i < files.length; i++) { // added by tknall: do not try to remove svn-metadata if (files[i].getName().endsWith(".svn")) { continue; } log.debug(" Clearing temporary file: " + files[i]); boolean delete_success = files[i].delete(); if (!delete_success) { log.error("Couldn't delete the temporary file: " + files[i]); } } } 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 false; // 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; } public 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; } public static File formTempFile(String fileNameSuffix) { String fileName = formatFileName(fileNameSuffix); File tmpFile = getFileInTempDir(fileName); return tmpFile; } protected static File getFileInTempDir (String fileName) { // File tempDir = new File(new File(SettingsReader.RESOURCES_PATH), "pdfastmp"); File tempDir = assembleTemporaryDirectoryFile(); File tmpFile = new File(tempDir, fileName); 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 tmpFile = getFileInTempDir(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.flush(); // // } // // 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) { if (file == null || file.trim().length() == 0) { return "nofilename"; } File f = new File(file); return f.getName(); } }