[java-idp-plugin-scripting] 12/15: Add Rhino plugin Implementation.

Ian Young ian at iay.org.uk
Mon Jun 22 13:03:48 UTC 2020


This is an automated email from the git hooks/post-receive script.

iay pushed a commit to branch master
in repository java-idp-plugin-scripting.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-scripting.git;a=commit;h=c49ac411a5a7db937465b546618bf1ed221d0332

commit c49ac411a5a7db937465b546618bf1ed221d0332
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sun Jun 7 14:54:07 2020 +0100

    Add Rhino plugin Implementation.
---
 pom.xml                                            |   1 +
 rhino-impl/pom.xml                                 |  58 +++++++++++
 .../plugins/scripting/rhino/RhinoDescription.java  |  73 ++++++++++++++
 .../plugins/scripting/rhino/RhinoEngine.java       | 112 +++++++++++++++++++++
 .../plugins/scripting/rhino/RhinoFactory.java      |  50 +++++++++
 .../plugins/scripting/rhino/package-info.java      |  20 ++++
 .../0.0.1/version.details.properties               |   3 +
 .../versions.properties                            |   1 +
 .../services/javax.script.ScriptEngineFactory      |   1 +
 ...utilities.java.support.plugin.PluginDescription |   1 +
 .../plugins/scripting/rhino/EngineTests.java       |  75 ++++++++++++++
 .../plugins/scripting/rhino/PluginTest.java        |  57 +++++++++++
 12 files changed, 452 insertions(+)

diff --git a/pom.xml b/pom.xml
index dba1047..4382185 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
         <module>scripting-api</module>
         <module>nashorn-impl</module>
         <module>nashorn-dist</module>
+        <module>rhino-impl</module>
     </modules>
 
 </project>
diff --git a/rhino-impl/pom.xml b/rhino-impl/pom.xml
new file mode 100644
index 0000000..72e9517
--- /dev/null
+++ b/rhino-impl/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>net.shibboleth.plugin.scripting</groupId>
+        <artifactId>scripting</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    
+    <artifactId>rhino-impl</artifactId>
+    <packaging>jar</packaging>
+    
+    <properties>
+        <automatic.module.name>net.shibboleth.plugins.scripting.rhino</automatic.module.name>
+    </properties>
+    
+
+    <name>Shibboleth Project Rhino Plugin</name>
+    <description>
+        A project to build a Nashorn plugin jar.
+    </description>
+
+    <dependencies>
+	<dependency>
+            <groupId>net.shibboleth.plugin.scripting</groupId>
+            <artifactId>scripting-api</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mozilla</groupId>
+            <artifactId>rhino</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId> 
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Automatic-Module-Name>${automatic.module.name}</Automatic-Module-Name>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoDescription.java b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoDescription.java
new file mode 100644
index 0000000..b62d0ea
--- /dev/null
+++ b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoDescription.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.plugins.scripting.rhino;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.core.io.ClassPathResource;
+
+import net.shibboleth.ext.spring.resource.ResourceHelper;
+import net.shibboleth.utilities.java.support.collection.Pair;
+import net.shibboleth.utilities.java.support.plugin.PluginDescription;
+import net.shibboleth.utilities.java.support.resource.Resource;
+
+/**
+ * Details about the nashorn scripting plugin
+ *
+ */
+public class RhinoDescription extends PluginDescription {
+
+    @Override
+    public String getPluginId() {
+        return "net.shibboleth.plugins.scripting.rhino";
+    }
+
+    @Override
+    public List<Resource> getUpdateResources() {
+        return List.of(ResourceHelper.of(new ClassPathResource("META-INF/plugins/")));
+    }
+
+    @Override
+    public List<Pair<Resource, Path>> getExternalFilePathsToCopy() throws IOException {
+    	return Collections.emptyList();
+    }
+        
+    @Override
+    public List<Path> getFilePathsToCopy() {
+        return List.of(Path.of("conf", "testfile.xml"));
+    }
+
+    @Override
+    public int getMajorVersion() {
+        return 0;
+    }
+
+    @Override
+    public int getMinorVersion() {
+        return 0;
+    }
+
+    @Override
+    public int getPatchVersion() {
+        return 1;
+    }
+
+}
diff --git a/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoEngine.java b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoEngine.java
new file mode 100644
index 0000000..efcc00a
--- /dev/null
+++ b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoEngine.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.plugins.scripting.rhino;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ImporterTopLevel;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+import net.shibboleth.plugins.scripting.AbstractScriptEngine;
+
+/**
+ * A subset of {@link ScriptEngine} implemented using Mozilla rhino with enough function 
+ * that EvaluableScript can work with it. 
+ * 
+ * NOTE that this does not (currently) implement {@link javax.script.Compilable}.
+ */
+public class RhinoEngine extends AbstractScriptEngine implements ScriptEngine, Compilable {
+
+    /** {@inheritDoc} */
+    public Object eval(final String script, final Bindings bindings) throws ScriptException {
+        final Context ctx = Context.enter();
+        try {
+            final Scriptable scope = new ImporterTopLevel(ctx);
+            
+            for (final String name: bindings.keySet()) {
+                final Object jsObj = Context.javaToJS(bindings.get(name), scope);
+                ScriptableObject.putProperty(scope, name, jsObj);
+            }
+            final Object o = ctx.evaluateString(scope, script, "rhino source", 1, null);
+            return Context.jsToJava(o, Object.class);
+            
+        } catch (final RuntimeException e) {
+            throw new ScriptException(e);
+        } finally {
+            Context.exit();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public CompiledScript compile(final String script) throws ScriptException {
+        return new CompiledScriptImpl(script);
+    }
+    
+    /** Rhino {@link CompiledScript}. */
+    private class CompiledScriptImpl extends CompiledScript {
+
+        /** The compiled script. */
+        private final Script script;
+        
+        /** Constructor.
+         *
+         * @param source what to compile up.
+         */
+        public CompiledScriptImpl(final String source) {
+            final Context ctx = Context.enter();
+            try {
+                script = ctx.compileString(source, "Script", 1, null);  
+            } finally {
+                Context.exit();
+            }
+        }
+
+        /** {@inheritDoc} */
+        public Object eval(final ScriptContext context) throws ScriptException {
+            final Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
+            final Context ctx = Context.enter();
+            try {
+                final Scriptable scope = new ImporterTopLevel(ctx);
+                
+                for (final String name: bindings.keySet()) {
+                    final Object jsObj = Context.javaToJS(bindings.get(name), scope);
+                    ScriptableObject.putProperty(scope, name, jsObj);
+                }
+                final Object o = script.exec(ctx, scope);
+                return Context.jsToJava(o, Object.class);
+            } 
+            finally {
+                Context.exit();
+            }
+
+        }
+
+        /** {@inheritDoc} */
+        public ScriptEngine getEngine() {
+            return RhinoEngine.this;
+        }
+    }
+}
diff --git a/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoFactory.java b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoFactory.java
new file mode 100644
index 0000000..d131a69
--- /dev/null
+++ b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/RhinoFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.plugins.scripting.rhino;
+
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+import net.shibboleth.plugins.scripting.AbstractScriptEngineFactory;
+
+/**
+ * A JSR-223 factory for {@link RhinoEngine}.
+ */
+public class RhinoFactory extends AbstractScriptEngineFactory implements ScriptEngineFactory {
+    
+    /** {@inheritDoc} */
+    public String getEngineVersion() {
+        return "1";
+    }
+
+    /** {@inheritDoc} */
+    public List<String> getNames() {
+        return List.of("shibboleth-rhino", "shibboleth-Rhino", 
+                "shibboleth-js", "shibboleth-JS", "shibboleth-JavaScript", "shibboleth-javascript", 
+                "shibboleth-ECMAScript", "shibboleth-ecmascript");
+    }
+
+    /** {@inheritDoc} */
+    public ScriptEngine getScriptEngine() {
+       
+        return new RhinoEngine();
+    }
+
+}
diff --git a/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/package-info.java b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/package-info.java
new file mode 100644
index 0000000..1057c48
--- /dev/null
+++ b/rhino-impl/src/main/java/net/shibboleth/plugins/scripting/rhino/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+/** Classes for working with JSR-223 scripting environments. */
+
+package net.shibboleth.plugins.scripting.rhino;
\ No newline at end of file
diff --git a/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/0.0.1/version.details.properties b/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/0.0.1/version.details.properties
new file mode 100644
index 0000000..ccce079
--- /dev/null
+++ b/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/0.0.1/version.details.properties
@@ -0,0 +1,3 @@
+idp.version.max=5.0.0
+idp.version.min=4.1.0
+support.level = 2
diff --git a/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/versions.properties b/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/versions.properties
new file mode 100644
index 0000000..64ee821
--- /dev/null
+++ b/rhino-impl/src/main/resources/META-INF/plugins/net.shibboleth.plugins.scripting.rhino/versions.properties
@@ -0,0 +1 @@
+net.shibboleth.plugins.scripting.rhino.versions=0.0.1
\ No newline at end of file
diff --git a/rhino-impl/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/rhino-impl/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 0000000..d2b426c
--- /dev/null
+++ b/rhino-impl/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1 @@
+net.shibboleth.plugins.scripting.rhino.RhinoFactory
diff --git a/rhino-impl/src/main/resources/META-INF/services/net.shibboleth.utilities.java.support.plugin.PluginDescription b/rhino-impl/src/main/resources/META-INF/services/net.shibboleth.utilities.java.support.plugin.PluginDescription
new file mode 100644
index 0000000..7127ada
--- /dev/null
+++ b/rhino-impl/src/main/resources/META-INF/services/net.shibboleth.utilities.java.support.plugin.PluginDescription
@@ -0,0 +1 @@
+net.shibboleth.plugins.scripting.rhino.RhinoDescription
diff --git a/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/EngineTests.java b/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/EngineTests.java
new file mode 100644
index 0000000..87785a2
--- /dev/null
+++ b/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/EngineTests.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.plugins.scripting.rhino;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.testng.annotations.Test;
+
+/** Minimal tests for our two JSR-223 engine plug ins. */
+ at SuppressWarnings({"javadoc", "rawtypes", })
+public class EngineTests {
+    
+    @Test public void testRhino() throws ScriptException {
+        final ScriptEngineManager engineManager = new ScriptEngineManager();
+        final ScriptEngine scriptEngine = engineManager.getEngineByName("shibboleth-rhino");
+        final ScriptContext ctx = new SimpleScriptContext();
+        final String script = "var s = new java.util.HashMap(2); s.put('a',b); s";
+
+        ctx.setAttribute("b", this, ScriptContext.ENGINE_SCOPE);
+        
+        final Object o = scriptEngine.eval(script, ctx);
+        
+        assertTrue(o instanceof Map);
+        final Map map = (Map) o;
+        assertEquals(map.size(), 1);
+        assertEquals(map.get("a"), this);
+    }
+
+    @Test public void testRhinoCompiled() throws ScriptException {
+        final ScriptEngineManager engineManager = new ScriptEngineManager();
+        final ScriptEngine scriptEngine = engineManager.getEngineByName("shibboleth-rhino");
+        final Compilable compiler = (Compilable) scriptEngine;
+
+        
+        final ScriptContext ctx = new SimpleScriptContext();
+        final String script = "var s = new java.util.HashMap(2); s.put('a',b); s";
+
+        ctx.setAttribute("b", this, ScriptContext.ENGINE_SCOPE);
+        
+        final CompiledScript compiled = compiler.compile(script);
+        final Object o = compiled.eval(ctx);
+        
+        assertTrue(o instanceof Map);
+        final Map map = (Map) o;
+        assertEquals(map.size(), 1);
+        assertEquals(map.get("a"), this);
+    }
+
+}
diff --git a/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/PluginTest.java b/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/PluginTest.java
new file mode 100644
index 0000000..17fbfa6
--- /dev/null
+++ b/rhino-impl/src/test/java/net/shibboleth/plugins/scripting/rhino/PluginTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.plugins.scripting.rhino;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.util.ServiceLoader;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.installer.plugin.impl.PluginState;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.plugin.PluginDescription;
+
+/**  basic sanity tests */
+ at SuppressWarnings("javadoc")
+public class PluginTest {
+
+	private PluginDescription rhino;
+
+	@BeforeClass
+	public void SetupPlugin() {
+		final ServiceLoader<PluginDescription> loader = ServiceLoader.load(PluginDescription.class);
+		for (final PluginDescription service:loader) {
+			if ("net.shibboleth.plugins.scripting.rhino".contentEquals(service.getPluginId())) {
+				rhino = service;
+				break;
+			}
+		}
+		assertNotNull(rhino);
+	}
+
+	@Test
+	public void testState() throws ComponentInitializationException {
+		
+		final PluginState state = new PluginState(rhino); 
+		state.initialize();
+
+	}
+	
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list