org.echocat.nodoodle.NodoodleInformationFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.echocat.nodoodle.NodoodleInformationFactory.java

Source

/*****************************************************************************************
 * *** BEGIN LICENSE BLOCK *****
 *
 * Version: MPL 2.0
 *
 * echocat NoDoodle, Copyright (c) 2010-2012 echocat
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * *** END LICENSE BLOCK *****
 ****************************************************************************************/

package org.echocat.nodoodle;

import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.jar.Attributes.Name;
import java.util.jar.Manifest;

import static java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE;
import static java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static org.apache.commons.collections.IteratorUtils.*;

public class NodoodleInformationFactory {

    private final Class<?> _baseClass;

    public NodoodleInformationFactory() {
        this(NodoodleInformationFactory.class);
    }

    public NodoodleInformationFactory(Class<?> baseClass) {
        _baseClass = baseClass;
    }

    public String getManifestValue(Name mainAttributes) {
        final String result;
        final Manifest manifest = getManifest();
        if (manifest != null) {
            final Object plainVersion = manifest.getMainAttributes().get(mainAttributes);
            if (plainVersion != null) {
                result = plainVersion.toString();
            } else {
                result = null;
            }
        } else {
            result = null;
        }
        return result;
    }

    public String getImplementationVersion() {
        return getManifestValue(IMPLEMENTATION_VERSION);
    }

    public String getImplementationTitle() {
        return getManifestValue(IMPLEMENTATION_TITLE);
    }

    public Manifest getManifest() {
        final Manifest manifest;
        final URL manifestUrl = findManifestUrl();
        if (manifestUrl != null) {
            try {
                final InputStream is = manifestUrl.openStream();
                try {
                    manifest = new Manifest(is);
                } finally {
                    IOUtils.closeQuietly(is);
                }
            } catch (IOException e) {
                throw new RuntimeException("Could not read manifest from " + manifestUrl + ".", e);
            }
        } else {
            manifest = null;
        }
        return manifest;
    }

    private URL findManifestUrl() {
        final String className = _baseClass.getName();
        final String classResourceName = className.replace('.', '/') + ".class";
        final Iterator<URL> i = findResources(classResourceName);
        if (!i.hasNext()) {
            throw new IllegalStateException("Could not find resource of " + className + ".");
        }
        URL manifestUrl = null;
        while (i.hasNext() && manifestUrl == null) {
            final URL classUrl = i.next();
            final String base = getBaseFor(classUrl, classResourceName);
            if (base != null) {
                manifestUrl = findManifestUrlStartsWith(base);
            }
        }
        return manifestUrl;
    }

    private String getBaseFor(URL classUrl, String classResourceName) {
        final String classUrlString = classUrl.toString();
        final int cutBefore = classUrlString.lastIndexOf(classResourceName);
        final String base;
        if (cutBefore > 0 && classUrlString.endsWith(classResourceName)) {
            base = classUrlString.substring(0, cutBefore);
        } else {
            base = null;
        }
        return base;
    }

    private URL findManifestUrlStartsWith(String manifestUrlStartsWith) {
        URL manifestUrl = null;
        final Iterator<URL> j = findResources(MANIFEST_NAME);
        while (j.hasNext() && manifestUrl == null) {
            final URL currentManifestUrl = j.next();
            if (currentManifestUrl.toString().startsWith(manifestUrlStartsWith)) {
                manifestUrl = currentManifestUrl;
            }
        }
        return manifestUrl;
    }

    Iterator<URL> findResources(String name) {
        try {
            final Enumeration<URL> enumeration = _baseClass.getClassLoader().getResources(name);
            //noinspection unchecked
            return enumeration != null ? asIterator(enumeration) : emptyIterator();
        } catch (IOException e) {
            throw new RuntimeException("Could not find all resources of " + name + ".", e);
        }
    }
}