package net.sf.cotta; import net.sf.cotta.memory.InMemoryFileSystem; import net.sf.cotta.physical.PhysicalFileSystem; import net.sf.cotta.system.FileSystem; import java.io.File; import java.net.MalformedURLException; import java.net.URL; /** * The factory class for creating TFile and TDirectory. * The static methods are used for a quick way to create TFile and TDirectory with PhysicalFileSystem. There are two * sets of static factories, one for factory creation and one for file/directory ceration * <p/> * <p/> * File factory creation: * <ul> * <li>physical() will create the physical file factory</li> * <li>inMemory() will cerate the in-memory file factory</li> * </ul> * <p/> * File/Directory creation: * <ul> * <li>physicalFile() and physicalDir() will create the physical file and directory</li> * </ul> * * @see net.sf.cotta.TFile * @see net.sf.cotta.TDirectory */ public class TFileFactory { private FileSystem fileSystem; private String defaultEncoding; /** * Creat the factory using physical file system * * @see net.sf.cotta.physical.PhysicalFileSystem */ public TFileFactory() { this(PhysicalFileSystem.instance); } public TFileFactory(FileSystem fileSystem) { this(fileSystem, null); } public TFileFactory(FileSystem fileSystem, String defaultEncoding) { this.fileSystem = fileSystem; this.defaultEncoding = defaultEncoding; } public FileSystem getFileSystem() { return fileSystem; } /** * Create the TFile that is represented by the path and backed by the file system * * @param pathString The path string that represents the file * @return The TFile object * @see net.sf.cotta.TPath#parse(java.lang.String) * @see #file(TPath) */ public TFile file(String pathString) { return file(TPath.parse(pathString)); } /** * Create the TFile that is repsented by the path and backed by the file system * * @param path the path that represents the file * @return the TFile object */ public TFile file(TPath path) { return new TFile(this, path); } /** * Create the TDirectory that is represented by the path and backed by the file system * * @param pathString The pat string that represento the directory * @return The TDirectory object * @see net.sf.cotta.TPath#parse(String) * @see #dir(TPath) */ public TDirectory dir(String pathString) { return dir(TPath.parse(pathString)); } /** * Create the TDirectory that is repersented by the path and backed by the file system * * @param path the path that represents the directory * @return the TDirectory object */ public TDirectory dir(TPath path) { return new TDirectory(this, path); } /** * Create a TFile instance is represented by URL. The supported URL are: * <table> * <tr> * <th>Protocol</th> * <th>Sample code</th> * </tr> * <tr> * <td>jar</td> * <td><code>getClass().getResource(this.resourceString);</code></td> * </tr> * <tr> * <td>file</td> * <td><code>new java.io.File("/tmp/file.txt").toURL();</code></td> * </tr> * </table> * * @param url The url that points to a zipTo entry in a zipTo file * @return The TFile instance * @throws IllegalArgumentException if the url is not a zipTo file url */ public static TFile fileFromUrl(URL url) { if (isJarUrl(url)) { return urlToFileEntryInJar(url); } else if (isFileUrl(url)) { return physicalFile(new File(url.getFile().replace("%20", " "))); } else { throw new IllegalArgumentException("Not supported url: " + url); } } private static TFile urlToFileEntryInJar(URL url) { String file = url.getFile(); int index = file.indexOf("!"); if (index == -1) { throw new IllegalArgumentException(url.toExternalForm() + " does not have '!' for a Jar URL"); } String jarUrlString = file.substring(0, index); URL jarUrl = url(jarUrlString); return physical().file(jarUrl.getFile().replace("%20", " ")); } private static URL url(String jarUrlString) { try { return new URL(jarUrlString); } catch (MalformedURLException e) { throw new RuntimeException("file portion is not a URL: " + jarUrlString, e); } } /** * Convert the Java file to a TFile directly by using a physical file system * * @param file the Java file object * @return The TFile that represents the Java file * @see net.sf.cotta.physical.PhysicalFileSystem * @see #physicalFile(java.io.File) * @deprecated use file(java.io.File) */ public static TFile fileFromJavaFile(File file) { return physical().file(file.getAbsolutePath()); } /** * Convert the Java file to a TDirectory directly by using a physical file system * * @param file the Java file object * @return The TDirectory that represents the Java file * @see net.sf.cotta.physical.PhysicalFileSystem * @see #physicalDir(java.io.File) * @deprecated use #physicalDir */ @Deprecated public static TDirectory directoryFromJavaFile(File file) { return physical().dir(file.getAbsolutePath()); } /** * The method to check is an URL can be converted to TFile or TDirectory * * @param url The url * @return true if the url protocol is supported */ public static boolean canConvertUrl(URL url) { return isJarUrl(url) || isFileUrl(url); } private static boolean isFileUrl(URL url) { return "file".equalsIgnoreCase(url.getProtocol()); } private static boolean isJarUrl(URL url) { return "jar".equalsIgnoreCase(url.getProtocol()); } private static final TFileFactory PHYSICAL = new TFileFactory(PhysicalFileSystem.instance); /** * File factory backed by a physical file system * * @deprecated use TFileFactory#phylical instead. This will become private */ @Deprecated public static final TFileFactory PHYSICAL_FILE_FACTORY = PHYSICAL; public static TFile physicalFile(String path) { return physical().file(path); } public static TFile physicalFile(File file) { return physicalFile(file.getAbsolutePath()); } public static TFile file(File file) { return physicalFile(file); } public static TDirectory physicalDir(String path) { return physical().dir(path); } public static TDirectory physicalDir(File file) { return physicalDir(file.getAbsolutePath()); } public static TDirectory dir(File file) { return physicalDir(file); } public String defaultEncoding() { return defaultEncoding; } /** * Creates a file factory with in-memory file system. Please note that this method returns a new in-memory * file factory each time * * @return in-memory file factory */ public static TFileFactory inMemory() { return new TFileFactory(new InMemoryFileSystem()); } /** * Retruns the shared file factory for the physical file system * * @return phylical file factory */ public static TFileFactory physical() { return PHYSICAL; } }