You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gn...@apache.org on 2009/04/21 11:46:41 UTC
svn commit: r767090 [1/2] - in /geronimo/sandbox/blueprint:
blueprint-core/src/main/java/org/apache/geronimo/blueprint/
blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/
blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils...
Author: gnodet
Date: Tue Apr 21 09:46:41 2009
New Revision: 767090
URL: http://svn.apache.org/viewvc?rev=767090&view=rev
Log:
Implement ref-list and ref-set
Added:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/Destroyable.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceUnregisteredException.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java
- copied, changed from r766654, geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicCollection.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicList.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSet.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedList.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedSet.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java (contents, props changed)
- copied, changed from r766654, geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java
geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/utils/
geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/utils/DynamicCollectionTest.java
Removed:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/LifeCycle.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java
Modified:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceRegistrationProxy.java
geronimo/sandbox/blueprint/blueprint-itests/src/test/java/org/apache/geronimo/blueprint/itests/TestReferences.java
geronimo/sandbox/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/Destroyable.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/Destroyable.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/Destroyable.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/Destroyable.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,30 @@
+/**
+ * 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.geronimo.blueprint;
+
+/**
+ * Interface used as a callback to destroy a given object.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766508 $, $Date: 2009-04-19 22:09:27 +0200 (Sun, 19 Apr 2009) $
+ */
+public interface Destroyable {
+
+ void destroy() throws Exception;
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,267 @@
+/*
+ * 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.geronimo.blueprint.context;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Collection;
+import java.lang.reflect.Method;
+
+import org.apache.xbean.recipe.AbstractRecipe;
+import org.apache.xbean.recipe.Recipe;
+import org.apache.xbean.recipe.ConstructionException;
+import org.apache.geronimo.blueprint.ModuleContextEventSender;
+import org.apache.geronimo.blueprint.BlueprintConstants;
+import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.utils.ReflectionUtils;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.reflect.ServiceReferenceComponentMetadata;
+import org.osgi.service.blueprint.reflect.BindingListenerMetadata;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Dispatcher;
+
+/**
+ * Abstract class for service reference recipes.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
+ */
+public abstract class AbstractServiceReferenceRecipe extends AbstractRecipe implements ServiceListener, Destroyable {
+
+ protected final ModuleContext moduleContext;
+ protected final ModuleContextEventSender sender;
+ protected final ServiceReferenceComponentMetadata metadata;
+ protected final Recipe listenersRecipe;
+ protected List<Listener> listeners;
+ private String filter;
+ protected final ClassLoader proxyClassLoader;
+
+ protected AbstractServiceReferenceRecipe(ModuleContext moduleContext,
+ ModuleContextEventSender sender,
+ ServiceReferenceComponentMetadata metadata,
+ Recipe listenersRecipe) {
+ this.moduleContext = moduleContext;
+ this.sender = sender;
+ this.metadata = metadata;
+ this.listenersRecipe = listenersRecipe;
+ // Create a ClassLoader delegating to the bundle, but also being able to see our bundle classes
+ // so that the created proxy can access cglib classes.
+ this.proxyClassLoader = new BundleDelegatingClassLoader(moduleContext.getBundleContext().getBundle(),
+ getClass().getClassLoader());
+ }
+
+ protected String getOsgiFilter() {
+ if (filter == null) {
+ List<String> members = new ArrayList<String>();
+ // Handle filter
+ String flt = metadata.getFilter();
+ if (flt != null && flt.length() > 0) {
+ if (!flt.startsWith("(")) {
+ flt = "(" + flt + ")";
+ }
+ members.add(flt);
+ }
+ // Handle interfaces
+ Set<String> interfaces = (Set<String>) metadata.getInterfaceNames();
+ if (interfaces != null && !interfaces.isEmpty()) {
+ for (String itf : interfaces) {
+ members.add("(" + Constants.OBJECTCLASS + "=" + itf + ")");
+ }
+ }
+ // Handle component name
+ String componentName = metadata.getComponentName();
+ if (componentName != null && componentName.length() > 0) {
+ members.add("(" + BlueprintConstants.COMPONENT_NAME_PROPERTY + "=" + componentName + ")");
+ }
+ // Create filter
+ if (members.isEmpty()) {
+ throw new IllegalStateException("No constraints were specified on the service reference");
+ }
+ StringBuilder sb = new StringBuilder("(&");
+ for (String member : members) {
+ sb.append(member);
+ }
+ sb.append(")");
+ filter = sb.toString();
+ }
+ return filter;
+ }
+
+ protected void createListeners() throws ClassNotFoundException {
+ if (listenersRecipe != null) {
+ listeners = (List<Listener>) listenersRecipe.create(proxyClassLoader);
+ for (Listener listener : listeners) {
+ listener.init(getAllClasses(metadata.getInterfaceNames()));
+ }
+ } else {
+ listeners = Collections.emptyList();
+ }
+ }
+
+ protected List<Class> getAllClasses(Iterable<String> interfaceNames) throws ClassNotFoundException {
+ List<Class> classes = new ArrayList<Class>();
+ for (String name : interfaceNames) {
+ Class clazz = proxyClassLoader.loadClass(name);
+ classes.add(clazz);
+ }
+ return classes;
+ }
+
+ protected Class[] getInterfaces(Iterable<String> interfaceNames) throws ClassNotFoundException {
+ List<Class> interfaces = new ArrayList<Class>();
+ for (String name : interfaceNames) {
+ Class clazz = proxyClassLoader.loadClass(name);
+ if (clazz.isInterface()) {
+ interfaces.add(clazz);
+ }
+ }
+ return interfaces.toArray(new Class[interfaces.size()]);
+ }
+
+ protected Class getTargetClass(Iterable<String> interfaceNames) throws ClassNotFoundException {
+ Class root = Object.class;
+ for (String name : interfaceNames) {
+ Class clazz = proxyClassLoader.loadClass(name);
+ if (!clazz.isInterface()) {
+ if (root == Object.class) {
+ root = clazz;
+ continue;
+ }
+ // Check that all classes are in the same hierarchy
+ for (Class p = clazz; p != Object.class; p = p.getSuperclass()) {
+ if (p == root) {
+ root = clazz;
+ continue;
+ }
+ }
+ for (Class p = root; p != Object.class; p = p.getSuperclass()) {
+ if (p == clazz) {
+ continue;
+ }
+ }
+ throw new ConstructionException("Classes " + root.getClass().getName() + " and " + clazz.getName() + " are not in the same hierarchy");
+ }
+ }
+ return root;
+ }
+
+ protected Object createProxy(Dispatcher dispatcher, Iterable<String> interfaces) throws Exception {
+ Enhancer e = new Enhancer();
+ e.setClassLoader(proxyClassLoader);
+ e.setSuperclass(getTargetClass(interfaces));
+ e.setInterfaces(getInterfaces(interfaces));
+ e.setInterceptDuringConstruction(false);
+ e.setCallback(dispatcher);
+ e.setUseFactory(false);
+ return e.create();
+ }
+
+ public void serviceChanged(ServiceEvent event) {
+ int eventType = event.getType();
+ ServiceReference ref = event.getServiceReference();
+ switch (eventType) {
+ case ServiceEvent.REGISTERED:
+ case ServiceEvent.MODIFIED:
+ track(ref);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ untrack(ref);
+ break;
+ }
+ }
+
+ protected abstract void track(ServiceReference reference);
+
+ protected abstract void untrack(ServiceReference reference);
+
+ public static class Listener {
+
+ /* Inject by ObjectRecipe */
+ private Object listener;
+ /* Inject by ObjectRecipe */
+ private BindingListenerMetadata metadata;
+
+ private Set<Method> bindMethodsOneArg = new HashSet<Method>();
+ private Set<Method> bindMethodsTwoArgs = new HashSet<Method>();
+ private Set<Method> unbindMethodsOneArg = new HashSet<Method>();
+ private Set<Method> unbindMethodsTwoArgs = new HashSet<Method>();
+
+ public void init(Collection<Class> classes) {
+ Set<Class> clazzes = new HashSet<Class>(classes);
+ clazzes.add(Object.class);
+ Class listenerClass = listener.getClass();
+ String bindName = metadata.getBindMethodName();
+ if (bindName != null) {
+ bindMethodsOneArg.addAll(ReflectionUtils.findCompatibleMethods(listenerClass, bindName, new Class[] { ServiceReference.class }));
+ for (Class clazz : clazzes) {
+ bindMethodsTwoArgs.addAll(ReflectionUtils.findCompatibleMethods(listenerClass, bindName, new Class[] { clazz, Map.class }));
+ }
+ }
+ String unbindName = metadata.getUnbindMethodName();
+ if (unbindName != null) {
+ unbindMethodsOneArg.addAll(ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, new Class[] { ServiceReference.class }));
+ for (Class clazz : clazzes) {
+ unbindMethodsTwoArgs.addAll(ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, new Class[] { clazz, Map.class }));
+ }
+ }
+ }
+
+ public void bind(ServiceReference reference, Object service) {
+ invokeMethods(bindMethodsOneArg, bindMethodsTwoArgs, reference, service);
+ }
+
+ public void unbind(ServiceReference reference, Object service) {
+ invokeMethods(unbindMethodsOneArg, unbindMethodsTwoArgs, reference, service);
+ }
+
+ private void invokeMethods(Set<Method> oneArgMethods, Set<Method> twoArgsMethods, ServiceReference reference, Object service) {
+ for (Method method : oneArgMethods) {
+ try {
+ method.invoke(listener, reference);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ Map<String, Object> props = null;
+ for (Method method : twoArgsMethods) {
+ if (props == null) {
+ props = new HashMap<String, Object>();
+ for (String name : reference.getPropertyKeys()) {
+ props.put(name, reference.getProperty(name));
+ }
+ }
+ try {
+ method.invoke(listener, service, props);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+ }
+
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,505 @@
+/*
+ * 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.geronimo.blueprint.context;
+
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.AbstractList;
+import java.util.Iterator;
+import java.util.AbstractSet;
+import java.util.RandomAccess;
+import java.util.SortedSet;
+import java.util.Set;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import net.sf.cglib.proxy.Dispatcher;
+import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.ModuleContextEventSender;
+import org.apache.geronimo.blueprint.utils.DynamicSortedList;
+import org.apache.geronimo.blueprint.utils.DynamicList;
+import org.apache.geronimo.blueprint.utils.DynamicSet;
+import org.apache.geronimo.blueprint.utils.DynamicSortedSet;
+import org.apache.geronimo.blueprint.utils.DynamicCollection;
+import org.apache.xbean.recipe.ConstructionException;
+import org.apache.xbean.recipe.ExecutionContext;
+import org.apache.xbean.recipe.Recipe;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.reflect.CollectionBasedServiceReferenceComponentMetadata;
+
+/**
+ * A recipe to create a managed collection of service references
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
+ */
+public class CollectionBasedServiceReferenceRecipe extends AbstractServiceReferenceRecipe {
+
+ private final CollectionBasedServiceReferenceComponentMetadata metadata;
+ private final Recipe comparatorRecipe;
+ private Comparator comparator;
+
+ private ManagedCollection collection;
+
+ public CollectionBasedServiceReferenceRecipe(ModuleContext moduleContext,
+ ModuleContextEventSender sender,
+ CollectionBasedServiceReferenceComponentMetadata metadata,
+ Recipe listenersRecipe,
+ Recipe comparatorRecipe) {
+ super(moduleContext, sender, metadata, listenersRecipe);
+ this.metadata = metadata;
+ this.comparatorRecipe = comparatorRecipe;
+ }
+
+ public boolean canCreate(Type type) {
+ return true;
+ }
+
+ protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
+ try {
+
+ if (comparatorRecipe != null) {
+ comparator = (Comparator) comparatorRecipe.create(proxyClassLoader);
+ } else if (metadata.getOrderingComparisonBasis() != 0) {
+ comparator = new NaturalOrderComparator();
+ }
+ boolean orderReferences = metadata.getOrderingComparisonBasis() == CollectionBasedServiceReferenceComponentMetadata.ORDER_BASIS_SERVICE_REFERENCES;
+ boolean memberReferences = metadata.getMemberType() == CollectionBasedServiceReferenceComponentMetadata.MEMBER_TYPE_SERVICE_REFERENCES;
+ if (metadata.getCollectionType() == List.class) {
+ if (comparator != null) {
+ collection = new ManagedSortedList(memberReferences, orderReferences, comparator);
+ } else {
+ collection = new ManagedList(memberReferences);
+ }
+ } else if (metadata.getCollectionType() == Set.class) {
+ if (comparator != null) {
+ collection = new ManagedSortedSet(memberReferences, orderReferences, comparator);
+ } else {
+ collection = new ManagedSet(memberReferences);
+ }
+ } else {
+ throw new IllegalArgumentException("Unsupported collection type " + metadata.getCollectionType().getName());
+ }
+
+ // Create the listeners and initialize them
+ createListeners();
+
+ // Add the created proxy to the context
+ if (getName() != null) {
+ ExecutionContext.getContext().addObject(getName(), collection);
+ }
+
+ // Start tracking the service
+ moduleContext.getBundleContext().addServiceListener(this, getOsgiFilter());
+ retrack();
+
+ return collection;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new ConstructionException(t);
+ }
+ }
+
+ public void destroy() throws Exception {
+ moduleContext.getBundleContext().removeServiceListener(this);
+ List<ServiceDispatcher> dispatchers = new ArrayList<ServiceDispatcher>(collection.getDispatchers());
+ for (ServiceDispatcher dispatcher : dispatchers) {
+ untrack(dispatcher.reference);
+ }
+ }
+
+ private void retrack() {
+ try {
+ ServiceReference[] refs = moduleContext.getBundleContext().getServiceReferences(null, getOsgiFilter());
+ if (refs != null) {
+ for (ServiceReference ref : refs) {
+ track(ref);
+ }
+ }
+ } catch (InvalidSyntaxException e) {
+ // Ignore, should never happen
+ }
+ }
+
+ protected void track(ServiceReference reference) {
+ try {
+ ServiceDispatcher dispatcher = new ServiceDispatcher(reference);
+ dispatcher.proxy = createProxy(dispatcher, Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)));
+ collection.addDispatcher(dispatcher);
+ for (Listener listener : listeners) {
+ listener.bind(dispatcher.reference, dispatcher.proxy);
+ }
+ } catch (Throwable t) {
+ t.printStackTrace(); // TODO: log
+ }
+ }
+
+ protected void untrack(ServiceReference reference) {
+ ServiceDispatcher dispatcher = collection.findDispatcher(reference);
+ if (dispatcher != null) {
+ for (Listener listener : listeners) {
+ listener.unbind(dispatcher.reference, dispatcher.proxy);
+ }
+ collection.removeDispatcher(dispatcher);
+ dispatcher.destroy();
+ }
+ }
+
+ public static class NaturalOrderComparator implements Comparator<Comparable> {
+
+ public int compare(Comparable o1, Comparable o2) {
+ return o1.compareTo(o2);
+ }
+
+ }
+
+
+ public static class ServiceDispatcher implements Dispatcher, Destroyable {
+
+ public ServiceReference reference;
+ public Object service;
+ public Object proxy;
+
+ public ServiceDispatcher(ServiceReference reference) throws Exception {
+ this.reference = reference;
+ this.service = reference.getBundle().getBundleContext().getService(reference);
+ }
+
+ public void destroy() {
+ if (reference != null) {
+ reference.getBundle().getBundleContext().ungetService(reference);
+ service = null;
+ proxy = null;
+ }
+ }
+
+ public Object loadObject() throws Exception {
+ if (service == null) {
+ throw new ServiceUnregisteredException();
+ }
+ return service;
+ }
+ }
+
+ public static class DispatcherComparator implements Comparator<ServiceDispatcher> {
+
+ private final Comparator comparator;
+ private final boolean orderingReferences;
+
+ public DispatcherComparator(Comparator comparator, boolean orderingReferences) {
+ this.comparator = comparator;
+ this.orderingReferences = orderingReferences;
+ }
+
+ public int compare(ServiceDispatcher d1, ServiceDispatcher d2) {
+ return comparator.compare(getOrdering(d1), getOrdering(d2));
+ }
+
+ protected Object getOrdering(ServiceDispatcher d) {
+ return orderingReferences ? d.reference : d.proxy;
+ }
+
+ }
+
+ public static class ManagedCollection extends AbstractCollection {
+
+ protected final boolean references;
+ protected final DynamicCollection<ServiceDispatcher> dispatchers;
+
+ public ManagedCollection(boolean references, DynamicCollection<ServiceDispatcher> dispatchers) {
+ this.references = references;
+ this.dispatchers = dispatchers;
+ }
+
+ public boolean addDispatcher(ServiceDispatcher dispatcher) {
+ return dispatchers.add(dispatcher);
+ }
+
+ public boolean removeDispatcher(ServiceDispatcher dispatcher) {
+ return dispatchers.remove(dispatcher);
+ }
+
+ public DynamicCollection<ServiceDispatcher> getDispatchers() {
+ return dispatchers;
+ }
+
+ public ServiceDispatcher findDispatcher(ServiceReference reference) {
+ for (ServiceDispatcher dispatcher : dispatchers) {
+ if (dispatcher.reference == reference) {
+ return dispatcher;
+ }
+ }
+ return null;
+ }
+
+ public Iterator iterator() {
+ return new ManagedIterator(dispatchers.iterator());
+ }
+
+ public int size() {
+ return dispatchers.size();
+ }
+
+ protected Object getMember(ServiceDispatcher d) {
+ return references ? d.reference : d.proxy;
+ }
+
+ @Override
+ public boolean add(Object o) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ @Override
+ public boolean addAll(Collection c) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ @Override
+ public boolean retainAll(Collection c) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ @Override
+ public boolean removeAll(Collection c) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public class ManagedIterator implements Iterator {
+
+ private final Iterator<ServiceDispatcher> iterator;
+
+ public ManagedIterator(Iterator<ServiceDispatcher> iterator) {
+ this.iterator = iterator;
+ }
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public Object next() {
+ return getMember(iterator.next());
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+ }
+
+ }
+
+
+ public static class ManagedList extends ManagedCollection implements List, RandomAccess {
+
+ protected DynamicList<ServiceDispatcher> dispatchers;
+
+ public ManagedList(boolean references) {
+ this(references, new DynamicList<ServiceDispatcher>());
+ }
+
+ protected ManagedList(boolean references, DynamicList<ServiceDispatcher> dispatchers) {
+ super(references, dispatchers);
+ this.dispatchers = dispatchers;
+ }
+
+ @Override
+ public int size() {
+ return dispatchers.size();
+ }
+
+ public Object get(int index) {
+ return getMember(dispatchers.get(index));
+ }
+
+ public int indexOf(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ ListIterator e = listIterator();
+ while (e.hasNext()) {
+ if (o.equals(e.next())) {
+ return e.previousIndex();
+ }
+ }
+ return -1;
+ }
+
+ public int lastIndexOf(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ ListIterator e = listIterator(size());
+ while (e.hasPrevious()) {
+ if (o.equals(e.previous())) {
+ return e.nextIndex();
+ }
+ }
+ return -1;
+ }
+
+ public ListIterator listIterator() {
+ return listIterator(0);
+ }
+
+ public ListIterator listIterator(int index) {
+ return new ManagedListIterator(dispatchers.listIterator(index));
+ }
+
+ public List<ServiceDispatcher> subList(int fromIndex, int toIndex) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public Object set(int index, Object element) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public void add(int index, Object element) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public Object remove(int index) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public boolean addAll(int index, Collection c) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public class ManagedListIterator implements ListIterator {
+
+ protected final ListIterator<ServiceDispatcher> iterator;
+
+ public ManagedListIterator(ListIterator<ServiceDispatcher> iterator) {
+ this.iterator = iterator;
+ }
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public Object next() {
+ return getMember(iterator.next());
+ }
+
+ public boolean hasPrevious() {
+ return iterator.hasPrevious();
+ }
+
+ public Object previous() {
+ return getMember(iterator.previous());
+ }
+
+ public int nextIndex() {
+ return iterator.nextIndex();
+ }
+
+ public int previousIndex() {
+ return iterator.previousIndex();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public void set(Object o) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+
+ public void add(Object o) {
+ throw new UnsupportedOperationException("This collection is read only");
+ }
+ }
+
+ }
+
+ public static class ManagedSortedList extends ManagedList {
+
+ public ManagedSortedList(boolean references, boolean orderingReferences, Comparator comparator) {
+ super(references, new DynamicSortedList<ServiceDispatcher>(new DispatcherComparator(comparator, orderingReferences)));
+ }
+
+ }
+
+ public static class ManagedSet extends ManagedCollection implements Set {
+
+ public ManagedSet(boolean references) {
+ this(references, new DynamicSet<ServiceDispatcher>());
+ }
+
+ protected ManagedSet(boolean references, DynamicSet<ServiceDispatcher> dispatchers) {
+ super(references, dispatchers);
+ }
+
+ }
+
+ public static class ManagedSortedSet extends ManagedSet implements SortedSet {
+
+ protected final DynamicSortedSet<ServiceDispatcher> dispatchers;
+ protected final Comparator comparator;
+
+ public ManagedSortedSet(boolean references, boolean orderingReferences, Comparator comparator) {
+ super(references, new DynamicSortedSet<ServiceDispatcher>(new DispatcherComparator(comparator, orderingReferences)));
+ this.dispatchers = (DynamicSortedSet<ServiceDispatcher>) super.dispatchers;
+ this.comparator = comparator;
+ }
+
+ public Comparator comparator() {
+ return comparator;
+ }
+
+ public SortedSet subSet(Object fromElement, Object toElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public SortedSet headSet(Object toElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public SortedSet tailSet(Object fromElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public Object first() {
+ return getMember(dispatchers.first());
+ }
+
+ public Object last() {
+ return getMember(dispatchers.last());
+ }
+
+ }
+
+}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java?rev=767090&r1=767089&r2=767090&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java Tue Apr 21 09:46:41 2009
@@ -26,13 +26,13 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Comparator;
import org.apache.geronimo.blueprint.namespace.ComponentDefinitionRegistryImpl;
import org.apache.geronimo.blueprint.reflect.ServiceExportComponentMetadataImpl;
import org.apache.xbean.recipe.ArrayRecipe;
import org.apache.xbean.recipe.CollectionRecipe;
import org.apache.xbean.recipe.ConstructionException;
-import org.apache.xbean.recipe.DefaultRepository;
import org.apache.xbean.recipe.MapRecipe;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
@@ -140,15 +140,33 @@
cr.add(createRecipe(listener));
}
}
- ReferenceServiceRecipe recipe = new ReferenceServiceRecipe(moduleContext,
+ UnaryServiceReferenceRecipe recipe = new UnaryServiceReferenceRecipe(moduleContext,
moduleContext.getSender(),
metadata,
cr);
recipe.setName(component.getName());
return recipe;
} else if (component instanceof CollectionBasedServiceReferenceComponentMetadata) {
- // TODO
- throw new IllegalStateException("Unsupported component type " + component.getClass());
+ CollectionBasedServiceReferenceComponentMetadata metadata = (CollectionBasedServiceReferenceComponentMetadata) component;
+ CollectionRecipe listenersRecipe = null;
+ if (metadata.getBindingListeners() != null) {
+ listenersRecipe = new CollectionRecipe(ArrayList.class);;
+ for (BindingListenerMetadata listener : (Collection<BindingListenerMetadata>) metadata.getBindingListeners()) {
+ listenersRecipe.add(createRecipe(listener));
+ }
+ }
+ Recipe comparatorRecipe = null;
+ if (metadata.getComparator() != null) {
+ comparatorRecipe = (Recipe) getValue(metadata.getComparator(), Comparator.class);
+ }
+ CollectionBasedServiceReferenceRecipe recipe = new CollectionBasedServiceReferenceRecipe(
+ moduleContext,
+ moduleContext.getSender(),
+ metadata,
+ listenersRecipe,
+ comparatorRecipe);
+ recipe.setName(component.getName());
+ return recipe;
} else {
throw new IllegalStateException("Unsupported component type " + component.getClass());
}
@@ -234,7 +252,7 @@
}
private Recipe createRecipe(BindingListenerMetadata listener) throws Exception {
- ObjectRecipe recipe = new ObjectRecipe(ReferenceServiceRecipe.Listener.class);
+ ObjectRecipe recipe = new ObjectRecipe(AbstractServiceReferenceRecipe.Listener.class);
recipe.allow(Option.PRIVATE_PROPERTIES);
recipe.setProperty("listener", getValue(listener.getListenerComponent(), null));
recipe.setProperty("metadata", listener);
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java?rev=767090&r1=767089&r2=767090&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java Tue Apr 21 09:46:41 2009
@@ -716,6 +716,8 @@
} else if (MEMBER_TYPE_SERVICE_REFERENCE.equals(memberType)) {
references.setMemberType(CollectionBasedServiceReferenceComponentMetadata.MEMBER_TYPE_SERVICE_REFERENCES);
}
+ } else {
+ references.setMemberType(CollectionBasedServiceReferenceComponentMetadata.MEMBER_TYPE_SERVICES);
}
if (element.hasAttribute(ORDERING_BASIS_ATTRIBUTE)) {
String ordering = element.getAttribute(ORDERING_BASIS_ATTRIBUTE);
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceRegistrationProxy.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceRegistrationProxy.java?rev=767090&r1=767089&r2=767090&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceRegistrationProxy.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceRegistrationProxy.java Tue Apr 21 09:46:41 2009
@@ -27,6 +27,7 @@
import java.util.Set;
import org.apache.geronimo.blueprint.BlueprintConstants;
+import org.apache.geronimo.blueprint.utils.ReflectionUtils;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceUnregisteredException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceUnregisteredException.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceUnregisteredException.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceUnregisteredException.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,11 @@
+package org.apache.geronimo.blueprint.context;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: gnodet
+ * Date: Apr 20, 2009
+ * Time: 3:53:19 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ServiceUnregisteredException extends RuntimeException {
+}
Copied: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java (from r766654, geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java?p2=geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java&p1=geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java&r1=766654&r2=767090&rev=767090&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceServiceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java Tue Apr 21 09:46:41 2009
@@ -19,39 +19,23 @@
package org.apache.geronimo.blueprint.context;
import java.lang.reflect.Type;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.Collection;
-import java.util.Map;
-import java.util.HashMap;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.Set;
-import org.apache.xbean.recipe.AbstractRecipe;
+import net.sf.cglib.proxy.Dispatcher;
+import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.ModuleContextEventSender;
import org.apache.xbean.recipe.ConstructionException;
-import org.apache.xbean.recipe.Recipe;
-import org.apache.xbean.recipe.CollectionRecipe;
import org.apache.xbean.recipe.ExecutionContext;
-import org.apache.geronimo.blueprint.LifeCycle;
-import org.apache.geronimo.blueprint.BlueprintConstants;
-import org.apache.geronimo.blueprint.ModuleContextEventSender;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceEvent;
+import org.apache.xbean.recipe.Recipe;
import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.blueprint.reflect.UnaryServiceReferenceComponentMetadata;
-import org.osgi.service.blueprint.reflect.BindingListenerMetadata;
-import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.blueprint.context.ModuleContext;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import net.sf.cglib.proxy.ProxyRefDispatcher;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Dispatcher;
+import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.osgi.service.blueprint.reflect.UnaryServiceReferenceComponentMetadata;
/**
* A recipe to create an unary OSGi service reference.
@@ -61,62 +45,41 @@
* @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
* @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
*/
-public class ReferenceServiceRecipe extends AbstractRecipe implements Dispatcher, LifeCycle, ServiceListener {
+public class UnaryServiceReferenceRecipe extends AbstractServiceReferenceRecipe {
- private final ModuleContext moduleContext;
- private final ModuleContextEventSender sender;
private final UnaryServiceReferenceComponentMetadata metadata;
- private final CollectionRecipe listenersRecipe;
private Class proxyClass;
- private String filter;
- private List<Listener> listeners;
private volatile ServiceReference trackedServiceReference;
private volatile Object trackedService;
private final Object monitor = new Object();
- public ReferenceServiceRecipe(ModuleContext moduleContext,
- ModuleContextEventSender sender,
- UnaryServiceReferenceComponentMetadata metadata,
- CollectionRecipe listenersRecipe) {
- this.moduleContext = moduleContext;
- this.sender = sender;
+ public UnaryServiceReferenceRecipe(ModuleContext moduleContext,
+ ModuleContextEventSender sender,
+ UnaryServiceReferenceComponentMetadata metadata,
+ Recipe listenersRecipe) {
+ super(moduleContext, sender, metadata, listenersRecipe);
this.metadata = metadata;
- this.listenersRecipe = listenersRecipe;
}
protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
// TODO: serviceAvailabilitySpecification
try {
- ClassLoader classLoader = new BundleDelegatingClassLoader(moduleContext.getBundleContext().getBundle(),
- getClass().getClassLoader());
- Enhancer e = new Enhancer();
- e.setClassLoader(classLoader);
- e.setSuperclass(getTargetClass(classLoader));
- e.setInterfaces(getInterfaces(classLoader));
- e.setInterceptDuringConstruction(false);
- e.setCallback(this);
- e.setUseFactory(false);
- Object obj = e.create();
+ // Create the proxy
+ Object obj = createProxy(new ServiceDispatcher(), metadata.getInterfaceNames());
proxyClass = obj.getClass();
-
- if (listenersRecipe != null) {
- listeners = (List<Listener>) listenersRecipe.create(classLoader);
- for (Listener listener : listeners) {
- listener.init(proxyClass);
- }
- } else {
- listeners = Collections.emptyList();
- }
-
- filter = getOsgiFilter();
- moduleContext.getBundleContext().addServiceListener(this, filter);
- retrack();
-
+ // Create the listeners and initialize them
+ createListeners();
+ // Add the created proxy to the context
if (getName() != null) {
ExecutionContext.getContext().addObject(getName(), obj);
}
+ // Start tracking the service
+ moduleContext.getBundleContext().addServiceListener(this, getOsgiFilter());
+ retrack();
+
+ // Return the object
return obj;
} catch (Throwable t) {
t.printStackTrace();
@@ -124,148 +87,25 @@
}
}
- private String getOsgiFilter() {
- List<String> members = new ArrayList<String>();
- // Handle filter
- String filter = metadata.getFilter();
- if (filter != null && filter.length() > 0) {
- if (!filter.startsWith("(")) {
- filter = "(" + filter + ")";
- }
- members.add(filter);
- }
- // Handle interfaces
- Set<String> interfaces = (Set<String>) metadata.getInterfaceNames();
- if (interfaces != null && !interfaces.isEmpty()) {
- for (String itf : interfaces) {
- members.add("(" + Constants.OBJECTCLASS + "=" + itf + ")");
- }
- }
- // Handle component name
- String componentName = metadata.getComponentName();
- if (componentName != null && componentName.length() > 0) {
- members.add("(" + BlueprintConstants.COMPONENT_NAME_PROPERTY + "=" + componentName + ")");
- }
- // Create filter
- if (members.isEmpty()) {
- throw new IllegalStateException("No constraints were specified on the service reference");
- }
- StringBuilder sb = new StringBuilder("(&");
- for (String member : members) {
- sb.append(member);
- }
- sb.append(")");
- return sb.toString();
- }
-
- private Class[] getInterfaces(ClassLoader classLoader) throws ClassNotFoundException {
- List<Class> interfaces = new ArrayList<Class>();
- for (String name : (Set<String>) metadata.getInterfaceNames()) {
- Class clazz = classLoader.loadClass(name);
- if (clazz.isInterface()) {
- interfaces.add(clazz);
- }
- }
- return interfaces.toArray(new Class[interfaces.size()]);
- }
-
- private Class getTargetClass(ClassLoader classLoader) throws ClassNotFoundException {
- Class root = Object.class;
- for (String name : (Set<String>) metadata.getInterfaceNames()) {
- Class clazz = classLoader.loadClass(name);
- if (!clazz.isInterface()) {
- if (root == Object.class) {
- root = clazz;
- continue;
- }
- // Check that all classes are in the same hierarchy
- for (Class p = clazz; p != Object.class; p = p.getSuperclass()) {
- if (p == root) {
- root = clazz;
- continue;
- }
- }
- for (Class p = root; p != Object.class; p = p.getSuperclass()) {
- if (p == clazz) {
- continue;
- }
- }
- throw new ConstructionException("Classes " + root.getClass().getName() + " and " + clazz.getName() + " are not in the same hierarchy");
- }
- }
- return root;
- }
-
public boolean canCreate(Type type) {
return true;
}
- public Object loadObject() throws Exception {
- Object svc = trackedService;
- if (svc == null && metadata.getTimeout() > 0) {
- Set<String> interfaces = (Set<String>) metadata.getInterfaceNames();
- sender.sendWaiting(moduleContext, interfaces.toArray(new String[interfaces.size()]), filter);
- synchronized (monitor) {
- monitor.wait(metadata.getTimeout());
- }
- svc = trackedService;
- }
- if (svc == null) {
- throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", proxyClass.getSuperclass(), filter);
- }
- return svc;
- }
-
- public void init() throws Exception {
- }
-
public void destroy() throws Exception {
moduleContext.getBundleContext().removeServiceListener(this);
+ unbind();
}
private ServiceReference getBestServiceReference(ServiceReference[] references) {
- int length = (references == null) ? 0 : references.length;
- if (length == 0) { /* if no service is being tracked */
+ if (references == null || references.length == 0) {
return null;
}
- int index = 0;
- if (length > 1) { /* if more than one service, select highest ranking */
- int rankings[] = new int[length];
- int count = 0;
- int maxRanking = Integer.MIN_VALUE;
- for (int i = 0; i < length; i++) {
- Object property = references[i].getProperty(Constants.SERVICE_RANKING);
- int ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
- rankings[i] = ranking;
- if (ranking > maxRanking) {
- index = i;
- maxRanking = ranking;
- count = 1;
- } else {
- if (ranking == maxRanking) {
- count++;
- }
- }
- }
- if (count > 1) { /* if still more than one service, select lowest id */
- long minId = Long.MAX_VALUE;
- for (int i = 0; i < length; i++) {
- if (rankings[i] == maxRanking) {
- long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
- if (id < minId) {
- index = i;
- minId = id;
- }
- }
- }
- }
- }
- return references[index];
+ return Collections.max(Arrays.asList(references));
}
private void retrack() {
try {
- ServiceReference[] refs = moduleContext.getBundleContext().getServiceReferences(null, filter);
+ ServiceReference[] refs = moduleContext.getBundleContext().getServiceReferences(null, getOsgiFilter());
ServiceReference ref = getBestServiceReference(refs);
if (ref != null) {
bind(ref);
@@ -277,27 +117,21 @@
}
}
- private void track(ServiceReference ref) {
+ protected void track(ServiceReference ref) {
if (trackedServiceReference == null) {
bind(ref);
} else {
- Object property = trackedServiceReference.getProperty(Constants.SERVICE_RANKING);
- int trackedRanking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
- property = ref.getProperty(Constants.SERVICE_RANKING);
- int newRanking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
- if (trackedRanking > newRanking) {
+ if (trackedServiceReference.compareTo(ref) > 0) {
return;
- } else if (trackedRanking == newRanking) {
- long trackedId = ((Long) (trackedServiceReference.getProperty(Constants.SERVICE_ID))).longValue();
- long newId = ((Long) (ref.getProperty(Constants.SERVICE_ID))).longValue();
- if (trackedId < newId) {
- return;
- }
}
bind(ref);
}
}
+ protected void untrack(ServiceReference ref) {
+ retrack();
+ }
+
private void bind(ServiceReference ref) {
synchronized (monitor) {
if (trackedServiceReference != null) {
@@ -324,82 +158,24 @@
}
}
- public void serviceChanged(ServiceEvent event) {
- int eventType = event.getType();
- ServiceReference ref = event.getServiceReference();
- switch (eventType) {
- case ServiceEvent.REGISTERED:
- case ServiceEvent.MODIFIED:
- track(ref);
- break;
- case ServiceEvent.UNREGISTERING:
- retrack();
- break;
- }
- }
-
- public static class Listener {
+ public class ServiceDispatcher implements Dispatcher {
- private Object listener;
- private BindingListenerMetadata metadata;
- private List<Method> bindMethodsOneArg;
- private List<Method> bindMethodsTwoArgs;
- private List<Method> unbindMethodsOneArg;
- private List<Method> unbindMethodsTwoArgs;
-
- public void init(Class proxyClass) {
- Class listenerClass = listener.getClass();
- Class[] oneArgParams = new Class[] { ServiceReference.class };
- Class[] twoArgsParams = new Class[] { proxyClass, Map.class };
- String bindName = metadata.getBindMethodName();
- if (bindName != null) {
- bindMethodsOneArg = ReflectionUtils.findCompatibleMethods(listenerClass, bindName, oneArgParams);
- bindMethodsTwoArgs = ReflectionUtils.findCompatibleMethods(listenerClass, bindName, twoArgsParams);
- } else {
- bindMethodsOneArg = Collections.emptyList();
- bindMethodsTwoArgs = Collections.emptyList();
- }
- String unbindName = metadata.getUnbindMethodName();
- if (unbindName != null) {
- unbindMethodsOneArg = ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, oneArgParams);
- unbindMethodsTwoArgs = ReflectionUtils.findCompatibleMethods(listenerClass, unbindName, twoArgsParams);
- } else {
- unbindMethodsOneArg = Collections.emptyList();
- unbindMethodsTwoArgs = Collections.emptyList();
- }
- }
-
- public void bind(ServiceReference reference, Object service) {
- invokeMethods(bindMethodsOneArg, bindMethodsTwoArgs, reference, service);
- }
-
- public void unbind(ServiceReference reference, Object service) {
- invokeMethods(unbindMethodsOneArg, unbindMethodsTwoArgs, reference, service);
- }
-
- private void invokeMethods(List<Method> oneArgMethods, List<Method> twoArgsMethods, ServiceReference reference, Object service) {
- for (Method method : oneArgMethods) {
- try {
- method.invoke(listener, reference);
- } catch (Exception e) {
- e.printStackTrace(); // TODO: log
+ public Object loadObject() throws Exception {
+ Object svc = trackedService;
+ if (svc == null && metadata.getTimeout() > 0) {
+ Set<String> interfaces = (Set<String>) metadata.getInterfaceNames();
+ sender.sendWaiting(moduleContext, interfaces.toArray(new String[interfaces.size()]), getOsgiFilter());
+ synchronized (monitor) {
+ monitor.wait(metadata.getTimeout());
}
+ svc = trackedService;
}
- Map<String, Object> props = null;
- for (Method method : twoArgsMethods) {
- if (props == null) {
- props = new HashMap<String, Object>();
- for (String name : reference.getPropertyKeys()) {
- props.put(name, reference.getProperty(name));
- }
- }
- try {
- method.invoke(listener, service, props);
- } catch (Exception e) {
- e.printStackTrace(); // TODO: log
- }
+ if (svc == null) {
+ throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", proxyClass.getSuperclass(), getOsgiFilter());
}
+ return svc;
}
}
+
}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicCollection.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicCollection.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicCollection.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicCollection.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,263 @@
+/*
+ * 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.geronimo.blueprint.utils;
+
+import java.lang.ref.WeakReference;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Collection that allows iterators to see addition or removals of elements while iterating.
+ * This collection and its iterators are thread safe but all operations happen under a
+ * synchronization lock, so the performance in heavy concurrency load is far from optimal.
+ * If such a use is needed, a CopyOnWriteArrayList may be more suited.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766653 $, $Date: 2009-04-20 13:19:48 +0200 (Mon, 20 Apr 2009) $
+ */
+public class DynamicCollection<E> extends AbstractCollection<E> {
+
+ protected final Object lock = new Object();
+ protected final List<E> storage;
+ protected final List<WeakReference<DynamicIterator>> iterators;
+
+ public DynamicCollection() {
+ this.storage = new ArrayList<E>();
+ this.iterators = new ArrayList<WeakReference<DynamicIterator>>();
+ }
+
+ public Iterator<E> iterator() {
+ return iterator(0);
+ }
+
+ public Iterator<E> iterator(int index) {
+ DynamicIterator iterator = createIterator(index);
+ synchronized (lock) {
+ for (Iterator<WeakReference<DynamicIterator>> it = iterators.iterator(); it.hasNext();) {
+ if (it.next().get() == null) {
+ it.remove();
+ }
+ }
+ iterators.add(new WeakReference<DynamicIterator>(iterator));
+ }
+ return iterator;
+ }
+
+ protected DynamicIterator createIterator(int index) {
+ return new DynamicIterator(index);
+ }
+
+ public int size() {
+ synchronized (lock) {
+ return storage.size();
+ }
+ }
+
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ public boolean contains(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ return storage.contains(o);
+ }
+ }
+
+ public Object[] toArray() {
+ synchronized (lock) {
+ return storage.toArray();
+ }
+ }
+
+ public <T> T[] toArray(T[] a) {
+ synchronized (lock) {
+ return storage.toArray(a);
+ }
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ synchronized (lock) {
+ return storage.containsAll(c);
+ }
+ }
+
+ public boolean add(E o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ return storage.add(o);
+ }
+ }
+
+ public boolean remove(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ int index = storage.indexOf(o);
+ return remove(index) != null;
+ }
+ }
+
+ public void add(int index, E o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ storage.add(index, o);
+ for (Iterator<WeakReference<DynamicIterator>> it = iterators.iterator(); it.hasNext();) {
+ DynamicIterator i = it.next().get();
+ if (i == null) {
+ it.remove();
+ } else {
+ i.addedIndex(index);
+ }
+ }
+ }
+ }
+
+ public E remove(int index) {
+ synchronized (lock) {
+ E o = storage.remove(index);
+ for (Iterator<WeakReference<DynamicIterator>> it = iterators.iterator(); it.hasNext();) {
+ WeakReference<DynamicIterator> r = it.next();
+ DynamicIterator i = r.get();
+ if (i == null) {
+ it.remove();
+ } else {
+ i.removedIndex(index);
+ }
+ }
+ return o;
+ }
+ }
+
+ public class DynamicIterator implements Iterator<E> {
+
+ protected int index;
+ protected boolean hasNextCalled;
+ protected E next;
+ protected boolean hasPreviousCalled;
+ protected E previous;
+ protected E last;
+
+ public DynamicIterator() {
+ this(0);
+ }
+
+ public DynamicIterator(int index) {
+ this.index = index;
+ }
+
+ protected synchronized void removedIndex(int index) {
+ if (index < this.index || (index == this.index && (hasNextCalled || hasPreviousCalled))) {
+ this.index--;
+ }
+ }
+
+ protected synchronized void addedIndex(int index) {
+ if (index < this.index || (index == this.index && (hasNextCalled || hasPreviousCalled))) {
+ this.index++;
+ }
+ }
+
+ public synchronized boolean hasNext() {
+ synchronized (lock) {
+ hasPreviousCalled = false;
+ hasNextCalled = true;
+ next = index < storage.size() ? storage.get(index) : null;
+ return next != null;
+ }
+ }
+
+ public synchronized boolean hasPrevious() {
+ synchronized (lock) {
+ hasPreviousCalled = true;
+ hasNextCalled = false;
+ previous = index > 0 ? storage.get(index - 1) : null;
+ return previous != null;
+ }
+ }
+
+ public synchronized E next() {
+ try {
+ if (!hasNextCalled) {
+ hasNext();
+ }
+ last = next;
+ if (next != null) {
+ ++index;
+ return next;
+ } else {
+ throw new NoSuchElementException();
+ }
+ } finally {
+ hasPreviousCalled = false;
+ hasNextCalled = false;
+ }
+ }
+
+ public synchronized E previous() {
+ try {
+ if (!hasPreviousCalled) {
+ hasPrevious();
+ }
+ last = previous;
+ if (previous != null) {
+ --index;
+ return previous;
+ } else {
+ throw new NoSuchElementException();
+ }
+ } finally {
+ hasPreviousCalled = false;
+ hasNextCalled = false;
+ }
+ }
+
+ public synchronized int nextIndex() {
+ return index;
+ }
+
+ public synchronized int previousIndex() {
+ return index - 1;
+ }
+
+ public synchronized void remove() {
+ if (last == null) {
+ throw new IllegalStateException();
+ }
+ synchronized (lock) {
+ if (storage.get(index - 1) == last) {
+ storage.remove(index - 1);
+ }
+ }
+ last = null;
+
+ }
+ }
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicList.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicList.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicList.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicList.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,115 @@
+/*
+ * 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.geronimo.blueprint.utils;
+
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.RandomAccess;
+import java.lang.ref.WeakReference;
+
+/**
+ * Same as DynamicCollection but implementing the List interface.
+ * All list method implemetations are actually provided by the DynamicCollection class
+ * itself as it already relies on a List storage.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766653 $, $Date: 2009-04-20 13:19:48 +0200 (Mon, 20 Apr 2009) $
+ */
+public class DynamicList<E> extends DynamicCollection<E> implements List<E>, RandomAccess {
+
+ public ListIterator<E> listIterator() {
+ return listIterator(0);
+ }
+
+ public ListIterator<E> listIterator(int index) {
+ return (ListIterator<E>) iterator(index);
+ }
+
+ @Override
+ protected DynamicIterator createIterator(int index) {
+ return new DynamicListIterator(index);
+ }
+
+ public E get(int index) {
+ synchronized (lock) {
+ return storage.get(index);
+ }
+ }
+
+ public E set(int index, E o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ return storage.set(index, o);
+ }
+ }
+
+ public int indexOf(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ return storage.indexOf(o);
+ }
+ }
+
+ public int lastIndexOf(Object o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ synchronized (lock) {
+ return storage.lastIndexOf(o);
+ }
+ }
+
+ public boolean addAll(int index, Collection<? extends E> c) {
+ synchronized (lock) {
+ boolean modified = false;
+ Iterator<? extends E> e = c.iterator();
+ while (e.hasNext()) {
+ add(index++, e.next());
+ modified = true;
+ }
+ return modified;
+ }
+ }
+
+ public List<E> subList(int fromIndex, int toIndex) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ protected class DynamicListIterator extends DynamicIterator implements ListIterator<E> {
+
+ public DynamicListIterator(int index) {
+ super(index);
+ }
+
+ public synchronized void set(E o) {
+ DynamicList.this.set(index, o);
+ }
+
+ public synchronized void add(E o) {
+ DynamicList.this.add(index++, o);
+ }
+
+ }
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSet.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSet.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSet.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSet.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,48 @@
+/*
+ * 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.geronimo.blueprint.utils;
+
+import java.util.Set;
+import java.util.Iterator;
+import java.lang.ref.WeakReference;
+
+/**
+ * Same as DynamicCollection but implementing the Set interface, thus not allowing
+ * duplicates.
+ * Note that the insertion performance of this set is not very good due to the underlying
+ * storage as a list which enforce a full traversal of the storage before adding any element.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766653 $, $Date: 2009-04-20 13:19:48 +0200 (Mon, 20 Apr 2009) $
+ */
+public class DynamicSet<E> extends DynamicCollection<E> implements Set<E> {
+
+ @Override
+ public boolean add(E o) {
+ synchronized (lock) {
+ if (!storage.contains(o)) {
+ storage.add(o);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedList.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedList.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedList.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedList.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,74 @@
+/*
+ * 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.geronimo.blueprint.utils;
+
+import java.util.Comparator;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ *
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766653 $, $Date: 2009-04-20 13:19:48 +0200 (Mon, 20 Apr 2009) $
+ */
+public class DynamicSortedList<E> extends DynamicList<E> {
+
+ protected Comparator<E> comparator;
+
+ public DynamicSortedList() {
+ }
+
+ public DynamicSortedList(Comparator<E> comparator) {
+ this.comparator = comparator;
+ }
+
+ @Override
+ public boolean add(E o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ if (comparator == null && !(o instanceof Comparable)) {
+ throw new IllegalArgumentException("Elements in this sorted list must implement the " + Comparable.class.getName() + " interface");
+ }
+ synchronized (lock) {
+ int index = Collections.binarySearch(storage, o, comparator);
+ if (index < 0) {
+ index = -index - 1;
+ } else {
+ index = index + 1;
+ }
+ super.add(index, o);
+ return true;
+ }
+ }
+
+ public void add(int index, Object o) {
+ throw new UnsupportedOperationException("Insertion at a given position is not allowed on a sorted list");
+ }
+
+ public boolean addAll(int index, Collection c) {
+ throw new UnsupportedOperationException("Insertion at a given position is not allowed on a sorted list");
+ }
+
+ public Object set(int index, Object o) {
+ throw new UnsupportedOperationException("Insertion at a given position is not allowed on a sorted list");
+ }
+
+}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedSet.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedSet.java?rev=767090&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedSet.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/DynamicSortedSet.java Tue Apr 21 09:46:41 2009
@@ -0,0 +1,103 @@
+/*
+ * 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.geronimo.blueprint.utils;
+
+import java.util.Comparator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.NoSuchElementException;
+
+/**
+ *
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 766653 $, $Date: 2009-04-20 13:19:48 +0200 (Mon, 20 Apr 2009) $
+ */
+public class DynamicSortedSet<E> extends DynamicSet<E> implements SortedSet<E> {
+
+ protected Comparator<? super E> comparator;
+
+ public DynamicSortedSet() {
+ }
+
+ public DynamicSortedSet(Comparator<? super E> comparator) {
+ this.comparator = comparator;
+ }
+
+ @Override
+ public boolean add(E o) {
+ if (o == null) {
+ throw new NullPointerException();
+ }
+ if (comparator == null && !(o instanceof Comparable)) {
+ throw new IllegalArgumentException("Elements in this sorted list must implement the " + Comparable.class.getName() + " interface");
+ }
+ synchronized (lock) {
+ int index = Collections.binarySearch(storage, o, comparator);
+ if (index < 0) {
+ super.add(-index - 1, o);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public Comparator<? super E> comparator() {
+ return comparator;
+ }
+
+ public SortedSet<E> subSet(E fromElement, E toElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public SortedSet<E> headSet(E toElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public SortedSet<E> tailSet(E fromElement) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public E first() {
+ synchronized (lock) {
+ if (storage.isEmpty()) {
+ throw new NoSuchElementException();
+ } else {
+ return storage.get(0);
+ }
+ }
+ }
+
+ public E last() {
+ synchronized (lock) {
+ if (storage.isEmpty()) {
+ throw new NoSuchElementException();
+ } else {
+ return storage.get(storage.size() - 1);
+ }
+ }
+ }
+
+ @Override
+ public void add(int index, E o) {
+ throw new UnsupportedOperationException("Insertion at a given position is not allowed on a sorted list");
+ }
+}
\ No newline at end of file
Copied: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java (from r766654, geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java?p2=geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java&p1=geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java&r1=766654&r2=767090&rev=767090&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReflectionUtils.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java Tue Apr 21 09:46:41 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.geronimo.blueprint.context;
+package org.apache.geronimo.blueprint.utils;
import java.lang.reflect.Method;
import java.util.Set;
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain