001/*
002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.webengine.loader;
020
021import java.io.File;
022import java.io.IOException;
023import java.net.URL;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.nuxeo.ecm.webengine.WebEngine;
028import org.nuxeo.ecm.webengine.loader.store.FileResourceStore;
029import org.nuxeo.ecm.webengine.scripting.GroovyScripting;
030import org.osgi.framework.Bundle;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class WebLoader {
036
037    private static final Log log = LogFactory.getLog(WebLoader.class);
038
039    protected final WebEngine engine;
040
041    protected final ReloadingClassLoader classLoader;
042
043    protected final GroovyScripting gScripting; // TODO refactor groovy loading
044
045    public WebLoader(WebEngine engine) {
046        this.engine = engine;
047        File root = engine.getRootDirectory();
048        classLoader = new ReloadingClassLoader(getParentLoader());
049        gScripting = new GroovyScripting(classLoader);
050        addClassPathElement(new File(root, "WEB-INF/classes"));
051    }
052
053    public WebEngine getEngine() {
054        return engine;
055    }
056
057    /**
058     * Adds a class or resource container to the reloading class loader. The container is either a jar or a directory.
059     */
060    public void addClassPathElement(File container) {
061        try {
062            classLoader.addResourceStore(new FileResourceStore(container));
063            gScripting.getGroovyClassLoader().addURL(container.toURI().toURL());
064        } catch (IOException e) {
065            log.error("Failed to create file store: " + container, e);
066        }
067    }
068
069    public URL getResource(String name) {
070        return classLoader.getResource(name);
071    }
072
073    public Class<?> loadClass(String name) throws ClassNotFoundException {
074        return classLoader.loadClass(name);
075    }
076
077    public ReloadingClassLoader getClassLoader() {
078        return classLoader;
079    }
080
081    public GroovyScripting getGroovyScripting() {
082        return gScripting;
083    }
084
085    public void flushCache() {
086        log.info("Flushing loader cache");
087        classLoader.reload();
088        gScripting.clearCache();
089    }
090
091    public ClassProxy getGroovyClassProxy(String className) throws ClassNotFoundException {
092        return new StaticClassProxy(gScripting.loadClass(className));
093    }
094
095    public ClassProxy getClassProxy(String className) throws ClassNotFoundException {
096        return new StaticClassProxy(classLoader.loadClass(className));
097    }
098
099    public ClassProxy getClassProxy(Bundle bundle, String className) throws ClassNotFoundException {
100        return new StaticClassProxy(bundle.loadClass(className));
101    }
102
103    public static ClassLoader getParentLoader() {
104        ClassLoader cl = Thread.currentThread().getContextClassLoader();
105        return cl == null ? GroovyScripting.class.getClassLoader() : cl;
106    }
107
108}