Browse DevX
Sign up for e-mail newsletters from DevX


Extend the JDK Classes with Jakarta Commons, Part III : Page 2

Explore Jakarta Commons components that enable you to parse arguments in a command-line application, connect to various file systems at the same time, allow an application to uniformly access configurations loaded from various sources, and pool any object.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Commons Virtual File System (VFS) provides an abstraction layer for accessing various file systems uniformly. This component can be configured to connect to one or more file systems at the same time. This is analogous to the mount facility in the Linux operating system.

VFS supports the following file systems:

  • Local files – The local files and folders (file://)
  • Zip, jar, tar, tgz, tbz2, gzip, bzip2 – Various compression formatted files that can be processed transparently (zip://, jar://, etc.)
  • CIFS – Samba server or a Windows share (smb://)
  • FTP – FTP server (ftp://)
  • HTTP and HTTPS (http://)
  • SFTP – SSH or SCP server (sftp://)
  • Temporary files (tmp://)
  • WebDAV – Web-based Distributed Authoring and Versioning (webdav://)
  • Resource from class loader – Loading classes or other resources using the class loader (res://)

You'll find the complete syntax for the supported protocols URI here and the uses for the API at a high level here.

This component is very useful for applications that require seamless access to various file types. For instance, a desktop search tool is a very good analogy for this framework. It lets a user search for a file or file contents in various file formats. Integrating a Windows Explorer-like feature to a Java application is another good analogy.

The sample application is a tool that uses Commons VFS for searching in folders as well as in zip and jar files. The application doesn't have a user interface, but a test case demonstrates it well. You'll find the application and test sources in the package in.co.narayanan.commons.vfs. In order to run the sample application, download the source archive and run the Ant build script to create the Commons VFS library. The Ant script is smart enough to download other dependant library files. You can start the sample application by running the JUnit test case class in.co.narayanan.commons.vfs.TestSearchBuddy.

The basic idea of using the Commons VFS is to create providers for each supported file type and add to the DefautFileSystemManager instance (referred to as manager hereafter). A reference to the FileObject instance needs to fetched, using resolveFile methods in the manager for further processing. The manager and the FileObject have various other useful methods that are worth exploring in the javadocs. The following paragraphs describe how you can use the Commons VFS API in a search tool.

Listing 6 presents a code snippet from the in.co.narayanan.commons.vfs.SearchBuddy class used to initialize the DefaultFileSystemManager class.

Listing 6. Initializing the File System Manager
/** * Initialize the DefaultFileSystemManager to support * file, zip and jar providers. A virtual file system * is created and passed to the SearchableVirtualFileSystem * decorator class. * * @throws SearchException Error in initializing the file * FileSystemManager */ private void init() throws SearchException { defFileSysMgr = new DefaultFileSystemManager(); try { defFileSysMgr.addProvider("file", new DefaultLocalFileProvider()); defFileSysMgr.addProvider("zip", new ZipFileProvider()); defFileSysMgr.addProvider("jar", new JarFileProvider()); defFileSysMgr.init(); // Create the virtual file system VirtualFileSystem vfs = (VirtualFileSystem)defFileSysMgr.createVirtualFileSystem("vfs://").getFileSystem(); searchableVfs = new SearchableVirtualFileSystem(vfs); } catch (FileSystemException e) { throw new SearchException("Unable to initialize the FileSystemManager.", e); } }

The highlighted lines add providers for searching in the local file system, zip files, and jar files. The code creates an instance of a VirtualFileSystem, which it will use for mounting other file systems. (You will see more details on this and the SearchableVirtualFileSystem class shortly.)

Listing 7 is a code snippet from the test case class TestSearchBuddy. It illustrates how the sample application can be used to search files.

Listing 7. Usage of the Search Tool
/** * Adds the folder, zip, and a jar file to search * * @throws Exception Error in the test. */ public void testSearchInZips() throws Exception { SearchBuddy searchTool = new SearchBuddy(); searchTool.addSearchableZip("testroot.zip"); searchTool.addSearchableJar("testjar.jar"); searchTool.addSearchableFolder("."); System.out.println("Searching for news.txt"); searchTool.search("news", "txt"); System.out.println("Searching for Range.class"); searchTool.search("range", "class"); System.out.println("Searching for test.xml"); searchTool.search("test", "xml"); System.out.println("Searching for *.properties"); searchTool.search(null, "properties"); searchTool.close(); }

The highlighted lines add the zip and jar files to search. The search method is later called with the file name and extension for which to search.

Listing 8 presents a code snippet from the SearchBuddy class that demonstrates mounting various file types to the virtual file system.

Listing 8. Code for Mounting a Zip File to the Virtual File System
/** * Mount a zip file to the searchable virtual * file system. * * @param pathToFolder Absolute or relative path to the zip file. * @throws SearchException Error while adding the zip file to the virtual file system. */ public void addSearchableZip(String pathToZip) throws SearchException { File zipFile = new File(pathToZip); if(!zipFile.exists()) { throw new SearchException("Invalid zip file path"); } try { FileObject zipFileObject = defFileSysMgr.toFileObject(zipFile); searchableVfs.addJunction("/" + zipFile, defFileSysMgr.resolveFile("zip:" + zipFileObject + "!/")); } catch (FileSystemException e) { throw new SearchException("Unable to add zip file to the virtual file system", e); } }

The zip file is mounted by calling the addJunction method in the VirtualFileSystem class. The junctions (or the mount points) are cached in the decorator class SearchableVirtualFileSystem, which will be used later during the search operation.

Listing 9 presents the code used for searching the mounted file systems.

Listing 9. Search Operation
Class SearchBuddy /** * Delegate the search call to the Searchable virtual file * system decorator. * * @param fileNamePart Name of the file. * @param extension Extension to search * @throws SearchException Error from the VirtualFileSystem when searching for file. */ public void search(String fileNamePart, String extension) throws SearchException { searchableVfs.search(fileNamePart, extension); } Class SearchableVirtualFileSystem /** * Iterate the junctions to search for the given file name. * * @param fileNamePart File name to search * @param extension Extension to search * @throws SearchException */ public void search(String fileNamePart, String extension) throws SearchException { try { Iterator<String> searchPoints = junctions.iterator(); FileObject matchingFiles[]; while(searchPoints.hasNext()) { String searchPoint = searchPoints.next(); FileObject searchRoot = vfs.resolveFile(searchPoint); filter.setExtension(extension); filter.setFileNamePart(fileNamePart); matchingFiles = searchRoot.findFiles(filter); for(FileObject file : matchingFiles) { System.out.println("Result:" + file); } } } catch (FileSystemException e) { throw new SearchException("Search failed", e); } }

The search method iterates the mounted file systems, resolves the root, and calls the findFiles method in the FileObject class by passing a search filter. The result gets printed to the console. The primary responsibility of the decorator class SearchableVirtualFileSystem is to remember the mounted file systems. Other method calls are delegated to the wrapped VirtualFileSystem instance.

The source files in the sample application contain a good amount of documentation to explain the code.

Using the Common VFS framework in desktop and server applications totally isolates the consumer program from file type-specific code, thereby improving the application's modularity and making development easier.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date