| /* |
| * 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.namespace; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import org.apache.aries.blueprint.ComponentDefinitionRegistry; |
| import org.apache.aries.blueprint.ComponentNameAlreadyInUseException; |
| import org.apache.aries.blueprint.Interceptor; |
| import org.apache.aries.blueprint.reflect.PassThroughMetadataImpl; |
| import org.osgi.service.blueprint.reflect.ComponentMetadata; |
| import org.osgi.service.blueprint.reflect.Target; |
| |
| /** |
| * ComponentDefinitionRegistry implementation. |
| * |
| * This implementation uses concurrent lists and maps to store components and converters metadata |
| * to allow its use by concurrent threads. |
| * |
| * @version $Rev: 1002318 $, $Date: 2010-09-28 19:47:49 +0100 (Tue, 28 Sep 2010) $ |
| */ |
| public class ComponentDefinitionRegistryImpl implements ComponentDefinitionRegistry { |
| |
| private final Map<String, ComponentMetadata> components; |
| private final List<Target> typeConverters; |
| private final Map<ComponentMetadata, List<Interceptor>> interceptors; |
| |
| public ComponentDefinitionRegistryImpl() { |
| // Use a linked hash map to keep the declaration order |
| components = Collections.synchronizedMap(new LinkedHashMap<String, ComponentMetadata>()); |
| typeConverters = new CopyOnWriteArrayList<Target>(); |
| interceptors = Collections.synchronizedMap(new HashMap<ComponentMetadata, List<Interceptor>>()); |
| } |
| |
| public void reset() { |
| components.clear(); |
| typeConverters.clear(); |
| interceptors.clear(); |
| } |
| |
| public boolean containsComponentDefinition(String name) { |
| return components.containsKey(name); |
| } |
| |
| public ComponentMetadata getComponentDefinition(String name) { |
| return components.get(name); |
| } |
| |
| public Set<String> getComponentDefinitionNames() { |
| return Collections.unmodifiableSet(components.keySet()); |
| } |
| |
| public void registerComponentDefinition(ComponentMetadata component) { |
| String id = component.getId(); |
| if (id == null) { |
| // TODO: should we generate a unique name? |
| throw new IllegalArgumentException("Component must have a valid id"); |
| } |
| if (id.startsWith("blueprint") && !(component instanceof PassThroughMetadataImpl)) { |
| // TODO: log a warning |
| } |
| // TODO: perform other validation: scope, class/runtimeClass/factoryMethod, etc... |
| if (components.containsKey(id)) { |
| throw new ComponentNameAlreadyInUseException(id); |
| } |
| components.put(id, component); |
| } |
| |
| public void removeComponentDefinition(String name) { |
| ComponentMetadata removed = components.remove(name); |
| if(removed!=null){ |
| interceptors.remove(removed); |
| } |
| } |
| |
| public void registerTypeConverter(Target component) { |
| typeConverters.add(component); |
| if (component instanceof ComponentMetadata) { |
| registerComponentDefinition((ComponentMetadata) component); |
| } |
| } |
| |
| public List<Target> getTypeConverters() { |
| return typeConverters; |
| } |
| |
| public void registerInterceptorWithComponent(ComponentMetadata component, Interceptor interceptor) { |
| if(interceptor!=null){ |
| List<Interceptor> componentInterceptorList = interceptors.get(component); |
| if(componentInterceptorList==null){ |
| componentInterceptorList = new ArrayList<Interceptor>(); |
| interceptors.put(component, componentInterceptorList); |
| } |
| if(!componentInterceptorList.contains(interceptor)){ |
| componentInterceptorList.add(interceptor); |
| Collections.sort(componentInterceptorList, new Comparator<Interceptor>(){ |
| public int compare(Interceptor object1, Interceptor object2) { |
| //invert the order so higher ranks are sorted 1st |
| return object2.getRank() - object1.getRank(); |
| } |
| }); |
| } |
| } |
| } |
| |
| public List<Interceptor> getInterceptors(ComponentMetadata component) { |
| List<Interceptor> result = interceptors.get(component); |
| return (result == null) ? Collections.<Interceptor>emptyList() : result; |
| } |
| |
| } |