]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils/src/org/simantics/utils/FileUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / FileUtils.java
diff --git a/bundles/org.simantics.utils/src/org/simantics/utils/FileUtils.java b/bundles/org.simantics.utils/src/org/simantics/utils/FileUtils.java
new file mode 100644 (file)
index 0000000..aae9666
--- /dev/null
@@ -0,0 +1,1016 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.Closeable;\r
+import java.io.File;\r
+import java.io.FileFilter;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.OutputStream;\r
+import java.io.RandomAccessFile;\r
+import java.io.UnsupportedEncodingException;\r
+import java.net.URI;\r
+import java.net.URL;\r
+import java.nio.channels.FileChannel;\r
+import java.nio.charset.Charset;\r
+import java.nio.file.FileVisitResult;\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+import java.nio.file.SimpleFileVisitor;\r
+import java.nio.file.StandardCopyOption;\r
+import java.nio.file.attribute.BasicFileAttributes;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Deque;\r
+import java.util.LinkedList;\r
+import java.util.Random;\r
+import java.util.zip.DataFormatException;\r
+import java.util.zip.Deflater;\r
+import java.util.zip.Inflater;\r
+import java.util.zip.ZipEntry;\r
+import java.util.zip.ZipException;\r
+import java.util.zip.ZipInputStream;\r
+import java.util.zip.ZipOutputStream;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.adapter.Adapter;\r
+import org.simantics.databoard.adapter.AdapterConstructionException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.utils.bytes.LEInt;\r
+import org.simantics.utils.strings.FileNameUtils;\r
+\r
+/**\r
+ * Utilities for common file operations.\r
+ *\r
+ * see StreamUtil in databoard for Input/OutputStream reading/writing utils\r
+ * @see FileNameUtils for more utils\r
+ * \r
+ * @author Toni Kalajainen\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class FileUtils {\r
+\r
+       /**\r
+        * Create escaped filename\r
+        * \r
+        * @param name any string\r
+        * @return file compatible string\r
+        */\r
+       public static String escapeFileName(String name) {\r
+               try {\r
+                       return java.net.URLEncoder.encode(name, "UTF-8");\r
+               } catch (UnsupportedEncodingException e) {\r
+                       // never expected\r
+                       throw new RuntimeException(e);\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Unescape filename into string \r
+        * \r
+        * @param filename \r
+        * @return any string\r
+        */\r
+       public static String unescapeFileName(String filename) {\r
+               try {\r
+                       return java.net.URLDecoder.decode(filename, "UTF-8");\r
+               } catch (UnsupportedEncodingException e) {\r
+                       // never expected\r
+                       throw new RuntimeException(e);\r
+               }\r
+       }\r
+\r
+    public static File ensureParentDirectoryExists(String path) throws IOException {\r
+       return ensureParentDirectoryExists(new File(path));\r
+    }\r
+\r
+    /**\r
+     * Ensures the parent directory pointed by the specified file path exists as a\r
+     * directory.\r
+     * \r
+     * @param path the directory whose existence is to be ensured\r
+     * @return the requested directory\r
+     * @throws IOException if the specified directory cannot be created or\r
+     *         already exists as a file\r
+     */\r
+    public static File ensureParentDirectoryExists(File path) throws IOException {\r
+       return ensureDirectoryExists(path.getParentFile());\r
+    }\r
+       \r
+       \r
+    public static File ensureDirectoryExists(String path) throws IOException {\r
+       return ensureDirectoryExists(new File(path));\r
+    }\r
+\r
+    /**\r
+     * Ensures the directory pointed by the specified file path exists as a\r
+     * directory.\r
+     * \r
+     * @param path the directory whose existence is to be ensured\r
+     * @return the requested directory\r
+     * @throws IOException if the specified directory cannot be created or\r
+     *         already exists as a file\r
+     */\r
+    public static File ensureDirectoryExists(File path) throws IOException {\r
+        if (path.isDirectory())\r
+            // Already exists, everything OK.\r
+            return path;\r
+\r
+        if (path.exists())\r
+            // Path is not a directory but it exists, fail!\r
+            throw new IOException("file '" + path + "', already exists but it is not a directory");\r
+\r
+        path.mkdirs();\r
+        if (!path.exists())\r
+            // Path is not a directory but it exists, fail!\r
+            throw new IOException("could not create directory '" + path + "' for an unknown reason");\r
+\r
+        // Directory created OK.\r
+        return path;\r
+    }\r
+\r
+    /**\r
+     * Copies the contents of a source file to the destination file.\r
+     * \r
+     * @param sourceFile the source file descriptor\r
+     * @param destFile the destination file descriptor\r
+     * @throws IOException when anything IO-related goes wrong during the copy\r
+     */\r
+    public static void copyFile(File sourceFile, File destFile) throws IOException {\r
+        if (!destFile.exists()) {\r
+            destFile.createNewFile();\r
+        }\r
+\r
+        FileInputStream fis = null;\r
+        FileOutputStream fos = null;\r
+        try {\r
+            fis = new FileInputStream(sourceFile);\r
+            fos = new FileOutputStream(destFile);\r
+            FileChannel source = fis.getChannel();\r
+            FileChannel destination = fos.getChannel();\r
+\r
+            long count = 0;\r
+            long size = source.size();\r
+            while (count < size) {\r
+                count += destination.transferFrom(source, count, size - count);\r
+            }\r
+        } finally {\r
+            if (fis != null) {\r
+                uncheckedClose(fis);\r
+            }\r
+            if (fos != null) {\r
+                uncheckedClose(fos);\r
+            }\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Copy file or dir recursively.\r
+     * \r
+     * @param src\r
+     * @param dst\r
+     * @throws IOException\r
+     */\r
+    public static void copy(File src, File dst) throws IOException\r
+    {\r
+       if (src.isDirectory()) {\r
+               if(!dst.exists()) dst.mkdir();\r
+\r
+               for (String file : src.list()) {\r
+                       File srcFile = new File(src, file);\r
+                       File dstFile = new File(dst, file);\r
+                       copy(srcFile,dstFile);\r
+               }\r
+       } else {\r
+               copyFile(src, dst);\r
+       }\r
+    }\r
+    \r
+\r
+//    public static File createTempFileFromResource(URL sourceUrl) throws IOException {\r
+//        sourceUrl = FileLocator.resolve(sourceUrl);\r
+//        File sourceFile;\r
+//        try {\r
+//            if (sourceUrl.getProtocol().equalsIgnoreCase("file"))\r
+//                sourceFile = new File(sourceUrl.getPath());\r
+//            else\r
+//                sourceFile = new File(sourceUrl.toURI());\r
+//        } catch (URISyntaxException e) {\r
+//            throw new RuntimeException(e);\r
+//        }\r
+//\r
+//        File tempFile = File.createTempFile("tmp", ".tmp");\r
+//        FileUtils.copyFile(sourceFile, tempFile);\r
+//        return tempFile;\r
+//    }\r
+\r
+    /**\r
+     * Reads entire binary file\r
+     * @param file file\r
+     * @return contents of binary file\r
+     * @throws IOException on i/o problems\r
+     */\r
+    public static byte[] readFile(File file)\r
+    throws IOException\r
+    {\r
+        try (FileInputStream fis = new FileInputStream(file)) {\r
+            long size = file.length();\r
+            if (size>Integer.MAX_VALUE)\r
+                throw new IOException("File too big");\r
+            int len = (int) size;\r
+            byte data [] = new byte[len];\r
+            int pos = 0;\r
+\r
+            while (pos<size) {\r
+                int read = fis.read(data, pos, len-pos);\r
+                pos += read;\r
+            }\r
+            return data;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Creates and writes a binary file\r
+     * @param file file\r
+     * @param data data\r
+     * @throws IOException on i/o problems\r
+     */\r
+    public static void writeFile(File file, byte[] data)\r
+    throws IOException\r
+    {\r
+//        file.createNewFile();\r
+//        file.setWritable(true);\r
+        try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {\r
+            raf.setLength(data.length);\r
+            raf.seek(0);\r
+            raf.write(data);\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Fetch the entire contents of the input stream text file, and return it in\r
+     * a String. This style of implementation does not throw Exceptions to the\r
+     * caller.\r
+     * \r
+     * @param stream the stream to completely read in\r
+     */\r
+    public static String getContents(InputStream stream) throws IOException {\r
+        return getContents(stream, Charset.defaultCharset());\r
+    }\r
+\r
+    /**\r
+     * Fetch the entire contents of the input stream text file, and return it in\r
+     * a String. This style of implementation does not throw Exceptions to the\r
+     * caller.\r
+     * \r
+     * @param stream the stream to completely read in\r
+     */\r
+    public static String getContents(InputStream stream, Charset charset, String lineSeparator) throws IOException {\r
+        StringBuilder contents = new StringBuilder();\r
+        BufferedReader input = null;\r
+        try {\r
+            input = new BufferedReader(new InputStreamReader(stream, charset));\r
+\r
+            String line = null;\r
+            while ((line = input.readLine()) != null) {\r
+                contents.append(line);\r
+                contents.append(lineSeparator);\r
+            }\r
+        } finally {\r
+            try {\r
+                if (input != null) {\r
+                    // flush and close both "input" and its underlying\r
+                    // FileReader\r
+                    input.close();\r
+                }\r
+            } catch (IOException ex) {\r
+                ex.printStackTrace();\r
+            }\r
+        }\r
+        return contents.toString();\r
+    }\r
+\r
+    public static String getContents(File f) throws IOException {\r
+       return getContents(f, Charset.defaultCharset());\r
+    }\r
+    \r
+    public static String getContents(File f, Charset charset) throws IOException {\r
+       return getContents(new FileInputStream(f), charset);\r
+    }\r
+\r
+    public static String getContents(InputStream stream, Charset charset) throws IOException {\r
+       return getContents(stream, charset, System.getProperty("line.separator"));\r
+    }\r
+\r
+    public static String getContents(InputStream stream, String lineSeparator) throws IOException {\r
+       return getContents(stream, Charset.defaultCharset(), lineSeparator);\r
+    }\r
+    \r
+    /**\r
+     * Fetch the entire contents of a text file, and return it in a String. This\r
+     * style of implementation does not throw Exceptions to the caller.\r
+     * \r
+     * @param sourcePath is a file which already exists and can be read.\r
+     */\r
+    public static String getContents(String sourcePath) throws IOException {\r
+        return getContents(sourcePath, Charset.defaultCharset(), System.getProperty("line.separator"));\r
+    }\r
+\r
+    public static String getContents(String sourcePath, String lineSeparator) throws IOException {\r
+        return getContents(sourcePath, Charset.defaultCharset(), lineSeparator);\r
+    }\r
+\r
+    public static String getContents(String sourcePath, Charset charset) throws IOException {\r
+        return getContents(sourcePath, charset, System.getProperty("line.separator"));\r
+    }\r
+\r
+    /**\r
+     * Fetch the entire contents of a text file, and return it in a String. This\r
+     * style of implementation does not throw Exceptions to the caller.\r
+     * \r
+     * @param sourcePath is a file which already exists and can be read.\r
+     */\r
+    public static String getContents(String sourcePath, Charset charset, String lineSeparator) throws IOException {\r
+        FileInputStream input = null;\r
+        try {\r
+            input = new FileInputStream(sourcePath);\r
+            return getContents(input, charset, lineSeparator);\r
+        } finally {\r
+            uncheckedClose(input);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the contents of a file which is located inside a given bundle.\r
+     * This works regardless of whether the bundle is jarred or not.\r
+     * \r
+     * @param URL the resource to read in\r
+     * @return the contents of the resource\r
+     * @throws IOException if the file is not found or other io errors occur\r
+     */\r
+    public static String getContents(URL url) throws IOException {\r
+        if (url == null)\r
+            throw new IllegalArgumentException("null URL");\r
+        InputStream input = null;\r
+        try {\r
+            input = url.openStream();\r
+            return FileUtils.getContents(input);\r
+        } finally {\r
+            uncheckedClose(input);\r
+        }\r
+    }\r
+\r
+       /**\r
+        * Read a binary file into a java instance. Binary file is a variant, \r
+        * there is a filetype in the header of the file. \r
+        * If requested binding is not the exact binding of the file, an adapter is tried.\r
+        * \r
+        * @param file file\r
+        * @param binding content binding\r
+        * @return instance\r
+        * @throws IOException \r
+        */\r
+       public static Object readFile(InputStream stream, Binding binding) throws IOException {\r
+               Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );\r
+               Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( stream );\r
+\r
+               if (type.equals(binding.type())) {\r
+                       return Bindings.getSerializerUnchecked( binding ).deserialize(stream);\r
+               } else {\r
+                       try {\r
+                               Binding fileContentBinding = Bindings.getMutableBinding(type);\r
+                               Adapter adapter = Bindings.adapterFactory.getAdapter(fileContentBinding, binding, true, false);\r
+                               Object value = Bindings.getSerializerUnchecked( fileContentBinding ).deserialize(stream);\r
+                               return adapter.adapt( value );\r
+                       } catch (AdapterConstructionException e) {\r
+                               throw new IOException(e);\r
+                       } catch (AdaptException e) {\r
+                               throw new IOException(e);\r
+                       }\r
+               }\r
+       }\r
+    \r
+    /**\r
+     * Deletes all files and sub-directories from the specified directory. If a\r
+     * file is specified, only that fill will be deleted.\r
+     * \r
+     * @param dir\r
+     * @throws IOException\r
+     */\r
+    public static void deleteAll(File dir) throws IOException {\r
+        if (dir.isFile()) {\r
+            dir.delete();\r
+            return;\r
+        }\r
+\r
+        if (dir.isDirectory()) {\r
+            File[] fs = dir.listFiles((FileFilter) null);\r
+            if (fs == null)\r
+                return;\r
+\r
+            for (File f : fs) {\r
+                if (f.isDirectory()) {\r
+                    deleteAll(f);\r
+                } else {\r
+                    if (!f.delete()) {\r
+                        throw new IOException("Could not delete file: " + f.getAbsolutePath());\r
+                    }\r
+                }\r
+            }\r
+\r
+            if (!dir.delete()) {\r
+                throw new IOException("Could not delete directory: " + dir.getAbsolutePath());\r
+            }\r
+        } else if (dir.exists()) {\r
+            if (!dir.delete()) {\r
+                throw new IOException("Could not delete file: " + dir.getAbsolutePath());\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Deletes all files and sub-directories from the specified directory. If a\r
+     * file is specified, only that fill will be deleted.\r
+     * \r
+     * If the given directory contains files listed in the filter those files are not deleted\r
+     * \r
+     * @param dir\r
+     *                         directory from where to start the deletion \r
+     * @param filter\r
+     *                                 filter containing specific file paths not to delete\r
+     * @throws IOException\r
+     */\r
+    public static void deleteAllWithFilter(File dir, ArrayList<String> filter) throws IOException {\r
+        if (dir.isFile()) {\r
+               if (!filter.contains(dir.getAbsolutePath())) {\r
+                       dir.delete();\r
+                       return;                         \r
+               }\r
+        }\r
+\r
+        if (dir.isDirectory()) {\r
+            File[] fs = dir.listFiles((FileFilter) null);\r
+            if (fs == null)\r
+                return;\r
+\r
+            for (File f : fs) {\r
+                if (f.isDirectory()) {\r
+                    deleteAllWithFilter(f, filter);\r
+                } else {\r
+                       if (!filter.contains(f.getAbsolutePath())) {\r
+                        if (!f.delete()) {\r
+                            throw new IOException("Could not delete file: " + f.getAbsolutePath());\r
+                        }      \r
+                       }\r
+                }\r
+            }\r
+            if (!filter.contains(dir.getAbsolutePath())) {\r
+                if (!dir.delete()) {\r
+                    throw new IOException("Could not delete directory: " + dir.getAbsolutePath());\r
+                }              \r
+            }\r
+        } else if (dir.exists()) {\r
+               if (filter.contains(dir.getAbsolutePath())) {\r
+                if (!dir.delete()) {\r
+                    throw new IOException("Could not delete file: " + dir.getAbsolutePath());\r
+                }\r
+               }\r
+        }\r
+    }\r
+    \r
+    public static ArrayList<String> createFileFilter(File dir, ArrayList<String> filter) {\r
+       if (filter == null)\r
+               filter = new ArrayList<String>();\r
+       if (dir.isFile()) {\r
+               filter.add(dir.getAbsolutePath());\r
+               return filter;\r
+       }\r
+       \r
+        if (dir.isDirectory()) {\r
+            File[] fs = dir.listFiles((FileFilter) null);\r
+            if (fs == null)\r
+                return filter;\r
+\r
+            for (File f : fs) {\r
+                if (f.isDirectory()) {\r
+                    createFileFilter(f, filter);\r
+                } else {\r
+                       filter.add(f.getAbsolutePath());\r
+                }\r
+            }\r
+            filter.add(dir.getAbsolutePath());\r
+        } else if (dir.exists()) {\r
+               filter.add(dir.getAbsolutePath());\r
+        }\r
+               return filter;\r
+    }\r
+\r
+\r
+    /**\r
+     * Delete a directory incl. all files and sub-directories by best effort.\r
+     * Does not throw exceptions if deletion fails, simply tries to delete the\r
+     * provided directory to the best of Java File API's abilities.\r
+     * \r
+     * @param dir\r
+     *            directory to delete recursively\r
+     * @boolean <code>true</code> if all files were successfully deleted,\r
+     *          <code>false</code> if some or all failed to be deleted\r
+     */\r
+    public static boolean deleteDir(File dir) {\r
+        Logger myLogger = Logger.getLogger(FileUtils.class);\r
+        myLogger.debug("Deleting directory "+dir);\r
+        boolean result = true;\r
+\r
+        if (!dir.isDirectory()) return false;\r
+        File[] fs = dir.listFiles();\r
+        if (fs != null) {\r
+            for (File f : fs) {\r
+                if (f.isDirectory()) result &= deleteDir(f);\r
+                if (f.isFile()) result &= f.delete();\r
+            }\r
+        }\r
+        boolean ok = dir.delete();\r
+//             if (!ok) dir.deleteOnExit();\r
+        result &= ok;\r
+        return result;\r
+    }\r
+    \r
+    public static String deleteDirs(File dir) {        \r
+        Logger myLogger = Logger.getLogger(FileUtils.class);\r
+        myLogger.debug("Deleting directory "+dir);\r
+        boolean result = true;\r
+\r
+        if (!dir.isDirectory()) \r
+               return dir + " is not a directory!";\r
+        File[] fs = dir.listFiles();\r
+        if (fs != null) {\r
+            for (File f : fs) {\r
+               //System.out.println("file f :" + f);\r
+                if (f.isDirectory()) { \r
+                       boolean a = deleteDir(f);\r
+                       result &= a;\r
+                }\r
+                if (f.isFile()) {\r
+                       boolean a = f.delete();\r
+                       result &= a;\r
+                }\r
+                       \r
+            }\r
+        }\r
+        boolean ok = dir.delete();\r
+//             if (!ok) dir.deleteOnExit();\r
+        result &= ok;\r
+       return "deleteDirs succesful for " + dir + " : " + result;\r
+    }\r
+\r
+    /**\r
+     * Closes a stream and ignores any resulting exception. This is useful\r
+     * when doing stream cleanup in a finally block where secondary exceptions\r
+     * are not worth logging.\r
+     */\r
+    public static void uncheckedClose(Closeable closeable) {\r
+        try {\r
+            if (closeable != null)\r
+                closeable.close();\r
+        } catch (IOException e) {\r
+            //ignore\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Extracts the specified source file in the specified bundle into the\r
+     * specified local directory.\r
+     * \r
+     * @param url the source URL to stream the resource from\r
+     * @param targetFile the target file to write the resource to\r
+     * @param deleteOnExit <code>true</code> to use {@link File#deleteOnExit()}\r
+     *        on the resulting file. Note that this does not guarantee that the\r
+     *        file is deleted when the JVM exits\r
+     * @return the resulting file\r
+     * @throws FileNotFoundException\r
+     */\r
+    public static File copyResource(URL url, File targetFile, boolean deleteOnExit) throws IOException, FileNotFoundException {\r
+        if (url == null)\r
+            throw new IllegalArgumentException("null url");\r
+\r
+        FileOutputStream os = null;\r
+        InputStream is = null;\r
+        try {\r
+            if (targetFile.exists())\r
+                targetFile.delete();\r
+\r
+            is = url.openStream();\r
+            int read;\r
+            byte [] buffer = new byte [16384];\r
+            os = new FileOutputStream (targetFile);\r
+            while ((read = is.read (buffer)) != -1) {\r
+                os.write(buffer, 0, read);\r
+            }\r
+            os.close ();\r
+            is.close ();\r
+\r
+            // Request removal of the extracted files on JVM exit.\r
+            if (deleteOnExit)\r
+                targetFile.deleteOnExit();\r
+            return targetFile;\r
+        } finally {\r
+            FileUtils.uncheckedClose(os);\r
+            FileUtils.uncheckedClose(is);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Creates the requested location under the system's temporary directories\r
+     * for temporary data storage.\r
+     * \r
+     * @param pathSegments the path segments that are appended to\r
+     *        java.io.tmpdir. The path segments musn't contain path separators.\r
+     * @return the resulting temporary directory as a File object\r
+     * @throws IOException if anything goes wrong\r
+     */\r
+    public static File getOrCreateTemporaryDirectory(boolean requireEmptyDirectory, String... pathSegments) throws IOException {\r
+        String separator = System.getProperty("file.separator");\r
+        String tempDir = System.getProperty("java.io.tmpdir");\r
+        if (tempDir == null)\r
+            throw new IllegalStateException("'java.io.tmpdir' property is not defined, is the system TMP environment variable defined?");\r
+\r
+        if (!hasTrailingSeparator(tempDir))\r
+            tempDir = tempDir + separator;\r
+\r
+        for (int i = 0; i < pathSegments.length-1; ++i) {\r
+            if (containsSeparator(pathSegments[i]))\r
+                throw new IllegalArgumentException("path segments contain path separators: " + Arrays.toString(pathSegments));\r
+            tempDir = pathSegments[i] + separator;\r
+        }\r
+\r
+        // Find name for an empty or non-existing temporary directory\r
+        if (pathSegments.length > 0) {\r
+            String lastSegment = pathSegments[pathSegments.length - 1];\r
+            String suffix = "";\r
+            int counter = 0;\r
+            // This loop will not exit until it succeeds or some error occurs.\r
+            while (true) {\r
+                File temp = new File(tempDir + lastSegment + suffix);\r
+\r
+                if (!temp.exists()) {\r
+                    // Found non-existent temporary directory!\r
+                    if (temp.mkdirs()) {\r
+                        // Ok, everything seems to be fine.\r
+                        return temp;\r
+                    }\r
+                    // For some reason the directory could not be created, lets\r
+                    // try another name.\r
+                } else {\r
+                    // Found an existing temporary file.\r
+                    if (temp.isDirectory() && temp.canWrite()) {\r
+                        if (requireEmptyDirectory) {\r
+                            String[] files = temp.list();\r
+                            if (files != null) {\r
+                                if (files.length == 0) {\r
+                                    // Ok, the directory is empty and writable.\r
+                                    return temp;\r
+                                }\r
+                            }\r
+                        } else {\r
+                            return temp;\r
+                        }\r
+                        // Either the directory was empty or it could not be\r
+                        // checked. In any case, don't use the directory.\r
+                    }\r
+                }\r
+\r
+                // Try another directory name if no success with this one.\r
+                suffix = Integer.toHexString(counter);\r
+                ++counter;\r
+            }\r
+        }\r
+        return new File(tempDir);\r
+    }\r
+\r
+    private static boolean containsSeparator(String s) {\r
+        return s.contains("/") || s.contains("\\");\r
+    }\r
+\r
+    private static boolean hasTrailingSeparator(String s) {\r
+        return s.endsWith("/") || s.endsWith("\\");\r
+    }\r
+\r
+    /**\r
+     * Very simple compression using ZLib\r
+     * @param input the uncompressed data\r
+     * @return the compressed data\r
+     */\r
+    public static byte[] deflate(byte[] input) {\r
+        // Compress the bytes\r
+        Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION);\r
+        compresser.setInput(input);\r
+        compresser.finish();\r
+\r
+        int bufferSize = input.length<16 ? 16 : input.length;\r
+        byte buffer[] = new byte[bufferSize];\r
+        int  bufferPos = 0;\r
+        do {\r
+            int compressedDataLength = compresser.deflate(buffer, bufferPos, buffer.length-bufferPos);\r
+            bufferPos += compressedDataLength;\r
+            if (!compresser.finished())\r
+                buffer = Arrays.copyOf(buffer, buffer.length + bufferSize);\r
+        } while (!compresser.finished());\r
+\r
+        byte[] result = new byte[bufferPos+4];\r
+        System.arraycopy(buffer, 0, result, 4, bufferPos);\r
+        byte sizeData[] = LEInt.toBytes(input.length);\r
+        System.arraycopy(sizeData, 0, result, 0, 4);\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Very simple decompression using ZLib.\r
+     * @param input the compressed input\r
+     * @return the uncompressed data\r
+     * @throws DataFormatException\r
+     */\r
+    public static byte[] inflate(byte[] input) throws DataFormatException {\r
+        // Decompress the bytes\r
+        int inflatedSize = LEInt.toInt(input);\r
+        Inflater decompresser = new Inflater();\r
+        decompresser.setInput(input, 4, input.length - 4);\r
+        byte[] result = new byte[inflatedSize];\r
+        int resultLength = decompresser.inflate(result);\r
+        assert(resultLength == inflatedSize);\r
+        decompresser.end();\r
+        return result;\r
+    }\r
+\r
+\r
+    public static boolean isValidFileName(String name) {\r
+        File f = new File(name) ;\r
+        if (!f.exists()) {\r
+            try {\r
+                boolean ok = f.createNewFile();\r
+                if (ok)\r
+                    f.delete();\r
+                return ok;\r
+            } catch (IOException ioe) {\r
+                return false;\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Create a temporary directory\r
+     * \r
+     * @return temporary directory\r
+     */\r
+    public static File createTmpDir()\r
+    {\r
+        String tmp = System.getenv("tmp");\r
+        if (tmp==null) tmp = "c:/temp";\r
+        Random r = new Random();\r
+        String randomName = "simantics-tmp-"+(r.nextInt(10000)+10000);\r
+        File tmpDir = new File(tmp+"/"+randomName);\r
+        tmpDir.deleteOnExit();\r
+        Boolean ok = tmpDir.mkdirs();\r
+        if (!ok) throw new RuntimeException("tmp dir "+tmpDir+" was not created");\r
+        return tmpDir;\r
+    }\r
+    \r
+    public static void compressZip(String sourcePath, String zipDir) throws IOException {\r
+       Logger myLogger = Logger.getLogger(FileUtils.class);\r
+       myLogger.debug("Compressing file " + sourcePath + " to zip " + zipDir + ".");\r
+\r
+       System.out.println("Compressing file " + sourcePath + " to zip " + zipDir + ".");\r
+\r
+       File filesource = new File(sourcePath);\r
+       URI base = filesource.toURI();\r
+       Deque<File> queue = new LinkedList<File>();\r
+       queue.push(filesource);\r
+       try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipDir))) {\r
+               while (!queue.isEmpty()) {\r
+                       filesource = queue.pop();\r
+                       for (File child : filesource.listFiles()) {\r
+                               String name = base.relativize(child.toURI()).getPath();\r
+                               if (child.isDirectory()) {\r
+                                       queue.push(child);\r
+                                       name = name.endsWith("/") ? name : name + "/";\r
+                                       zout.putNextEntry(new ZipEntry(name));\r
+                               } else {\r
+                                       zout.putNextEntry(new ZipEntry(name));\r
+                                       copy(child, zout);\r
+                                       zout.closeEntry();\r
+                               }\r
+                       }\r
+               }\r
+       } finally {\r
+               myLogger.debug("Filecompression done.");\r
+               System.out.println("Filecompression done.");\r
+       }\r
+    }\r
+\r
+    private static void copy(File file, ZipOutputStream zout) throws IOException {\r
+       try (InputStream in = new FileInputStream(file)) {\r
+               copy(in, zout);\r
+       }\r
+    }\r
+\r
+       /**\r
+     * Extract a zip file into a directory\r
+     * \r
+     * @param zipFile\r
+     * @param dst\r
+     * @throws IOException\r
+     */\r
+    public static void extractZip(File zipFile, File dst) throws IOException {\r
+        Logger myLogger = Logger.getLogger(FileUtils.class);\r
+        myLogger.debug("Extracting zip "+zipFile);\r
+        try (FileInputStream fis = new FileInputStream(zipFile)) {\r
+            extractZip(fis, dst);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Extract a zip file into a directory\r
+     * \r
+     * @param zipInput\r
+     * @param dst directory\r
+     * @throws IOException\r
+     */\r
+    public static void extractZip(InputStream zipInput, File dst) throws IOException {\r
+        Logger myLogger = Logger.getLogger(FileUtils.class);\r
+        byte[] buf = new byte[8192];\r
+        ZipInputStream zis = new ZipInputStream(zipInput);\r
+        ZipEntry entry;\r
+\r
+        entry = zis.getNextEntry();\r
+        while (entry != null) {\r
+            // for each entry to be extracted\r
+            String name = entry.getName();\r
+            myLogger.debug("Extracting "+name);\r
+            File file = new File(dst, name);\r
+\r
+            if (entry.isDirectory())\r
+            {\r
+                if ( !file.exists() ) file.mkdirs();\r
+            } else {\r
+                File parent = file.getParentFile();\r
+                if (!parent.exists()) parent.mkdirs();\r
+                if (!file.exists()) file.createNewFile();\r
+\r
+                FileOutputStream fileoutputstream = new FileOutputStream(file);\r
+                try {\r
+                    int n = 0;\r
+                    while ((n = zis.read(buf, 0, buf.length)) > -1)\r
+                        fileoutputstream.write(buf, 0, n);\r
+                } catch (ZipException e) {\r
+                       throw new IOException("Failed to extract '" + name + "'.", e);\r
+                } finally {\r
+                    fileoutputstream.close();\r
+                }\r
+            }\r
+\r
+            zis.closeEntry();\r
+            entry = zis.getNextEntry();\r
+        }// while\r
+\r
+        zis.close();\r
+    }\r
+\r
+    // Test inflate & deflate\r
+    public static void main(String[] args) {\r
+        try {\r
+            // Test compression\r
+            String str = "abcdefghijklmnopqrstuvwxyz";\r
+            byte data[] = str.getBytes();\r
+            System.out.println("Data:\t"+data.length);\r
+            byte deflated[] = deflate(data);\r
+            System.out.println("Deflated:\t"+deflated.length);\r
+            byte inflated[] = inflate(deflated);\r
+            System.out.println("Inflated:\t"+inflated.length);\r
+            String str2 = new String(inflated);\r
+            System.out.println("Strings are equal: "+str.endsWith(str2));\r
+        } catch (DataFormatException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    public static File[] listFilesByExtension(File directory, final String extension) {\r
+       return directory.listFiles(new ExtensionFilter(extension));\r
+    }\r
+    \r
+    /**\r
+     * Copy the content of the input stream into the output stream, using a temporary\r
+     * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.\r
+     *\r
+     * @param in The input stream to copy from.\r
+     * @param out The output stream to copy to.\r
+     *\r
+     * @throws IOException If any error occurs during the copy.\r
+     */\r
+    private static final int IO_BUFFER_SIZE = 64 * 1024;\r
+\r
+    public static void copy(InputStream in, OutputStream out) throws IOException {\r
+        byte[] b = new byte[IO_BUFFER_SIZE];\r
+        int read;\r
+        while (true) {\r
+            read = in.read(b);\r
+            if (read < 0)\r
+                break;\r
+            out.write(b, 0, read);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param in\r
+     * @param out\r
+     * @param maxBytesToCopy the maximum amount of bytes to copy\r
+     * @return the amount of bytes copied\r
+     * @throws IOException\r
+     */\r
+    public static long copy(InputStream in, OutputStream out, long maxBytesToCopy) throws IOException {\r
+        byte[] b = new byte[IO_BUFFER_SIZE];\r
+        int read = 0;\r
+        while (read < maxBytesToCopy) {\r
+            int l = (int) Math.min((long) IO_BUFFER_SIZE, maxBytesToCopy-read);\r
+            int r = in.read(b, 0, l);\r
+            if (r < 0)\r
+                break;\r
+            out.write(b, 0, r);\r
+            read += r;\r
+        }\r
+        return read;\r
+    }\r
+\r
+    public static void delete(Path databaseLocation) throws IOException {\r
+        Files.walkFileTree(databaseLocation, new DeleteDirectoriesVisitor());\r
+    }\r
+    \r
+    public static void copy(Path from, Path to) throws IOException {\r
+        Files.walkFileTree(from, new CopyDirectoriesVisitor(from, to));\r
+    }\r
+    \r
+    public static class DeleteDirectoriesVisitor extends SimpleFileVisitor<Path> {\r
+        \r
+        @Override\r
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
+            Files.delete(file);\r
+            if (Files.exists(file))\r
+                throw new IOException("Could not delete file " + file.toAbsolutePath().toString());\r
+            return FileVisitResult.CONTINUE;\r
+        }\r
+        \r
+        @Override\r
+        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {\r
+            if (exc != null)\r
+                throw exc;\r
+            Files.delete(dir);\r
+            if (Files.exists(dir))\r
+                throw new IOException("Could not delete file " + dir.toAbsolutePath().toString());\r
+            return FileVisitResult.CONTINUE;\r
+        }\r
+    }\r
+    \r
+    public static class CopyDirectoriesVisitor extends SimpleFileVisitor<Path> {\r
+        \r
+        private final Path fromPath;\r
+        private final Path toPath;\r
+        \r
+        public CopyDirectoriesVisitor(Path fromPath, Path toPath) {\r
+            this.fromPath = fromPath;\r
+            this.toPath = toPath;\r
+        }\r
+        \r
+        @Override\r
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
+            Path targetPath = toPath.resolve(fromPath.relativize(dir));\r
+            if(!Files.exists(targetPath)){\r
+                Files.createDirectory(targetPath);\r
+            }\r
+            return FileVisitResult.CONTINUE;\r
+        }\r
+\r
+        @Override\r
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
+            Files.copy(file, toPath.resolve(fromPath.relativize(file)), StandardCopyOption.REPLACE_EXISTING);\r
+            return FileVisitResult.CONTINUE;\r
+        }\r
+    }\r
+}\r