You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by eo...@apache.org on 2019/03/07 15:27:59 UTC

[maven-scripting-plugin] 11/11: MSCRIPTNG-1 Allow scripting in files

This is an automated email from the ASF dual-hosted git repository.

eolivelli pushed a commit to branch MSCRIPTING-1
in repository https://gitbox.apache.org/repos/asf/maven-scripting-plugin.git

commit b20e1c3dc647ddc3e522f286cc6252321509dd96
Author: Rusi Popov <po...@mdatools.net>
AuthorDate: Sat Jan 26 12:49:10 2019 +0200

    MSCRIPTNG-1 Allow scripting in files
---
 pom.xml                                            |  10 +-
 .../pom.xml                                        |  14 ++-
 src/it/groovy-script-file-name/test.groov          |  21 ++++
 .../{groovy-script => groovy-script-file}/pom.xml  |  16 ++-
 src/it/groovy-script-file/test.groovy              |  21 ++++
 src/it/groovy-script/pom.xml                       |   8 ++
 .../apache/maven/plugins/scripting/EvalMojo.java   | 117 ++++++++++---------
 .../apache/maven/plugins/scripting/Execute.java    |  71 ++++++++++++
 .../maven/plugins/scripting/ExecuteFile.java       | 126 +++++++++++++++++++++
 .../maven/plugins/scripting/ExecuteString.java     |  87 ++++++++++++++
 10 files changed, 419 insertions(+), 72 deletions(-)

diff --git a/pom.xml b/pom.xml
index ca3ad41..eb92171 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,8 @@ under the License.
 
   <name>Apache Maven Scripting Plugin</name>
   <description>
-    The Maven Scripting Plugin is a plugin that wrapped the Scripting API accoring to JSR223
+    The Maven Scripting Plugin is a plugin that wrapped the Scripting API according to JSR223.
+    Add the scripting engines as dependencies of this plugin on its use.
   </description>
   <inceptionYear>2016</inceptionYear>
 
@@ -94,13 +95,6 @@ under the License.
       <scope>provided</scope>
     </dependency>
 
-    <!-- ScriptEngines -->
-    <dependency>
-      <groupId>org.codehaus.groovy</groupId>
-      <artifactId>groovy-jsr223</artifactId>
-      <version>2.4.7</version>
-    </dependency>
-
     <!-- Test -->
     <dependency>
       <groupId>junit</groupId>
diff --git a/src/it/groovy-script/pom.xml b/src/it/groovy-script-file-name/pom.xml
similarity index 81%
copy from src/it/groovy-script/pom.xml
copy to src/it/groovy-script-file-name/pom.xml
index 5098a79..a5fdfca 100644
--- a/src/it/groovy-script/pom.xml
+++ b/src/it/groovy-script-file-name/pom.xml
@@ -35,12 +35,16 @@ under the License.
         <version>@project.version@</version>
         <configuration>
           <engineName>groovy</engineName>
-          <script>
-          <![CDATA[
-            (1..10).sum() + ' ' + project.artifactId
-          ]]>
-          </script>
+          <scriptFile>test.groov</scriptFile>
         </configuration>
+        <dependencies>
+          <!-- ScriptEngines -->
+          <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-jsr223</artifactId>
+            <version>2.4.7</version>
+          </dependency>
+        </dependencies>
       </plugin>
     </plugins>
   </build>
diff --git a/src/it/groovy-script-file-name/test.groov b/src/it/groovy-script-file-name/test.groov
new file mode 100644
index 0000000..94d935c
--- /dev/null
+++ b/src/it/groovy-script-file-name/test.groov
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+
+(1..10).sum() + ' ' + project.artifactId
\ No newline at end of file
diff --git a/src/it/groovy-script/pom.xml b/src/it/groovy-script-file/pom.xml
similarity index 78%
copy from src/it/groovy-script/pom.xml
copy to src/it/groovy-script-file/pom.xml
index 5098a79..6093e33 100644
--- a/src/it/groovy-script/pom.xml
+++ b/src/it/groovy-script-file/pom.xml
@@ -34,13 +34,17 @@ under the License.
         <artifactId>maven-scripting-plugin</artifactId>
         <version>@project.version@</version>
         <configuration>
-          <engineName>groovy</engineName>
-          <script>
-          <![CDATA[
-            (1..10).sum() + ' ' + project.artifactId
-          ]]>
-          </script>
+          <!--engineName>groovy</engineName-->
+          <scriptFile>test.groovy</scriptFile>
         </configuration>
+        <dependencies>
+          <!-- ScriptEngines -->
+          <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-jsr223</artifactId>
+            <version>2.4.7</version>
+          </dependency>
+        </dependencies>
       </plugin>
     </plugins>
   </build>
diff --git a/src/it/groovy-script-file/test.groovy b/src/it/groovy-script-file/test.groovy
new file mode 100644
index 0000000..94d935c
--- /dev/null
+++ b/src/it/groovy-script-file/test.groovy
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+
+(1..10).sum() + ' ' + project.artifactId
\ No newline at end of file
diff --git a/src/it/groovy-script/pom.xml b/src/it/groovy-script/pom.xml
index 5098a79..0c949f7 100644
--- a/src/it/groovy-script/pom.xml
+++ b/src/it/groovy-script/pom.xml
@@ -41,6 +41,14 @@ under the License.
           ]]>
           </script>
         </configuration>
+        <dependencies>
+          <!-- ScriptEngines -->
+          <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-jsr223</artifactId>
+            <version>2.4.7</version>
+          </dependency>
+        </dependencies>
       </plugin>
     </plugins>
   </build>
diff --git a/src/main/java/org/apache/maven/plugins/scripting/EvalMojo.java b/src/main/java/org/apache/maven/plugins/scripting/EvalMojo.java
index f4c349a..6dfc038 100644
--- a/src/main/java/org/apache/maven/plugins/scripting/EvalMojo.java
+++ b/src/main/java/org/apache/maven/plugins/scripting/EvalMojo.java
@@ -19,10 +19,10 @@ package org.apache.maven.plugins.scripting;
  * under the License.
  */
 
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
+import java.io.File;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
 
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -33,7 +33,7 @@ import org.apache.maven.project.MavenProject;
 
 /**
  * Evaluate the specified script
- * 
+ *
  * @author Robert Scholte
  * @since 3.0.0
  */
@@ -41,8 +41,8 @@ import org.apache.maven.project.MavenProject;
 public class EvalMojo
     extends AbstractMojo
 {
-    @Parameter( required = true )
-    private String engineName; // or map extension to engineName??
+    @Parameter
+    private String engineName;
 
     /**
      * When used, also specify the engineName
@@ -50,60 +50,71 @@ public class EvalMojo
     @Parameter
     private String script;
 
+    /**
+     * Provide the script as an external file as an alternative to &lt;script&gt;.
+     * When scriptFile provided the script is ignored.
+     * The file name extension identifies the script language to use, as of javax.script.ScriptEngineManager
+     * and {@linkplain "https://jcp.org/aboutJava/communityprocess/final/jsr223/index.html"}
+     */
+    @Parameter
+    private File scriptFile;
+
     // script variables
     @Parameter( defaultValue = "${project}", readonly = true )
     private MavenProject project;
-    
-    private ScriptEngineManager manager = new ScriptEngineManager();
 
     @Override
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
-        ScriptEngine engine = null;
-        
-        if ( script != null )
-        {
-            engine = getScriptEngine( engineName );
-
-            if ( engine == null )
-            {
-                throw new MojoFailureException( "Missing scriptEngine" );
-            }
-        }
-        else
-        {
-            // from file
-        }
-
-        try
-        {
-            ScriptContext context = engine.getContext();
-            context.setAttribute( "project", project, ScriptContext.GLOBAL_SCOPE );
-            
-            Object result = engine.eval( script );
-            
-            getLog().info( "Result:" );
-            if ( result != null )
-            {
-                getLog().info( result.toString() );
-            }
-        }
-        catch ( ScriptException e )
-        {
-            throw new MojoExecutionException( e.getMessage(), e );
-        }
+       Execute execute;
+       Object result;
+       Bindings bindings;
+
+       try
+       {
+         execute = constructExecute();
+
+         bindings = new SimpleBindings();
+         bindings.put( "project", project );
+         bindings.put( "log", getLog() );
+
+         result = execute.run( bindings );
+
+         getLog().info( "Result:" );
+         if ( result != null )
+         {
+           getLog().info( result.toString() );
+         }
+       }
+       catch ( IllegalArgumentException e ) // configuring the plugin failed
+       {
+         throw new MojoExecutionException( e.getMessage(), e );
+       }
+       catch ( Exception e ) // execution failure
+       {
+           throw new MojoFailureException( e.getMessage(), e );
+       }
     }
-    
-    private ScriptEngine getScriptEngine( String name )
+
+    private Execute constructExecute() throws IllegalArgumentException
     {
-        if ( name == null ) 
-        {
-            return null;
-        }
-        else
-        {
-            return manager.getEngineByName( engineName );
-        }
+      Execute execute;
+
+      if ( scriptFile != null )
+      {
+         execute = new ExecuteFile( engineName, scriptFile );
+
+      }
+      else if ( script != null )
+      {
+         execute = new ExecuteString( engineName, script );
+
+      }
+      else
+      {
+         throw new IllegalArgumentException( "Missing script or scriptFile provided" );
+      }
+      return execute;
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/maven/plugins/scripting/Execute.java b/src/main/java/org/apache/maven/plugins/scripting/Execute.java
new file mode 100644
index 0000000..5563bc5
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/scripting/Execute.java
@@ -0,0 +1,71 @@
+package org.apache.maven.plugins.scripting;
+
+/*
+ * 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.
+ */
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+/**
+ * Execute a script in the appropriate context and return its possibly null result
+ * @author Rusi Popov
+ */
+abstract class Execute
+{
+
+  /**
+   * @param bindings not null bindings to provide to the script to execute
+   * @return the possibly null result the script produced
+   * @throws IllegalArgumentException when the engine is not configured correctly
+   * @throws ScriptException
+   */
+  public final Object run( Bindings bindings ) throws IllegalArgumentException, ScriptException
+  {
+    ScriptEngine engine;
+    ScriptEngineManager manager;
+    ScriptContext context;
+
+    manager = new ScriptEngineManager();
+    engine = constructEngine( manager );
+    context = engine.getContext();
+
+    context.setBindings( bindings, ScriptContext.GLOBAL_SCOPE );
+
+    return execute( engine, context );
+  }
+
+  /**
+   * Execute the script
+   * @param engine not null
+   * @param context not null, initialized
+   * @return possibly null result of the script
+   * @throws ScriptException
+   */
+  protected abstract Object execute( ScriptEngine engine, ScriptContext context ) throws ScriptException;
+
+  /**
+   * @param manager not null
+   * @return non-null engine to execute the script
+   * @throws IllegalArgumentException when no engine could be identified
+   */
+  protected abstract ScriptEngine constructEngine( ScriptEngineManager manager ) throws IllegalArgumentException;
+}
diff --git a/src/main/java/org/apache/maven/plugins/scripting/ExecuteFile.java b/src/main/java/org/apache/maven/plugins/scripting/ExecuteFile.java
new file mode 100644
index 0000000..0c9ce9c
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/scripting/ExecuteFile.java
@@ -0,0 +1,126 @@
+package org.apache.maven.plugins.scripting;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+/**
+ * Execute a script held in a file. Use the engine name to override the engine if the file name does not refer/decode
+ * to a valid engine name or not define any at all.
+ * @author Rusi Popov
+ */
+public class ExecuteFile extends Execute
+{
+
+  /**
+   * Not null, existing readable file with the script
+   */
+  private final File scriptFile;
+
+  /**
+   * Possibly null engine name
+   */
+  private final String engineName;
+
+  /**
+   * @param engineName optional engine name, used to override the engine selection from the file extension
+   * @param scriptFile not null
+   * @throws IllegalArgumentException when the combination of parameters is incorrect
+   */
+  public ExecuteFile( String engineName, File scriptFile ) throws IllegalArgumentException
+  {
+    if ( scriptFile == null
+         || !scriptFile.isFile()
+         || !scriptFile.exists()
+         || !scriptFile.canRead() )
+    {
+      throw new IllegalArgumentException( "Expected an existing readable file \"" + scriptFile + "\" provided" );
+    }
+    this.scriptFile = scriptFile;
+
+    this.engineName = engineName;
+  }
+
+  /**
+   * @param engine
+   * @param context
+   * @return
+   * @throws ScriptException
+   * @see org.apache.maven.plugins.scripting.Execute#execute(javax.script.ScriptEngine, javax.script.ScriptContext)
+   */
+  protected Object execute( ScriptEngine engine, ScriptContext context ) throws ScriptException
+  {
+    FileReader reader;
+
+    try
+    {
+      reader = new FileReader( scriptFile );
+    }
+    catch ( IOException ex )
+    {
+      throw new IllegalArgumentException( scriptFile + " caused:", ex );
+    }
+    return engine.eval( reader, context );
+  }
+
+  /**
+   * @see org.apache.maven.plugins.scripting.Execute#constructEngine(javax.script.ScriptEngineManager)
+   */
+  protected ScriptEngine constructEngine( ScriptEngineManager manager ) throws IllegalArgumentException
+  {
+    ScriptEngine result;
+    String extension;
+    int position;
+
+    if ( engineName != null && !engineName.trim().isEmpty() )
+    {
+      result = manager.getEngineByName( engineName );
+
+      if ( result == null )
+      {
+        throw new IllegalArgumentException( "No engine found by name \"" + engineName + "\n" );
+      }
+    }
+    else
+    {
+      extension = scriptFile.getName();
+      position = extension.indexOf( "." );
+
+      if ( position >= 0 )
+      {
+        extension = extension.substring( position + 1 );
+      }
+      result = manager.getEngineByExtension( extension );
+
+      if ( result == null )
+      {
+        throw new IllegalArgumentException( "No engine found by extension \"" + extension + "\n" );
+      }
+    }
+    return result;
+  }
+}
diff --git a/src/main/java/org/apache/maven/plugins/scripting/ExecuteString.java b/src/main/java/org/apache/maven/plugins/scripting/ExecuteString.java
new file mode 100644
index 0000000..b3171e5
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/scripting/ExecuteString.java
@@ -0,0 +1,87 @@
+package org.apache.maven.plugins.scripting;
+
+/*
+ * 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.
+ */
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+/**
+ * Execute a script held in a string
+ * @author Rusi Popov
+ */
+public class ExecuteString extends Execute
+{
+
+  /**
+   * Not null name of the engine to execute the script
+   */
+  private final String engineName;
+
+  /**
+   * The non-null script itself
+   */
+  private final String script;
+
+  /**
+   * @param engineName
+   * @param script
+   * @throws IllegalArgumentException
+   */
+  public ExecuteString( String engineName, String script ) throws IllegalArgumentException
+  {
+    if ( engineName == null || engineName.trim().isEmpty() )
+    {
+      throw new IllegalArgumentException( "Expected a non-empty engine name provided" );
+    }
+    this.engineName = engineName;
+
+    if ( script == null || script.trim().isEmpty() )
+    {
+      throw new IllegalArgumentException( "Expected a non-empty script provided" );
+    }
+    this.script = script;
+  }
+
+  /**
+   * @throws IllegalArgumentException
+   * @see org.apache.maven.plugins.scripting.Execute#constructEngine(javax.script.ScriptEngineManager)
+   */
+  protected ScriptEngine constructEngine( ScriptEngineManager manager ) throws IllegalArgumentException
+  {
+    ScriptEngine result;
+
+    result = manager.getEngineByName( engineName );
+    if ( result == null )
+    {
+      throw new IllegalArgumentException( "Unknown engine specified with name \"" + engineName + "\"" );
+    }
+    return result;
+  }
+
+  /**
+   * @see org.apache.maven.plugins.scripting.Execute#execute(javax.script.ScriptEngine, javax.script.ScriptContext)
+   */
+  protected Object execute( ScriptEngine engine, ScriptContext context ) throws ScriptException
+  {
+    return engine.eval( script, context );
+  }
+}
\ No newline at end of file