Package org.apache.aries.jndi

Source Code of org.apache.aries.jndi.ContextHelper

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.aries.jndi;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.ObjectFactory;

import org.apache.aries.jndi.startup.Activator;
import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
import org.apache.aries.util.service.registry.ServicePair;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;

/**
* Provides helper methods for the DelegateContext. This provides the methods so
* there can be many DelegateContexts, but few service trackers.
*/
public final class ContextHelper {

    /** Ensure no one constructs us */
    private ContextHelper() {
        throw new RuntimeException();
    }

    /**
     * This method is used to create a URL Context. It does this by looking for
     * the URL context's ObjectFactory in the service registry.
     *
     * @param context
     * @param urlScheme
     * @param env
     * @return a Context
     * @throws NamingException
     */
    public static ContextProvider createURLContext(final BundleContext context,
                                           final String urlScheme,
                                           final Hashtable<?, ?> env)
        throws NamingException {
     
        ServicePair<ObjectFactory> urlObjectFactory = getURLObjectFactory(context, urlScheme, env);
       
        if (urlObjectFactory != null) {
            ObjectFactory factory = urlObjectFactory.get();
           
            if (factory != null) {
                return new URLContextProvider(context, urlObjectFactory.getReference(), factory, env);
            }
        }

        // if we got here then we couldn't find a URL context factory so return null.
        return null;
    }
   
    public static final ServicePair<ObjectFactory> getURLObjectFactory(final BundleContext ctx, String urlScheme, Hashtable<?, ?> environment)
      throws NamingException
    {
      ServicePair<ObjectFactory> result = null;
     
      ServiceReference ref = ServiceTrackerCustomizers.URL_FACTORY_CACHE.find(urlScheme);
     
      if (ref == null) {
        ServiceReference[] refs = AccessController.doPrivileged(new PrivilegedAction<ServiceReference[]>() {
            public ServiceReference[] run() {
                return Activator.getURLObectFactoryFinderServices();
            }
        });       
       
        if (refs != null) {
          for (final ServiceReference finderRef : refs) {
            URLObjectFactoryFinder finder = (URLObjectFactoryFinder) Utils.getServicePrivileged(ctx, finderRef);
               
            if (finder != null) {
              ObjectFactory f = finder.findFactory(urlScheme, environment);
             
              if (f != null) {
                result = new ServicePair<ObjectFactory>(ctx, finderRef, f);
                break;
              } else {
                ctx.ungetService(finderRef);
              }
            }
          }
        }
      } else {
        result = new ServicePair<ObjectFactory>(ctx, ref);
      }
     
      return result;
    }
       
    public static Context getInitialContext(BundleContext context, Hashtable<?, ?> environment)
        throws NamingException {
     
      final Bundle jndiBundle = FrameworkUtil.getBundle(ContextHelper.class);
      // if we are outside OSGi (like in our unittests) then we would get Null back here, so just make sure we don't.
      if (jndiBundle != null) {
       
        BundleContext jndiBundleContext = AccessController.doPrivileged(new PrivilegedAction<BundleContext>() {
          public BundleContext run()
          {
            return jndiBundle.getBundleContext();
          }
        });
       
        if (!!!jndiBundleContext.getClass().equals(context.getClass())){
          //the context passed in must have come from a child framework
          //use the parent context instead
          context = jndiBundleContext;
        }
      }
     
        ContextProvider provider = getContextProvider(context, environment);
       
        if (provider != null) {
          return new DelegateContext(context, provider);
        } else {
          String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
          if (contextFactoryClass == null) {
            return new DelegateContext(context, environment);
          } else {
            throw new NoInitialContextException(Utils.MESSAGES.getMessage("no.initial.context.factory", contextFactoryClass));
          }
        }
    }
   
    public static ContextProvider getContextProvider(BundleContext context,
                                                     Hashtable<?, ?> environment)
        throws NamingException {
       
        ContextProvider provider = null;
        String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
        if (contextFactoryClass == null) {
            // 1. get ContextFactory using builder
            provider = getInitialContextUsingBuilder(context, environment);

            // 2. lookup all ContextFactory services
            if (provider == null) {
               
                ServiceReference[] references = AccessController.doPrivileged(new PrivilegedAction<ServiceReference[]>() {
                    public ServiceReference[] run() {
                        return Activator.getInitialContextFactoryServices();
                    }
                });
               
                if (references != null) {
                    Context initialContext = null;
                    for (ServiceReference reference : references) {
                        InitialContextFactory factory = (InitialContextFactory) Utils.getServicePrivileged(context, reference);
                        try {
                            initialContext = factory.getInitialContext(environment);
                            if (initialContext != null) {
                              provider = new SingleContextProvider(context, reference, initialContext);
                              break;
                          }
                        } finally {
                            if (provider == null) context.ungetService(reference);
                        }
                    }
                }
            }
        } else {
            ServiceReference ref = ServiceTrackerCustomizers.ICF_CACHE.find(contextFactoryClass);
           
            if (ref != null) {
              Context initialContext = null;
              InitialContextFactory factory = (InitialContextFactory) Utils.getServicePrivileged(context, ref);
              if (factory != null) {
                try {
                    initialContext = factory.getInitialContext(environment);
                    provider = new SingleContextProvider(context, ref, initialContext);
                } finally {
                    if (provider == null) context.ungetService(ref);
                }
              }
            }
           
            // 2. get ContextFactory using builder
            if (provider == null) {
                provider = getInitialContextUsingBuilder(context, environment);
            }
        }
       
        return provider;
    }

    private static ContextProvider getInitialContextUsingBuilder(BundleContext context,
                                                                 Hashtable<?, ?> environment)
            throws NamingException {
       
        ContextProvider provider = null;
        ServiceReference[] refs = AccessController.doPrivileged(new PrivilegedAction<ServiceReference[]>() {
            public ServiceReference[] run() {
                return Activator.getInitialContextFactoryBuilderServices();
            }           
        });
           
        if (refs != null) {
            InitialContextFactory factory = null;
            for (ServiceReference ref : refs) {                   
                InitialContextFactoryBuilder builder = (InitialContextFactoryBuilder) Utils.getServicePrivileged(context, ref);
                try {
                  factory = builder.createInitialContextFactory(environment);
                } catch (NamingException ne) {
                  // TODO: log
                  // ignore this, if the builder fails we want to move onto the next one
                }
               
                if (factory != null) {
                  try {
                    provider = new SingleContextProvider(context, ref, factory.getInitialContext(environment));
                  } finally {
                    if (provider == null) context.ungetService(ref); // we didn't get something back, so this was no good.
                  }
                  break;
                } else {
                  context.ungetService(ref); // we didn't get something back, so this was no good.
                }
            }
        }
        return provider;
    }

}
TOP

Related Classes of org.apache.aries.jndi.ContextHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.