com.crosstreelabs.cognitio.common.ExtensionLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.crosstreelabs.cognitio.common.ExtensionLoader.java

Source

/*
 * Copyright 2015 Crosstree Labs.
 *
 * Licensed 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 com.crosstreelabs.cognitio.common;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.security.AccessControlContext;
import java.util.StringTokenizer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExtensionLoader extends URLClassLoader {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionLoader.class);

    public ExtensionLoader(URL[] urls) {
        super(urls);
    }

    public ExtensionLoader(URL[] urls, ClassLoader cl) {
        super(urls, cl);
    }

    public ExtensionLoader(URL[] urls, ClassLoader cl, URLStreamHandlerFactory urlshf) {
        super(urls, cl, urlshf);
    }

    /**
     * Add given path(s) to the loader's classpath.
     * 
     * The single argument may optionally be a semi-colon (;) delimited list of
     * paths in much the same way a normal class definition would be.
     * 
     * Paths may either point to a jar, or a directory containing jars.
     * Directories should end with a slash (/), otherwise they will be
     * interpreted as jar paths.
     * 
    //     * A path may contain a wildcard name. 
    //     * 
    //     * Add classPath to this loader's classpath.
    //     * <p>
    //     * The classpath may contain elements that include a generic file base name.
    //     * A generic basename is a filename without the extension that may begin
    //     * and/or end with an asterisk. Use of the asterisk denotes a partial match.
    //     * Any files with an extension of ".jar" whose base name match the specified
    //     * basename will be added to this class loaders classpath. The case of the
    //     * filename is ignored. For example "/somedir/*abc" means all files in
    //     * somedir that end with "abc.jar", "/somedir/abc*" means all files that
    //     * start with "abc" and end with ".jar", and "/somedir/*abc*" means all
    //     * files that contain "abc" and end with ".jar".
     *
     */
    public void add(final String raw) throws MalformedURLException {
        LOGGER.error("Adding classpath: {}", raw);
        final String[] paths = raw.split(";");
        for (String path : paths) {
            handlePath(path);
        }

        //        String separators = File.pathSeparator;
        //        if (!separators.equals(";")) {
        //            separators += ";";
        //        }               
        //        String XXXXpathElement = "";
        //        for (StringTokenizer tokenizer = new StringTokenizer(raw, separators, false);
        //                tokenizer.hasMoreTokens();
        //                XXXXpathElement = tokenizer.nextToken()) {
        //            File XXXXfileElement;
        //            String bn = null;
        //
        //            if (XXXXpathElement.isEmpty()) {
        //                continue;
        //            }
        //
        //            XXXXfileElement = new File(XXXXpathElement);
        //            if (XXXXfileElement.getName().indexOf('*') != -1) {
        //                bn = XXXXfileElement.getName();
        //                XXXXfileElement = XXXXfileElement.getParentFile();
        //            }
        //
        //            if (!XXXXfileElement.isAbsolute() && XXXXpathElement.charAt(0) != '/' && XXXXpathElement.charAt(0) != '\\') {
        //                XXXXfileElement = new File(rootPath, XXXXfileElement.getPath());
        //            }
        //            try {
        //                XXXXfileElement = XXXXfileElement.getCanonicalFile();
        //            } catch (IOException thr) {
        //                LOGGER.warn("Skipping non-existent classpath element '" + XXXXfileElement + "' (" + thr + ").");
        //                continue;
        //            }
        //            if (!StringUtils.isBlank(bn)) {
        //                XXXXfileElement = new File(XXXXfileElement, bn);
        //            }
        //            if (classPathElements.contains(XXXXfileElement.getPath())) {
        //                LOGGER.warn("Skipping duplicate classpath element '" + XXXXfileElement + "'.");
        //                continue;
        //            } else {
        //                this.
        //                classPathElements.add(XXXXfileElement.getPath());
        //            }
        //
        //            if (!StringUtils.isBlank(bn)) {
        //                addJars(XXXXfileElement.getParentFile(), bn);
        //            } else if (!XXXXfileElement.exists()) {                                                 // s/never be due getCanonicalFile() above
        //                LOGGER.warn("Could not find classpath element '" + XXXXfileElement + "'");
        //            } else if (XXXXfileElement.isDirectory()) {
        //                addURL(createUrl(XXXXfileElement));
        //            } else if (XXXXfileElement.getName().toLowerCase().endsWith(".zip") || XXXXfileElement.getName().toLowerCase().endsWith(".jar")) {
        //                addURL(createUrl(XXXXfileElement));
        //            } else {
        //                LOGGER.warn("ClassPath element '" + XXXXfileElement + "' is not an existing directory and is not a file ending with '.zip' or '.jar'");
        //            }
        //        }
        //        LOGGER.info("Class loader is using classpath: \"" + classPath + "\".");
    }

    protected void handlePath(final String path) throws MalformedURLException {
        if (path == null || path.isEmpty()) {
            return;
        }

        if (!path.trim().toLowerCase().endsWith(File.separator)) {
            addJar(path);
            return;
        }

        // We're dealing with a directory, so let's find all jars
        File dir = new File(path);
        File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File file, String name) {
                return name.endsWith(".jar");
            }
        });
        for (File file : files) {
            addJar(file.getAbsolutePath());
        }
    }

    public void addJar(String path) throws MalformedURLException {
        File file;
        if (!path.endsWith(".jar")) {
            file = new File(path + ".jar");
        } else {
            file = new File(path);
        }

        if (!file.exists()) {
            LOGGER.warn("Could not find jar at {}", file);
            return;
        }
        if (!file.canRead()) {
            LOGGER.warn("Could not read jar at {}", file);
            return;
        }

        addURL(file.toURL());
    }

    //    private URL createUrl(File fe) {
    //        try {
    //            URL url = fe.toURI().toURL();
    //            LOGGER.diagln("Added URL: '" + url.toString() + "'");
    //            if (classPath.length() > 0) {
    //                classPath += File.pathSeparator;
    //            }
    //            this.classPath += fe.getPath();
    //            return url;
    //        } catch (MalformedURLException thr) {
    //            LOGGER.diagln("Classpath element '" + fe + "' could not be used to create a valid file system URL");
    //            return null;
    //        }
    //    }
}