Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * #%L
   * JBossOSGi Framework
   * %%
   * Copyright (C) 2010 - 2012 JBoss by Red Hat
   * %%
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
  *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * <http://www.gnu.org/licenses/lgpl-2.1.html>.
  * #L%
  */
 package org.jboss.osgi.framework.internal;
 
 import static org.jboss.osgi.framework.FrameworkLogger.LOGGER;
 import static org.jboss.osgi.framework.FrameworkMessages.MESSAGES;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
The service implementation.

Author(s):
thomas.diesler@jboss.com
David Bosschaert
Since:
29-Jun-2010
 
 @SuppressWarnings("rawtypes")
 final class ServiceStateImpl implements ServiceState {
 
     private final ServiceManager serviceManager;
     private final XBundle ownerBundle;
     private final String[] classNames;
     private final long serviceId;
     private final ValueProvider valueProvider;
     private final ServiceReference reference;
     private ServiceRegistration registration;
     private Set<XBundleusingBundles;
 
     // The properties
 
     @SuppressWarnings("unchecked")
     ServiceStateImpl(ServiceManager serviceManagerXBundle ownerlong serviceIdString[] classNamesValueProvider valueProviderDictionary properties) {
         assert serviceManager != null : "Null serviceManager";
         assert owner != null : "Null owner";
         assert classNames != null && classNames.length > 0 : "Null clazzes";
         assert valueProvider != null : "Null valueProvider";
 
         this. = serviceManager;
         this. = owner;
         this. = serviceId;
         this. = valueProvider;
         this. = classNames;
 
         if (!valueProvider.isFactoryValue() && !checkValidClassNames(ownerclassNamesvalueProvider.getValue()))
             throw .illegalArgumentInvalidObjectClass(Arrays.toString(classNames));
 
         if (properties == null)
             properties = new Hashtable();
 
         properties.put(.serviceId);
        properties.put(.classNames);
        this. = new CaseInsensitiveDictionary(properties);
        // Create the {@link ServiceRegistration} and {@link ServiceReference}
        this. = new ServiceRegistrationWrapper(this);
        this. = new ServiceReferenceWrapper(this);
    }
        assert sref != null : "Null sref";
        if (sref instanceof ServiceReferenceWrapper) {
            sref = ((ServiceReferenceWrappersref).getServiceState();
        }
        return (ServiceStateImplsref;
    }
    @Override
    public long getServiceId() {
        return ;
    }
    @Override
    public Object getScopedValue(XBundle bundle) {
        // For non-factory services, return the value
        if (.isFactoryValue() == false)
            return .getValue();
        // Get the ServiceFactory value
        Object result = null;
        try {
            if ( == null)
                 = new HashMap<LongServiceFactoryHolder>();
            ServiceFactoryHolder factoryHolder = getFactoryHolder(bundle);
            if (factoryHolder == null) {
                ServiceFactory factory = (ServiceFactory.getValue();
                factoryHolder = new ServiceFactoryHolder(bundlefactory);
                .put(bundle.getBundleId(), factoryHolder);
            }
            result = factoryHolder.getService();
            // If the service object returned by the ServiceFactory object is not an instanceof all the classes named
            // when the service was registered or the ServiceFactory object throws an exception,
            // null is returned and a Framework event of type {@link FrameworkEvent#ERROR}
            // containing a {@link ServiceException} describing the error is fired.
            if (result == null) {
                ServiceException sex = new ServiceException("Cannot get factory value".);
                .fireFrameworkEvent(bundle.sex);
            }
        } catch (Throwable th) {
            ServiceException sex = new ServiceException("Cannot get factory value".th);
            .fireFrameworkEvent(bundle.sex);
        }
        return result;
    }
    @Override
    public void ungetScopedValue(XBundle bundle) {
        if (.isFactoryValue()) {
            ServiceFactoryHolder factoryHolder = getFactoryHolder(bundle);
            if (factoryHolder != null) {
                try {
                    factoryHolder.ungetService();
                } catch (RuntimeException rte) {
                    ServiceException sex = new ServiceException("Cannot unget factory value".rte);
                    .fireFrameworkEvent(bundle.sex);
                }
            }
        }
    }
    private ServiceFactoryHolder getFactoryHolder(XBundle bundle) {
        return  != null ? .get(bundle.getBundleId()) : null;
    }
    @Override
        return ;
    }
    @Override
    public List<StringgetClassNames() {
        return Arrays.asList();
    }
    @Override
    public ServiceReference getReference() {
        assertNotUnregistered();
        return ;
    }
    @Override
    public void unregister() {
        assertNotUnregistered();
        unregisterInternal();
    }
    @Override
    public void unregisterInternal() {
        .unregisterService(this);
         = null;
         = null;
    }
    @Override
    public Object getProperty(String key) {
        if (key == null)
            return null;
        return .get(key);
    }
    @Override
    public String[] getPropertyKeys() {
        List<Stringresult = new ArrayList<String>();
        if ( != null) {
            Enumeration<Stringkeys = .keys();
            while (keys.hasMoreElements())
                result.add(keys.nextElement());
        }
        return result.toArray(new String[result.size()]);
    }
    @Override
    @SuppressWarnings({ "unchecked" })
    public void setProperties(Dictionary properties) {
        assertNotUnregistered();
        // Remember the previous properties for a potential
        // delivery of the MODIFIED_ENDMATCH event
         = ;
        if (properties == null)
            properties = new Hashtable();
         = new CaseInsensitiveDictionary(properties);
        // This event is synchronously delivered after the service properties have been modified.
    }
    @Override
    public Dictionary getPreviousProperties() {
        return ;
    }
    @Override
    public XBundle getServiceOwner() {
        return ;
    }
    @Override
    public Bundle getBundle() {
        if (isUnregistered())
            return null;
        return ;
    }
    @Override
    public void addUsingBundle(XBundle bundleState) {
        synchronized (this) {
            if ( == null)
                 = new HashSet<XBundle>();
            .add(bundleState);
        }
    }
    @Override
    public void removeUsingBundle(XBundle bundle) {
        synchronized (this) {
            if ( != null)
                .remove(bundle);
        }
    }
    @Override
    public Set<XBundlegetUsingBundlesInternal() {
        synchronized (this) {
            if ( == null)
                return Collections.emptySet();
            // Return an unmodifieable snapshot of the set
            return Collections.unmodifiableSet(new HashSet<XBundle>());
        }
    }
    @Override
    public Bundle[] getUsingBundles() {
        synchronized (this) {
            if ( == null)
                return null;
            Set<Bundlebundles = new HashSet<Bundle>();
            for (XBundle aux : )
                bundles.add(aux);
            return bundles.toArray(new Bundle[bundles.size()]);
        }
    }
    @Override
    public boolean isAssignableTo(Bundle bundleString className) {
        if (bundle == null)
            throw .illegalArgumentNull("bundle");
        if (className == null)
            throw .illegalArgumentNull("className");
        if (bundle ==  || className.startsWith("java."))
            return true;
        int bundleState = bundle.getState();
        if (bundleState == .)
            return false;
        XBundleRevision bundleRev = ((XBundlebundle).getBundleRevision();
        ClassLoader bundleClassLoader = bundleRev.getModuleClassLoader();
        if (bundleClassLoader == null) {
            .infof("NO CLASSLOADER [%s,%s] for: %s"bundle, ConstantsHelper.bundleState(bundleState), className);
            return false;
        }
        FallbackLoader fallbackLoader = null;
        if (bundleRev instanceof HostBundleRevision) {
            fallbackLoader = ((HostBundleRevisionbundleRev).getFallbackLoader();
        }
        Class<?> targetClass;
        try {
            if (fallbackLoader != null) {
                try {
                    fallbackLoader.lockFallbackLoader();
                    fallbackLoader.setEnabled(false);
                    targetClass = bundleClassLoader.loadClass(className);
                } finally {
                    fallbackLoader.setEnabled(true);
                    fallbackLoader.unlockFallbackLoader();
                }
            } else {
                targetClass = bundleClassLoader.loadClass(className);
            }
        } catch (ClassNotFoundException ex) {
            // If the requesting bundle does not have a wire to the
            // service package it cannot be constraint on that package.
            .tracef("Requesting bundle [%s] cannot load class: %s"bundleclassName);
            return true;
        }
        XBundleRevision ownerRev = .getBundleRevision();
        ClassLoader ownerClassLoader = ownerRev.getModuleClassLoader();
        if (ownerClassLoader == null) {
            .tracef("Registrant bundle [%s] has no class loader for: %s"className);
            return true;
        }
        // For the bundle that registered the service referenced by this ServiceReference (registrant bundle);
        // find the source for the package. If no source is found then return true if the registrant bundle
        // is equal to the specified bundle; otherwise return false
        Class<?> serviceClass;
        try {
            serviceClass = ownerClassLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            .tracef("Registrant bundle [%s] cannot load class: %s"className);
            return true;
        }
        // If the package source of the registrant bundle is equal to the package source of the specified bundle
        // then return true; otherwise return false.
        if (targetClass != serviceClass) {
            .tracef("Not assignable: %s"className);
            return false;
        }
        return true;
    }
    @Override
    public int compareTo(Object sref) {
        if (sref instanceof ServiceReference == false)
            throw .illegalArgumentInvalidServiceRef(sref);
        Comparator<ServiceReferencecomparator = ServiceReferenceComparator.getInstance();
        return comparator.compare(this, (ServiceReferencesref);
    }
    @Override
    public int getServiceRanking() {
        Object prop = getProperty(.);
        if (prop instanceof Integer == false)
            return 0;
        return ((Integerprop).intValue();
    }
    @Override
    public boolean isUnregistered() {
        return  == null;
    }
    private void assertNotUnregistered() {
        if (isUnregistered())
            throw .illegalStateServiceUnregistered(this);
    }
    private boolean checkValidClassNames(XBundle bundleStateString[] classNamesObject value) {
        assert bundleState != null : "Null bundleState";
        assert classNames != null && classNames.length > 0 : "Null service classes";
        assert value != null : "Null value";
        if (value instanceof ServiceFactory)
            return true;
        boolean result = true;
        for (String className : classNames) {
            if (className == null) {
                result = false;
                break;
            }
            try {
                Class<?> valueClass = value.getClass();
                // Use Class.forName with classloader argument as the classloader
                // might be null (for JRE provided types).
                Class<?> clazz = Class.forName(classNamefalsevalueClass.getClassLoader());
                if (clazz.isAssignableFrom(valueClass) == false) {
                    .errorServiceNotAssignable(classNameclazz.getClassLoader(), valueClass.getName(), valueClass.getClassLoader());
                    result = false;
                    break;
                }
            } catch (ClassNotFoundException ex) {
                .errorCannotLoadService(classNamebundleState);
                result = false;
                break;
            }
        }
        return result;
    }
    @Override
    @SuppressWarnings("unchecked")
    public String toString() {
        Hashtable<StringObjectprops = new Hashtable<StringObject>();
        String[] classes = (String[]) props.get(.);
        props.put(., Arrays.asList(classes));
        return "ServiceState" + props;
    }
    class ServiceFactoryHolder {
        ServiceFactory factory;
        XBundle bundle;
        AtomicInteger useCount;
        Object value;
        ServiceFactoryHolder(XBundle bundleServiceFactory factory) {
            this. = bundle;
            this. = factory;
            this. = new AtomicInteger();
        }
        Object getService() {
            // Multiple calls to getService() return the same value
            if (.get() == 0) {
                // The Framework must not allow this method to be concurrently called for the same bundle
                synchronized () {
                    Object retValue = .getService(getRegistration());
                    if (retValue == null)
                        return null;
                    // The Framework will check if the returned service object is an instance of all the
                    // classes named when the service was registered. If not, then null is returned to the bundle.
                    if (checkValidClassNames(, (String[]) getProperty(.), retValue) == false)
                        return null;
                     = retValue;
                }
            }
            .incrementAndGet();
            return ;
        }
        void ungetService() {
            if (.get() == 0)
                return;
            // Call unget on the factory when done
            if (.decrementAndGet() == 0) {
                synchronized () {
                    .ungetService(getRegistration(), );
                     = null;
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X