You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/03/25 12:30:14 UTC

svn commit: r640774 - in /incubator/sling/trunk/scripting/javascript: ./ src/main/java/org/apache/sling/scripting/javascript/wrapper/ src/test/java/org/apache/sling/scripting/ src/test/java/org/apache/sling/scripting/wrapper/

Author: fmeschbe
Date: Tue Mar 25 04:30:05 2008
New Revision: 640774

URL: http://svn.apache.org/viewvc?rev=640774&view=rev
Log:
SLING-289 Support Calendar property access
SLING-290 Support binary property access
SLING-341 Properly setup wrappers returned from node and property access

In addition fixed the support for the getDefaultValue method in the
ScriptableProperty class by replacing the overwritten method by valueOf
and toString JavaScript methods implementing desired behaviour.

Modified:
    incubator/sling/trunk/scripting/javascript/pom.xml
    incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java
    incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java
    incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java
    incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/ScriptEngineHelper.java
    incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/wrapper/ScriptableNodeTest.java

Modified: incubator/sling/trunk/scripting/javascript/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/pom.xml?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/pom.xml (original)
+++ incubator/sling/trunk/scripting/javascript/pom.xml Tue Mar 25 04:30:05 2008
@@ -87,6 +87,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.resource</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.testing</artifactId>
             <version>2.0.0-incubator-SNAPSHOT</version>
             <scope>test</scope>

Modified: incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java Tue Mar 25 04:30:05 2008
@@ -42,23 +42,21 @@
     private Map<String, Item> items = new LinkedHashMap<String, Item>();
 
     public ScriptableItemMap() {
-        // prevent modification, seal the object
-        sealObject();
     }
 
-    public ScriptableItemMap(Iterator<?> itemIterator) {
-        while (itemIterator.hasNext()) {
-            Item item = (Item) itemIterator.next();
-            try {
-                items.put(item.getName(), item);
-            } catch (RepositoryException re) {
-                log.error("ScriptableItemMap<init>: Cannot get name of item "
-                    + item, re);
+    public void jsConstructor(Object res) {
+        if (res instanceof Iterator) {
+            Iterator<?> itemIterator = (Iterator<?>) res;
+            while (itemIterator.hasNext()) {
+                Item item = (Item) itemIterator.next();
+                try {
+                    items.put(item.getName(), item);
+                } catch (RepositoryException re) {
+                    log.error("ScriptableItemMap<init>: Cannot get name of item "
+                        + item, re);
+                }
             }
         }
-
-        // prevent modification, seal the object
-        sealObject();
     }
 
     @Override

Modified: incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java Tue Mar 25 04:30:05 2008
@@ -32,7 +32,9 @@
 import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.NodeType;
 
+import org.apache.sling.jcr.resource.JcrResourceUtil;
 import org.apache.sling.scripting.javascript.helper.SlingWrapper;
+import org.mozilla.javascript.Context;
 import org.mozilla.javascript.NativeArray;
 import org.mozilla.javascript.ScriptRuntime;
 import org.mozilla.javascript.Scriptable;
@@ -58,11 +60,6 @@
     public ScriptableNode() {
     }
 
-    public ScriptableNode(Node item) {
-        super();
-        this.node = item;
-    }
-
     public void jsConstructor(Object res) {
         this.node = (Node) res;
     }
@@ -91,16 +88,16 @@
         return ScriptRuntime.toObject(this, node.getNode(path));
     }
 
-    public ScriptableItemMap jsFunction_getChildren() {
+    public Object jsFunction_getChildren() {
         try {
-            return new ScriptableItemMap(node.getNodes());
+            return toScriptableItemMap(node.getNodes());
         } catch (RepositoryException re) {
             log.warn("Cannot get children of " + jsFunction_getPath(), re);
-            return new ScriptableItemMap();
+            return toScriptableItemMap(null);
         }
     }
 
-    public ScriptableItemMap jsFunction_getNodes(String namePattern) {
+    public Object jsFunction_getNodes(String namePattern) {
         try {
             NodeIterator iter = null;
             if(namePattern == null || "undefined".equals(namePattern)) {
@@ -108,19 +105,19 @@
             } else {
                 iter = node.getNodes(namePattern);
             }
-            return new ScriptableItemMap(iter);
+            return toScriptableItemMap(iter);
         } catch (RepositoryException re) {
             log.warn("Cannot get children of " + jsFunction_getPath() + " with pattern " + namePattern, re);
-            return new ScriptableItemMap();
+            return toScriptableItemMap(null);
         }
     }
     
-    public ScriptableItemMap jsFunction_getProperties() {
+    public Object jsFunction_getProperties() {
         try {
-            return new ScriptableItemMap(node.getProperties());
+            return toScriptableItemMap(node.getProperties());
         } catch (RepositoryException re) {
             log.warn("Cannot get properties of " + jsFunction_getPath(), re);
-            return new ScriptableItemMap();
+            return toScriptableItemMap(null);
         }
     }
 
@@ -132,8 +129,10 @@
         }
     }
     
-    public ScriptableProperty jsFunction_getProperty(String name) throws RepositoryException {
-        return new ScriptableProperty(node.getProperty(name));
+    public Object jsFunction_getProperty(String name) throws RepositoryException {
+        Object[] args = { node.getProperty(name) };
+        return ScriptRuntime.newObject(Context.getCurrentContext(), this,
+            ScriptableProperty.CLASSNAME, args);
     }
 
     public String jsFunction_getUUID() {
@@ -296,7 +295,7 @@
         try {
             NodeIterator it = node.getNodes(name);
             while (it.hasNext()) {
-                items.add(new ScriptableNode(it.nextNode()));
+                items.add(ScriptRuntime.toObject(this, it.nextNode()));
             }
         } catch (RepositoryException e) {
             log.debug("RepositoryException while collecting Node children",e);
@@ -311,13 +310,13 @@
                 if (prop.getDefinition().isMultiple()) {
                     Value[] values = prop.getValues();
                     for (int i=0;i<values.length;i++) {
-                        items.add(wrap(values[i], type));
+                        items.add(wrap(values[i]));
                     }
                 } else {
                     if (type==PropertyType.REFERENCE) {
-                        items.add(new ScriptableNode(prop.getNode()));
+                        items.add(ScriptRuntime.toObject(this, prop.getNode()));
                     } else {
-                        items.add(wrap(prop.getValue(), type));
+                        items.add(wrap(prop.getValue()));
                     }
                 }
             }
@@ -338,19 +337,9 @@
     }
 
     /** Wrap JCR Values in a simple way */
-    private Scriptable wrap(Value value, int type) throws ValueFormatException, IllegalStateException, RepositoryException {
-        Object valObj;
-        if (type==PropertyType.BINARY) {
-            valObj = value.getBoolean();
-        } else if (type==PropertyType.DOUBLE) {
-            valObj = value.getDouble();
-        } else if (type==PropertyType.LONG) {
-            valObj = value.getLong();
-        } else {
-            valObj = value.getString();
-        }
-
-        return ScriptRuntime.toObject(this, valObj);
+    private Scriptable wrap(Value value) throws ValueFormatException,
+            IllegalStateException, RepositoryException {
+        return ScriptRuntime.toObject(this, JcrResourceUtil.toJavaObject(value));
     }
 
     @Override
@@ -409,5 +398,13 @@
     // returns the wrapped node
     public Object unwrap() {
         return node;
+    }
+    
+    //---------- Helper -------------------------------------------------------
+    
+    private Object toScriptableItemMap(Iterator<?> iter) {
+        Object[] args = (iter != null) ? new Object[] { iter } : null;
+        return ScriptRuntime.newObject(Context.getCurrentContext(), this,
+            ScriptableItemMap.CLASSNAME, args);
     }
 }

Modified: incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java Tue Mar 25 04:30:05 2008
@@ -27,23 +27,18 @@
 import org.mozilla.javascript.ScriptableObject;
 import org.mozilla.javascript.Undefined;
 
-public class ScriptableProperty extends ScriptableObject implements SlingWrapper {
+public class ScriptableProperty extends ScriptableObject implements
+        SlingWrapper {
 
     public static final String CLASSNAME = "Property";
-    public static final Class<?> [] WRAPPED_CLASSES = { Property.class };
+
+    public static final Class<?>[] WRAPPED_CLASSES = { Property.class };
 
     private Property property;
 
     public ScriptableProperty() {
     }
 
-    public ScriptableProperty(Property property) {
-        this.property = property;
-    }
-
-    public void jsConstructor() {
-    }
-
     public void jsConstructor(Object res) {
         this.property = (Property) res;
     }
@@ -53,7 +48,7 @@
         return CLASSNAME;
     }
 
-    public Class<?> [] getWrappedClasses() {
+    public Class<?>[] getWrappedClasses() {
         return WRAPPED_CLASSES;
     }
 
@@ -209,9 +204,57 @@
         return property.isModified();
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object getDefaultValue(Class typeHint) {
+    public Object jsFunction_valueOf(String hint) {
+        if ("undefined".equals(hint)) {
+            
+            try {
+                switch (property.getType()) {
+                    case PropertyType.BOOLEAN:
+                        return property.getBoolean();
+                    case PropertyType.DATE:
+                        return property.getDate();
+                    case PropertyType.DOUBLE:
+                        return property.getDouble();
+                    case PropertyType.LONG:
+                        return property.getLong();
+                    default:
+                        return toString();
+                }
+            } catch (RepositoryException re) {
+                // don't care, just return the string value
+                return toString();
+            }
+            
+        } else if ("object".equals(hint)) {
+            // return this as a Scriptable :-)
+            return this;
+            
+        } else if ("function".equals(hint)) {
+            // cannot return this as a Function
+            return Undefined.instance;
+            
+        } else if ("boolean".equals(hint)) {
+            // boolean value
+            try {
+                property.getBoolean();
+            } catch (RepositoryException re) {
+                return false;
+            }
+            
+        } else if ("number".equals(hint)) {
+            // numeric value
+            try {
+                property.getDouble();
+            } catch (RepositoryException re) {
+                return 0.0;
+            }
+        }
+
+        // unknown hint or "string"
+        return toString();
+    }
+
+    public Object jsFunction_toString() {
         return toString();
     }
 
@@ -224,7 +267,7 @@
         }
     }
 
-    //---------- Wrapper interface --------------------------------------------
+    // ---------- Wrapper interface --------------------------------------------
 
     public Object unwrap() {
         return property;

Modified: incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/ScriptEngineHelper.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/ScriptEngineHelper.java?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/ScriptEngineHelper.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/ScriptEngineHelper.java Tue Mar 25 04:30:05 2008
@@ -32,6 +32,8 @@
 import javax.script.SimpleScriptContext;
 
 import org.apache.sling.scripting.javascript.RhinoJavaScriptEngineFactory;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Wrapper;
 
 /** Helpers to run javascript code fragments in tests */
 public class ScriptEngineHelper {
@@ -81,7 +83,17 @@
         ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
         ctx.setWriter(sw);
         ctx.setErrorWriter(new OutputStreamWriter(System.err));
-        return getEngine().eval(javascriptCode, ctx);
+        Object result = getEngine().eval(javascriptCode, ctx);
+        
+        if (result instanceof Wrapper) {
+            result = ((Wrapper) result).unwrap();
+        }
+        
+        if (result instanceof ScriptableObject) {
+            result = ((ScriptableObject) result).getDefaultValue(null);
+        }
+
+        return result;
     }
 
 }

Modified: incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/wrapper/ScriptableNodeTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/wrapper/ScriptableNodeTest.java?rev=640774&r1=640773&r2=640774&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/wrapper/ScriptableNodeTest.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/test/java/org/apache/sling/scripting/wrapper/ScriptableNodeTest.java Tue Mar 25 04:30:05 2008
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.scripting.wrapper;
 
+import java.util.Calendar;
+
 import javax.jcr.Node;
 import javax.jcr.Property;
 
@@ -33,6 +35,10 @@
     private Node node;
     private Property textProperty;
     private String testText;
+    private Property numProperty;
+    private double testNum;
+    private Property calProperty;
+    private Calendar testCal;
     private ScriptEngineHelper.Data data;
     
     @Override
@@ -44,10 +50,20 @@
         node.setProperty("text", testText);
         node.setProperty("otherProperty", node.getPath());
         
+        testNum = System.currentTimeMillis();
+        node.setProperty("num", testNum);
+        
+        testCal = Calendar.getInstance();
+        node.setProperty("cal", testCal);
+        
         data = new ScriptEngineHelper.Data();
         data.put("node", node);
         textProperty = node.getProperty("text");
         data.put("property", textProperty);
+        numProperty = node.getProperty("num");
+        data.put("numProperty", numProperty);
+        calProperty = node.getProperty("cal");
+        data.put("calProperty", calProperty);
     }
 
     public void testDefaultValue() throws Exception {
@@ -79,23 +95,57 @@
 
     public void testViaPropertyNoWrappers() throws Exception {
         assertEquals(
-                testText,
-                script.evalToString("out.print(property.value.string)", data)
+            testText,
+            script.evalToString("out.print(property.value.string)", data)
         );
     }
     
     public void testViaPropertyWithWrappers() throws Exception {
-        // TODO why does that not return the property value??
         assertEquals(
-                textProperty.getPath(),
-                script.evalToString("out.print(property)", data)
+            textProperty.getString(),
+            script.evalToString("out.print(property)", data)
         );
     }
     
     public void testViaNodeDirectPropertyAccess() throws Exception {
         assertEquals(
-                testText,
-                script.evalToString("out.print(node.text)", data)
+            testText,
+            script.evalToString("out.print(node.text)", data)
+        );
+    }
+    
+    public void testViaPropertyNoWrappersNum() throws Exception {
+        assertEquals(
+            testNum,
+            script.eval("numProperty.value.getDouble()", data)
+        );
+    }
+    
+    public void testViaPropertyWithWrappersNum() throws Exception {
+        assertEquals(
+            testNum,
+            script.eval("0+numProperty", data)
+        );
+    }
+    
+    public void testViaNodeDirectPropertyAccessNum() throws Exception {
+        assertEquals(
+            testNum,
+            script.eval("node.num", data)
+        );
+    }
+    
+    public void testViaPropertyNoWrappersCal() throws Exception {
+        assertEquals(
+                testCal,
+                script.eval("calProperty.value.getDate()", data)
+        );
+    }
+    
+    public void testViaNodeDirectPropertyAccessCal() throws Exception {
+        assertEquals(
+                testCal,
+                script.eval("node.cal", data)
         );
     }