001/*
002 * (C) Copyright 2006-2011 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 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.runtime.osgi;
023
024import java.net.URL;
025
026import org.nuxeo.runtime.AbstractRuntimeService;
027import org.nuxeo.runtime.RuntimeService;
028import org.nuxeo.runtime.api.Framework;
029import org.nuxeo.runtime.model.impl.DefaultRuntimeContext;
030import org.osgi.framework.Bundle;
031import org.osgi.framework.Constants;
032
033/**
034 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
035 */
036public class OSGiRuntimeContext extends DefaultRuntimeContext {
037
038    protected final Bundle bundle;
039
040    protected String hostBundleId;
041
042    protected Bundle hostBundle;
043
044    public OSGiRuntimeContext(Bundle bundle) {
045        this(Framework.getRuntime(), bundle);
046    }
047
048    public OSGiRuntimeContext(RuntimeService runtime, Bundle bundle) {
049        super(runtime);
050        this.bundle = bundle;
051        // workaround to correctly handle fragment class loaders
052        hostBundleId = (String) bundle.getHeaders().get(Constants.FRAGMENT_HOST);
053        if (hostBundleId != null) {
054            int p = hostBundleId.indexOf(';');
055            if (p > -1) { // remove version or other extra information if any
056                hostBundleId = hostBundleId.substring(0, p);
057            }
058        }
059    }
060
061    @Override
062    public Bundle getBundle() {
063        return bundle;
064    }
065
066    @Override
067    public URL getResource(String name) {
068        URL url = null;
069        if (hostBundleId != null) {
070            url = getHostBundle().getResource(name);
071        } else {
072            url = bundle.getResource(name);
073        }
074        if (url == null) {
075            url = Framework.getResourceLoader().getResource(name);
076        }
077        return url;
078    }
079
080    @Override
081    public URL getLocalResource(String name) {
082        URL url = null;
083        if (hostBundleId != null) {
084            url = getHostBundle().getEntry(name);
085        } else {
086            url = bundle.getEntry(name);
087        }
088        if (url == null) {
089            url = Framework.getResourceLoader().getResource(name);
090        }
091        return url;
092    }
093
094    @Override
095    public Class<?> loadClass(String className) throws ClassNotFoundException {
096        try {
097            if (hostBundleId != null) { // workaround to handle fragment bundles that doesn't have class loaders
098                return getHostBundle().loadClass(className);
099            }
100            return bundle.loadClass(className);
101        } catch (ClassNotFoundException e) {
102            return Framework.getResourceLoader().loadClass(className);
103        }
104    }
105
106    public Bundle getHostBundle() {
107        if (hostBundleId != null) {
108            if (hostBundle == null && runtime instanceof AbstractRuntimeService) {
109                hostBundle = ((OSGiRuntimeService) runtime).findHostBundle(bundle);
110            }
111        }
112        return hostBundle;
113    }
114
115}