From 04dcd09976ecc5aa2948993b9a9a2d90d239ee44 Mon Sep 17 00:00:00 2001 From: antelder Date: Thu, 28 Jul 2011 10:58:07 +0000 Subject: Delete old beta3 branch as its going to be recreated from the current trunk git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1151789 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/core/DefaultExtensionPointRegistry.java | 194 --- .../sca/core/DefaultFactoryExtensionPoint.java | 162 --- .../core/DefaultModuleActivatorExtensionPoint.java | 154 --- .../sca/core/DefaultUtilityExtensionPoint.java | 219 ---- .../tuscany/sca/core/ExtensionPointRegistry.java | 66 - .../sca/core/ExtensionPointRegistryLocator.java | 44 - .../tuscany/sca/core/FactoryExtensionPoint.java | 55 - .../apache/tuscany/sca/core/LifeCycleListener.java | 37 - .../apache/tuscany/sca/core/ModuleActivator.java | 72 - .../sca/core/ModuleActivatorExtensionPoint.java | 53 - .../tuscany/sca/core/UtilityExtensionPoint.java | 74 -- .../sca/extensibility/ClassLoaderContext.java | 253 ---- .../ContextClassLoaderServiceDiscoverer.java | 194 --- .../sca/extensibility/ServiceDeclaration.java | 85 -- .../extensibility/ServiceDeclarationParser.java | 375 ------ .../sca/extensibility/ServiceDiscoverer.java | 54 - .../sca/extensibility/ServiceDiscovery.java | 306 ----- .../tuscany/sca/extensibility/ServiceHelper.java | 226 ---- .../extensibility/impl/ClassLoaderDelegate.java | 89 -- .../extensibility/impl/InvalidSyntaxException.java | 86 -- .../tuscany/sca/extensibility/impl/LDAPFilter.java | 1373 -------------------- 21 files changed, 4171 deletions(-) delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistry.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistryLocator.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/FactoryExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/LifeCycleListener.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivator.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivatorExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/UtilityExtensionPoint.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java delete mode 100644 sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java (limited to 'sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany') diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java deleted file mode 100644 index f7fe4df87c..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import static org.apache.tuscany.sca.extensibility.ServiceHelper.newInstance; - -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.tuscany.sca.extensibility.ServiceDeclaration; -import org.apache.tuscany.sca.extensibility.ServiceDiscovery; -import org.apache.tuscany.sca.extensibility.ServiceHelper; - -/** - * Default implementation of a registry to hold all the Tuscany core extension - * points. As the point of contact for all extension artifacts this registry - * allows loaded extensions to find all other parts of the system and register - * themselves appropriately. - * - * @tuscany.spi.extension.asclient - * - * @version $Rev$ $Date$ - */ -public class DefaultExtensionPointRegistry implements ExtensionPointRegistry { - protected Map, Object> extensionPoints = new HashMap, Object>(); - private ServiceDiscovery discovery; - /** - * Constructs a new registry. - */ - public DefaultExtensionPointRegistry() { - this.discovery = ServiceDiscovery.getInstance(); - } - - public DefaultExtensionPointRegistry(ServiceDiscovery discovery) { - this.discovery = discovery; - } - - /** - * Add an extension point to the registry. This default implementation - * stores extensions against the interfaces that they implement. - * - * @param extensionPoint The instance of the extension point - * - * @throws IllegalArgumentException if extensionPoint is null - */ - public synchronized void addExtensionPoint(Object extensionPoint) { - addExtensionPoint(extensionPoint, null); - } - - public synchronized void addExtensionPoint(Object extensionPoint, ServiceDeclaration declaration) { - if (extensionPoint == null) { - throw new IllegalArgumentException("Cannot register null as an ExtensionPoint"); - } - ServiceHelper.start(extensionPoint); - - Set> interfaces = getAllInterfaces(extensionPoint.getClass()); - for (Class i : interfaces) { - registerExtensionPoint(i, extensionPoint, declaration); - } - } - - protected void registerExtensionPoint(Class i, Object extensionPoint, ServiceDeclaration declaration) { - extensionPoints.put(i, extensionPoint); - } - - /** - * Get the extension point by the interface that it implements - * - * @param extensionPointType The lookup key (extension point interface) - * @return The instance of the extension point - * - * @throws IllegalArgumentException if extensionPointType is null - */ - public synchronized T getExtensionPoint(Class extensionPointType) { - if (extensionPointType == null) { - throw new IllegalArgumentException("Cannot lookup ExtensionPoint of type null"); - } - - Object extensionPoint = findExtensionPoint(extensionPointType); - if (extensionPoint == null) { - - // Dynamically load an extension point class declared under META-INF/services - try { - ServiceDeclaration extensionPointDeclaration = - getServiceDiscovery().getServiceDeclaration(extensionPointType); - if (extensionPointDeclaration != null) { - extensionPoint = newInstance(this, extensionPointDeclaration); - // Cache the loaded extension point - addExtensionPoint(extensionPoint, extensionPointDeclaration); - } - } catch (Throwable e) { - throw new IllegalArgumentException(e); - } - } - return extensionPointType.cast(extensionPoint); - } - - protected Object findExtensionPoint(Class extensionPointType) { - return extensionPoints.get(extensionPointType); - } - - /** - * Remove an extension point based on the interface that it implements - * - * @param extensionPoint The extension point to remove - * - * @throws IllegalArgumentException if extensionPoint is null - */ - public synchronized void removeExtensionPoint(Object extensionPoint) { - if (extensionPoint == null) { - throw new IllegalArgumentException("Cannot remove null as an ExtensionPoint"); - } - - ServiceHelper.stop(extensionPoint); - - Set> interfaces = getAllInterfaces(extensionPoint.getClass()); - for (Class i : interfaces) { - unregisterExtensionPoint(i); - } - } - - protected void unregisterExtensionPoint(Class i) { - extensionPoints.remove(i); - } - - /** - * Returns the set of interfaces implemented by the given class and its - * ancestors or a blank set if none - */ - private static Set> getAllInterfaces(Class clazz) { - Set> implemented = new HashSet>(); - getAllInterfaces(clazz, implemented); - implemented.remove(LifeCycleListener.class); - return implemented; - } - - private static void getAllInterfaces(Class clazz, Set> implemented) { - Class[] interfaces = clazz.getInterfaces(); - for (Class interfaze : interfaces) { - if (Modifier.isPublic(interfaze.getModifiers())) { - implemented.add(interfaze); - } - } - Class superClass = clazz.getSuperclass(); - // Object has no superclass so check for null - if (superClass != null && !superClass.equals(Object.class)) { - getAllInterfaces(superClass, implemented); - } - } - - public synchronized void start() { - ExtensionPointRegistryLocator.addExtensionPointRegistry(this); - } - - public synchronized void stop() { - // Get a unique map as an extension point may exist in the map by different keys - Map map = new IdentityHashMap(); - for (Object extp : extensionPoints.values()) { - if (extp instanceof LifeCycleListener) { - LifeCycleListener listener = (LifeCycleListener)extp; - map.put(listener, listener); - } - } - ServiceHelper.stop(map.values()); - extensionPoints.clear(); - ExtensionPointRegistryLocator.removeExtensionPointRegistry(this); - } - - public ServiceDiscovery getServiceDiscovery() { - return discovery; - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java deleted file mode 100644 index 1c49ea4ee4..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultFactoryExtensionPoint.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import static org.apache.tuscany.sca.extensibility.ServiceHelper.newInstance; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.tuscany.sca.extensibility.ServiceDeclaration; - - - -/** - * Default implementation of a model factory extension point. - * - * @version $Rev$ $Date$ - */ -public class DefaultFactoryExtensionPoint implements FactoryExtensionPoint { - private ExtensionPointRegistry registry; - private Map, Object> factories = new ConcurrentHashMap, Object>(); - - /** - * Constructs a new DefaultModelFactoryExtensionPoint. - */ - public DefaultFactoryExtensionPoint(ExtensionPointRegistry extensionPointRegistry) { - this.registry = extensionPointRegistry; - } - - /** - * Add a model factory extension. - * - * @param factory The factory to add - */ - public void addFactory(Object factory) { - Class[] interfaces = factory.getClass().getInterfaces(); - if (interfaces.length == 0) { - Class sc = factory.getClass().getSuperclass(); - if (sc != Object.class) { - factories.put(sc, factory); - } - } else { - for (int i = 0; i[] interfaces = factory.getClass().getInterfaces(); - if (interfaces.length == 0) { - Class sc = factory.getClass().getSuperclass(); - if (sc != Object.class) { - factories.remove(sc); - } - } else { - for (int i = 0; i() { - public ClassLoader run() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (classLoader != null) { - Thread.currentThread().setContextClassLoader(classLoader); - } - return tccl; - } - }); - } - - /** - * Get a factory implementing the given interface. - * @param factoryInterface The lookup key (factory interface) - * @return The factory - */ - public T getFactory(Class factoryInterface) { - Object factory = factories.get(factoryInterface); - if (factory == null) { - - // Dynamically load a factory class declared under META-INF/services - try { - ServiceDeclaration factoryDeclaration = - registry.getServiceDiscovery().getServiceDeclaration(factoryInterface); - if (factoryDeclaration != null) { - try { - // Constructor taking the extension point registry - factory = newInstance(registry, factoryDeclaration); - } catch (NoSuchMethodException e) { - factory = newInstance(factoryDeclaration.loadClass(), FactoryExtensionPoint.class, this); - } - - // Cache the loaded factory - factories.put(factoryInterface, factory); - - return factoryInterface.cast(factory); - - } else { - - // If the input interface is an abstract class - if (!factoryInterface.isInterface() && Modifier.isAbstract(factoryInterface.getModifiers())) { - Method newInstanceMethod = factoryInterface.getDeclaredMethod("newInstance"); - ClassLoader tccl = setContextClassLoader(factoryInterface.getClassLoader()); - try { - - // Create a new instance - factory = newInstanceMethod.invoke(null); - - // Cache the factory - factories.put(factoryInterface, factory); - - return factoryInterface.cast(factory); - } catch (Exception e) { - // Sorry no factory found - return null; - } finally { - setContextClassLoader(tccl); - } - } else { - - // Sorry no factory found - return null; - } - } - } catch (Exception e) { - throw new IllegalArgumentException(e); - } - } else { - return factoryInterface.cast(factory); - } - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java deleted file mode 100644 index 99792d0215..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultModuleActivatorExtensionPoint.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import static org.apache.tuscany.sca.extensibility.ServiceHelper.newInstance; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.tuscany.sca.extensibility.ServiceDeclaration; - -/** - * Default implementation of an extension point to hold Tuscany module activators. - * - * @version $Rev$ $Date$ - */ -public class DefaultModuleActivatorExtensionPoint implements ModuleActivatorExtensionPoint { - private final static Logger logger = Logger.getLogger(DefaultModuleActivatorExtensionPoint.class.getName()); - private List activators = new ArrayList(); - private boolean loadedActivators; - private boolean started; - private ExtensionPointRegistry registry; - - /** - * Constructs a new extension point. - */ - public DefaultModuleActivatorExtensionPoint(ExtensionPointRegistry registry) { - this.registry = registry; - } - - public void addModuleActivator(ModuleActivator activator) { - activators.add(activator); - } - - public List getModuleActivators() { - loadModuleActivators(); - return activators; - } - - public void removeModuleActivator(ModuleActivator activator) { - if (activators.remove(activator)) { - activator.stop(); - } - } - - /** - * Dynamically load module activators declared under META-INF/services - */ - private synchronized void loadModuleActivators() { - if (loadedActivators) - return; - - // Get the activator service declarations - Collection activatorDeclarations; - try { - // Load the module activators by ranking - activatorDeclarations = registry.getServiceDiscovery().getServiceDeclarations(ModuleActivator.class.getName(), true); - } catch (IOException e) { - throw new IllegalStateException(e); - } - - // Load and instantiate module activators - for (ServiceDeclaration activatorDeclaration : activatorDeclarations) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("Loading " + activatorDeclaration.getClassName()); - } - ModuleActivator activator = null; - try { - Class activatorClass = (Class)activatorDeclaration.loadClass(); - try { - activator = newInstance(activatorClass, ExtensionPointRegistry.class, registry); - } catch (NoSuchMethodException e) { - try { - activator = - newInstance(activatorClass, - new Class[] {ExtensionPointRegistry.class, Map.class}, - registry, - activatorDeclaration.getAttributes()); - - } catch (NoSuchMethodException e1) { - activator = newInstance(activatorClass); - - } - } - } catch (Throwable e) { - String optional = activatorDeclaration.getAttributes().get("optional"); - if ("true".equalsIgnoreCase(optional)) { - // If the optional flag is true, just log the error - logger.log(Level.SEVERE, e.getMessage(), e); - continue; - } else { - throw new IllegalArgumentException(e); - } - } - addModuleActivator(activator); - } - - loadedActivators = true; - } - - public void start() { - if (started) { - return; - } - getModuleActivators(); - for (ModuleActivator activator : activators) { - try { - activator.start(); - } catch (Throwable e) { - // Ignore the failing module for now - logger.log(Level.SEVERE, e.getMessage(), e); - } - } - started = true; - } - - public void stop() { - if (!started) { - return; - } - for (int i = activators.size() - 1; i >= 0; i--) { - try { - activators.get(i).stop(); - } catch (Throwable e) { - // Ignore the failing module for now - logger.log(Level.SEVERE, e.getMessage(), e); - } - } - started = false; - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java deleted file mode 100644 index 40e4635d77..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultUtilityExtensionPoint.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import static org.apache.tuscany.sca.extensibility.ServiceHelper.newInstance; - -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.tuscany.sca.extensibility.ServiceDeclaration; - -/** - * Default implementation of an extension point to hold Tuscany utility utilities. - * - * @version $Rev$ $Date$ - */ -public class DefaultUtilityExtensionPoint implements UtilityExtensionPoint { - private Map utilities = new ConcurrentHashMap(); - - private ExtensionPointRegistry registry; - /** - * Constructs a new extension point. - */ - public DefaultUtilityExtensionPoint(ExtensionPointRegistry extensionPoints) { - this.registry = extensionPoints; - } - - /** - * Add a utility to the extension point. This default implementation - * stores utilities against the interfaces that they implement. - * - * @param utility The instance of the utility - * - * @throws IllegalArgumentException if utility is null - */ - public void addUtility(Object utility) { - addUtility(null, utility); - } - - public void addUtility(Object key, Object utility) { - if (utility == null) { - throw new IllegalArgumentException("Cannot register null as a Service"); - } - - if (utility instanceof LifeCycleListener) { - ((LifeCycleListener)utility).start(); - } - - if (key == null) { - Class cls = utility.getClass(); - Set> interfaces = getAllInterfaces(cls); - for (Class i : interfaces) { - utilities.put(i, utility); - } - if (interfaces.isEmpty() || isConcreteClass(cls)) { - utilities.put(cls, utility); - } - } else { - utilities.put(key, utility); - } - } - - /** - * Get the utility by the interface that it implements - * - * @param utilityType The lookup key (utility interface) - * @return The instance of the utility - * - * @throws IllegalArgumentException if utilityType is null - */ - public T getUtility(Class utilityType) { - return getUtility(utilityType, null); - } - - /** - * Remove a utility based on the interface that it implements - * - * @param utility The utility to remove - * - * @throws IllegalArgumentException if utility is null - */ - public void removeUtility(Object utility) { - if (utility == null) { - throw new IllegalArgumentException("Cannot remove null as a Service"); - } - - if(utility instanceof LifeCycleListener) { - ((LifeCycleListener) utility).stop(); - } - - for (Iterator> i = utilities.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = i.next(); - if (entry.getValue() == utility) { - i.remove(); - } - } - } - - /** - * Returns the set of interfaces implemented by the given class and its - * ancestors or a blank set if none - */ - private static Set> getAllInterfaces(Class clazz) { - Set> implemented = new HashSet>(); - getAllInterfaces(clazz, implemented); - implemented.remove(LifeCycleListener.class); - return implemented; - } - - private static void getAllInterfaces(Class clazz, Set> implemented) { - Class[] interfaces = clazz.getInterfaces(); - for (Class interfaze : interfaces) { - if (Modifier.isPublic(interfaze.getModifiers())) { - implemented.add(interfaze); - } - } - Class superClass = clazz.getSuperclass(); - // Object has no superclass so check for null - if (superClass != null && !superClass.equals(Object.class)) { - getAllInterfaces(superClass, implemented); - } - } - - public T getUtility(Class utilityType, Object key) { - if (utilityType == null) { - throw new IllegalArgumentException("Cannot lookup Service of type null"); - } - - if (key == null) { - key = utilityType; - } - - Object utility = utilities.get(key); - - if (utility == null) { - - // Dynamically load a utility class declared under META-INF/services/"utilityType" - try { - ServiceDeclaration utilityDeclaration = - registry.getServiceDiscovery().getServiceDeclaration(utilityType.getName()); - Class utilityClass = null; - if (utilityDeclaration != null) { - utilityClass = utilityDeclaration.loadClass(); - } else if (isConcreteClass(utilityType)) { - utilityClass = utilityType; - key = utilityType; - } - if (utilityClass != null) { - // Construct the utility - if (utilityDeclaration != null) { - utility = newInstance(registry, utilityDeclaration); - } else { - try { - utility = newInstance(utilityClass, ExtensionPointRegistry.class, registry); - } catch (NoSuchMethodException e) { - utility = newInstance(utilityClass); - } - } - // Cache the loaded utility - if (key == utilityType) { - addUtility(utility); - } else { - addUtility(key, utility); - } - } - } catch (Throwable e) { - throw new IllegalArgumentException(e); - } - } - return utilityType.cast(utility); - } - - private boolean isConcreteClass(Class utilityType) { - int modifiers = utilityType.getModifiers(); - return !utilityType.isInterface() && Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers); - } - - public void start() { - // NOOP - } - - public synchronized void stop() { - // Get a unique map as an extension point may exist in the map by different keys - Map map = new IdentityHashMap(); - for (Object util : utilities.values()) { - if (util instanceof LifeCycleListener) { - LifeCycleListener listener = (LifeCycleListener)util; - map.put(listener, listener); - } - } - for (LifeCycleListener listener : map.values()) { - listener.stop(); - } - utilities.clear(); - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistry.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistry.java deleted file mode 100644 index 8f9ab7ed3e..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistry.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import org.apache.tuscany.sca.extensibility.ServiceDiscovery; - - -/** - * The registry for the Tuscany core extension points. As the point of contact - * for all extension artifacts this registry allows loaded extensions to find - * all other parts of the system and register themselves appropriately. - * - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.asclient - */ -public interface ExtensionPointRegistry extends LifeCycleListener { - - /** - * Add an extension point to the registry - * @param extensionPoint The instance of the extension point - * - * @throws IllegalArgumentException if extensionPoint is null - */ - void addExtensionPoint(Object extensionPoint); - - /** - * Get the extension point by the interface - * @param extensionPointType The lookup key (extension point interface) - * @return The instance of the extension point - * - * @throws IllegalArgumentException if extensionPointType is null - */ - T getExtensionPoint(Class extensionPointType); - - /** - * Remove an extension point - * @param extensionPoint The extension point to remove - * - * @throws IllegalArgumentException if extensionPoint is null - */ - void removeExtensionPoint(Object extensionPoint); - - /** - * Get an instance of the ServiceDiscovery - * @return an instance of the ServiceDiscovery associated with the environment - */ - ServiceDiscovery getServiceDiscovery(); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistryLocator.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistryLocator.java deleted file mode 100644 index 8027f0ac50..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ExtensionPointRegistryLocator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import java.util.ArrayList; -import java.util.List; - -public class ExtensionPointRegistryLocator { - - private static List extensionPointRegistries = new ArrayList(); - - public static ExtensionPointRegistry getExtensionPointRegistry() { - return extensionPointRegistries.size() > 0 ? extensionPointRegistries.get(0) : null; - } - - public static List getExtensionPointRegistries() { - return extensionPointRegistries; - } - - public static void addExtensionPointRegistry(ExtensionPointRegistry extensionPointRegistry) { - extensionPointRegistries.add(extensionPointRegistry); - } - - public static void removeExtensionPointRegistry(ExtensionPointRegistry extensionPointRegistry) { - extensionPointRegistries.remove(extensionPointRegistry); - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/FactoryExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/FactoryExtensionPoint.java deleted file mode 100644 index c3d2fd282a..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/FactoryExtensionPoint.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.tuscany.sca.core; - -/** - * An extension point for model factories. Model factories are provided to - * abstract the classes that represent artifacts in the assembly model away - * from their creation mechanism. When the runtime needs to extend the model - * as it reads in contributed artifacts it looks up the factory for the - * artifact required in this registry - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.asclient - */ -public interface FactoryExtensionPoint { - - /** - * Add a model factory extension. - * - * @param factory The factory to add - */ - void addFactory(Object factory); - - /** - * Remove a model factory extension. - * - * @param factory The factory to remove - */ - void removeFactory(Object factory); - - /** - * Get a factory implementing the given interface. - * @param factoryInterface the lookup key (factory interface) - * @return The factory - */ - T getFactory(Class factoryInterface); - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/LifeCycleListener.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/LifeCycleListener.java deleted file mode 100644 index ca92cb8129..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/LifeCycleListener.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.tuscany.sca.core; - -/** - * A listener that responds to the start/stop event of the ExtensionPointRegistry. Tuscany extension - * points or extensions can implement this interface to receive callbacks when the registry is started - * or stopped - * @tuscany.spi.extension.inheritfrom - */ -public interface LifeCycleListener { - /** - * The method will be invoked when the extension point registry is started - */ - void start(); - /** - * The method will be invoked when the extension point registry is stopped - */ - void stop(); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivator.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivator.java deleted file mode 100644 index ddc9a6981c..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.tuscany.sca.core; - - -/** - * ModuleActivator represents a module that plugs into the Tuscany system. Each - * module should provide an implementation of this interface and register the - * ModuleActivator implementation class by defining a file named - * - * "META-INF/services/org.apache.tuscany.core.ModuleActivator" - * - * The content of the file is the class name of the ModuleActivator implementation. - * The implementation class can have different flavors of constructors. The following - * order will be searched: - *
    - *
  • (ExtensionRegistry.class) - *
  • (ExtensionRegistry.class, Map.class) - *
  • () - *
- * - * - * - * - * The same instance - * will be used to invoke all the methods during different phases of the module - * activation. Note that the start and stop methods defined by this interface - * take a reference to the Tuscany SCA runtime ExtensionPointRegistry. This - * gives the ModuleActivator the opportunity to add extension points to the - * registry as it is requested to start up and remove them when it is requested - * to shut down. - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.inheritfrom - */ -public interface ModuleActivator extends LifeCycleListener { - - /** - * This method is invoked when the module is started by the Tuscany runtime. - * It can be used by this module to register extensions against extension - * points. - * - * @param registry The extension point registry - */ - void start(); - - /** - * This method is invoked when the module is stopped by the Tuscany runtime. - * It can be used by this module to unregister extensions against the - * extension points. - * - * @param registry The extension point registry - */ - void stop(); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivatorExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivatorExtensionPoint.java deleted file mode 100644 index 7070d33f2c..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/ModuleActivatorExtensionPoint.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.tuscany.sca.core; - -import java.util.List; - - -/** - * The extension point for the Tuscany module activator extensions. - * - * @version $Rev$ $Date$ - */ -public interface ModuleActivatorExtensionPoint extends LifeCycleListener { - - /** - * Add a module activator extension to the extension point - * @param activator The instance of the module activator - * - * @throws IllegalArgumentException if activator is null - */ - void addModuleActivator(ModuleActivator activator); - - /** - * Returns the module activator extensions. - * @return The module activator extensions - */ - List getModuleActivators(); - - /** - * Remove a module activator - * @param activator The module activator to remove - * - * @throws IllegalArgumentException if activator is null - */ - void removeModuleActivator(ModuleActivator activator); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/UtilityExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/UtilityExtensionPoint.java deleted file mode 100644 index 7acc7fc409..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/UtilityExtensionPoint.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.tuscany.sca.core; - - -/** - * The extension point for the Tuscany core utility extensions. - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.asclient - */ -public interface UtilityExtensionPoint extends LifeCycleListener { - - /** - * Add a utility to the extension point - * @param utility The instance of the utility - * - * @throws IllegalArgumentException if utility is null - */ - void addUtility(Object utility); - - /** - * Add a utility to the extension point for a given key - * @param utility The instance of the utility - * - * @throws IllegalArgumentException if utility is null - */ - void addUtility(Object key, Object utility); - - /** - * Get the utility by the interface - * @param utilityType The lookup key (utility interface) - * @return The instance of the utility - * - * @throws IllegalArgumentException if utilityType is null - */ - T getUtility(Class utilityType); - - /** - * Get an instance of the utility by the interface and key - * @param utilityType The lookup key (utility interface) - * @param key A key associated with the utility, if it is null, - * then the utilityType is used as the key - * @return The instance of the utility - * - * @throws IllegalArgumentException if utilityType is null - */ - T getUtility(Class utilityType, Object key); - - /** - * Remove a utility - * @param utility The utility to remove - * - * @throws IllegalArgumentException if utility is null - */ - void removeUtility(Object utility); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java deleted file mode 100644 index 598c897402..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.IOException; -import java.net.URL; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.List; - -import org.apache.tuscany.sca.extensibility.impl.ClassLoaderDelegate; - -/** - * A utility that controls context class loaders - * @tuscany.spi.extension.asclient - */ -public class ClassLoaderContext { - private ClassLoader classLoader; - - /** - * Create a context with the parent classloader and a list of service types that can be discovered - * by the {@link ServiceDiscovery} - * @param parent - * @param discovery - * @param serviceTypes - */ - public ClassLoaderContext(ClassLoader parent, ServiceDiscovery discovery, Class... serviceTypes) { - this(parent, getClassLoaders(discovery, serviceTypes)); - } - - private ClassLoaderContext(ClassLoader parent, List delegates) { - List loaders = new ArrayList(delegates); - loaders.remove(parent); - if (delegates.isEmpty()) { - classLoader = parent; - } else { - classLoader = new ClassLoaderDelegate(parent, loaders); - } - } - - /** - * Create a context that is visible to the parent classloader as well as the list of classloaders - * @param parent - * @param delegates - */ - public ClassLoaderContext(ClassLoader parent, ClassLoader... delegates) { - this(parent, Arrays.asList(delegates)); - } - - /** - * Create a context with the parent classloader and a list of service types that can be discovered - * by the {@link ServiceDiscovery} - * @param parent - * @param discovery - * @param serviceTypes - */ - public ClassLoaderContext(ClassLoader parent, ServiceDiscovery discovery, String... serviceTypes) { - this(parent, getClassLoaders(discovery, serviceTypes)); - } - - public T doPrivileged(PrivilegedAction action) { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl != classLoader) { - Thread.currentThread().setContextClassLoader(classLoader); - } - try { - return action.run(); - } finally { - if (tccl != classLoader) { - Thread.currentThread().setContextClassLoader(tccl); - } - } - } - - public T doPrivileged(PrivilegedExceptionAction action) throws PrivilegedActionException { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl != classLoader) { - Thread.currentThread().setContextClassLoader(classLoader); - } - try { - return action.run(); - } catch (Exception e) { - throw new PrivilegedActionException(e); - } finally { - if (tccl != classLoader) { - Thread.currentThread().setContextClassLoader(tccl); - } - } - } - - /** - * Set the thread context classloader (TCCL) to a classloader that delegates to a collection - * of classloaders - * @param parent The parent classloader - * @param delegates A list of classloaders to try - * @return The existing TCCL - */ - public static ClassLoader setContextClassLoader(ClassLoader parent, ClassLoader... delegates) { - ClassLoaderContext context = new ClassLoaderContext(parent, delegates); - return context.setContextClassLoader(); - } - - /** - * Set the context classloader so that it can access the list of service providers - * @param parent The parent classloader - * @param serviceNames A list of service provider names - * @return The old TCCL if a new one is set, otherwise null - */ - public static ClassLoader setContextClassLoader(ClassLoader parent, - ServiceDiscovery discovery, - String... serviceNames) { - ClassLoaderContext context = new ClassLoaderContext(parent, discovery, serviceNames); - return context.setContextClassLoader(); - } - - /** - * Set the context classloader so that it can access the list of service providers - * @param parent The parent classloader - * @param serviceNames A list of service provider names - * @return The old TCCL if a new one is set, otherwise null - */ - public static ClassLoader setContextClassLoader(ClassLoader parent, - ServiceDiscovery discovery, - Class... serviceTypes) { - ClassLoaderContext context = new ClassLoaderContext(parent, discovery, serviceTypes); - return context.setContextClassLoader(); - } - - public ClassLoader setContextClassLoader() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl != classLoader) { - Thread.currentThread().setContextClassLoader(classLoader); - return tccl; - } else { - return null; - } - } - - private static ClassLoader getClassLoader(ServiceDiscovery discovery, String serviceProvider) { - try { - ServiceDeclaration sd = discovery.getServiceDeclaration(serviceProvider); - if (sd != null) { - try { - if (sd.loadClass() != null) { - return sd.loadClass().getClassLoader(); - } else { - return new ClassLoaderImpl(sd); - } - } catch (ClassNotFoundException e) { - return new ClassLoaderImpl(sd); - } - } - } catch (Exception e) { - // Ignore - } - return null; - } - - private static List getClassLoaders(ServiceDiscovery discovery, String... serviceNames) { - List loaders = new ArrayList(); - for (String sp : serviceNames) { - ClassLoader loader = getClassLoader(discovery, sp); - if (loader != null) { - if (!loaders.contains(loader)) { - loaders.add(loader); - } - } - } - ClassLoader tccl = discovery.getContextClassLoader(); - if (!loaders.contains(tccl)) { - loaders.add(tccl); - } - return loaders; - } - - private static ClassLoader getClassLoader(ServiceDiscovery discovery, Class serviceType) { - try { - ServiceDeclaration sd = discovery.getServiceDeclaration(serviceType); - if (sd != null) { - return sd.loadClass().getClassLoader(); - } - } catch (Exception e) { - // Ignore - } - return null; - } - - private static List getClassLoaders(ServiceDiscovery discovery, Class... serviceTypes) { - List loaders = new ArrayList(); - for (Class serviceType : serviceTypes) { - ClassLoader classLoader = getClassLoader(discovery, serviceType); - if (classLoader != null && !loaders.contains(classLoader)) { - loaders.add(classLoader); - } - } - ClassLoader tccl = discovery.getContextClassLoader(); - if (!loaders.contains(tccl)) { - loaders.add(tccl); - } - return loaders; - } - - public ClassLoader getClassLoader() { - return classLoader; - } - - private static class ClassLoaderImpl extends ClassLoader { - private final ServiceDeclaration sd; - - public ClassLoaderImpl(ServiceDeclaration sd) { - super(); - this.sd = sd; - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - return sd.loadClass(name); - } - - @Override - protected URL findResource(String name) { - return sd.getResource(name); - } - - @Override - protected Enumeration findResources(String name) throws IOException { - return sd.getResources(name); - } - - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java deleted file mode 100644 index d40c37e4be..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ContextClassLoaderServiceDiscoverer.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * A ServiceDiscoverer that find META-INF/services/... using the Context ClassLoader. - * - * @version $Rev$ $Date$ - */ -public class ContextClassLoaderServiceDiscoverer implements ServiceDiscoverer { - private static final Logger logger = Logger.getLogger(ContextClassLoaderServiceDiscoverer.class.getName()); - - public class ServiceDeclarationImpl implements ServiceDeclaration { - private URL url; - private String className; - private Class javaClass; - private Map attributes; - - public ServiceDeclarationImpl(URL url, String className, Map attributes) { - super(); - this.url = url; - this.className = className; - this.attributes = attributes; - } - - public Map getAttributes() { - return attributes; - } - - public String getClassName() { - return className; - } - - public URL getLocation() { - return url; - } - - public Class loadClass() throws ClassNotFoundException { - if (className == null) { - return null; - } - if (javaClass == null) { - javaClass = loadClass(className); - } - return javaClass; - } - - public Class loadClass(String className) throws ClassNotFoundException { - return Class.forName(className, false, classLoaderReference.get()); - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("Location: ").append(url); - sb.append(" ClassLoader: ").append(classLoaderReference.get()); - sb.append(" Attributes: ").append(attributes); - return sb.toString(); - } - - public URL getResource(final String name) { - return AccessController.doPrivileged(new PrivilegedAction() { - public URL run() { - return classLoaderReference.get().getResource(name); - } - }); - } - - public boolean isAssignableTo(Class serviceType) { - try { - loadClass(); - } catch (ClassNotFoundException e) { - // Ignore - } - return (javaClass != null && serviceType.isAssignableFrom(javaClass)); - } - - @Override - public Enumeration getResources(String name) throws IOException { - return Collections.enumeration(ContextClassLoaderServiceDiscoverer.this.getResources(name)); - } - } - - private WeakReference classLoaderReference; - - public ContextClassLoaderServiceDiscoverer() { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - this.classLoaderReference = new WeakReference(classLoader); - } - - public ContextClassLoaderServiceDiscoverer(ClassLoader classLoader) { - if (classLoader == null) { - classLoader = Thread.currentThread().getContextClassLoader(); - } - this.classLoaderReference = new WeakReference(classLoader); - } - - public ClassLoader getContextClassLoader() { - //return classLoaderReference.get(); - return Thread.currentThread().getContextClassLoader(); - } - - private Collection getResources(final String name) throws IOException { - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction>() { - public Collection run() throws IOException { - List urls = Collections.list(classLoaderReference.get().getResources(name)); - // Eliminate the duplicate URLs (which can be found from child/parent classloaders) - return new HashSet(urls); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); - } - } - - public ServiceDeclaration getServiceDeclaration(String name) throws IOException { - Collection declarations = getServiceDeclarations(name); - if (declarations.isEmpty()) { - return null; - } else { - return declarations.iterator().next(); - } - } - - public Collection getServiceDeclarations(String serviceName) { - Collection descriptors = new HashSet(); - - // http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPathFactory.html - boolean isPropertyFile = "javax.xml.xpath.XPathFactory".equals(serviceName); - - String name = serviceName; - if (serviceName.startsWith("/")) { - // If the service name starts with /, treat it as the entry name - name = serviceName.substring(1); - } else { - // Use JDK SPI pattern - name = "META-INF/services/" + serviceName; - } - - boolean debug = logger.isLoggable(Level.FINE); - try { - for (final URL url : getResources(name)) { - if (debug) { - logger.fine("Reading service provider file: " + url.toExternalForm()); - } - - for (Map attributes : ServiceDeclarationParser.load(url, isPropertyFile)) { - String className = attributes.get("class"); - ServiceDeclarationImpl descriptor = new ServiceDeclarationImpl(url, className, attributes); - descriptors.add(descriptor); - } - } - } catch (IOException e) { - logger.log(Level.SEVERE, e.getMessage(), e); - } - return descriptors; - - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java deleted file mode 100644 index 24b2c17a0f..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.IOException; -import java.net.URL; -import java.util.Enumeration; -import java.util.Map; - -/** - * Service declaration using J2SE Jar service provider spec Classes specified - * inside this declaration are loaded using the ClassLoader used to read the - * configuration file corresponding to this declaration. - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.asclient - */ -public interface ServiceDeclaration { - /** - * Load a java class in the same context as the service definition - * @param className The class name - * @return The loaded class - * @throws ClassNotFoundException - */ - Class loadClass(String className) throws ClassNotFoundException; - - /** - * Get the java class for the service impl - * @return The java class - */ - Class loadClass() throws ClassNotFoundException; - - /** - * Get all attributes (name=value pairs) defined for the given entry - * @return All attributes keyed by name - */ - Map getAttributes(); - - /** - * Check if the service implementation class is a type of the service - * @param serviceType The java class of the service SPI - * @return true if the implementation class is a type of the service - */ - boolean isAssignableTo(Class serviceType); - - URL getLocation(); - - /** - * Return the class name for the service provider - * @return - */ - String getClassName(); - - URL getResource(String name); - Enumeration getResources(String name) throws IOException; - - /** - * The service descriptor might be hashed - * @param obj Another object - * @return - */ - boolean equals(Object obj); - /** - * The service descriptor might be hashed - * @return - */ - int hashCode(); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java deleted file mode 100644 index f546e44dfb..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclarationParser.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.xml.namespace.QName; - -/** - * Parser for the service descriptors. The syntax of the service declaration is similar with the OSGi - * headers with the following exceptions: - *
    - *
  • Tuscany uses , and ; as the separator for attibutes - *
  • Tuscany - */ -public class ServiceDeclarationParser { - - // private static final String PATH_SEPARATOR = ","; // OSGi style - private static final String PATH_SEPARATOR = "|"; - - // private static final String SEGMENT_SEPARATOR = ";"; // OSGi style - private static final String SEGMENT_SEPARATOR = ";,"; - - private static final String ATTRIBUTE_SEPARATOR = "="; - private static final String DIRECTIVE_SEPARATOR = ":="; - - private static final char QUOTE_CHAR = '"'; - private static final String QUOTE = "\""; - - // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2, - // path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2 - public static List parse(String header) { - - if (header != null) { - if (header.length() == 0) { - throw new IllegalArgumentException("A header cannot be an empty string."); - } - - String[] clauseStrings = parseDelimitedString(header, PATH_SEPARATOR); - - List completeList = new ArrayList(); - for (int i = 0; (clauseStrings != null) && (i < clauseStrings.length); i++) { - completeList.add(parseClause(clauseStrings[i])); - } - - return completeList; - } - - return null; - - } - - /** - * Parse the declaration into a map of name/value pairs. The class name is added under "class" - * and directives are added using @ as the key. - * @param declaration - * @return A map of attributes - */ - public static Map parseDeclaration(String declaration) { - List descriptors = parse(declaration); - Descriptor descriptor = descriptors.get(0); - Map map = new HashMap(); - map.putAll(descriptor.getAttributes()); - map.put("class", descriptor.getValue()); - for (Map.Entry e : descriptor.getDirectives().entrySet()) { - // For directives, add @ as the prefix for the key - map.put("@" + e.getKey(), e.getValue()); - } - return map; - } - - // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2 - private static Descriptor parseClause(String clauseString) throws IllegalArgumentException { - // Break string into semi-colon delimited pieces. - String[] pieces = parseDelimitedString(clauseString, SEGMENT_SEPARATOR); - - // Count the number of different paths; paths - // will not have an '=' in their string. This assumes - // that paths come first, before directives and - // attributes. - int pathCount = 0; - for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++) { - if (pieces[pieceIdx].indexOf('=') >= 0) { - break; - } - pathCount++; - } - - // Create an array of paths. - String[] paths = new String[pathCount]; - System.arraycopy(pieces, 0, paths, 0, pathCount); - - // Parse the directives/attributes. - Map dirsMap = new HashMap(); - Map attrsMap = new HashMap(); - int idx = -1; - String sep = null; - for (int pieceIdx = pathCount; pieceIdx < pieces.length; pieceIdx++) { - // Check if it is a directive. - if ((idx = pieces[pieceIdx].indexOf(DIRECTIVE_SEPARATOR)) >= 0) { - sep = DIRECTIVE_SEPARATOR; - } - // Check if it is an attribute. - else if ((idx = pieces[pieceIdx].indexOf(ATTRIBUTE_SEPARATOR)) >= 0) { - sep = ATTRIBUTE_SEPARATOR; - } - // It is an error. - else { - throw new IllegalArgumentException("Not a directive/attribute: " + clauseString); - } - - String key = pieces[pieceIdx].substring(0, idx).trim(); - String value = pieces[pieceIdx].substring(idx + sep.length()).trim(); - - // Remove quotes, if value is quoted. - if (value.startsWith(QUOTE) && value.endsWith(QUOTE)) { - value = value.substring(1, value.length() - 1); - } - - // Save the directive/attribute in the appropriate array. - if (sep.equals(DIRECTIVE_SEPARATOR)) { - // Check for duplicates. - if (dirsMap.get(key) != null) { - throw new IllegalArgumentException("Duplicate directive: " + key); - } - dirsMap.put(key, value); - } else { - // Check for duplicates. - if (attrsMap.get(key) != null) { - throw new IllegalArgumentException("Duplicate attribute: " + key); - } - attrsMap.put(key, value); - } - } - - StringBuffer path = new StringBuffer(); - for (int i = 0; i < paths.length; i++) { - path.append(paths[i]); - if (i != paths.length - 1) { - path.append(';'); - } - } - - Descriptor descriptor = new Descriptor(); - descriptor.text = clauseString; - descriptor.value = path.toString(); - descriptor.valueComponents = paths; - descriptor.attributes = attrsMap; - descriptor.directives = dirsMap; - - return descriptor; - } - - /** - * Parses delimited string and returns an array containing the tokens. This - * parser obeys quotes, so the delimiter character will be ignored if it is - * inside of a quote. This method assumes that the quote character is not - * included in the set of delimiter characters. - * @param value the delimited string to parse. - * @param delim the characters delimiting the tokens. - * @return an array of string tokens or null if there were no tokens. - **/ - private static String[] parseDelimitedString(String value, String delim) { - if (value == null) { - value = ""; - } - - List list = new ArrayList(); - - int CHAR = 1; - int DELIMITER = 2; - int STARTQUOTE = 4; - int ENDQUOTE = 8; - - StringBuffer sb = new StringBuffer(); - - int expecting = (CHAR | DELIMITER | STARTQUOTE); - - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - - boolean isDelimiter = (delim.indexOf(c) >= 0); - boolean isQuote = (c == QUOTE_CHAR); - - if (isDelimiter && ((expecting & DELIMITER) > 0)) { - list.add(sb.toString().trim()); - sb.delete(0, sb.length()); - expecting = (CHAR | DELIMITER | STARTQUOTE); - } else if (isQuote && ((expecting & STARTQUOTE) > 0)) { - sb.append(c); - expecting = CHAR | ENDQUOTE; - } else if (isQuote && ((expecting & ENDQUOTE) > 0)) { - sb.append(c); - expecting = (CHAR | STARTQUOTE | DELIMITER); - } else if ((expecting & CHAR) > 0) { - sb.append(c); - } else { - throw new IllegalArgumentException("Invalid delimited string: " + value); - } - } - - if (sb.length() > 0) { - list.add(sb.toString().trim()); - } - - return (String[])list.toArray(new String[list.size()]); - } - - public static class Descriptor { - private String text; - private String value; - private String[] valueComponents; - private Map attributes; - private Map directives; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String[] getValueComponents() { - return valueComponents; - } - - public void setValueComponents(String[] valueComponents) { - this.valueComponents = valueComponents; - } - - public Map getAttributes() { - return attributes; - } - - public Map getDirectives() { - return directives; - } - - public String toString() { - return text; - } - - } - - /** - * Returns a QName object from a QName expressed as {ns}name - * or ns#name. - * - * @param qname - * @return - */ - public static QName getQName(String qname) { - if (qname == null) { - return null; - } - qname = qname.trim(); - if (qname.startsWith("{")) { - int h = qname.indexOf('}'); - if (h != -1) { - return new QName(qname.substring(1, h), qname.substring(h + 1)); - } - } else { - int h = qname.indexOf('#'); - if (h != -1) { - return new QName(qname.substring(0, h), qname.substring(h + 1)); - } - } - return new QName(qname); - } - - public static Collection> load(final URL url, boolean isPropertyFile) throws IOException { - Collection> descriptors = new ArrayList>(); - - // Allow privileged access to open URL stream. Add FilePermission to added to security - // policy file. - InputStream is; - try { - is = AccessController.doPrivileged(new PrivilegedExceptionAction() { - public InputStream run() throws IOException { - URLConnection connection = url.openConnection(); - // TUSCANY-2539 - // Don't cache connections by default to stop Tuscany locking contribution jar files - // done here as this is one of the first places we open a stream and the only way to - // set the default is to set it on an instance of URLConnection - connection.setDefaultUseCaches(false); - connection.setUseCaches(false); - return url.openStream(); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); - } - if (isPropertyFile) { - // Load as a property file - Properties props = new Properties(); - props.load(is); - is.close(); - for (Map.Entry e : props.entrySet()) { - Map attributes = new HashMap(); - String key = (String)e.getKey(); - String value = (String)e.getValue(); - // Unfortunately, the xalan file only has the classname - if (value == null || "".equals(value)) { - value = key; - key = ""; - } - if (!"".equals(key)) { - attributes.put(key, value); - attributes.put("uri", key); - } - attributes.putAll(parseDeclaration(value)); - descriptors.add(attributes); - } - return descriptors; - } - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(is)); - while (true) { - String line = reader.readLine(); - if (line == null) - break; - line = line.trim(); - if (!line.startsWith("#") && !"".equals(line)) { - String reg = line.trim(); - - Map attributes = parseDeclaration(reg); - descriptors.add(attributes); - } - } - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // Ignore - } - } - } - return descriptors; - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java deleted file mode 100644 index aebd6cd3de..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.IOException; -import java.util.Collection; - -/** - * A SPI that allows different implementations of discovering service declarations - */ -public interface ServiceDiscoverer { - - /** - * Get all service declarations for this interface - * - * @param name - * @return set of service declarations - * @throws IOException - */ - public Collection getServiceDeclarations(String name) throws IOException; - - /** - * Get first service declaration class for the given interface - * - * @param name - * @return service implementation class - * @throws IOException - * @throws ClassNotFoundException - */ - public ServiceDeclaration getServiceDeclaration(String name) throws IOException; - - /** - * Get a classloader that can be used for thread context loader - * @return A classloader that can provide access to public classes and resources - */ - public ClassLoader getContextClassLoader(); -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java deleted file mode 100644 index 973664f382..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.tuscany.sca.extensibility.impl.LDAPFilter; - -/** - * Service discovery for Tuscany based on J2SE Jar service provider spec. - * Services are described using configuration files in META-INF/services. - * Service description specifies a class name followed by optional properties. - * - * TODO: this is broken as it uses a static INSTANCE but non-static serviceAttributes - * and discoverer so the same INSTANCE gets used across NodeFactories and picks up - * old values - * - * @version $Rev$ $Date$ - * @tuscany.spi.extension.asclient - */ -public final class ServiceDiscovery implements ServiceDiscoverer { - private final static Logger logger = Logger.getLogger(ServiceDiscovery.class.getName()); - private final static ServiceDiscovery INSTANCE = new ServiceDiscovery(); - - private final Map> serviceAttributes = new HashMap>(); - private ServiceDiscoverer discoverer; - - private ServiceDiscovery() { - super(); - } - - private ServiceDiscovery(ServiceDiscoverer discoverer) { - super(); - this.discoverer = discoverer; - } - - /** - * Get an instance of Service discovery, one instance is created per - * ClassLoader that this class is loaded from - * - * @return - */ - public static ServiceDiscovery getInstance() { - return INSTANCE; - } - - public static ServiceDiscovery getInstance(ServiceDiscoverer discoverer) { - return new ServiceDiscovery(discoverer); - } - - public ServiceDiscoverer getServiceDiscoverer() { - if (discoverer != null) { - return discoverer; - } - try { - // FIXME: This is a hack to trigger the activation of the extensibility-equinox bundle in OSGi - Class.forName("org.apache.tuscany.sca.extensibility.equinox.EquinoxServiceDiscoverer"); - if (discoverer != null) { - return discoverer; - } - } catch (Throwable e) { - } - discoverer = new ContextClassLoaderServiceDiscoverer(getClass().getClassLoader()); - return discoverer; - } - - public void setServiceDiscoverer(ServiceDiscoverer sd) { - if (discoverer != null && sd != null) { - logger.warning("ServiceDiscoverer is reset to " + sd); - } - discoverer = sd; - } - - public Collection getServiceDeclarations(String name) throws IOException { - return getServiceDeclarations(name, false); - } - - public Collection getServiceDeclarations(String name, boolean byRanking) throws IOException { - Collection declarations = getServiceDiscoverer().getServiceDeclarations(name); - // Check if any of the service declarations has attributes that are overrided - if (!serviceAttributes.isEmpty()) { - for (ServiceDeclaration declaration : declarations) { - Map attrs = getAttributes(name); - if (attrs != null) { - declaration.getAttributes().putAll(attrs); - } - } - } - if (!byRanking) { - return declarations; - } - if (!declarations.isEmpty()) { - List declarationList = new ArrayList(declarations); - /* - for (ServiceDeclaration sd1 : declarations) { - for (Iterator i = declarationList.iterator(); i.hasNext();) { - ServiceDeclaration sd2 = i.next(); - if (sd1 != sd2 && sd1.getAttributes().equals(sd2.getAttributes())) { - logger - .warning("Duplicate service declarations: " + sd1.getLocation() + "," + sd2.getLocation()); - i.remove(); - } - } - } - */ - Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); - return declarationList; - } else { - return Collections.emptyList(); - } - } - - /** - * Get the service declaration. If there are more than one services, the one with highest ranking will - * be returned. - */ - public ServiceDeclaration getServiceDeclaration(final String name) throws IOException { - Collection declarations = getServiceDeclarations(name, true); - if (!declarations.isEmpty()) { - // List declarationList = new ArrayList(declarations); - // Collections.sort(declarationList, ServiceComparator.DESCENDING_ORDER); - return declarations.iterator().next(); - } else { - return null; - } - } - - /** - * Get service declarations that are filtered by the service type. In an OSGi runtime, there - * might be different versions of the services - * @param serviceType - * @return - * @throws IOException - */ - public Collection getServiceDeclarations(Class serviceType, boolean byRanking) - throws IOException { - Collection sds = getServiceDeclarations(serviceType.getName(), byRanking); - for (Iterator i = sds.iterator(); i.hasNext();) { - ServiceDeclaration sd = i.next(); - if (!sd.isAssignableTo(serviceType)) { - logger.log(Level.WARNING, "Service provider {0} is not a type of {1}", new Object[] {sd,serviceType.getName()}); - i.remove(); - } - } - return sds; - } - - /** - * Discover all service providers that are compatible with the service type - * @param serviceType - * @return - * @throws IOException - */ - public Collection getServiceDeclarations(Class serviceType) throws IOException { - return getServiceDeclarations(serviceType, false); - } - - /** - * Discover all service providers that are compatible with the service type and match the filter - * @param serviceType - * @param filter - * @return - * @throws IOException - */ - public Collection getServiceDeclarations(Class serviceType, String filter) throws IOException { - Collection sds = getServiceDeclarations(serviceType, false); - Collection filtered = new ArrayList(); - LDAPFilter filterImpl = LDAPFilter.newInstance(filter); - for(ServiceDeclaration sd: sds) { - if(filterImpl.match(sd.getAttributes())) { - filtered.add(sd); - } - } - return filtered; - } - - /** - * @param serviceName - * @param filter - * @return - * @throws IOException - */ - public Collection getServiceDeclarations(String serviceName, String filter) throws IOException { - Collection sds = getServiceDeclarations(serviceName, false); - Collection filtered = new ArrayList(); - LDAPFilter filterImpl = LDAPFilter.newInstance(filter); - for(ServiceDeclaration sd: sds) { - if(filterImpl.match(sd.getAttributes())) { - filtered.add(sd); - } - } - return filtered; - } - - public ServiceDeclaration getServiceDeclaration(Class serviceType) throws IOException { - Collection sds = getServiceDeclarations(serviceType, true); - if (sds.isEmpty()) { - return null; - } else { - return sds.iterator().next(); - } - } - - /** - * Compare service declarations by ranking - */ - private static class ServiceComparator implements Comparator { - private final static Comparator DESCENDING_ORDER = new ServiceComparator(); - - public int compare(ServiceDeclaration o1, ServiceDeclaration o2) { - int rank1 = 0; - String r1 = o1.getAttributes().get("ranking"); - if (r1 != null) { - rank1 = Integer.parseInt(r1); - } - int rank2 = 0; - String r2 = o2.getAttributes().get("ranking"); - if (r2 != null) { - rank2 = Integer.parseInt(r2); - } - return rank2 - rank1; // descending - } - } - - public ClassLoader getContextClassLoader() { - return discoverer.getContextClassLoader(); - } - - /** - * Set the attributes for a given service type - * @param serviceType - * @param attributes - */ - public void setAttribute(String serviceType, Map attributes) { - serviceAttributes.put(serviceType, attributes); - } - - /** - * Set an attribute to the given value for a service type - * @param serviceType The service type - * @param attribute The attribute name - * @param value The attribute value - */ - public void setAttribute(String serviceType, String attribute, String value) { - Map attributes = serviceAttributes.get(serviceType); - if (attributes == null) { - attributes = new HashMap(); - serviceAttributes.put(serviceType, attributes); - } - attributes.put(attribute, value); - } - - /** - * Return a map of attributes for a given service type - * @param serviceType - * @return - */ - public Map getAttributes(String serviceType) { - return serviceAttributes.get(serviceType); - } - - /** - * Remove the duplicate service declarations. The duplication happens when we have the same jar from more than one entries on the classpath - * @param declarations - * @return - */ - public static Collection removeDuplicateDeclarations(Collection declarations) { - // Use LinkedHashMap to maintain the insertion order - Map map = new LinkedHashMap(); - for (ServiceDeclaration sd : declarations) { - ServiceDeclaration existed = map.put(sd.getClassName(), sd); - if (existed != null) { - logger.warning("Duplicate service declaration is ignored: " + existed + " <-> " + sd); - } - } - return map.values(); - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java deleted file mode 100644 index 7f38aa6d06..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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.tuscany.sca.extensibility; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Collection; -import java.util.Map; - -import org.apache.tuscany.sca.core.ExtensionPointRegistry; -import org.apache.tuscany.sca.core.LifeCycleListener; - -/** - * A helper for handling service lifecycle and instantiations - * @tuscany.spi.extension.asclient - */ -public class ServiceHelper { - private ServiceHelper() { - } - - /** - * Start the service instance - * @param instance - */ - public static boolean start(Object instance) { - if (instance instanceof LifeCycleListener) { - ((LifeCycleListener)instance).start(); - return true; - } - return false; - } - - /** - * Stop the service instance - * @param instance - */ - public static boolean stop(Object instance) { - if (instance instanceof LifeCycleListener) { - ((LifeCycleListener)instance).stop(); - return true; - } - return false; - } - - /** - * Stop a collection of service instances - * @param instances - */ - public static void stop(Collection instances) { - if (instances == null) { - return; - } - for (Object instance : instances) { - if (instance instanceof LifeCycleListener) { - ((LifeCycleListener)instance).stop(); - } - } - } - - /** - * Create a service instance with one parameter - * @param cls The service type - * @param parameterType The parameter type - * @param parameter The parameter value - * @return The newly created service instance - * @throws Exception - */ - public static T newInstance(Class cls, Class parameterType, Object parameter) throws Exception { - Constructor constructor = cls.getConstructor(parameterType); - return constructor.newInstance(parameter); - } - - /** - * Create a service instance with an array of parameters - * @param cls The service type - * @param parameterTypes An array of parameter types - * @param parameters An array of parameter values - * @return The newly created service instance - * @throws Exception - */ - public static T newInstance(Class cls, Class parameterTypes[], Object... parameters) throws Exception { - Constructor constructor = cls.getConstructor(parameterTypes); - return constructor.newInstance(parameters); - } - - /** - * Create a service instance with the default no-arg constructor - * @param cls The service type - * @return The newly created service instance - * @throws Exception - */ - public static T newInstance(Class cls) throws Exception { - Constructor constructor = cls.getConstructor(); - return constructor.newInstance(); - } - - private final static Class[] ARG_TYPES = new Class[] {ExtensionPointRegistry.class, Map.class}; - - /** - * Create a service instance from the service declaration - * @param - * @param registry The extension point registry - * @param sd The service declaration - * @return The newly created service instance - * @throws Exception - */ - public static T newInstance(ExtensionPointRegistry registry, ServiceDeclaration sd) throws Exception { - Class cls = (Class)sd.loadClass(); - T instance = null; - try { - // Try constructor(ExtensionPointRegistry.class) - instance = newInstance(cls, ExtensionPointRegistry.class, registry); - } catch (NoSuchMethodException e) { - try { - // Try Try constructor(ExtensionPointRegistry.class, Map.class) - instance = newInstance(cls, ARG_TYPES, registry, sd.getAttributes()); - } catch (NoSuchMethodException e1) { - // Try constructor() - instance = newInstance(cls); - } - } - return instance; - } - - public static T newLazyInstance(ExtensionPointRegistry registry, ServiceDeclaration sd, Class serviceType) { - return serviceType.cast(Proxy.newProxyInstance(serviceType.getClassLoader(), - new Class[] {serviceType, LifeCycleListener.class}, - new InvocationHandlerImpl(registry, serviceType, sd))); - } - - private static class InvocationHandlerImpl implements InvocationHandler { - private ExtensionPointRegistry registry; - private Class type; - private ServiceDeclaration sd; - private Object instance; - - private final static Method STOP_METHOD = getMethod(LifeCycleListener.class, "stop"); - private final static Method START_METHOD = getMethod(LifeCycleListener.class, "start"); - private final static Method EQUALS_METHOD = getMethod(Object.class, "equals"); - private final static Method HASHCODE_METHOD = getMethod(Object.class, "hashCode"); - private final static Method TOSTRING_METHOD = getMethod(Object.class, "toString"); - - private static Method getMethod(Class type, String name) { - Method[] methods = type.getMethods(); - for (Method method : methods) { - if (name.equals(method.getName())) { - return method; - } - } - return null; - } - - public InvocationHandlerImpl(ExtensionPointRegistry registry, Class type, ServiceDeclaration sd) { - super(); - this.registry = registry; - this.sd = sd; - this.type = type; - } - - private Object getAttribute(Method method) throws Exception { - if (method.getParameterTypes().length != 0) { - return null; - } - String name = method.getName(); - if (name.equals("getModelType") && method.getReturnType() == Class.class) { - return sd.loadClass(sd.getAttributes().get("model")); - } else if (name.equals("getArtifactType")) { - return ServiceDeclarationParser.getQName(sd.getAttributes().get("qname")); - } - return null; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - synchronized (this) { - // Check if the method is to get the qname/model attribute - Object value = getAttribute(method); - if (value != null) { - return value; - } - if (instance == null && method.getDeclaringClass() == type) { - // Only initialize the instance when a method on the service type is invoked - instance = newInstance(registry, sd); - start(instance); - } - if (method.equals(EQUALS_METHOD)) { - return proxy == args[0]; - } else if (method.equals(HASHCODE_METHOD)) { - return System.identityHashCode(proxy); - } else if (method.equals(TOSTRING_METHOD)) { - return "Proxy: " + sd.toString(); - } - if (instance == null) { - return null; - } - } - if (method.equals(STOP_METHOD)) { - stop(instance); - return null; - } else if (method.equals(START_METHOD)) { - // Skip the start() - return null; - } else { - return method.invoke(instance, args); - } - } - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java deleted file mode 100644 index d052d6b10f..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.tuscany.sca.extensibility.impl; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * A classloader that can delegate to a list of other classloaders - */ -public class ClassLoaderDelegate extends ClassLoader { - private final List classLoaders = new ArrayList(); - - /** - * @param parent The parent classloaders - * @param loaders A list of classloaders to be used to load classes or resources - */ - public ClassLoaderDelegate(ClassLoader parent, Collection loaders) { - super(parent); - if (loaders != null) { - for (ClassLoader cl : loaders) { - if (cl != null && cl != parent && !classLoaders.contains(cl)) { - this.classLoaders.add(cl); - } - } - } - } - - @Override - protected Class findClass(String className) throws ClassNotFoundException { - for (ClassLoader delegate : classLoaders) { - try { - return delegate.loadClass(className); - } catch (ClassNotFoundException e) { - continue; - } - } - throw new ClassNotFoundException(className); - } - - @Override - protected URL findResource(String resName) { - for (ClassLoader delegate : classLoaders) { - URL url = delegate.getResource(resName); - if (url != null) { - return url; - } - } - return null; - } - - @Override - protected Enumeration findResources(String resName) throws IOException { - Set urlSet = new HashSet(); - for (ClassLoader delegate : classLoaders) { - Enumeration urls = delegate.getResources(resName); - if (urls != null) { - while (urls.hasMoreElements()) { - urlSet.add(urls.nextElement()); - } - } - } - return Collections.enumeration(urlSet); - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java deleted file mode 100644 index 77f6f3e8db..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.tuscany.sca.extensibility.impl; - -/** - * A Framework exception used to indicate that a filter string has an invalid - * syntax. - * - *

    - * An InvalidSyntaxException object indicates that a filter - * string parameter has an invalid syntax and cannot be parsed. - * - *

    - * This exception conforms to the general purpose exception chaining mechanism. - * - */ - -public class InvalidSyntaxException extends RuntimeException { - static final long serialVersionUID = -4295194420816491875L; - /** - * The invalid filter string. - */ - private final String filter; - - /** - * Creates an exception of type InvalidSyntaxException. - * - *

    - * This method creates an InvalidSyntaxException object with - * the specified message and the filter string which generated the - * exception. - * - * @param msg The message. - * @param filter The invalid filter string. - */ - public InvalidSyntaxException(String msg, String filter) { - super(msg); - this.filter = filter; - } - - /** - * Creates an exception of type InvalidSyntaxException. - * - *

    - * This method creates an InvalidSyntaxException object with - * the specified message and the filter string which generated the - * exception. - * - * @param msg The message. - * @param filter The invalid filter string. - * @param cause The cause of this exception. - * @since 1.3 - */ - public InvalidSyntaxException(String msg, String filter, Throwable cause) { - super(msg, cause); - this.filter = filter; - } - - /** - * Returns the filter string that generated the - * InvalidSyntaxException object. - * - * @return The invalid filter string. - * @see BundleContext#getServiceReferences - * @see BundleContext#addServiceListener(ServiceListener,String) - */ - public String getFilter() { - return filter; - } -} \ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java b/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java deleted file mode 100644 index 8d3630baa4..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved. - * - * Licensed 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.tuscany.sca.extensibility.impl; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.apache.tuscany.sca.extensibility.ServiceDeclaration; - - -/** - * This code is derived from FrameworkUtil - *

    - * RFC 1960-based Filter. Filter objects can be created by calling the - * constructor with the desired filter string. A Filter object can be called - * numerous times to determine if the match argument matches the filter - * string that was used to create the Filter object. - * - *

    - * The syntax of a filter string is the string representation of LDAP search - * filters as defined in RFC 1960: A String Representation of LDAP Search - * Filters (available at http://www.ietf.org/rfc/rfc1960.txt). It should - * be noted that RFC 2254: A String Representation of LDAP Search - * Filters (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes - * RFC 1960 but only adds extensible matching and is not applicable for this - * API. - * - *

    - * The string representation of an LDAP search filter is defined by the - * following grammar. It uses a prefix format. - * - *

    - *   <filter> ::= '(' <filtercomp> ')'
    - *   <filtercomp> ::= <and> | <or> | <not> | <item>
    - *   <and> ::= '&' <filterlist>
    - *   <or> ::= '|' <filterlist>
    - *   <not> ::= '!' <filter>
    - *   <filterlist> ::= <filter> | <filter> <filterlist>
    - *   <item> ::= <simple> | <present> | <substring>
    - *   <simple> ::= <attr> <filtertype> <value>
    - *   <filtertype> ::= <equal> | <approx> | <greater> | <less>
    - *   <equal> ::= '='
    - *   <approx> ::= '˜='
    - *   <greater> ::= '>='
    - *   <less> ::= '<='
    - *   <present> ::= <attr> '=*'
    - *   <substring> ::= <attr> '=' <initial> <any> <final>
    - *   <initial> ::= NULL | <value>
    - *   <any> ::= '*' <starval>
    - *   <starval> ::= NULL | <value> '*' <starval>
    - *   <final> ::= NULL | <value>
    - * 
    - * - * <attr> is a string representing an attribute, or key, - * in the properties objects of the registered services. Attribute names are - * not case sensitive; that is cn and CN both refer to the same attribute. - * <value> is a string representing the value, or part of - * one, of a key in the properties objects of the registered services. If a - * <value> must contain one of the characters ' - * *' or '(' or ')', these characters - * should be escaped by preceding them with the backslash '\' - * character. Note that although both the <substring> and - * <present> productions can produce the 'attr=*' - * construct, this construct is used only to denote a presence filter. - * - *

    - * Examples of LDAP filters are: - * - *

    - *   "(cn=Babs Jensen)"
    - *   "(!(cn=Tim Howes))"
    - *   "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
    - *   "(o=univ*of*mich*)"
    - * 
    - * - *

    - * The approximate match (~=) is implementation specific but - * should at least ignore case and white space differences. Optional are - * codes like soundex or other smart "closeness" comparisons. - * - *

    - * Comparison of values is not straightforward. Strings are compared - * differently than numbers and it is possible for a key to have multiple - * values. Note that that keys in the match argument must always be strings. - * The comparison is defined by the object type of the key's value. The - * following rules apply for comparison: - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Property Value Type Comparison Type
    StringString comparison
    Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimalnumerical comparison
    Charactercharacter comparison
    Booleanequality comparisons only
    [] (array)recursively applied to values
    Collectionrecursively applied to values
    - * Note: arrays of primitives are also supported.
    - * - * A filter matches a key that has multiple values if it matches at least - * one of those values. For example, - * - *
    - * Dictionary d = new Hashtable();
    - * d.put("cn", new String[] {"a", "b", "c"});
    - * 
    - * - * d will match (cn=a) and also (cn=b) - * - *

    - * A filter component that references a key having an unrecognizable data - * type will evaluate to false . - */ -public class LDAPFilter { - /* filter operators */ - private static final int EQUAL = 1; - private static final int APPROX = 2; - private static final int GREATER = 3; - private static final int LESS = 4; - private static final int PRESENT = 5; - private static final int SUBSTRING = 6; - private static final int AND = 7; - private static final int OR = 8; - private static final int NOT = 9; - - /** filter operation */ - private final int op; - /** filter attribute or null if operation AND, OR or NOT */ - private final String attr; - /** filter operands */ - private final Object value; - - /* normalized filter string for Filter object */ - private transient volatile String filterString; - - /** - * Constructs a {@link LDAPFilter} object. This filter object may be - * used to match a {@link ServiceReference} or a Dictionary. - * - *

    - * If the filter cannot be parsed, an {@link InvalidSyntaxException} - * will be thrown with a human readable message where the filter became - * unparsable. - * - * @param filterString the filter string. - * @exception InvalidSyntaxException If the filter parameter contains an - * invalid filter string that cannot be parsed. - */ - public static LDAPFilter newInstance(String filterString) throws InvalidSyntaxException { - return new Parser(filterString).parse(); - } - - LDAPFilter(int operation, String attr, Object value) { - this.op = operation; - this.attr = attr; - this.value = value; - } - - /** - * Filter using a Dictionary. This Filter is - * executed using the specified Dictionary's keys and - * values. The keys are case insensitively matched with this - * Filter. - * - * @param dictionary The Dictionary whose keys are used in - * the match. - * @return true if the Dictionary's keys and - * values match this filter; false otherwise. - * @throws IllegalArgumentException If dictionary contains - * case variants of the same key name. - */ - public boolean match(Dictionary dictionary) { - return match0(new CaseInsensitiveDictionary(dictionary)); - } - - public boolean match(Map map) { - Properties props = new Properties(); - props.putAll(map); - return match0(new CaseInsensitiveDictionary(props)); - } - - public static boolean matches(ServiceDeclaration declaration, String filter) { - if (filter == null) { - return true; - } - LDAPFilter filterImpl = newInstance(filter); - return filterImpl.match(declaration.getAttributes()); - } - - /** - * Filter with case sensitivity using a Dictionary. This - * Filter is executed using the specified - * Dictionary's keys and values. The keys are case - * sensitively matched with this Filter. - * - * @param dictionary The Dictionary whose keys are used in - * the match. - * @return true if the Dictionary's keys and - * values match this filter; false otherwise. - * @since 1.3 - */ - public boolean matchCase(Dictionary dictionary) { - return match0(dictionary); - } - - /** - * Returns this Filter's filter string. - *

    - * The filter string is normalized by removing whitespace which does not - * affect the meaning of the filter. - * - * @return This Filter's filter string. - */ - public String toString() { - String result = filterString; - if (result == null) { - filterString = result = normalize(); - } - return result; - } - - /** - * Returns this Filter's normalized filter string. - *

    - * The filter string is normalized by removing whitespace which does not - * affect the meaning of the filter. - * - * @return This Filter's filter string. - */ - private String normalize() { - StringBuffer sb = new StringBuffer(); - sb.append('('); - - switch (op) { - case AND: { - sb.append('&'); - - LDAPFilter[] filters = (LDAPFilter[])value; - for (int i = 0, size = filters.length; i < size; i++) { - sb.append(filters[i].normalize()); - } - - break; - } - - case OR: { - sb.append('|'); - - LDAPFilter[] filters = (LDAPFilter[])value; - for (int i = 0, size = filters.length; i < size; i++) { - sb.append(filters[i].normalize()); - } - - break; - } - - case NOT: { - sb.append('!'); - LDAPFilter filter = (LDAPFilter)value; - sb.append(filter.normalize()); - - break; - } - - case SUBSTRING: { - sb.append(attr); - sb.append('='); - - String[] substrings = (String[])value; - - for (int i = 0, size = substrings.length; i < size; i++) { - String substr = substrings[i]; - - if (substr == null) /* * */{ - sb.append('*'); - } else /* xxx */{ - sb.append(encodeValue(substr)); - } - } - - break; - } - case EQUAL: { - sb.append(attr); - sb.append('='); - sb.append(encodeValue((String)value)); - - break; - } - case GREATER: { - sb.append(attr); - sb.append(">="); - sb.append(encodeValue((String)value)); - - break; - } - case LESS: { - sb.append(attr); - sb.append("<="); - sb.append(encodeValue((String)value)); - - break; - } - case APPROX: { - sb.append(attr); - sb.append("~="); - sb.append(encodeValue(approxString((String)value))); - - break; - } - - case PRESENT: { - sb.append(attr); - sb.append("=*"); - - break; - } - } - - sb.append(')'); - - return sb.toString(); - } - - /** - * Compares this Filter to another Filter. - * - *

    - * This implementation returns the result of calling - * this.toString().equals(obj.toString(). - * - * @param obj The object to compare against this Filter. - * @return If the other object is a Filter object, then - * returns the result of calling - * this.toString().equals(obj.toString(); - * false otherwise. - */ - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof LDAPFilter)) { - return false; - } - - return this.toString().equals(obj.toString()); - } - - /** - * Returns the hashCode for this Filter. - * - *

    - * This implementation returns the result of calling - * this.toString().hashCode(). - * - * @return The hashCode of this Filter. - */ - public int hashCode() { - return this.toString().hashCode(); - } - - /** - * Internal match routine. Dictionary parameter must support - * case-insensitive get. - * - * @param properties A dictionary whose keys are used in the match. - * @return If the Dictionary's keys match the filter, return - * true. Otherwise, return false. - */ - private boolean match0(Dictionary properties) { - switch (op) { - case AND: { - LDAPFilter[] filters = (LDAPFilter[])value; - for (int i = 0, size = filters.length; i < size; i++) { - if (!filters[i].match0(properties)) { - return false; - } - } - - return true; - } - - case OR: { - LDAPFilter[] filters = (LDAPFilter[])value; - for (int i = 0, size = filters.length; i < size; i++) { - if (filters[i].match0(properties)) { - return true; - } - } - - return false; - } - - case NOT: { - LDAPFilter filter = (LDAPFilter)value; - - return !filter.match0(properties); - } - - case SUBSTRING: - case EQUAL: - case GREATER: - case LESS: - case APPROX: { - Object prop = (properties == null) ? null : properties.get(attr); - - return compare(op, prop, value); - } - - case PRESENT: { - Object prop = (properties == null) ? null : properties.get(attr); - - return prop != null; - } - } - - return false; - } - - /** - * Encode the value string such that '(', '*', ')' and '\' are escaped. - * - * @param value unencoded value string. - * @return encoded value string. - */ - private static String encodeValue(String value) { - boolean encoded = false; - int inlen = value.length(); - int outlen = inlen << 1; /* inlen 2 */ - - char[] output = new char[outlen]; - value.getChars(0, inlen, output, inlen); - - int cursor = 0; - for (int i = inlen; i < outlen; i++) { - char c = output[i]; - - switch (c) { - case '(': - case '*': - case ')': - case '\\': { - output[cursor] = '\\'; - cursor++; - encoded = true; - - break; - } - } - - output[cursor] = c; - cursor++; - } - - return encoded ? new String(output, 0, cursor) : value; - } - - private boolean compare(int operation, Object value1, Object value2) { - if (value1 == null) { - return false; - } - if (value1 instanceof String) { - return compare_String(operation, (String)value1, value2); - } - - Class clazz = value1.getClass(); - if (clazz.isArray()) { - Class type = clazz.getComponentType(); - if (type.isPrimitive()) { - return compare_PrimitiveArray(operation, type, value1, value2); - } - return compare_ObjectArray(operation, (Object[])value1, value2); - } - if (value1 instanceof Collection) { - return compare_Collection(operation, (Collection)value1, value2); - } - if (value1 instanceof Integer) { - return compare_Integer(operation, ((Integer)value1).intValue(), value2); - } - if (value1 instanceof Long) { - return compare_Long(operation, ((Long)value1).longValue(), value2); - } - if (value1 instanceof Byte) { - return compare_Byte(operation, ((Byte)value1).byteValue(), value2); - } - if (value1 instanceof Short) { - return compare_Short(operation, ((Short)value1).shortValue(), value2); - } - if (value1 instanceof Character) { - return compare_Character(operation, ((Character)value1).charValue(), value2); - } - if (value1 instanceof Float) { - return compare_Float(operation, ((Float)value1).floatValue(), value2); - } - if (value1 instanceof Double) { - return compare_Double(operation, ((Double)value1).doubleValue(), value2); - } - if (value1 instanceof Boolean) { - return compare_Boolean(operation, ((Boolean)value1).booleanValue(), value2); - } - if (value1 instanceof Comparable) { - return compare_Comparable(operation, (Comparable)value1, value2); - } - return compare_Unknown(operation, value1, value2); // RFC 59 - } - - private boolean compare_Collection(int operation, Collection collection, Object value2) { - for (Iterator iterator = collection.iterator(); iterator.hasNext();) { - if (compare(operation, iterator.next(), value2)) { - return true; - } - } - return false; - } - - private boolean compare_ObjectArray(int operation, Object[] array, Object value2) { - for (int i = 0, size = array.length; i < size; i++) { - if (compare(operation, array[i], value2)) { - return true; - } - } - return false; - } - - private boolean compare_PrimitiveArray(int operation, Class type, Object primarray, Object value2) { - if (Integer.TYPE.isAssignableFrom(type)) { - int[] array = (int[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Integer(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Long.TYPE.isAssignableFrom(type)) { - long[] array = (long[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Long(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Byte.TYPE.isAssignableFrom(type)) { - byte[] array = (byte[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Byte(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Short.TYPE.isAssignableFrom(type)) { - short[] array = (short[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Short(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Character.TYPE.isAssignableFrom(type)) { - char[] array = (char[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Character(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Float.TYPE.isAssignableFrom(type)) { - float[] array = (float[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Float(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Double.TYPE.isAssignableFrom(type)) { - double[] array = (double[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Double(operation, array[i], value2)) { - return true; - } - } - return false; - } - if (Boolean.TYPE.isAssignableFrom(type)) { - boolean[] array = (boolean[])primarray; - for (int i = 0, size = array.length; i < size; i++) { - if (compare_Boolean(operation, array[i], value2)) { - return true; - } - } - return false; - } - return false; - } - - private boolean compare_String(int operation, String string, Object value2) { - switch (operation) { - case SUBSTRING: { - String[] substrings = (String[])value2; - int pos = 0; - for (int i = 0, size = substrings.length; i < size; i++) { - String substr = substrings[i]; - - if (i + 1 < size) /* if this is not that last substr */{ - if (substr == null) /* * */{ - String substr2 = substrings[i + 1]; - - if (substr2 == null) /* ** */ - continue; /* ignore first star */ - /* xxx */ - int index = string.indexOf(substr2, pos); - if (index == -1) { - return false; - } - - pos = index + substr2.length(); - if (i + 2 < size) // if there are more - // substrings, increment - // over the string we just - // matched; otherwise need - // to do the last substr - // check - i++; - } else /* xxx */{ - int len = substr.length(); - if (string.regionMatches(pos, substr, 0, len)) { - pos += len; - } else { - return false; - } - } - } else /* last substr */{ - if (substr == null) /* * */{ - return true; - } - /* xxx */ - return string.endsWith(substr); - } - } - - return true; - } - case EQUAL: { - return string.equals(value2); - } - case APPROX: { - string = approxString(string); - String string2 = approxString((String)value2); - - return string.equalsIgnoreCase(string2); - } - case GREATER: { - return string.compareTo((String)value2) >= 0; - } - case LESS: { - return string.compareTo((String)value2) <= 0; - } - } - return false; - } - - private boolean compare_Integer(int operation, int intval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - int intval2 = Integer.parseInt(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return intval == intval2; - } - case GREATER: { - return intval >= intval2; - } - case LESS: { - return intval <= intval2; - } - } - return false; - } - - private boolean compare_Long(int operation, long longval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - long longval2 = Long.parseLong(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return longval == longval2; - } - case GREATER: { - return longval >= longval2; - } - case LESS: { - return longval <= longval2; - } - } - return false; - } - - private boolean compare_Byte(int operation, byte byteval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - byte byteval2 = Byte.parseByte(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return byteval == byteval2; - } - case GREATER: { - return byteval >= byteval2; - } - case LESS: { - return byteval <= byteval2; - } - } - return false; - } - - private boolean compare_Short(int operation, short shortval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - short shortval2 = Short.parseShort(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return shortval == shortval2; - } - case GREATER: { - return shortval >= shortval2; - } - case LESS: { - return shortval <= shortval2; - } - } - return false; - } - - private boolean compare_Character(int operation, char charval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - char charval2 = (((String)value2).trim()).charAt(0); - switch (operation) { - case EQUAL: { - return charval == charval2; - } - case APPROX: { - return (charval == charval2) || (Character.toUpperCase(charval) == Character.toUpperCase(charval2)) - || (Character.toLowerCase(charval) == Character.toLowerCase(charval2)); - } - case GREATER: { - return charval >= charval2; - } - case LESS: { - return charval <= charval2; - } - } - return false; - } - - private boolean compare_Boolean(int operation, boolean boolval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - boolean boolval2 = Boolean.valueOf(((String)value2).trim()).booleanValue(); - switch (operation) { - case APPROX: - case EQUAL: - case GREATER: - case LESS: { - return boolval == boolval2; - } - } - return false; - } - - private boolean compare_Float(int operation, float floatval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - float floatval2 = Float.parseFloat(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return Float.compare(floatval, floatval2) == 0; - } - case GREATER: { - return Float.compare(floatval, floatval2) >= 0; - } - case LESS: { - return Float.compare(floatval, floatval2) <= 0; - } - } - return false; - } - - private boolean compare_Double(int operation, double doubleval, Object value2) { - if (operation == SUBSTRING) { - return false; - } - double doubleval2 = Double.parseDouble(((String)value2).trim()); - switch (operation) { - case APPROX: - case EQUAL: { - return Double.compare(doubleval, doubleval2) == 0; - } - case GREATER: { - return Double.compare(doubleval, doubleval2) >= 0; - } - case LESS: { - return Double.compare(doubleval, doubleval2) <= 0; - } - } - return false; - } - - private static final Class[] constructorType = new Class[] {String.class}; - - private boolean compare_Comparable(int operation, Comparable value1, Object value2) { - if (operation == SUBSTRING) { - return false; - } - Constructor constructor; - try { - constructor = value1.getClass().getConstructor(constructorType); - } catch (NoSuchMethodException e) { - return false; - } - try { - if (!constructor.isAccessible()) - AccessController.doPrivileged(new SetAccessibleAction(constructor)); - value2 = constructor.newInstance(new Object[] {((String)value2).trim()}); - } catch (IllegalAccessException e) { - return false; - } catch (InvocationTargetException e) { - return false; - } catch (InstantiationException e) { - return false; - } - - switch (operation) { - case APPROX: - case EQUAL: { - return value1.compareTo(value2) == 0; - } - case GREATER: { - return value1.compareTo(value2) >= 0; - } - case LESS: { - return value1.compareTo(value2) <= 0; - } - } - return false; - } - - private boolean compare_Unknown(int operation, Object value1, Object value2) { - if (operation == SUBSTRING) { - return false; - } - Constructor constructor; - try { - constructor = value1.getClass().getConstructor(constructorType); - } catch (NoSuchMethodException e) { - return false; - } - try { - if (!constructor.isAccessible()) - AccessController.doPrivileged(new SetAccessibleAction(constructor)); - value2 = constructor.newInstance(new Object[] {((String)value2).trim()}); - } catch (IllegalAccessException e) { - return false; - } catch (InvocationTargetException e) { - return false; - } catch (InstantiationException e) { - return false; - } - - switch (operation) { - case APPROX: - case EQUAL: - case GREATER: - case LESS: { - return value1.equals(value2); - } - } - return false; - } - - /** - * Map a string for an APPROX (~=) comparison. - * - * This implementation removes white spaces. This is the minimum - * implementation allowed by the OSGi spec. - * - * @param input Input string. - * @return String ready for APPROX comparison. - */ - private static String approxString(String input) { - boolean changed = false; - char[] output = input.toCharArray(); - int cursor = 0; - for (int i = 0, length = output.length; i < length; i++) { - char c = output[i]; - - if (Character.isWhitespace(c)) { - changed = true; - continue; - } - - output[cursor] = c; - cursor++; - } - - return changed ? new String(output, 0, cursor) : input; - } - - /** - * Parser class for OSGi filter strings. This class parses the complete - * filter string and builds a tree of Filter objects rooted at the - * parent. - */ - private static class Parser { - private final String filterstring; - private final char[] filterChars; - private int pos; - - Parser(String filterstring) { - this.filterstring = filterstring; - filterChars = filterstring.toCharArray(); - pos = 0; - } - - LDAPFilter parse() throws InvalidSyntaxException { - LDAPFilter filter; - try { - filter = parse_filter(); - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidSyntaxException("Filter ended abruptly", filterstring); - } - - if (pos != filterChars.length) { - throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), - filterstring); - } - return filter; - } - - private LDAPFilter parse_filter() throws InvalidSyntaxException { - LDAPFilter filter; - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); - } - - pos++; - - filter = parse_filtercomp(); - - skipWhiteSpace(); - - if (filterChars[pos] != ')') { - throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring); - } - - pos++; - - skipWhiteSpace(); - - return filter; - } - - private LDAPFilter parse_filtercomp() throws InvalidSyntaxException { - skipWhiteSpace(); - - char c = filterChars[pos]; - - switch (c) { - case '&': { - pos++; - return parse_and(); - } - case '|': { - pos++; - return parse_or(); - } - case '!': { - pos++; - return parse_not(); - } - } - return parse_item(); - } - - private LDAPFilter parse_and() throws InvalidSyntaxException { - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); - } - - List operands = new ArrayList(10); - - while (filterChars[pos] == '(') { - LDAPFilter child = parse_filter(); - operands.add(child); - } - - return new LDAPFilter(LDAPFilter.AND, null, operands.toArray(new LDAPFilter[operands.size()])); - } - - private LDAPFilter parse_or() throws InvalidSyntaxException { - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); - } - - List operands = new ArrayList(10); - - while (filterChars[pos] == '(') { - LDAPFilter child = parse_filter(); - operands.add(child); - } - - return new LDAPFilter(LDAPFilter.OR, null, operands.toArray(new LDAPFilter[operands.size()])); - } - - private LDAPFilter parse_not() throws InvalidSyntaxException { - skipWhiteSpace(); - - if (filterChars[pos] != '(') { - throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); - } - - LDAPFilter child = parse_filter(); - - return new LDAPFilter(LDAPFilter.NOT, null, child); - } - - private LDAPFilter parse_item() throws InvalidSyntaxException { - String attr = parse_attr(); - - skipWhiteSpace(); - - switch (filterChars[pos]) { - case '~': { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new LDAPFilter(LDAPFilter.APPROX, attr, parse_value()); - } - break; - } - case '>': { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new LDAPFilter(LDAPFilter.GREATER, attr, parse_value()); - } - break; - } - case '<': { - if (filterChars[pos + 1] == '=') { - pos += 2; - return new LDAPFilter(LDAPFilter.LESS, attr, parse_value()); - } - break; - } - case '=': { - if (filterChars[pos + 1] == '*') { - int oldpos = pos; - pos += 2; - skipWhiteSpace(); - if (filterChars[pos] == ')') { - return new LDAPFilter(LDAPFilter.PRESENT, attr, null); - } - pos = oldpos; - } - - pos++; - Object string = parse_substring(); - - if (string instanceof String) { - return new LDAPFilter(LDAPFilter.EQUAL, attr, string); - } - return new LDAPFilter(LDAPFilter.SUBSTRING, attr, string); - } - } - - throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring); - } - - private String parse_attr() throws InvalidSyntaxException { - skipWhiteSpace(); - - int begin = pos; - int end = pos; - - char c = filterChars[pos]; - - while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') { - pos++; - - if (!Character.isWhitespace(c)) { - end = pos; - } - - c = filterChars[pos]; - } - - int length = end - begin; - - if (length == 0) { - throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring); - } - - return new String(filterChars, begin, length); - } - - private String parse_value() throws InvalidSyntaxException { - StringBuffer sb = new StringBuffer(filterChars.length - pos); - - parseloop: while (true) { - char c = filterChars[pos]; - - switch (c) { - case ')': { - break parseloop; - } - - case '(': { - throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), - filterstring); - } - - case '\\': { - pos++; - c = filterChars[pos]; - /* fall through into default */ - } - - default: { - sb.append(c); - pos++; - break; - } - } - } - - if (sb.length() == 0) { - throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); - } - - return sb.toString(); - } - - private Object parse_substring() throws InvalidSyntaxException { - StringBuffer sb = new StringBuffer(filterChars.length - pos); - - List operands = new ArrayList(10); - - parseloop: while (true) { - char c = filterChars[pos]; - - switch (c) { - case ')': { - if (sb.length() > 0) { - operands.add(sb.toString()); - } - - break parseloop; - } - - case '(': { - throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), - filterstring); - } - - case '*': { - if (sb.length() > 0) { - operands.add(sb.toString()); - } - - sb.setLength(0); - - operands.add(null); - pos++; - - break; - } - - case '\\': { - pos++; - c = filterChars[pos]; - /* fall through into default */ - } - - default: { - sb.append(c); - pos++; - break; - } - } - } - - int size = operands.size(); - - if (size == 0) { - throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); - } - - if (size == 1) { - Object single = operands.get(0); - - if (single != null) { - return single; - } - } - - return operands.toArray(new String[size]); - } - - private void skipWhiteSpace() { - for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) { - pos++; - } - } - } - - /** - * This Dictionary is used for case-insensitive key lookup during filter - * evaluation. This Dictionary implementation only supports the get - * operation using a String key as no other operations are used by the - * Filter implementation. - */ - static class CaseInsensitiveDictionary extends Dictionary { - private final Dictionary dictionary; - private final String[] keys; - - /** - * Create a case insensitive dictionary from the specified dictionary. - * - * @param dictionary - * @throws IllegalArgumentException If dictionary contains - * case variants of the same key name. - */ - CaseInsensitiveDictionary(Dictionary dictionary) { - if (dictionary == null) { - this.dictionary = null; - this.keys = new String[0]; - return; - } - this.dictionary = dictionary; - List keyList = new ArrayList(dictionary.size()); - for (Enumeration e = dictionary.keys(); e.hasMoreElements();) { - Object k = e.nextElement(); - if (k instanceof String) { - String key = (String)k; - for (Iterator i = keyList.iterator(); i.hasNext();) { - if (key.equalsIgnoreCase((String)i.next())) { - throw new IllegalArgumentException(); - } - } - keyList.add(key); - } - } - this.keys = (String[])keyList.toArray(new String[keyList.size()]); - } - - public Object get(Object o) { - String k = (String)o; - for (int i = 0, length = keys.length; i < length; i++) { - String key = keys[i]; - if (key.equalsIgnoreCase(k)) { - return dictionary.get(key); - } - } - return null; - } - - public boolean isEmpty() { - throw new UnsupportedOperationException(); - } - - public Enumeration keys() { - throw new UnsupportedOperationException(); - } - - public Enumeration elements() { - throw new UnsupportedOperationException(); - } - - public Object put(Object key, Object value) { - throw new UnsupportedOperationException(); - } - - public Object remove(Object key) { - throw new UnsupportedOperationException(); - } - - public int size() { - throw new UnsupportedOperationException(); - } - } - - static class SetAccessibleAction implements PrivilegedAction { - private final AccessibleObject accessible; - - SetAccessibleAction(AccessibleObject accessible) { - this.accessible = accessible; - } - - public Object run() { - accessible.setAccessible(true); - return null; - } - } -} \ No newline at end of file -- cgit v1.2.3