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@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
rhq-commits@lists.fedorahosted.org