You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gn...@apache.org on 2009/04/14 00:34:50 UTC
svn commit: r764641 - in
/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint:
./ context/ convert/ namespace/
Author: gnodet
Date: Mon Apr 13 22:34:49 2009
New Revision: 764641
URL: http://svn.apache.org/viewvc?rev=764641&view=rev
Log:
Import activator / conversion service from Jarek / Rick
Added:
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/Activator.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/ModuleContextEventSender.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/NamespaceHandlerRegistry.java
- copied, changed from r764560, geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistry.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/DefaultModuleContextEventSender.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/WaitForDependencyException.java
Removed:
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistry.java
Modified:
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Instanciator.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/ModuleContextImpl.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Parser.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/convert/ConversionServiceImpl.java
geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistryImpl.java
Added: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/Activator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/Activator.java?rev=764641&view=auto
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/Activator.java (added)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/Activator.java Mon Apr 13 22:34:49 2009
@@ -0,0 +1,103 @@
+package org.apache.felix.blueprint;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.blueprint.context.DefaultModuleContextEventSender;
+import org.apache.felix.blueprint.context.ModuleContextImpl;
+import org.apache.felix.blueprint.namespace.NamespaceHandlerRegistryImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * TODO: javadoc
+ *
+ * TODO: handle ModuleContextListener
+ */
+public class Activator implements BundleActivator, BundleListener {
+
+ private StopBundleListener stopBundleListener = new StopBundleListener();
+ private Map<Bundle, ModuleContextImpl> contextMap = new HashMap<Bundle, ModuleContextImpl>();
+ private ModuleContextEventSender sender;
+ private NamespaceHandlerRegistry handlers;
+
+ public void start(BundleContext context) {
+ System.out.println("Starting to listen for bundle events.");
+ context.addBundleListener(stopBundleListener);
+ context.addBundleListener(this);
+
+ sender = new DefaultModuleContextEventSender(context);
+ handlers = new NamespaceHandlerRegistryImpl(context);
+
+ Bundle[] bundles = context.getBundles();
+ for (Bundle b : bundles) {
+ if (b.getState() == Bundle.ACTIVE) {
+ checkBundle(b);
+ }
+ }
+ }
+
+
+ public void stop(BundleContext context) {
+ context.removeBundleListener(stopBundleListener);
+ context.removeBundleListener(this);
+ this.sender.destroy();
+ this.handlers.destroy();
+ System.out.println("Stopped listening for bundle events.");
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ System.out.println("bundle changed:" + event.getBundle().getSymbolicName() + " "+ event.getType());
+ if (event.getType() == BundleEvent.STARTED) {
+ checkBundle(event.getBundle());
+ }
+ }
+
+ private void destroyContext(Bundle bundle) {
+ ModuleContextImpl moduleContext = contextMap.remove(bundle);
+ if (moduleContext != null) {
+ moduleContext.destroy();
+ }
+ }
+
+ private void checkBundle(Bundle b) {
+ System.out.println("Checking: " + b.getSymbolicName());
+
+ List<URL> urls = new ArrayList<URL>();
+ Enumeration e = b.findEntries("OSGI-INF/blueprint", "*.xml", true);
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ URL u = (URL) e.nextElement();
+ System.out.println("found xml config:" + u);
+ urls.add(u);
+ }
+ }
+ if (urls.size() > 0) {
+ ModuleContextImpl moduleContext = new ModuleContextImpl(b.getBundleContext(), sender, urls.toArray(new URL[urls.size()]));
+ contextMap.put(b, moduleContext);
+ moduleContext.create();
+ }
+
+ Dictionary d = b.getHeaders();
+ System.out.println(d.get("Bundle-Blueprint"));
+ }
+
+
+ private class StopBundleListener implements SynchronousBundleListener {
+ public void bundleChanged(BundleEvent event) {
+ if (event.getType() == BundleEvent.STOPPING) {
+ destroyContext(event.getBundle());
+ }
+ }
+ }
+
+}
Added: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/ModuleContextEventSender.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/ModuleContextEventSender.java?rev=764641&view=auto
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/ModuleContextEventSender.java (added)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/ModuleContextEventSender.java Mon Apr 13 22:34:49 2009
@@ -0,0 +1,26 @@
+package org.apache.felix.blueprint;
+
+import org.apache.felix.blueprint.context.ModuleContextImpl;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.osgi.service.blueprint.context.ModuleContextEventConstants;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: gnodet
+ * Date: Apr 13, 2009
+ * Time: 11:18:06 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface ModuleContextEventSender extends ModuleContextEventConstants {
+
+ void sendCreating(ModuleContext moduleContext);
+ void sendCreated(ModuleContext moduleContext);
+ void sendDestroying(ModuleContext moduleContext);
+ void sendDestroyed(ModuleContext moduleContext);
+ void sendWaiting(ModuleContext moduleContext, String[] serviceObjectClass, String serviceFilter);
+ void sendFailure(ModuleContext moduleContext, Throwable cause);
+ void sendFailure(ModuleContext moduleContext, Throwable cause, String[] serviceObjectClass, String serviceFilter);
+
+ void destroy();
+
+}
Copied: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/NamespaceHandlerRegistry.java (from r764560, geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistry.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/NamespaceHandlerRegistry.java?p2=geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/NamespaceHandlerRegistry.java&p1=geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistry.java&r1=764560&r2=764641&rev=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistry.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/NamespaceHandlerRegistry.java Mon Apr 13 22:34:49 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.blueprint.namespace;
+package org.apache.felix.blueprint;
import java.net.URI;
@@ -30,5 +30,19 @@
*/
public interface NamespaceHandlerRegistry {
+ /**
+ * Retrieve the <code>NamespaceHandler</code> for the specified URI
+ *
+ * @param uri the namespace identifying the namespace handler
+ * @return the registered <code>NamespaceHandler</code> or <code>null</code> if none has been registered for the given namespace
+ */
NamespaceHandler getNamespaceHandler(URI uri);
+
+ /**
+ * Add a callback to be run each time the list of namespace handlers changes
+ * @param runnable
+ */
+ void addCallback(Runnable runnable);
+
+ void destroy();
}
Added: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/DefaultModuleContextEventSender.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/DefaultModuleContextEventSender.java?rev=764641&view=auto
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/DefaultModuleContextEventSender.java (added)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/DefaultModuleContextEventSender.java Mon Apr 13 22:34:49 2009
@@ -0,0 +1,94 @@
+package org.apache.felix.blueprint.context;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Bundle;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.event.Event;
+import org.osgi.service.blueprint.context.ModuleContextEventConstants;
+import org.osgi.service.blueprint.context.ModuleContext;
+import org.apache.felix.blueprint.ModuleContextEventSender;
+
+/**
+ * TODO: javadoc
+ */
+public class DefaultModuleContextEventSender implements ModuleContextEventSender {
+
+ private final ServiceTracker eventAdminServiceTracker;
+
+ public DefaultModuleContextEventSender(BundleContext bundleContext) {
+ this.eventAdminServiceTracker = new ServiceTracker(bundleContext, EventAdmin.class.getName(), null);
+ this.eventAdminServiceTracker.open();
+ }
+
+ public void sendCreating(ModuleContext moduleContext) {
+ sendEvent(moduleContext, TOPIC_CREATING, null, null, null);
+ }
+
+ public void sendCreated(ModuleContext moduleContext) {
+ sendEvent(moduleContext, TOPIC_CREATED, null, null, null);
+ }
+
+ public void sendDestroying(ModuleContext moduleContext) {
+ sendEvent(moduleContext, TOPIC_DESTROYING, null, null, null);
+ }
+
+ public void sendDestroyed(ModuleContext moduleContext) {
+ sendEvent(moduleContext, TOPIC_DESTROYED, null, null, null);
+ }
+
+ public void sendWaiting(ModuleContext moduleContext, String[] serviceObjectClass, String serviceFilter) {
+ sendEvent(moduleContext, TOPIC_WAITING, null, serviceObjectClass, serviceFilter);
+ }
+
+ public void sendFailure(ModuleContext moduleContext, Throwable cause) {
+ sendEvent(moduleContext, TOPIC_FAILURE, cause, null, null);
+ }
+
+ public void sendFailure(ModuleContext moduleContext, Throwable cause, String[] serviceObjectClass, String serviceFilter) {
+ sendEvent(moduleContext, TOPIC_FAILURE, cause, serviceObjectClass, serviceFilter);
+ }
+
+ public void sendEvent(ModuleContext moduleContext, String topic, Throwable cause, String[] serviceObjectClass, String serviceFilter) {
+ EventAdmin eventAdmin = getEventAdmin();
+ if (eventAdmin == null) {
+ return;
+ }
+
+ Bundle bundle = moduleContext.getBundleContext().getBundle();
+
+ Dictionary props = new Hashtable();
+ props.put("bundle.symbolicName", bundle.getSymbolicName());
+ props.put("bundle.id", bundle.getBundleId());
+ props.put("bundle", bundle);
+ props.put("bundle.version", "NA");
+ props.put("timestamp", System.currentTimeMillis());
+ props.put(ModuleContextEventConstants.EXTENDER_BUNDLE, "NA");
+ props.put(ModuleContextEventConstants.EXTENDER_ID, "NA");
+ props.put(ModuleContextEventConstants.EXTENDER_SYMBOLICNAME, "NA");
+ if (cause != null) {
+ props.put("exception", cause);
+ }
+ if (serviceObjectClass != null) {
+ props.put("service.objectClass", serviceObjectClass);
+ }
+ if (serviceFilter != null) {
+ props.put("service.filter", serviceFilter);
+ }
+
+ Event event = new Event(topic, props);
+ eventAdmin.postEvent(event);
+ System.out.println("Event sent: " + topic);
+ }
+
+ private EventAdmin getEventAdmin() {
+ return (EventAdmin)this.eventAdminServiceTracker.getService();
+ }
+
+ public void destroy() {
+ this.eventAdminServiceTracker.close();
+ }
+}
Modified: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Instanciator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Instanciator.java?rev=764641&r1=764640&r2=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Instanciator.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Instanciator.java Mon Apr 13 22:34:49 2009
@@ -96,7 +96,7 @@
if (v instanceof NullValue) {
return null;
} else if (v instanceof TypedStringValue) {
- // TODO: type name ?
+ // TODO: TypedStringValue#getTypeName()
return ((TypedStringValue) v).getStringValue();
} else if (v instanceof ReferenceValue) {
String componentName = ((ReferenceValue) v).getComponentName();
@@ -131,8 +131,7 @@
} else if (v instanceof ComponentValue) {
return createRecipe(((ComponentValue) v).getComponentMetadata());
} else if (v instanceof PropertiesValue) {
- // TODO
- throw new IllegalStateException("Unsupported value: " + v.getClass().getName());
+ return ((PropertiesValue) v).getPropertiesValue();
} else if (v instanceof ReferenceNameValue) {
return ((ReferenceNameValue) v).getReferenceName();
} else {
Modified: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/ModuleContextImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/ModuleContextImpl.java?rev=764641&r1=764640&r2=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/ModuleContextImpl.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/ModuleContextImpl.java Mon Apr 13 22:34:49 2009
@@ -22,8 +22,12 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
+import java.net.URL;
import org.apache.felix.blueprint.namespace.ComponentDefinitionRegistryImpl;
+import org.apache.felix.blueprint.ModuleContextEventSender;
+import org.apache.xbean.recipe.Repository;
+import org.apache.xbean.recipe.ObjectGraph;
import org.osgi.framework.BundleContext;
import org.osgi.service.blueprint.context.ModuleContext;
import org.osgi.service.blueprint.context.NoSuchComponentException;
@@ -40,10 +44,34 @@
*/
public class ModuleContextImpl implements ModuleContext {
- private BundleContext bundleContext;
+ private final BundleContext bundleContext;
+ private final ModuleContextEventSender sender;
+ private final URL[] urls;
private ComponentDefinitionRegistryImpl componentDefinitionRegistry;
- public ModuleContextImpl() {
+ public ModuleContextImpl(BundleContext bundleContext, ModuleContextEventSender sender, URL[] urls) {
+ this.bundleContext = bundleContext;
+ this.sender = sender;
+ this.urls = urls;
+ }
+
+ public void create() {
+ sender.sendCreating(this);
+ try {
+ Parser parser = new Parser();
+ parser.parse(urls);
+ componentDefinitionRegistry = parser.getRegistry();
+ Repository repository = Instanciator.createRepository(componentDefinitionRegistry);
+ ObjectGraph graph = new ObjectGraph(repository);
+ graph.createAll(new ArrayList<String>(componentDefinitionRegistry.getComponentDefinitionNames()));
+ sender.sendCreated(this);
+ } catch (WaitForDependencyException e) {
+ sender.sendWaiting(this, null, null); // TODO: give correct args
+ // TODO: wait for dependency
+ } catch (Exception e) {
+ // TODO: pass the exception to the event
+ sender.sendFailure(this, e);
+ }
}
public Set<String> getComponentNames() {
@@ -92,4 +120,12 @@
public BundleContext getBundleContext() {
return bundleContext;
}
+
+ public void destroy() {
+ sender.sendDestroying(this);
+ System.out.println("Module context destroyed: " + this.bundleContext);
+ // TODO: destroy all instances
+ sender.sendDestroyed(this);
+ }
+
}
Modified: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Parser.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Parser.java?rev=764641&r1=764640&r2=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Parser.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/Parser.java Mon Apr 13 22:34:49 2009
@@ -42,7 +42,7 @@
import org.w3c.dom.Attr;
import org.apache.felix.blueprint.namespace.ComponentDefinitionRegistryImpl;
-import org.apache.felix.blueprint.namespace.NamespaceHandlerRegistry;
+import org.apache.felix.blueprint.NamespaceHandlerRegistry;
import org.apache.felix.blueprint.reflect.ComponentValueImpl;
import org.apache.felix.blueprint.reflect.ListValueImpl;
import org.apache.felix.blueprint.reflect.LocalComponentMetadataImpl;
@@ -78,7 +78,6 @@
import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.CollectionBasedServiceReferenceComponentMetadata;
import org.osgi.service.blueprint.reflect.ArrayValue;
-import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
/**
@@ -181,7 +180,7 @@
private DocumentBuilderFactory documentBuilderFactory;
private ComponentDefinitionRegistryImpl registry;
private ConversionService conversionService;
- private NamespaceHandlerRegistry namespaceHandlerRegistry;
+ private NamespaceHandlerRegistry namespaceHandlerRegistry;
private int nameCounter;
private String defaultTimeout;
private String defaultAvailability;
Added: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/WaitForDependencyException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/WaitForDependencyException.java?rev=764641&view=auto
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/WaitForDependencyException.java (added)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/context/WaitForDependencyException.java Mon Apr 13 22:34:49 2009
@@ -0,0 +1,18 @@
+package org.apache.felix.blueprint.context;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: gnodet
+ * Date: Apr 14, 2009
+ * Time: 12:17:56 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class WaitForDependencyException extends Exception {
+
+ public WaitForDependencyException() {
+ }
+
+ public WaitForDependencyException(String message) {
+ super(message);
+ }
+}
Modified: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/convert/ConversionServiceImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/convert/ConversionServiceImpl.java?rev=764641&r1=764640&r2=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/convert/ConversionServiceImpl.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/convert/ConversionServiceImpl.java Mon Apr 13 22:34:49 2009
@@ -1,122 +1,141 @@
-/*
- * 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
+/**
+ * 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
+ * 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.
+ * 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.felix.blueprint.convert;
-import java.util.List;
+import java.io.ByteArrayInputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-import java.util.Map;
import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;
-import java.util.concurrent.ConcurrentHashMap;
-import java.lang.reflect.Constructor;
-import java.io.StringReader;
-import java.io.Reader;
-import java.io.ByteArrayInputStream;
import org.osgi.service.blueprint.convert.ConversionService;
import org.osgi.service.blueprint.convert.Converter;
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:dev@felix.apache.org">Apache Felix Project</a>
- * @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
- */
public class ConversionServiceImpl implements ConversionService {
- private static final Map<Class, Class> primitives;
- private List<Converter> converters = new ArrayList<Converter>();
-
- static {
- primitives = new HashMap<Class, Class>();
- primitives.put(byte.class, Byte.class);
- primitives.put(int.class, Integer.class);
- primitives.put(long.class, Long.class);
- primitives.put(float.class, Float.class);
- primitives.put(double.class, Double.class);
- primitives.put(short.class, Short.class);
- primitives.put(char.class, Character.class);
- primitives.put(boolean.class, Boolean.class);
- }
+ private Map<Class, List<Converter>> convertersMap = new HashMap<Class, List<Converter>>();
- public ConversionServiceImpl() {
+ public void registerConverter(Converter converter) {
+ Class type = converter.getTargetClass();
+ List<Converter> converters = convertersMap.get(type);
+ if (converters == null) {
+ converters = new ArrayList<Converter>();
+ convertersMap.put(type, converters);
+ }
+ converters.add(converter);
}
public Object convert(Object fromValue, Class toType) throws Exception {
- if (fromValue == null) {
- return null;
+ Converter converter = lookupConverter(toType);
+ if (converter == null) {
+ return convertDefault(fromValue, toType);
+ } else {
+ return converter.convert(fromValue);
}
- // Check converters
- for (Converter converter : converters) {
- if (converter.getTargetClass().equals(toType)) {
- return converter.convert(fromValue);
- }
+ }
+
+ private Converter lookupConverter(Class toType) {
+ // do explicit lookup
+ List<Converter> converters = convertersMap.get(toType);
+ if (converters != null && !converters.isEmpty()) {
+ return converters.get(0);
}
- // Default conversion
- if (fromValue instanceof String) {
- String fromString = (String) fromValue;
- if (primitives.containsKey(toType)) {
- toType = primitives.get(toType);
- }
- // Boolean
- if (toType.equals(Boolean.class)) {
- fromString = fromString.toLowerCase();
- if (fromString.equals("true") || fromString.equals("yes") || fromString.equals("on")) {
- return Boolean.TRUE;
- } else if (fromString.equals("false") || fromString.equals("no") || fromString.equals("off")) {
- return Boolean.FALSE;
- } else {
- throw new IllegalArgumentException("Illegal boolean value: " + fromString);
- }
- }
- // Character
- if (toType.equals(Character.class)) {
- if (fromString.length() == 1) {
- return fromString.charAt(0);
- } else {
- throw new IllegalArgumentException("Conversion from String to Character must have a strig argument of length equals to 1");
- }
- }
- // Locale
- if (toType.equals(Locale.class)) {
- // TODO
- }
- // Properties
- if (toType.equals(Properties.class)) {
- Properties props = new Properties();
- props.load(new ByteArrayInputStream(fromString.getBytes()));
- return props;
- }
- // Pattern
- if (toType.equals(Pattern.class)) {
- return Pattern.compile(fromString);
- }
- // Public constructor
- try {
- Constructor constructor = toType.getConstructor(String.class);
- return constructor.newInstance(fromString);
- } catch (NoSuchMethodException e) {
- // Ignore
+
+ // try to find converter that matches the type
+ for (Map.Entry<Class, List<Converter>> entry : convertersMap.entrySet()) {
+ Class converterClass = entry.getKey();
+ if (toType.isAssignableFrom(converterClass)) {
+ return entry.getValue().get(0);
}
}
+
return null;
}
-}
+
+ private Object convertDefault(Object fromValue, Class toType) throws Exception {
+ String value = (String)fromValue;
+ if (Locale.class == toType) {
+ String[] tokens = value.split("_");
+ if (tokens.length == 1) {
+ return new Locale(tokens[0]);
+ } else if (tokens.length == 2) {
+ return new Locale(tokens[0], tokens[1]);
+ } else if (tokens.length == 3) {
+ return new Locale(tokens[0], tokens[1], tokens[2]);
+ } else {
+ throw new Exception("Invalid locale string:" + value);
+ }
+ } else if (Pattern.class == toType) {
+ return Pattern.compile(value);
+ } else if (Properties.class == toType) {
+ Properties props = new Properties();
+ ByteArrayInputStream in = new ByteArrayInputStream(value.getBytes("UTF8"));
+ props.load(in);
+ return props;
+ } else if (Boolean.class == toType || boolean.class == toType) {
+ if ("yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value)) {
+ return Boolean.TRUE;
+ } else if ("no".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value) || "off".equalsIgnoreCase(value)) {
+ return Boolean.FALSE;
+ } else {
+ throw new RuntimeException("Invalid boolean value: " + value);
+ }
+ } else if (Integer.class == toType || int.class == toType) {
+ return Integer.valueOf(value);
+ } else if (Short.class == toType || short.class == toType) {
+ return Short.valueOf(value);
+ } else if (Long.class == toType || long.class == toType) {
+ return Long.valueOf(value);
+ } else if (Float.class == toType || float.class == toType) {
+ return Float.valueOf(value);
+ } else if (Double.class == toType || double.class == toType) {
+ return Double.valueOf(value);
+ } else if (Character.class == toType || char.class == toType) {
+ if (value.length() == 1) {
+ return Character.valueOf(value.charAt(0));
+ } else {
+ throw new Exception("Invalid value for character type: " + value);
+ }
+ } else if (Byte.class == toType || byte.class == toType) {
+ return Byte.valueOf(value);
+ } else {
+ return createObject(value, toType);
+ }
+ }
+
+ private Object createObject(String value, Class type) throws Exception {
+ Constructor constructor = null;
+ try {
+ constructor = type.getConstructor(String.class);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Unable to convert to " + type);
+ }
+ try {
+ return constructor.newInstance(value);
+ } catch (InvocationTargetException e) {
+ throw new Exception("Unable to convert ", e.getTargetException());
+ } catch (Exception e) {
+ throw new Exception("Unable to convert ", e);
+ }
+ }
+
+}
\ No newline at end of file
Modified: geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistryImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistryImpl.java?rev=764641&r1=764640&r2=764641&view=diff
==============================================================================
--- geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistryImpl.java (original)
+++ geronimo/sandbox/gnodet/blueprint/org.apache.felix.blueprint/src/main/java/org/apache/felix/blueprint/namespace/NamespaceHandlerRegistryImpl.java Mon Apr 13 22:34:49 2009
@@ -20,9 +20,17 @@
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ConcurrentHashMap;
import java.net.URI;
import org.osgi.service.blueprint.namespace.NamespaceHandler;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.apache.felix.blueprint.NamespaceHandlerRegistry;
/**
* TODO: javadoc
@@ -30,14 +38,53 @@
* @author <a href="mailto:dev@felix.apache.org">Apache Felix Project</a>
* @version $Rev: 760378 $, $Date: 2009-03-31 11:31:38 +0200 (Tue, 31 Mar 2009) $
*/
-public class NamespaceHandlerRegistryImpl implements NamespaceHandlerRegistry {
+public class NamespaceHandlerRegistryImpl implements NamespaceHandlerRegistry, ServiceTrackerCustomizer {
public static final String NAMESPACE = "org.osgi.blueprint.namespace";
+ private final BundleContext bundleContext;
private final Map<URI, NamespaceHandler> handlers;
+ private final List<Runnable> runnables;
+ private final ServiceTracker tracker;
- public NamespaceHandlerRegistryImpl() {
- handlers = new HashMap<URI, NamespaceHandler>();
+ public NamespaceHandlerRegistryImpl(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ handlers = new ConcurrentHashMap<URI, NamespaceHandler>();
+ runnables = new CopyOnWriteArrayList<Runnable>();
+ tracker = new ServiceTracker(bundleContext, NamespaceHandler.class.getName(), this);
+ }
+
+ public Object addingService(ServiceReference reference) {
+ NamespaceHandler handler = (NamespaceHandler) bundleContext.getService(reference);
+ Map props = new HashMap();
+ for (String name : reference.getPropertyKeys()) {
+ props.put(name, reference.getProperty(name));
+ }
+ try {
+ registerHandler(handler, props);
+ return handler;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void modifiedService(ServiceReference reference, Object service) {
+ removedService(reference, service);
+ addingService(reference);
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ NamespaceHandler handler = (NamespaceHandler) service;
+ Map props = new HashMap();
+ for (String name : reference.getPropertyKeys()) {
+ props.put(name, reference.getProperty(name));
+ }
+ try {
+ unregisterHandler(handler, props);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
public void registerHandler(NamespaceHandler handler, Map properties) throws Exception {
@@ -51,6 +98,10 @@
for (URI uri : (URI[]) ns) {
handlers.put(uri, handler);
}
+ for (Runnable r : runnables) {
+ r.run();
+ }
+
} else {
throw new IllegalArgumentException("NamespaceHandler service does not have an associated " + NAMESPACE + " property defined");
}
@@ -67,6 +118,9 @@
for (URI uri : (URI[]) ns) {
handlers.remove(uri);
}
+ for (Runnable r : runnables) {
+ r.run();
+ }
} else {
throw new IllegalArgumentException("NamespaceHandler service does not have an associated " + NAMESPACE + " property defined");
}
@@ -76,4 +130,11 @@
return handlers.get(uri);
}
+ public void addCallback(Runnable runnable) {
+ runnables.add(runnable);
+ }
+
+ public void destroy() {
+ tracker.close();
+ }
}