modules/enterprise/scripting/python/pom.xml
| 187 ++++++++++
modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineInitializer.java
| 101 +++++
modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineProvider.java
| 49 ++
modules/enterprise/scripting/python/src/main/resources/META-INF/services/org.rhq.scripting.ScriptEngineProvider
| 1
4 files changed, 338 insertions(+)
New commits:
commit 6bd2fa80f4871209de16e6560b374a24cd308666
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 30 20:13:46 2012 +0200
Experimental and unfinished support for python in the CLI.
There's no support for custom script sources and code completion.
diff --git a/modules/enterprise/scripting/python/pom.xml
b/modules/enterprise/scripting/python/pom.xml
new file mode 100644
index 0000000..4b48e52
--- /dev/null
+++ b/modules/enterprise/scripting/python/pom.xml
@@ -0,0 +1,187 @@
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-scripting-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.5.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>rhq-scripting-python</artifactId>
+ <version>4.5.0-SNAPSHOT</version>
+ <name>RHQ Python support</name>
+ <description>Provides RHQ scripting in Python using Jython</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-scripting-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.python</groupId>
+ <artifactId>jython-standalone</artifactId>
+ <version>2.5.2</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+
<rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+
<rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/lib</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${rhq.deploymentDir}"
/>
+ <property name="deployment.file"
location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating
+ ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}"
basedir="${project.build.outputDirectory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting
+ ${deployment.file}...</echo>
+ <delete file="${deployment.file}"
/>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>cobertura-plugins</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9.4.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>cobertura-instrument</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <tasks>
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/cobertura/backup"
/>
+ <!-- backup all classes so that we
+ can instrument the original classes -->
+ <copy
toDir="target/cobertura/backup" verbose="true"
overwrite="true">
+ <fileset
dir="target/classes">
+ <include name="**/*.class"
/>
+ </fileset>
+ </copy>
+ <!-- create a properties file and
+ save there location of cobertura data file
-->
+ <touch
file="target/classes/cobertura.properties" />
+ <echo
file="target/classes/cobertura.properties">net.sourceforge.cobertura.datafile=${project.build.directory}/cobertura/cobertura.ser</echo>
+ <taskdef
classpathref="maven.plugin.classpath" resource="tasks.properties"
/>
+ <!-- instrument all classes in target/classes
+ directory -->
+ <cobertura-instrument
datafile="${project.build.directory}/cobertura/cobertura.ser"
todir="${project.build.directory}/classes">
+ <fileset
dir="${project.build.directory}/classes">
+ <include name="**/*.class"
/>
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>cobertura-report</id>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <tasks>
+ <taskdef
classpathref="maven.plugin.classpath" resource="tasks.properties"
/>
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/site/cobertura"
/>
+ <!-- restore classes from backup
+ folder to classes folder -->
+ <copy toDir="target/classes"
verbose="true" overwrite="true">
+ <fileset
dir="target/cobertura/backup">
+ <include name="**/*.class"
/>
+ </fileset>
+ </copy>
+ <!-- delete backup folder -->
+ <delete
dir="target/cobertura/backup" />
+ <!-- create a code coverage report -->
+ <cobertura-report format="html"
datafile="${project.build.directory}/cobertura/cobertura.ser"
destdir="${project.build.directory}/site/cobertura">
+ <fileset
dir="${basedir}/src/main/java">
+ <include name="**/*.java"
/>
+ </fileset>
+ </cobertura-report>
+ <!-- delete cobertura.properties
+ file -->
+ <delete
file="target/classes/cobertura.properties" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git
a/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineInitializer.java
b/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineInitializer.java
new file mode 100644
index 0000000..9ee50b8
--- /dev/null
+++
b/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineInitializer.java
@@ -0,0 +1,101 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.scripting.python;
+
+import java.lang.reflect.Method;
+import java.security.PermissionCollection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.rhq.scripting.ScriptEngineInitializer;
+import org.rhq.scripting.ScriptSourceProvider;
+import org.rhq.scripting.util.SandboxedScriptEngine;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class PythonScriptEngineInitializer implements ScriptEngineInitializer {
+
+ private ScriptEngineManager engineManager = new ScriptEngineManager();
+
+ @Override
+ public ScriptEngine instantiate(Set<String> packages, ScriptSourceProvider
scriptSourceProvider,
+ PermissionCollection permissions) throws ScriptException {
+
+ ScriptEngine eng = engineManager.getEngineByName("python");
+
+ for (String pkg : packages) {
+ eng.eval("from " + pkg + " import *\n");
+ }
+
+ //TODO add support for script source providers... possibly using
http://www.python.org/dev/peps/pep-0302/
+
+ //fingers crossed we can secure jython like this
+ return new SandboxedScriptEngine(eng, permissions);
+ }
+
+ @Override
+ public Set<String> generateIndirectionMethods(String boundObjectName,
Set<Method> overloadedMethods) {
+ if (overloadedMethods == null || overloadedMethods.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ Set<Integer> argCnts = new HashSet<Integer>();
+ for(Method m : overloadedMethods) {
+ argCnts.add(m.getParameterTypes().length);
+ }
+
+ String methodName = overloadedMethods.iterator().next().getName();
+ StringBuilder functionBody = new StringBuilder();
+
+ functionBody.append("def ").append(methodName).append("(*args,
**kwargs):\n");
+ functionBody.append("\t").append("if len(kwargs) >
0:\n");
+ functionBody.append("\t\t").append("raise ValueError(\"Named
arguments not supported for Java methods\")\n");
+ functionBody.append("\t").append("argCnt = len(args)\n");
+
+ for(Integer argCnt : argCnts) {
+ functionBody.append("\t").append("if argCnt ==
").append(argCnt).append(":\n");
+ functionBody.append("\t\treturn
").append(boundObjectName).append(".").append(methodName).append("(");
+ int last = argCnt - 1;
+ for(int i = 0; i < argCnt; ++i) {
+ functionBody.append("args[").append(i).append("]");
+ if (i < last) {
+ functionBody.append(", ");
+ }
+ }
+ functionBody.append(")\n");
+ }
+
+ return Collections.singleton(functionBody.toString());
+ }
+
+ @Override
+ public String extractUserFriendlyErrorMessage(ScriptException e) {
+ return e.getMessage();
+ }
+
+}
diff --git
a/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineProvider.java
b/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineProvider.java
new file mode 100644
index 0000000..c0bfcac
--- /dev/null
+++
b/modules/enterprise/scripting/python/src/main/java/org/rhq/scripting/python/PythonScriptEngineProvider.java
@@ -0,0 +1,49 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.scripting.python;
+
+import org.rhq.scripting.CodeCompletion;
+import org.rhq.scripting.ScriptEngineInitializer;
+import org.rhq.scripting.ScriptEngineProvider;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class PythonScriptEngineProvider implements ScriptEngineProvider {
+
+ @Override
+ public String getSupportedLanguage() {
+ return "python";
+ }
+
+ @Override
+ public ScriptEngineInitializer getInitializer() {
+ return new PythonScriptEngineInitializer();
+ }
+
+ @Override
+ public CodeCompletion getCodeCompletion() {
+ // XXX are we gonna support code completion for multiple langs in the CLI?
+ return null;
+ }
+
+}
diff --git
a/modules/enterprise/scripting/python/src/main/resources/META-INF/services/org.rhq.scripting.ScriptEngineProvider
b/modules/enterprise/scripting/python/src/main/resources/META-INF/services/org.rhq.scripting.ScriptEngineProvider
new file mode 100644
index 0000000..3882776
--- /dev/null
+++
b/modules/enterprise/scripting/python/src/main/resources/META-INF/services/org.rhq.scripting.ScriptEngineProvider
@@ -0,0 +1 @@
+org.rhq.scripting.python.PythonScriptEngineProvider