org.freedesktop.mime.MIMEEntry.java Source code

Java tutorial

Introduction

Here is the source code for org.freedesktop.mime.MIMEEntry.java

Source

/**
 * SSHTOOLS Limited licenses this file to you under the Apache
 * License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.freedesktop.mime;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.vfs2.FileObject;
import org.freedesktop.FreedesktopResource;
import org.freedesktop.util.Log;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Represents a single <i>alias</i> as described in the <a
 * http://standards.freedesktop
 * .org/shared-mime-info-spec/shared-mime-info-spec-latest.html">Shared
 * MIME-info Database Specification</a>
 */
public class MIMEEntry extends DefaultHandler implements FreedesktopResource {

    private final static List<String> streamable = Arrays.asList(new String[] { "application", "audio", "image",
            "message", "model", "multipart", "video", "x-content", "x-epoc" });

    private String name;
    private java.util.List<AliasEntry> aliases;
    private Properties comments;
    private List<String> subclasses;
    private List<String> acronyms;
    private List<String> expandedAcronyms;
    private String icon;
    private String genericIcon;
    private String family;
    private String type;

    public MIMEEntry(String family, String type, FileObject file) throws IOException {
        this.family = family;
        this.type = type;
        this.name = family + "/" + type;
        this.icon = icon == null ? this.name.replace('/', '-') : icon;

        acronyms = new ArrayList<String>();
        expandedAcronyms = new ArrayList<String>();
        aliases = new ArrayList<AliasEntry>();
        subclasses = new ArrayList<String>();
        comments = new Properties();
        genericIcon = family + "-x-generic";

        load(file);

        // Some types are implicity subclasses
        if (family.equals("text")) {
            subclasses.add("text/plain");
        } else if (streamable.contains(family)) {
            subclasses.add("application/octet-stream");
        }
    }

    /**
     * Add a type to the list that are considered <i>streamable</i>, i.e. those
     * that are implicitly subclasses of application/octet-stream. Streamable
     * types must be configured before the directory is scanned.
     * 
     * @param mimeType type to add
     */
    public static void addStreamableType(String mimeType) {
        streamable.add(mimeType);
    }

    /**
     * Remove a type from the list that are considered <i>streamable</i>, i.e.
     * those that are implicitly subclasses of application/octet-stream.
     * Streamable types must be configured before the directory is scanned.
     * 
     * @param mimeType type to remove
     */
    public static void removeStreamableType(String mimeType) {
        streamable.remove(mimeType);
    }

    public String getFamilyName() {
        return family;
    }

    public String getTypeName() {
        return type;
    }

    public Collection<String> getAcronyms() {
        // TODO support localisation
        return acronyms;
    }

    public Collection<String> getSubclasses() {
        return subclasses;
    }

    public Collection<AliasEntry> getAliases() {
        return aliases;
    }

    public String getInternalName() {
        return name;
    }

    public String getComment() {
        return getComment((String) null);
    }

    public Collection<String> getExpandedAcronyms() {
        // TODO support localisation
        return expandedAcronyms;
    }

    public String getComment(String language) {
        return comments == null ? null : comments.getProperty(language == null ? "" : language);
    }

    public String getComment(Locale locale) {
        return getComment(locale == null ? (String) null : locale.getLanguage());
    }

    public String getName() {
        return getInternalName();
    }

    public String getName(Locale locale) {
        return getInternalName();
    }

    public String getName(String language) {
        return getInternalName();
    }

    public String getIcon() {
        return icon;
    }

    public String getGenericIcon() {
        return genericIcon;
    }

    void load(FileObject file) throws IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);
        factory.setNamespaceAware(true);
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream in = file.getContent().getInputStream();
            try {
                Document document = builder.parse(in);
                build(document);
            } finally {
                in.close();
            }
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception e) {
            IOException ioe = new IOException("Failed to parse XML.");
            ioe.initCause(e);
            throw ioe;
        }

    }

    void build(Document document) throws IOException {
        /*
         * Make sure the type attribute of the rool element is the same as the
         * mime type determined by the filename
         */
        Element root = document.getDocumentElement();
        String typeValue = root.getAttribute("type");
        if (!name.equals(typeValue)) {
            throw new IOException("Root elements type attribute ('" + typeValue
                    + "') oes not match MIME type determined by filename ('" + name + "').");
        }

        NodeList children = document.getElementsByTagName("icon");
        buildIcon(children);
        children = document.getElementsByTagName("generic-icon");
        buildGenericIcon(children);
        children = document.getElementsByTagName("comment");
        buildComments(children);
        children = document.getElementsByTagName("alias");
        buildAlias(children);
        children = document.getElementsByTagName("sub-class-of");
        buildSubclass(children);
        children = document.getElementsByTagName("acronym");
        buildAcronym(children);
        children = document.getElementsByTagName("expanded-acronym");
        buildExpandedAcronym(children);

    }

    void buildAcronym(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node langAttr = child.getAttributes().getNamedItem("xml:lang");
            String key = langAttr != null ? langAttr.getTextContent() : "";
            if (!key.equals("")) {
                Log.warn("Localised acronyms are not yet supported.");
            } else {
                acronyms.add(child.getTextContent());
            }
        }
    }

    void buildExpandedAcronym(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node langAttr = child.getAttributes().getNamedItem("xml:lang");
            String key = langAttr != null ? langAttr.getTextContent() : "";
            if (!key.equals("")) {
                Log.warn("Localised expanded acronyms are not yet supported.");
            } else {
                expandedAcronyms.add(child.getTextContent());
            }
        }
    }

    void buildSubclass(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node typeAttr = child.getAttributes().getNamedItem("type");
            String type = typeAttr.getTextContent();
            if (!subclasses.contains(type)) {
                subclasses.add(type);
            }
        }
    }

    void buildAlias(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node typeAttr = child.getAttributes().getNamedItem("type");
            String type = typeAttr.getTextContent();
            aliases.add(new AliasEntry(type, getInternalName()));
        }
    }

    void buildComments(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node langAttr = child.getAttributes().getNamedItem("xml:lang");
            String key = langAttr != null ? langAttr.getTextContent() : "";
            Log.debug("Putting comment '" + child.getTextContent() + "' for locale " + key);
            comments.put(key, child.getTextContent());
        }
    }

    void buildIcon(NodeList children) {
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            Node langAttr = child.getAttributes().getNamedItem("lang");
            if (langAttr != null) {
                String lang = langAttr.getTextContent();
                Log.warn("Localised icons not yet supported [" + lang + "].");
            } else {
                icon = child.getTextContent();
            }
        }
    }

    void buildGenericIcon(NodeList children) {
        if (children.getLength() > 0) {
            Node child = children.item(0);
            genericIcon = child.getTextContent();
        }
    }

    @Override
    public String toString() {
        return "MIMEEntry [name=" + name + ", aliases=" + aliases + ", comments=" + comments + ", subclasses="
                + subclasses + ", acronyms=" + acronyms + ", expandedAcronyms=" + expandedAcronyms + ", icon="
                + icon + ", genericIcon=" + genericIcon + ", family=" + family + ", type=" + type + "]";
    }

}