Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.blueprint.container;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
Abstract class for service reference recipes. TODO: if we have a single interface (which is the standard behavior), then we should be able to get rid of the proxyClassloader and just use this interface classloader to define the proxy TODO: it is allowed to have no interface defined at all, which should result in an empty proxy

Version:
$Rev: 1676682 $, $Date: 2015-04-29 09:16:31 +0200 (Wed, 29 Apr 2015) $
 
 @SuppressWarnings("rawtypes")
 public abstract class AbstractServiceReferenceRecipe extends AbstractRecipe implements ServiceListenerSatisfiableRecipe {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractServiceReferenceRecipe.class);
 
     protected final ExtendedBlueprintContainer blueprintContainer;
     protected final ServiceReferenceMetadata metadata;
     protected final ValueRecipe filterRecipe;
     protected final CollectionRecipe listenersRecipe;
     protected final List<RecipeexplicitDependencies;
     protected final boolean optional;
    
The OSGi filter for tracking references
 
     protected final String filter;
    
The list of listeners for this reference. This list will be lazy created
 
     protected List<Listenerlisteners;
 
     private final AtomicBoolean started = new AtomicBoolean();
     private final AtomicBoolean satisfied = new AtomicBoolean();
 
     private final AccessControlContext accessControlContext;
 
     private final Tracked tracked = new Tracked();
 
     protected AbstractServiceReferenceRecipe(String name,
                                              ExtendedBlueprintContainer blueprintContainer,
                                             ServiceReferenceMetadata metadata,
                                             ValueRecipe filterRecipe,
                                             CollectionRecipe listenersRecipe,
                                             List<RecipeexplicitDependencies) {
        super(name);
        this. = false;
        this. = blueprintContainer;
        this. = metadata;
        this. = filterRecipe;
        this. = listenersRecipe;
        this. = explicitDependencies;
        
        
        this. = (metadata.getAvailability() == .);
        this. = createOsgiFilter(metadatanull);
        
         = (System.getSecurityManager() != null) ? createAccessControlContext() : null;
    }
        return ;
    }
    public void start(SatisfactionListener listener) {
        if (listener == nullthrow new NullPointerException("satisfactionListener is null");
        if (.compareAndSet(falsetrue)) {
            try {
                 = listener;
                .set();
                // Synchronized block on references so that service events won't interfere with initial references tracking
                // though this may not be sufficient because we don't control ordering of those events
                synchronized () {
                    getBundleContextForServiceLookup().addServiceListener(thisgetOsgiFilter());
                    ServiceReference[] references = getBundleContextForServiceLookup().getServiceReferences((StringnullgetOsgiFilter());
                    .setInitial(references != null ? references : new ServiceReference[0]);
                }
                .trackInitial();
                .set( || !.isEmpty());
                retrack();
                .debug("Found initial references {} for OSGi service {}"getServiceReferences(), getOsgiFilter());
            } catch (InvalidSyntaxException e) {
                throw new ComponentDefinitionException(e);
            }
        }
    }
    public void stop() {
        if (.compareAndSet(truefalse)) {
            .close();
            try {
                getBundleContextForServiceLookup().removeServiceListener(this);
            } catch (IllegalStateException e) {
                // Ignore in case bundle context is already invalidated
            }
            doStop();
            for (ServiceReference ref : getServiceReferences()) {
                untrack(ref);
            }
            .set(false);
             = null;
        }
    }
    protected void doStop() {
    }
    protected boolean isStarted() {
        return .get();
    }
    public boolean isSatisfied() {
        return .get();
    }
    @Override
        List<Reciperecipes = new ArrayList<Recipe>();
        if ( != null) {
            recipes.addAll();
        }
        return recipes;
    }
    
    public List<RecipegetDependencies() {
        List<Reciperecipes = new ArrayList<Recipe>();
        if ( != null) {
            recipes.add();
        }
        recipes.addAll(getConstructorDependencies());
        return recipes;
    }
    public String getOsgiFilter() {
        if ( != null &&  instanceof BlueprintContainerImpl) {
            switch (state) {
                case :
                case :
                case :
                case :
                    return createOsgiFilter(getExtendedOsgiFilter());
            }
        }
        return ;
    }
    private String getExtendedOsgiFilter() {
        if ( != null) {
            Object object;
            BlueprintRepository repository = ((BlueprintContainerImpl).getRepository();
            ExecutionContext oldContext = null;
            try {
                oldContext = ExecutionContext.Holder.setContext(repository);
                object = .create();
            } finally {
                ExecutionContext.Holder.setContext(oldContext);
            }
            if (object != null) {
                String flt = object.toString();
                if (flt != null && flt.length() > 0) {
                    if (!flt.startsWith("(")) {
                        flt = "(" + flt + ")";
                    }
                    return flt;
                }
            }
        }
        return null;
    }
    @SuppressWarnings("unchecked")
    protected Object getServiceSecurely(final ServiceReference serviceReference) {
        if ( == null) {
            return getBundleContextForServiceLookup().getService(serviceReference);
        } else {
            // If we're operating with security, use the privileges of the bundle
            // we're managing to do the lookup
            return AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    return getBundleContextForServiceLookup().getService(serviceReference);
                }
            }, );
        }
    }

    
We may need to execute code within a doPrivileged block, and if so, it should be the privileges of the bundle with the blueprint file that get used, not the privileges of blueprint-core. To achieve this we use an access context.

Returns:
        return new AccessControlContext(AccessController.getContext(), new DomainCombiner() {
            public ProtectionDomain[] combine(ProtectionDomain[] arg0ProtectionDomain[] arg1) {
                ProtectionDomain protectionDomain = new ProtectionDomain(nullnull) {
                    public boolean implies(Permission permission) {
                        return getBundleContextForServiceLookup().getBundle().hasPermission(permission);
                    }
                };
                return new ProtectionDomain[] {
                    protectionDomain
                };
            }
        });
    }
    @SuppressWarnings("unchecked")
    protected void createListeners() {
        if ( != null) {
            List<Listenerlisteners = (List<Listener>).create();
            for (Listener listener : listeners) {
                List<ClassclassList = new ArrayList<Class>();
                Class clz = getInterfaceClass();
                if (clz != null) {
                    classList.add(clz);
                } else {
                    classList.add(Object.class);
                }
                listener.init(classList);
            }
            this. = listeners;
        } else {
            this. = Collections.emptyList();
        }
    }
    protected List<Class<?>> loadAllClasses(Iterable<StringinterfaceNames) {
        List<Class<?>> classes = new ArrayList<Class<?>>();
        for (String name : interfaceNames) {
            Class<?> clazz = loadClass(name);
            classes.add(clazz);
        }
        return classes;
    }
    protected ReifiedType loadType(String typeNameClassLoader fromClassLoader) {
        if (typeName == null) {
            return null;
        }
        try {
            // this method is overriden to use the blueprint container directly
            // because proxies can be created outside of the recipe creation which
            // would lead to an exception because the context is not set
            // TODO: consider having the context as a property on the recipe rather than a thread local
            return GenericType.parse(typeNamefromClassLoader != null ? fromClassLoader : );
        } catch (ClassNotFoundException e) {
            throw new ComponentDefinitionException("Unable to load class " + typeName + " from recipe " + thise);
        }
    }
    protected Object createProxy(final Callable<ObjectdispatcherSet<Class<?>> interfacesthrows Exception {
        if (!interfaces.iterator().hasNext()) {
            return new Object();
        } else {
            // Check class proxying
            boolean proxyClass = false;
            if ( instanceof ExtendedServiceReferenceMetadata) {
            }
            if (!proxyClass) {
                for (Class cl : interfaces) {
                    if (!cl.isInterface()) {
                        throw new ComponentDefinitionException("A class " + cl.getName() + " was found in the interfaces list, but class proxying is not allowed by default. The ext:proxy-method='classes' attribute needs to be added to this service reference.");
                    }
                }
            }
            //We don't use the #getBundleContextForServiceLookup() method here, the bundle requesting the proxy is the
            //blueprint client, not the context of the lookup
            return .getProxyManager().createDelegatingProxy(.getBundleContext().getBundle(), interfacesdispatchernull);
        }
    }
    public void serviceChanged(ServiceEvent event) {
      int eventType = event.getType();
      ServiceReference ref = event.getServiceReference();
      switch (eventType) {
          case .:
              serviceAdded(refevent);
              break;
          case .:
              serviceModified(refevent);
              break;
          case .:
              serviceRemoved(refevent);
              break;
      }
    }  
    private void serviceAdded(ServiceReference refServiceEvent event) {
        .debug("Tracking reference {} for OSGi service {}"refgetOsgiFilter());
        if (isStarted()) {
            .track(refevent);
            boolean satisfied;
            synchronized () {
                satisfied =  || !.isEmpty();
            }
            setSatisfied(satisfied);
            track(ref);
        }
    }
    private void serviceModified(ServiceReference refServiceEvent event) {
        // ref must be in references and must be satisfied
        if (isStarted()) {
            .track(refevent);
            track(ref);
        }
    }
    private void serviceRemoved(ServiceReference refServiceEvent event) {
        if (isStarted()) {
            .debug("Untracking reference {} for OSGi service {}"refgetOsgiFilter());
            .untrack(refevent);
            boolean satisfied;
            synchronized () {
                satisfied =  || !.isEmpty();
            }
            setSatisfied(satisfied);
            untrack(ref);
        }
    }
    
    protected Class getInterfaceClass() {
        Class clz = getRuntimeClass();
        if (clz != null)
            return clz;
        else if (.getInterface() != null)
            return loadClass(.getInterface());
        return null;
    }
    
    protected static Class getRuntimeClass(ServiceReferenceMetadata metadata) {
        if (metadata instanceof ExtendedServiceReferenceMetadata && ((ExtendedServiceReferenceMetadatametadata).getRuntimeInterface() != null) {
           return ((ExtendedServiceReferenceMetadatametadata).getRuntimeInterface();
        } 
        return null;
    }
            BundleContext context = ((ExtendedServiceReferenceMetadata).getBundleContext();
            if(context != null) {
              return context;
            }
        }
         
        return .getBundleContext();
    }
    
    protected void setSatisfied(boolean s) {
        // This check will ensure an atomic comparision and set
        // so that it will only be true if the value actually changed
        if (.getAndSet(s) != s) {
            .debug("Service reference with filter {} satisfied {}"getOsgiFilter(), this.);
            this..notifySatisfaction(this);
        }
    }
    protected abstract void track(ServiceReference reference);
    protected abstract void untrack(ServiceReference reference);
    protected abstract void retrack();
    protected void updateListeners() {
        boolean empty;
        synchronized () {
            empty = .isEmpty();
        }
        if (empty) {
            unbind(nullnull);
        } else {
            retrack();
        }
    }
    
    protected void bind(ServiceReference referenceObject service) {
        if ( != null) {    
            for (Listener listener : ) {
                if (listener != null) {
                    listener.bind(referenceservice);
                }
            } 
        }
    }
    
    protected void unbind(ServiceReference referenceObject service) {
        if ( != null) {    
            for (Listener listener : ) {
                if (listener != null) {
                    listener.unbind(referenceservice);
                }
            } 
        }
    }
    
        ServiceReference[] refs;
        synchronized () {
            refs = new ServiceReference[.size()];
            .copyKeys(refs);
        }
        return Arrays.asList(refs);
    }
        List<ServiceReferencereferences = getServiceReferences();
        int length = references.size();
        if (length == 0) { /* if no service is being tracked */
            return null;
        }
        int index = 0;
        if (length > 1) { /* if more than one service, select highest ranking */
            int maxRanking = .;
            long minId = .;
            for (int i = 0; i < lengthi++) {
                Object property = references.get(i).getProperty(.);
                int ranking = (property instanceof Integer) ? (Integerproperty : 0;
                long id = (Longreferences.get(i).getProperty(.);
                if ((ranking > maxRanking) || (ranking == maxRanking && id < minId)) {
                    index = i;
                    maxRanking = ranking;
                    minId = id;
                }
            }
        }
        return references.get(index);
    }
    public static class Listener {
        private static final Logger LOGGER = LoggerFactory.getLogger(Listener.class);
        private Object listener;
        private ReferenceListener metadata;
        private Set<MethodbindMethodsReference = new HashSet<Method>();
        private Set<MethodbindMethodsObjectProp = new HashSet<Method>();
        private Set<MethodbindMethodsObject = new HashSet<Method>();
        private Set<MethodunbindMethodsReference = new HashSet<Method>();
        private Set<MethodunbindMethodsObject = new HashSet<Method>();
        private Set<MethodunbindMethodsObjectProp = new HashSet<Method>();
        public void setListener(Object listener) {
            this. = listener;
        }
        public void setMetadata(ReferenceListener metadata) {
            this. = metadata;
        }
        public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
            this. = blueprintContainer;
        }
        
        public void init(Collection<Classclasses) {
            Set<Classclazzes = new HashSet<Class>(classes);
            clazzes.add(Object.class);
            Class listenerClass = .getClass();
            String bindName = .getBindMethod();
            if (bindName != null) {
                .addAll(ReflectionUtils.findCompatibleMethods(listenerClassbindNamenew Class[] { ServiceReference.class }));
                for (Class clazz : clazzes) {
                    .addAll(ReflectionUtils.findCompatibleMethods(listenerClassbindNamenew Class[] { clazz }));
                    .addAll(ReflectionUtils.findCompatibleMethods(listenerClassbindNamenew Class[] { clazzMap.class }));
                }
                if (.size() + .size() + .size() == 0) {
                    throw new ComponentDefinitionException("No matching methods found for listener bind method: " + bindName);
                }
            }
            String unbindName = .getUnbindMethod();
            if (unbindName != null) {
                .addAll(ReflectionUtils.findCompatibleMethods(listenerClassunbindNamenew Class[] { ServiceReference.class }));
                for (Class clazz : clazzes) {
                    .addAll(ReflectionUtils.findCompatibleMethods(listenerClassunbindNamenew Class[] { clazz }));
                    .addAll(ReflectionUtils.findCompatibleMethods(listenerClassunbindNamenew Class[] { clazzMap.class }));
                }
                if (.size() + .size() + .size() == 0) {
                    throw new ComponentDefinitionException("No matching methods found for listener unbind method: " + unbindName);
                }
            }
        }
        public void bind(ServiceReference referenceObject service) {
            invokeMethods(referenceservice);
        }
        public void unbind(ServiceReference referenceObject service) {
            invokeMethods(referenceservice);
        }
        private void invokeMethods(Set<MethodreferenceMethodsSet<MethodobjectMethodsSet<MethodobjectPropMethodsServiceReference referenceObject service) {
            for (Method method : referenceMethods) {
                try {
                    ReflectionUtils.invoke(.getAccessControlContext(), 
                                           methodreference);
                } catch (Exception e) {
                    .error("Error calling listener method " + methode);
                }
            }
            for (Method method : objectMethods) {
                try {
                    ReflectionUtils.invoke(.getAccessControlContext(), 
                                           methodservice);
                } catch (Exception e) {
                    .error("Error calling listener method " + methode);
                }
            }
            Map<StringObjectprops = null;
            for (Method method : objectPropMethods) {
                if (props == null) {
                    props = new HashMap<StringObject>();
                    if (reference != null) {
                        for (String name : reference.getPropertyKeys()) {
                            props.put(namereference.getProperty(name));
                        }
                    }
                }
                try {
                    ReflectionUtils.invoke(.getAccessControlContext(), 
                                           methodserviceprops);
                } catch (Exception e) {
                    .error("Error calling listener method " + methode);
                }
            }
        }
    }

    
Create the OSGi filter corresponding to the ServiceReferenceMetadata constraints

Parameters:
metadata the service reference metadata
Returns:
the OSGi filter
    private static String createOsgiFilter(ServiceReferenceMetadata metadataString extendedFilter) {
        List<Stringmembers = new ArrayList<String>();
        // Handle filter
        String flt = metadata.getFilter();
        if (flt != null && flt.length() > 0) {
            if (!flt.startsWith("(")) {
                flt = "(" + flt + ")";
            }
            members.add(flt);
        }
        // Handle extended filter
        if (extendedFilter != null && extendedFilter.length() > 0) {
            if (!extendedFilter.startsWith("(")) {
                extendedFilter = "(" + extendedFilter + ")";
            }
            members.add(extendedFilter);
        }
        // Handle interfaces
        String interfaceName = metadata.getInterface();
        Class runtimeClass = getRuntimeClass(metadata);
        if (runtimeClass != null) {
            interfaceName = runtimeClass.getName();
        }
        if (interfaceName != null && interfaceName.length() > 0) {
            if (metadata instanceof ExtendedReferenceMetadata) {
                ExtendedReferenceMetadata erm = (ExtendedReferenceMetadata)metadata;
                if (!erm.getExtraInterfaces().isEmpty()) {
                    StringBuilder sb = new StringBuilder("(&");
                    sb.append("(" + . + "=" + interfaceName + ")");
                    for (String s : erm.getExtraInterfaces()) {
                        sb.append("(" + . + "=" + s + ")");                        
                    }
                    sb.append(")");
                    members.add(sb.toString());
                } else {
                    members.add("(" + . + "=" + interfaceName + ")");                    
                }
            } else {
                members.add("(" + . + "=" + interfaceName + ")");
            }
        }
        // Handle component name
        String componentName = metadata.getComponentName();
        if (componentName != null && componentName.length() > 0) {
            members.add("(" + . + "=" + componentName + ")");
        }
        // Create filter
        if (members.isEmpty()) {
            throw new IllegalStateException("No constraints were specified on the service reference");
        }
        if (members.size() == 1) {
            return members.get(0);
        }
        StringBuilder sb = new StringBuilder("(&");
        for (String member : members) {
            sb.append(member);
        }
        sb.append(")");
        return sb.toString();
    }
    private class Tracked extends AbstractTracked<ServiceReferenceServiceReferenceServiceEvent> {
        @Override
            return item;
        }
        @Override
        void customizerModified(ServiceReference itemServiceEvent relatedServiceReference object) {
        }
        @Override
        void customizerRemoved(ServiceReference itemServiceEvent relatedServiceReference object) {
        }
    }
New to GrepCode? Check out our FAQ X