001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 * $Id$
013 */
014
015package org.nuxeo.runtime.osgi;
016
017import java.net.URL;
018
019import org.nuxeo.runtime.RuntimeService;
020import org.nuxeo.runtime.api.Framework;
021import org.nuxeo.runtime.model.impl.DefaultRuntimeContext;
022import org.osgi.framework.Bundle;
023import org.osgi.framework.Constants;
024
025/**
026 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
027 */
028public class OSGiRuntimeContext extends DefaultRuntimeContext {
029
030    protected final Bundle bundle;
031
032    protected String hostBundleId;
033
034    protected Bundle hostBundle;
035
036    public OSGiRuntimeContext(Bundle bundle) {
037        this(Framework.getRuntime(), bundle);
038    }
039
040    public OSGiRuntimeContext(RuntimeService runtime, Bundle bundle) {
041        super(runtime);
042        this.bundle = bundle;
043        // workaround to correctly handle fragment class loaders
044        hostBundleId = (String) bundle.getHeaders().get(Constants.FRAGMENT_HOST);
045        if (hostBundleId != null) {
046            int p = hostBundleId.indexOf(';');
047            if (p > -1) { // remove version or other extra information if any
048                hostBundleId = hostBundleId.substring(0, p);
049            }
050        }
051    }
052
053    @Override
054    public Bundle getBundle() {
055        return bundle;
056    }
057
058    @Override
059    public URL getResource(String name) {
060        URL url = null;
061        if (hostBundleId != null) {
062            url = getHostBundle().getResource(name);
063        } else {
064            url = bundle.getResource(name);
065        }
066        if (url == null) {
067            url = Framework.getResourceLoader().getResource(name);
068        }
069        return url;
070    }
071
072    @Override
073    public URL getLocalResource(String name) {
074        URL url = null;
075        if (hostBundleId != null) {
076            url = getHostBundle().getEntry(name);
077        } else {
078            url = bundle.getEntry(name);
079        }
080        if (url == null) {
081            url = Framework.getResourceLoader().getResource(name);
082        }
083        return url;
084    }
085
086    @Override
087    public Class<?> loadClass(String className) throws ClassNotFoundException {
088        try {
089            if (hostBundleId != null) { // workaround to handle fragment bundles that doesn't have class loaders
090                return getHostBundle().loadClass(className);
091            }
092            return bundle.loadClass(className);
093        } catch (ClassNotFoundException e) {
094            return Framework.getResourceLoader().loadClass(className);
095        }
096    }
097
098    public Bundle getHostBundle() {
099        if (hostBundleId != null) {
100            if (hostBundle == null && runtime instanceof OSGiRuntimeService) {
101                hostBundle = ((OSGiRuntimeService) runtime).findHostBundle(bundle);
102            }
103        }
104        return hostBundle;
105    }
106
107}