Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * http://glassfish.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 package com.sun.jersey.core.osgi;
 
 import java.net.URL;
 import java.util.List;
 import java.util.Map;
 
 
 
 import  org.osgi.framework.Bundle;
 import  org.osgi.framework.BundleContext;
 import  org.osgi.framework.BundleEvent;
 import  org.osgi.framework.BundleReference;
 import  org.osgi.framework.FrameworkUtil;
 import  org.osgi.framework.SynchronousBundleListener;

Utility class to deal with OSGi runtime specific behavior. This is mainly to handle META-INF/services lookup and generic/application class lookup issue in OSGi. When OSGi runtime is detected by the com.sun.jersey.core.reflection.ReflectionHelper class, an instance of OsgiRegistry is created and associated with given OSGi BundleContext. META-INF/services entries are then being accessed via the OSGi Bundle API as direct ClassLoader#getResource() method invocation does not work in this case within OSGi.

Author(s):
Jakub Podlesak (jakub.podlesak at oracle.com)
Michal Gajdos (michal.gajdos at oracle.com)
 
 public final class OsgiRegistry implements SynchronousBundleListener {
 
     private static final String CoreBundleSymbolicNAME = "com.sun.jersey.core";
     private static final Logger LOGGER = Logger.getLogger(OsgiRegistry.class.getName());
 
     private final BundleContext bundleContext;
     private final Map<LongMap<StringCallable<List<Class<?>>>>> factories = new HashMap<LongMap<StringCallable<List<Class<?>>>>>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private static OsgiRegistry instance;
    private Map<String, Bundle> classToBundleMapping = new HashMap<String, Bundle>();

    
Returns an OsgiRegistry instance. Call this method only if sure that the application is running in OSGi environment, otherwise a call to this method can lead to an ClassNotFoundException.

Returns:
an OsgiRegistry instance.
    public static synchronized OsgiRegistry getInstance() {
        if ( == null) {
            final ClassLoader classLoader = ReflectionHelper.class.getClassLoader();
            if (classLoader instanceof BundleReference) {
                final BundleContext context = FrameworkUtil.getBundle(OsgiRegistry.class).getBundleContext();
                if (context != null) { // context could be still null in GlassFish
                     = new OsgiRegistry(context);
                    .hookUp();
                }
            }
        }
        return ;
    }
    private final class OsgiServiceFinder<T> extends ServiceFinder.ServiceIteratorProvider<T> {
        @Override
        public Iterator<T> createIterator(final Class<T> serviceClassfinal String serviceNameClassLoader loaderboolean ignoreOnClassNotFound) {
            final List<Class<?>> providerClasses = locateAllProviders(serviceName);
            if (!providerClasses.isEmpty()) {
                return new Iterator<T>() {
                    Iterator<Class<?>> it = providerClasses.iterator();
                    @Override
                    public boolean hasNext() {
                        return .hasNext();
                    }
                    @Override
                    public T next() {
                        Class<T> nextClass = (Class<T>) .next();
                        try {
                            return serviceClass.cast(nextClass.newInstance());
                        } catch (Exception ex) {
                            ServiceConfigurationError sce = new ServiceConfigurationError(serviceName + ": "
                                    + SpiMessages.PROVIDER_COULD_NOT_BE_CREATED(nextClass.getName(), serviceClass,
                                    ex.getLocalizedMessage()));
                            sce.initCause(ex);
                            throw sce;
                        }
                    }
                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
            return .createIterator(serviceClassserviceNameloaderignoreOnClassNotFound);
        }
        @Override
        public Iterator<Class<T>> createClassIterator(Class<T> serviceString serviceNameClassLoader loaderboolean ignoreOnClassNotFound) {
            final List<Class<?>> providerClasses = locateAllProviders(serviceName);
            if (!providerClasses.isEmpty()) {
                return new Iterator<Class<T>>() {
                    Iterator<Class<?>> it = (Iterator<Class<?>>) providerClasses.iterator();
                    @Override
                    public boolean hasNext() {
                        return .hasNext();
                    }
                    @SuppressWarnings("unchecked")
                    @Override
                    public Class<T> next() {
                        return (Class<T>) .next();
                    }
                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
            return .createClassIterator(serviceserviceNameloaderignoreOnClassNotFound);
        }
    }
    private static class BundleSpiProvidersLoader implements Callable<List<Class<?>>> {
        private final String spi;
        private final URL spiRegistryUrl;
        private final Bundle bundle;
        BundleSpiProvidersLoader(final String spifinal URL spiRegistryUrlfinal Bundle bundle) {
            this. = spi;
            this. = spiRegistryUrl;
            this. = bundle;
        }
        @Override
        public List<Class<?>> call() throws Exception {
            try {
                if (.isLoggable(.)) {
                    .log(."Loading providers for SPI: {0}");
                }
                final BufferedReader br = new BufferedReader(new InputStreamReader(.openStream(), "UTF-8"));
                String providerClassName;
                final List<Class<?>> providerClasses = new ArrayList<Class<?>>();
                while ((providerClassName = br.readLine()) != null) {
                    if (providerClassName.trim().length() == 0) {
                        continue;
                    }
                    if (.isLoggable(.)) {
                        .log(."SPI provider: {0}"providerClassName);
                    }
                    providerClasses.add(.loadClass(providerClassName));
                }
                br.close();
                return providerClasses;
            } catch (Exception e) {
                .log(."exception caught while creating factories: " + e);
                throw e;
            } catch (Error e) {
                .log(."error caught while creating factories: " + e);
                throw e;
            }
        }
        @Override
        public String toString() {
            return .toString();
        }
        @Override
        public int hashCode() {
            return .hashCode();
        }
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof BundleSpiProvidersLoader) {
                return .equals(((BundleSpiProvidersLoaderobj).);
            } else {
                return false;
            }
        }
    }
    @Override
    public void bundleChanged(BundleEvent event) {
        if (event.getType() == BundleEvent.RESOLVED) {
            register(event.getBundle());
        } else if (event.getType() == BundleEvent.UNRESOLVED || event.getType() == BundleEvent.UNINSTALLED) {
            final Bundle unregisteredBundle = event.getBundle();
            .writeLock().lock();
            try {
                .remove(unregisteredBundle.getBundleId());
                if (unregisteredBundle.getSymbolicName().equals()) {
                    .removeBundleListener(this);
                    .clear();
                }
            } finally {
                .writeLock().unlock();
            }
        }
    }
    private void setOSGiPackageScannerResourceProvider() {
        PackageNamesScanner.setResourcesProvider(new PackageNamesScanner.ResourcesProvider() {
            @Override
            public Enumeration<URLgetResources(String packagePathClassLoader classLoaderthrows IOException {
                List<URLresult = new LinkedList<URL>();
                .clear();
                for (Bundle bundle : .getBundles()) {
                    // Look for resources at the given <packagePath> and at WEB-INF/classes/<packagePath> in case a WAR is
                    // being examined.
                    for (String bundlePackagePath : new String[]{packagePath"WEB-INF/classes/" + packagePath}) {
                        final Enumeration<URLenumeration = (Enumeration<URL>) bundle.findEntries(bundlePackagePath"*",
                                false);
                        if (enumeration != null) {
                            while (enumeration.hasMoreElements()) {
                                final URL url = enumeration.nextElement();
                                final String path = url.getPath();
                                final String className = (packagePath + path.substring(path.lastIndexOf('/'))).
                                        replace('/''.').replace(".class""");
                                .put(classNamebundle);
                                result.add(url);
                            }
                        }
                    }
                    // Now interested only in .jar provided by current bundle.
                    final Enumeration<URLjars = bundle.findEntries("/""*.jar"true);
                    if (jars != null) {
                        while (jars.hasMoreElements()) {
                            try {
                                final InputStream inputStream = classLoader.getResourceAsStream(jars.nextElement().getPath());
                                final JarInputStream jarInputStream = new JarInputStream(inputStream);
                                JarEntry jarEntry;
                                while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
                                    final String jarEntryName = jarEntry.getName();
                                    if (jarEntryName.endsWith(".class") && jarEntryName.contains(packagePath)) {
                                        .put(jarEntryName.replace(".class""").replace('/''.'), bundle);
                                        result.add(bundle.getResource(jarEntryName));
                                    }
                                }
                            } catch (Exception e) {
                                // Ignore.
                            }
                        }
                    }
                }
                return Collections.enumeration(result);
            }
        });
    }

    
Get the Class from the class name.

The context class loader will be utilized if accessible and non-null. Otherwise the defining class loader of this class will be utilized.

Parameters:
className the class name.
Returns:
the Class, otherwise null if the class cannot be found.
Throws:
ClassNotFoundException if the class cannot be found.
    public Class<?> classForNameWithException(final String classNamethrows ClassNotFoundException {
        final Bundle bundle = .get(className);
        if (bundle == null) {
            throw new ClassNotFoundException(className);
        }
        return bundle.loadClass(className);
    }

    
Creates a new OsgiRegistry instance bound to a particular OSGi runtime. The only parameter must be an instance of a BundleContext.

Parameters:
bundleContext must be a non-null instance of a BundleContext
    private OsgiRegistry(final BundleContext bundleContext) {
        this. = bundleContext;
    }

    
Will hook up this instance with the OSGi runtime. This is to actually update SPI provider lookup and class loading mechanisms in Jersey to utilize OSGi features.
    private void hookUp() {
        .addBundleListener(this);
        registerExistingBundles();
        // Register RuntimeDelegate.
        final Bundle jerseyServerBundle = getJerseyServerBundle();
        RuntimeDelegate runtimeDelegate = null;
        try {
            if (jerseyServerBundle == null) {
                .config("jersey-client bundle registers JAX-RS RuntimeDelegate");
                runtimeDelegate = (RuntimeDelegategetClass().getClassLoader().
                        loadClass("com.sun.ws.rs.ext.RuntimeDelegateImpl").newInstance();
            } else {
                .config("jersey-server bundle activator registers JAX-RS RuntimeDelegate instance");
                runtimeDelegate = (RuntimeDelegategetClass().getClassLoader().
                        loadClass("com.sun.jersey.server.impl.provider.RuntimeDelegateImpl").newInstance();
            }
        } catch (Exception e) {
            .log(."Unable to create RuntimeDelegate instance."e);
        }
        RuntimeDelegate.setInstance(runtimeDelegate);
    }
    private Bundle getJerseyServerBundle(BundleContext bc) {
        for (Bundle b : bc.getBundles()) {
            final String symbolicName = b.getSymbolicName();
            if ((symbolicName != null)
                    && (symbolicName.endsWith("jersey-server") || symbolicName.endsWith("jersey-gf-server"))) {
                return b;
            }
        }
        return null;
    }
    private void registerExistingBundles() {
        for (Bundle bundle : .getBundles()) {
            if (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.STARTING
                    || bundle.getState() == Bundle.ACTIVE || bundle.getState() == Bundle.STOPPING) {
                register(bundle);
            }
        }
    }
    private void setOSGiServiceFinderIteratorProvider() {
        ServiceFinder.setIteratorProvider(new OsgiServiceFinder());
    }
    private void register(final Bundle bundle) {
        if (.isLoggable(.)) {
            .log(."checking bundle {0}"bundle.getBundleId());
        }
        Map<StringCallable<List<Class<?>>>> map;
        .writeLock().lock();
        try {
            map = .get(bundle.getBundleId());
            if (map == null) {
                map = new ConcurrentHashMap<StringCallable<List<Class<?>>>>();
                .put(bundle.getBundleId(), map);
            }
        } finally {
            .writeLock().unlock();
        }
        Enumeration e = bundle.findEntries("META-INF/services/""*"false);
        if (e != null) {
            while (e.hasMoreElements()) {
                final URL u = (URLe.nextElement();
                final String url = u.toString();
                if (url.endsWith("/")) {
                    continue;
                }
                final String factoryId = url.substring(url.lastIndexOf("/") + 1);
                map.put(factoryIdnew BundleSpiProvidersLoader(factoryIdubundle));
            }
        }
    }
    private List<Class<?>> locateAllProviders(String serviceName) {
        .readLock().lock();
        try {
            final List<Class<?>> result = new LinkedList<Class<?>>();
            for (Map<StringCallable<List<Class<?>>>> value : .values()) {
                if (value.containsKey(serviceName)) {
                    try {
                        result.addAll(value.get(serviceName).call());
                    } catch (Exception ex) {
                        // ignore
                    }
                }
            }
            return result;
        } finally {
            .readLock().unlock();
        }
    }
New to GrepCode? Check out our FAQ X