You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2010/01/28 20:33:39 UTC

svn commit: r904226 - in /sling/trunk/bundles: extensions/groovy/ extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/ scripting/core/src/main/java/org/apache/sling/scripting/core/impl/

Author: justin
Date: Thu Jan 28 19:33:38 2010
New Revision: 904226

URL: http://svn.apache.org/viewvc?rev=904226&view=rev
Log:
SLING-1303 - support java.util.Map services

Modified:
    sling/trunk/bundles/extensions/groovy/pom.xml
    sling/trunk/bundles/extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/JSONGroovyBuilderBindingsValuesProvider.java
    sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/SlingScriptAdapterFactory.java

Modified: sling/trunk/bundles/extensions/groovy/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/groovy/pom.xml?rev=904226&r1=904225&r2=904226&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/groovy/pom.xml (original)
+++ sling/trunk/bundles/extensions/groovy/pom.xml Thu Jan 28 19:33:38 2010
@@ -86,12 +86,6 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.scripting.api</artifactId>
-            <version>2.1.0-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>

Modified: sling/trunk/bundles/extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/JSONGroovyBuilderBindingsValuesProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/JSONGroovyBuilderBindingsValuesProvider.java?rev=904226&r1=904225&r2=904226&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/JSONGroovyBuilderBindingsValuesProvider.java (original)
+++ sling/trunk/bundles/extensions/groovy/src/main/java/org/apache/sling/extensions/groovy/json/internal/JSONGroovyBuilderBindingsValuesProvider.java Thu Jan 28 19:33:38 2010
@@ -16,10 +16,9 @@
  */
 package org.apache.sling.extensions.groovy.json.internal;
 
-import javax.script.Bindings;
+import java.util.HashMap;
 
 import org.apache.sling.extensions.groovy.json.JSONGroovyBuilder;
-import org.apache.sling.scripting.api.BindingsValuesProvider;
 
 /**
  * BindingsValuesProvider which binds an instance of JSONGroovyBuilder.
@@ -32,13 +31,11 @@
  *
  * @scr.property name="javax.script.name" value="groovy"
  */
-public class JSONGroovyBuilderBindingsValuesProvider implements BindingsValuesProvider {
+public class JSONGroovyBuilderBindingsValuesProvider extends HashMap<String, Object> {
 
-    /**
-     * {@inheritDoc}
-     */
-    public void addBindings(Bindings bindings) {
-        bindings.put("jsonBuilder", new JSONGroovyBuilder());
+    public JSONGroovyBuilderBindingsValuesProvider() {
+        super();
+        put("jsonBuilder", new JSONGroovyBuilder());
     }
 
 }

Modified: sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/SlingScriptAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/SlingScriptAdapterFactory.java?rev=904226&r1=904225&r2=904226&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/SlingScriptAdapterFactory.java (original)
+++ sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/SlingScriptAdapterFactory.java Thu Jan 28 19:33:38 2010
@@ -21,18 +21,19 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
 import javax.script.ScriptEngineManager;
@@ -47,6 +48,9 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.event.Event;
@@ -80,6 +84,9 @@
 
     private static final String ENGINE_FACTORY_SERVICE = "META-INF/services/" + ScriptEngineFactory.class.getName();
 
+    /** list of service property values which indicate 'any' script engine */
+    private static final List<String> ANY_ENGINE = Arrays.asList("*", "ANY");
+
     private ScriptEngineManager scriptEngineManager;
 
     private List<Bundle> engineSpiBundles = new LinkedList<Bundle>();
@@ -99,14 +106,19 @@
     private ServiceTracker bindingsValuesProviderTracker;
 
     /**
-     * The BindingsValuesProvider impls which apply to all languages
+     * The service tracker for Map impls with scripting bindings
+     */
+    private ServiceTracker mapBindingsValuesProviderTracker;
+
+    /**
+     * The BindingsValuesProvider impls which apply to all languages. Keys are serviceIds.
      */
-    private Collection<BindingsValuesProvider> genericBindingsValuesProviders;
+    private Map<Object, BindingsValuesProvider> genericBindingsValuesProviders;
 
     /**
-     * The BindingsValuesProvider impls which apply to a specific language
+     * The BindingsValuesProvider impls which apply to a specific language.
      */
-    private Map<String, Collection<BindingsValuesProvider>> langBindingsValuesProviders;
+    private Map<String, Map<Object, BindingsValuesProvider>> langBindingsValuesProviders;
 
     // ---------- AdapterFactory -----------------------------------------------
 
@@ -275,15 +287,27 @@
         this.bundleContext = context.getBundleContext();
 
         // setup tracker first as this is used in the bind/unbind methods
-        this.eventAdminTracker = new ServiceTracker(context.getBundleContext(), EventAdmin.class.getName(), null);
+        this.eventAdminTracker = new ServiceTracker(this.bundleContext, EventAdmin.class.getName(), null);
         this.eventAdminTracker.open();
 
-        this.genericBindingsValuesProviders = new HashSet<BindingsValuesProvider>();
-        this.langBindingsValuesProviders = new HashMap<String, Collection<BindingsValuesProvider>>();
+        this.genericBindingsValuesProviders = new HashMap<Object, BindingsValuesProvider>();
+        this.langBindingsValuesProviders = new HashMap<String, Map<Object, BindingsValuesProvider>>();
+
+        ServiceTrackerCustomizer customizer = new BindingsValuesProviderCustomizer();
 
-        this.bindingsValuesProviderTracker = new ServiceTracker(context.getBundleContext(), BindingsValuesProvider.class.getName(),
-                new BindingsValuesProviderCustomizer());
+        this.bindingsValuesProviderTracker = new ServiceTracker(this.bundleContext, BindingsValuesProvider.class.getName(), customizer);
         this.bindingsValuesProviderTracker.open();
+
+        try {
+            Filter filter = this.bundleContext.createFilter(String.format("(&(objectclass=%s)(javax.script.name=*))",
+                    Map.class.getName()));
+
+            this.mapBindingsValuesProviderTracker = new ServiceTracker(this.bundleContext, filter, customizer);
+            this.mapBindingsValuesProviderTracker.open();
+        } catch (InvalidSyntaxException e) {
+            log.warn("Unable to create ServiceTracker for Map-based script bindiings", e);
+        }
+
         this.bundleContext.addBundleListener(this);
 
         Bundle[] bundles = this.bundleContext.getBundles();
@@ -321,6 +345,10 @@
             this.bindingsValuesProviderTracker.close();
             this.bindingsValuesProviderTracker = null;
         }
+        if (this.mapBindingsValuesProviderTracker != null) {
+            this.mapBindingsValuesProviderTracker.close();
+            this.mapBindingsValuesProviderTracker = null;
+        }
         this.bundleContext = null;
     }
 
@@ -353,12 +381,12 @@
     }
 
     private Collection<BindingsValuesProvider> getBindingsValuesProviders(ScriptEngineFactory scriptEngineFactory) {
-        Set<BindingsValuesProvider> results = new HashSet<BindingsValuesProvider>();
-        results.addAll(genericBindingsValuesProviders);
+        List<BindingsValuesProvider> results = new ArrayList<BindingsValuesProvider>();
+        results.addAll(genericBindingsValuesProviders.values());
         for (String name : scriptEngineFactory.getNames()) {
-            Collection<BindingsValuesProvider> langProviders = langBindingsValuesProviders.get(name);
+            Map<Object, BindingsValuesProvider> langProviders = langBindingsValuesProviders.get(name);
             if (langProviders != null) {
-                results.addAll(langProviders);
+                results.addAll(langProviders.values());
             }
         }
         return results;
@@ -380,36 +408,38 @@
 
     private class BindingsValuesProviderCustomizer implements ServiceTrackerCustomizer {
 
+        @SuppressWarnings("unchecked")
         public Object addingService(ServiceReference ref) {
             String engineName = (String) ref.getProperty(ScriptEngine.NAME);
-            BindingsValuesProvider service = (BindingsValuesProvider) bundleContext.getService(ref);
-            if (engineName == null) {
-                genericBindingsValuesProviders.add(service);
+            Object serviceId = ref.getProperty(Constants.SERVICE_ID);
+            Object service = bundleContext.getService(ref);
+            if (service instanceof Map) {
+                service = new MapWrappingBindingsValuesProvider((Map) service);
+            }
+            if (engineName == null || ANY_ENGINE.contains(engineName)) {
+                genericBindingsValuesProviders.put(serviceId, (BindingsValuesProvider) service);
             } else {
-                Collection<BindingsValuesProvider> langProviders = langBindingsValuesProviders.get(engineName);
+                Map<Object, BindingsValuesProvider> langProviders = langBindingsValuesProviders.get(engineName);
                 if (langProviders == null) {
-                    langProviders = new HashSet<BindingsValuesProvider>();
+                    langProviders = new HashMap<Object, BindingsValuesProvider>();
                     langBindingsValuesProviders.put(engineName, langProviders);
                 }
 
-                langProviders.add(service);
+                langProviders.put(serviceId, (BindingsValuesProvider) service);
             }
             return service;
         }
 
         public void modifiedService(ServiceReference ref, Object service) {
-            remove((BindingsValuesProvider) service);
+            removedService(ref, service);
             addingService(ref);
         }
 
         public void removedService(ServiceReference ref, Object service) {
-            remove((BindingsValuesProvider) service);
-        }
-
-        private void remove(BindingsValuesProvider service) {
-            if (!genericBindingsValuesProviders.remove(service)) {
-                for (Collection<BindingsValuesProvider> coll : langBindingsValuesProviders.values()) {
-                    if (coll.remove(service)) {
+            Object serviceId = ref.getProperty(Constants.SERVICE_ID);
+            if (genericBindingsValuesProviders.remove(serviceId) == null) {
+                for (Map<Object, BindingsValuesProvider> coll : langBindingsValuesProviders.values()) {
+                    if (coll.remove(service) != null) {
                         return;
                     }
                 }
@@ -418,4 +448,20 @@
 
     }
 
+    private class MapWrappingBindingsValuesProvider implements BindingsValuesProvider {
+
+        private Map<String,Object> map;
+
+        MapWrappingBindingsValuesProvider(Map<String, Object> map) {
+            this.map = map;
+        }
+
+        public void addBindings(Bindings bindings) {
+            for (String key : map.keySet()) {
+                bindings.put(key, map.get(key));
+            }
+        }
+
+    }
+
 }