NewFilenameExtensionForVFSAPI

Version 2.1 by Jean SIMARD on 2016/01/28 17:53

In this tutorial, you'll find a way to tell TrueVFS about your new filename extension without breaking existing configuration of XWiki.

VFS API allows you to play with the files inside an archive: you may store the archive as an attachment of a page (and not all of the files in the archive) and still get access to the files inside the archive.  This API is based on TrueVFS library which identify the type of the archive based on the filename extension.  For example, *.zip will be recognized as a ZIP archive but *.xff (see XFF Filter will not, even if it's also an archive compressed as a ZIP.

Here are the few steps to understand in order to make it possible.  You can find the complete project (pom.xml, the class and resources) as a ZIP attached to this page.

Register you filename extension in TrueVFS configuration

First, you have to register your filename extension to TrueVFS.  You could do like explained in TrueVFS documentation.  We'll use the JarDriver for the ZIP format.

// This should obtain the global configuration.
TConfig config = TConfig.current();
// Configure custom application file format.
config.setArchiveDetector(new TArchiveDetector("xff", new JarDriver()));

However, doing like this, you will remove every previous configuration of TrueVFS and only your filename extension will be considered.  To append your filename extension to the existing, we'll use another TArchiveDetector constructor.

// This should obtain the global configuration.
TConfig config = TConfig.current();
// Configure custom application file format.
config.setArchiveDetector(new TArchiveDetector(config.getArchiveDetector(), "xff", new JarDriver()));

OK, with this piece of code, you modifying the global configuration of TrueVFS.  However, you have to execute this piece of Java code; and better be at the launch of XWiki.  To realize that, we'll write an EventListener

Write the event listener to register the new configuration at launch

First of all, an EventListener must be a component.  You can do it in Java or with Groovy in a wiki page.  We'll see how to do it in Java.

It'll be a class that implements org.xwiki.observation.EventListener.  Then you'll have to choose which kind of events it'll listen by implementing the getEvents method.  In our example, we want it to listen to events that happen early in the boot process of XWiki.  We'll listen to the same event than VFS API is listening (see getEvents in VfsAttachDriverRegistrationListener.java): the event ApplicationReadyEvent.

public List<Event> getEvents()
{
   return Arrays.<Event>asList(new ApplicationReadyEvent());
}

And finally, we'll put our global configuration code in the onEvent method.

public void onEvent(Event event, Object source, Object data) {
    TConfig config = TConfig.current();
    config.setArchiveDetector(new TArchiveDetector(config.getArchiveDetector(), "xff", new JarDriver()));
}

Create the event listener component

Last thing but not least, you'll have to do the magic for the component (annotations at the beginning of the class and the file component.txt).

First of all, prefix your class with the needed annotations.

@Component
@Named("vfsXffDriver")
@Singleton
public class VfsLpzipDriverRegistrationListener implements EventListener {
   ...
}

Then add you new class to the list of components in the file src/main/resources/META-INF/components.txt.

my.package.VfsXffDriverRegistrationListener

Here you are.  We can now proceed to the build.

Creating the build file pom.xml

For the build, it's a pretty standard pom.xml with 2 dependencies for TrueVFS, 1 for XWiki components, 1 for XWiki event listener and finally one for the implementations of org.xwiki.bridge.event.ApplicationReadyEvent.

<dependencies>
   <dependency>
       <groupId>org.xwiki.commons</groupId>
       <artifactId>xwiki-commons-component-api</artifactId>
       <version>${commons.version}</version>
   </dependency>
   <dependency>
       <groupId>org.xwiki.commons</groupId>
       <artifactId>xwiki-commons-observation-api</artifactId>
       <version>${commons.version}</version>
   </dependency>
   <dependency>
     <groupId>org.xwiki.platform</groupId>
     <artifactId>xwiki-platform-bridge</artifactId>
         <version>${platform.version}</version>
   </dependency>
   <dependency>
       <groupId>net.java.truevfs</groupId>
       <artifactId>truevfs-access</artifactId>
       <version>0.11.0</version>
   </dependency>
   <dependency>
       <groupId>net.java.truevfs</groupId>
       <artifactId>truevfs-comp-zipdriver</artifactId>
       <version>0.11.0</version>
   </dependency>
</dependencies>
Tags:
   

Get Connected