JBoss.orgCommunity Documentation

Chapter 8. MIME types

8.1. JBoss DNA MIME type detectors
8.1.1. Aperture MIME type detector
8.2. Writing custom detectors
8.2.1. Creating the Maven 2 project

JBoss DNA often needs the ability to determine the MIME type for some binary content. When uploading content into a repository, we may want to add the MIME type as metadata. Or, we may want to make some processing decisions based upon the MIME type. So, JBoss DNA created a small pluggable framework for determining the MIME type by using the name of the file (e.g., extensions) and/or by reading the actual content. Technically, the framework delegates this to one or more extensions. And we've provided one extension that does a very good job at determining the MIME type from a large variety of file types. But if that isn't sufficient, you can always incorporate your own detector into JBoss DNA.

To use this system, you simply invoke a static method and supply the name of the content (e.g., the name of the file, with the extension) and the InputStream to the actual binary content:

MimeType.of(name,content)

The result is a String containing the MIME type (e.g., "text/plain") or null if the MIME type cannot be determined. Note that the name or InputStream may be null, making this a very versatile utility.

The principle component in this framework is the concept of a detector. A detector attempts to determine the MIME type using the name of the content (e.g., the file name) and the actual content itself. If the detector is able to determine the MIME type, it simply returns it as a string. If not, it merely returns null. Note, however, that a detector must be thread-safe.

Here is the interface:

package org.jboss.dna.graph.mimetype;
@ThreadSafe
public interface MimeTypeDetector {

    /**
     * Returns the MIME-type of a data source, using its supplied content and/or
     * its supplied name, depending upon the implementation. If the MIME-type 
     * cannot be determined, either a "default" MIME-type or null may 
     * be returned, where the former will prevent earlier registered MIME-type 
     * detectors from being consulted.
     * 
     * @param name The name of the data source; may be null.
     * @param content The content of the data source; may be null.
     * @return The MIME-type of the data source, or optionally null 
     * if the MIME-type could not be determined.
     * @throws IOException If an error occurs reading the supplied content.
     */
    String mimeTypeOf( String name,
                       InputStream content ) throws IOException;
}

Detectors can be added to the MimeType class using the addDetector(MimeTypeDetectorConfig config) method, where the MimeTypeDetectorConfig defines the name of the detector class, the name of the class loader, a name, and a description. It is also possible to set the ClassLoaderFactory that the MimeType singleton will use.

We'll next look at the MIME type detectors that are provided out by JBoss DNA out of the box, and how to write your own.

The ApertureMimeTypeDetector class is an implementation of MimeTypeDetector that uses the Aperture open-source library, which is a very capable utility for determining the MIME type for a wide range of file types, using both the file name and the actual content.

Creating a custom detector involves the following steps:

It's that simple.

The first step is to create the Maven 2 project that you can use to compile your code and build the JARs. Maven 2 automates a lot of the work, and since you're already set up to use Maven, using Maven for your project will save you a lot of time and effort. Of course, you don't have to use Maven 2, but then you'll have to get the required libraries and manage the compiling and building process yourself.

Note

JBoss DNA may provide in the future a Maven archetype for creating detector projects. If you'd find this useful and would like to help create it, please join the community.

Note

The dna-mimetype-detector-aperture project is a small, self-contained detector implementation that that you can use to help you get going. Starting with this project's source and modifying it to suit your needs may be the easiest way to get started. See the subversion repository: http://anonsvn.jboss.org/repos/dna/trunk/sequencers/dna-mimetype-detector-aperture/

You can create your Maven project any way you'd like. For examples, see the Maven 2 documentation. Once you've done that, just add the dependencies in your project's pom.xml dependencies section:


<dependency>
  <groupId>org.jboss.dna</groupId>
  <artifactId>dna-common</artifactId>
  <version>0.1</version>
</dependency>
<dependency>
  <groupId>org.jboss.dna</groupId>
  <artifactId>dna-graph</artifactId>
  <version>0.1</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
</dependency>

These are minimum dependencies required for compiling a detector. Of course, you'll have to add other dependencies that your sequencer needs.

As for testing, you probably will want to add more dependencies, such as those listed here:


<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.4</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-library</artifactId>
  <version>1.1</version>
  <scope>test</scope>
</dependency>
<!-- Logging with Log4J -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.4.3</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.14</version>
  <scope>test</scope>
</dependency>

After you've created the project, simply implement the MimeTypeDetector interface. And testing should be quite straightforward, MIME type detectors don't require any other components. In your tests, simply instantiate your MimeTypeDetector implementation, supply various combinations of names and/or InputStreams, and verify the output is what you expect.

To use in your application, create a MimeTypeDetectorConfig object with the name, description, and class information for your detector, and add to the MimeType class using the addDetector(MimeTypeDetectorConfig config) method. Then, just use the MimeType class.