All Downloads are FREE. Search and download functionalities are using the official Maven repository.

metridoc.runner.MetridocRunner Maven / Gradle / Ivy

There is a newer version: 0.30
Show newest version
/*
 * Copyright 2010 Trustees of the University of Pennsylvania Licensed under the
 * Educational Community 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.osedu.org/licenses/ECL-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 metridoc.runner;

import java.io.*;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

/**
 * Created by IntelliJ IDEA.
 * User: tbarker
 * Date: 2/4/12
 * Time: 8:26 PM
 */
public class MetridocRunner {

    public static final int BAD_URI_SYNTAX = 1;
    public static final int COULD_NOT_OPEN_CURRENT_JAR = 2;
    public static final int COULD_NOT_OPEN_OR_MANIPULATE_FILE = 3;
    public static final int COULD_NOT_LOAD_CONSOLE = 4;
    public static final int COULD_NOT_RUN_COMMAND = 5;
    public static final String METRIDOC_CONSOLE = "metridoc.console.MetridocConsole";
    public static final String SET_CONSOLE_CLASS_LOADER = "setClassLoader";
    public static final String RUN_CONSOLE_COMMAND = "runConsoleCommand";
    public static final boolean DO_LOGGING = Boolean.valueOf(System.getProperty("metridoc.runner.logging", "false"));

    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    public static void main(String[] args) {
    	JarFile thisJar = getCurrentFile();
        URL[] urlArray = createLibJarCopies(thisJar);

        log("the following number of urls will be added to the classpath: " + urlArray.length);
        for (URL url : urlArray) {
            log("adding the following url to classpath: " + url.toString());
        }
        runJob(urlArray, args);
    }
    
    private static JarFile getCurrentFile(){
    	ProtectionDomain domain = MetridocRunner.class.getProtectionDomain();
        URL location = domain.getCodeSource().getLocation();
        File thisFile = null;
        try {
            thisFile = new File(location.toURI());
        } catch (URISyntaxException e) {
            error(e, BAD_URI_SYNTAX);
        }

        JarFile thisJar = null;
        try {
            thisJar = new JarFile(thisFile);
        } catch (IOException e) {
            error(e, COULD_NOT_OPEN_CURRENT_JAR);
        }
        return thisJar;
    }
    
    private static void runJob(URL[] urlArray, String[] args){
    	 URLClassLoader urlClassLoader = new URLClassLoader(urlArray);
         Method runConsoleCommand = null;
         Object console = null;
         try {
             Class consoleClass = urlClassLoader.loadClass(METRIDOC_CONSOLE);
             console = consoleClass.newInstance();
             Method setClassLoader = consoleClass.getMethod(SET_CONSOLE_CLASS_LOADER, ClassLoader.class);
             setClassLoader.invoke(console, urlClassLoader);
             runConsoleCommand = consoleClass.getMethod(RUN_CONSOLE_COMMAND, String[].class);
         } catch (Exception e) {
             error(e, COULD_NOT_LOAD_CONSOLE);
         }

         Thread.currentThread().setContextClassLoader(urlClassLoader);
         try {
             Object[] params = new Object[1];
             params[0] = args;
             runConsoleCommand.invoke(console, params);
         } catch (Exception e) {
             error(e, COULD_NOT_RUN_COMMAND);
         }
    }
    
    private static  URL[] createLibJarCopies(JarFile mainJar){
    	Enumeration entries = mainJar.entries();
        List urls = new ArrayList();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            String entryName = entry.getName();
            boolean isJar = entryName.startsWith("META-INF/lib/") && entryName.endsWith(".jar");
            if (isJar) {
                log("Preparing to add entry " + entryName + " to the classpath");
                String temporaryFileName = entryName.replace("/", "_");
                try {
                    File jarTempFile = File.createTempFile(temporaryFileName, ".tmp");
                    jarTempFile.deleteOnExit();
                    OutputStream outputStream = new FileOutputStream(jarTempFile);
                    InputStream inputStream = mainJar.getInputStream(entry);
                    copy(inputStream, outputStream);
                    log(jarTempFile.toURI().toURL().toString());
                    urls.add(jarTempFile.toURI().toURL());
                } catch (IOException e) {
                    error(e, COULD_NOT_OPEN_OR_MANIPULATE_FILE);
                }
            }
        }
        return urls.toArray(new URL[urls.size()]);
    }
    /**
     * Basically stolen from IOUtils in apache commons.  Just wanted to avoid as much dependency issues as possible
     * 

* TODO: maybe we should do this in parallel to make it faster? * * @param inputStream stream that will be copied * @param outputStream destination for the stream * @throws IOException occurrs if copy operation occurs */ private static void copy(InputStream inputStream, OutputStream outputStream) throws IOException { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int n = 0; while (-1 != (n = inputStream.read(buffer))) { outputStream.write(buffer, 0, n); } } private static void log(String message) { if (DO_LOGGING) { System.out.println(message); } } private static void error(Exception exception, int exitCode) { exception.printStackTrace(); System.exit(exitCode); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy