001/*
002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 */
017package org.nuxeo.runtime.tomcat;
018
019import java.io.File;
020import java.io.IOException;
021import java.lang.reflect.Method;
022import java.net.URL;
023import java.net.URLClassLoader;
024import java.util.ArrayList;
025
026import org.apache.catalina.Lifecycle;
027import org.apache.catalina.LifecycleEvent;
028import org.apache.catalina.LifecycleListener;
029import org.apache.catalina.core.ContainerBase;
030import org.nuxeo.osgi.application.FrameworkBootstrap;
031
032import sun.misc.ClassLoaderUtil;
033
034/**
035 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
036 */
037public class NuxeoDeployer implements LifecycleListener {
038
039    protected String home = "nxserver";
040
041    protected FrameworkBootstrap bootstrap;
042
043    public void setHome(String home) {
044        this.home = home;
045    }
046
047    public String getHome() {
048        return home;
049    }
050
051    @Override
052    public void lifecycleEvent(LifecycleEvent event) {
053        Lifecycle lf = event.getLifecycle();
054        if (lf instanceof ContainerBase) {
055            ContainerBase container = (ContainerBase) lf;
056            handleEvent(container, event);
057        }
058    }
059
060    protected void handleEvent(ContainerBase container, LifecycleEvent event) {
061        try {
062            ClassLoader parentCl = container.getParentClassLoader();
063            String type = event.getType();
064            if (type == Lifecycle.BEFORE_START_EVENT) {
065                File homeDir = resolveHomeDirectory();
066                File bundles = new File(homeDir, "bundles");
067                File lib = new File(homeDir, "lib");
068                File deployerJar = FrameworkBootstrap.findFileStartingWidth(bundles, "nuxeo-runtime-deploy");
069                File commonJar = FrameworkBootstrap.findFileStartingWidth(bundles, "nuxeo-common");
070                if (deployerJar == null || commonJar == null) {
071                    System.out.println("Deployer and/or common JAR (nuxeo-runtime-deploy* | nuxeo-common*) not found in "
072                            + bundles);
073                    return;
074                }
075                ArrayList<URL> urls = new ArrayList<URL>();
076                File[] files = lib.listFiles();
077                if (files != null) {
078                    for (File f : files) {
079                        if (f.getPath().endsWith(".jar")) {
080                            urls.add(f.toURI().toURL());
081                        }
082                    }
083                }
084                files = bundles.listFiles();
085                if (files != null) {
086                    for (File f : files) {
087                        if (f.getPath().endsWith(".jar")) {
088                            urls.add(f.toURI().toURL());
089                        }
090                    }
091                }
092                urls.add(homeDir.toURI().toURL());
093                urls.add(new File(homeDir, "config").toURI().toURL());
094                URLClassLoader cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), parentCl);
095                // URLClassLoader cl = new URLClassLoader(new URL[]
096                // {deployerJar.toURI().toURL(),
097                // commonJar.toURI().toURL(),
098                // xercesJar.toURI().toURL(),
099                // new File(homeDir, "config").toURI().toURL() // for log4j
100                // config
101                // }, parentCl);
102                System.out.println("# Running Nuxeo Preprocessor ...");
103                Class<?> klass = cl.loadClass("org.nuxeo.runtime.deployment.preprocessor.DeploymentPreprocessor");
104                Method main = klass.getMethod("main", String[].class);
105                main.invoke(null, new Object[] { new String[] { homeDir.getAbsolutePath() } });
106                System.out.println("# Preprocessing done.");
107                ClassLoaderUtil.releaseLoader(cl);
108            }
109        } catch (IOException | ReflectiveOperationException e) {
110            throw new RuntimeException("Failed to handle event", e);
111        }
112    }
113
114    protected File resolveHomeDirectory() {
115        String path;
116        if (home.startsWith("/")) {
117            path = home;
118        } else {
119            path = getTomcatHome() + "/" + home;
120        }
121        return new File(path);
122    }
123
124    public String getTomcatHome() {
125        String tomcatHome = System.getProperty("catalina.base");
126        if (tomcatHome == null) {
127            tomcatHome = System.getProperty("catalina.home");
128        }
129        return tomcatHome;
130    }
131
132}