Mime Type Extension

This document describes how to recognize different file types we use.

Introduction

Originally, Multipurpose Internet Mail Extensions (MIME) was invented to attach binary data to e-mail. MIME's use, however, has grown beyond describing the content of e-mail to describing content type in general. Basically, this is just a way to categorize file types. File type consists of a type and subtype, for example image/jpg. Here image is type and jpg is subtype. Which means image files in jpeg format. You can give any name to any file type. But, of course, meaningful names are preferable. In our domain we have seismic/x-segy, horizon/x-xhz and so on. Which means seismic data is in SEG-Y format, horizon data in xhz (xml actually) format. Prefix x- means this type is not standard. This is just a convention. The Internet Assigned Numbers Authority (IANA) has directory of all MIME types. You can find image/jpg there, but there is no seismic/segy.

MIME type resolvers

The NetBeans platform has mechanism to resolve (map file to literal string) MIME type. This is abstract class MIMEResolver. Everyone who wants to add new resolver should extend this abstract class and override one method:

FINDMIMETYPE

public String findMIMEType(FileObject fo);

To let NetBeans know about this resolver you have to put the class name into META-INF/services/org.openide.filesystems.MIMEResolver file. Every time NetBeans should recognize file type it passes FileObject to all resolvers until it finds one which returns not null. NetBeans has powerful generic resolver which is used in most cases. Unfortunately, it doesn't allow to change file extension mapping on the fly. In other words, user can not change rules how to recognize files. So, new MIME resolver was introduced:

DYNAMICMIMERESOLVER

public class DynamicMimeResolver extends MIMEResolver {
    @Override
    public String findMIMEType(FileObject fo) {
        String ext = fo.getExt();
        if (ext.length()>0) {
            return MimeRepository.getDefault().getMime(ext);
        } else {
            if (!fo.isFolder() && fo.getName().endsWith("CIND")) 
                return "seismic/promax";
            return null;
        }
    }
}

It has one hard coded MIME type. Rest of mapping is coming from MimeRepository class which reads layer.xml file and keeps all data in memory. Layer.xml has configuration data describing all types. This is a small fragment:

MIMEREPOSITORY

<folder name = "MimeTypes">
    <folder name ="seismic">
        <folder name ="x-segy">
            <attr name="name" stringvalue = "Segy"/>
            <attr name="ext" stringvalue = "segy sgy y"/>
        </folder>
        <folder name ="x-tseismic">
            <attr name="name" stringvalue = "Transposed-Seismic"/>
            <attr name="ext" stringvalue = "xts"/>
        </folder>
    </folder>
</folder>

As you can see attribute name gives human readable name for this type, attribute ext gives extension list. This layer.xml file is located inside jar and is read-only. NetBeans has a nice feature, which allows to "override" this file. All changes are stored in working directory, but logically everything looks like you changed the layer.xml file. So, you can think about values in layer.xml as default values. When you make fresh installation layer.xml defines all mapping rules. Then you can modify them.

Right now there isn't any GUI to do that, just API. Class DataUtil has a static method:

DATAUTIL - SETEXTENSIONS

/**
* Set extensions for some mime type. All changes are stored in working directory.
* @param mime type
* @param exts array of extensions to set
* @throws IOException
*/
public static void setExtensions(String mime, String[] exts) throws IOException{
    MimeRepository.getDefault().setExtensions(mime, exts);
}
Also it has several more methods related to mime types: 

DATAUTIL - MIME TYPES METHODS

/**
* Returns all registered MIME types for data type. For example,
* horizon data may have several mime types- horizon/x-xhz, horizon/x-ascii, ...
* @param dataType data type name.
* @return Array of MIME types.
*/
public static String[] getMimeTypes(String dataType){...}
/**
* Returns human readable description (Segy files, for example)
* @param mime MIME type
* @return return Returns human readable description
*/
public static String getMimeDescription(String mime){...}
/**
* Return all registered file extensions.
* @param mime MIME type
* @return array of file extensions.
*/
public static String[] getExtensions(String mime){...}

These methods are supposed to be used when you create File Chooser, for example. Besides file chooser mime types are used to associate icons, actions, data loaders, pop up menus.