Skip to content

Commit

Permalink
[java223] Initial contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
dalgwen committed Oct 26, 2024
1 parent ab385ed commit 4f6b6a3
Show file tree
Hide file tree
Showing 112 changed files with 7,822 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
<artifactId>org.openhab.automation.groovyscripting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.java223</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jrubyscripting</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.automation.java223/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
567 changes: 567 additions & 0 deletions bundles/org.openhab.automation.java223/README.md

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions bundles/org.openhab.automation.java223/bnd.bnd
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Bundle-SymbolicName: ${project.artifactId}
DynamicImport-Package: *
Import-Package: \
javax.measure,\
javax.measure.quantity,\
org.openhab.core.audio,\
org.openhab.core.automation,\
org.openhab.core.automation.util,\
org.openhab.core.automation.module.script,\
org.openhab.core.automation.module.script.defaultscope,\
org.openhab.core.automation.module.script.rulesupport.shared,\
org.openhab.core.automation.module.script.rulesupport.shared.simple,\
org.openhab.core.common,\
org.openhab.core.common.registry,\
org.openhab.core.config.core,\
org.openhab.core.items,\
org.openhab.core.library.types,\
org.openhab.core.library.items,\
org.openhab.core.library.dimension,\
org.openhab.core.model.script,\
org.openhab.core.model.script.actions,\
org.openhab.core.model.rule,\
org.openhab.core.persistence,\
org.openhab.core.persistence.extensions,\
org.openhab.core.thing.binding,\
org.openhab.core.transform,\
org.openhab.core.transform.actions,\
org.openhab.core.types,\
org.openhab.core.voice,\
com.google.gson
118 changes: 118 additions & 0 deletions bundles/org.openhab.automation.java223/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>4.2.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.automation.java223</artifactId>

<name>openHAB Add-ons :: Bundles :: Automation :: Java Scripting</name>


<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
<scope>compile</scope>
</dependency>
<!-- jdt annotation classes are included because we want to be able to
export them to the dependencies jar -->
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.annotation</artifactId>
<version>2.2.600</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>

</dependencies>

<build>
<resources>
<resource>
<directory>src/helper/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</resource>
<resource>
<directory>src/main/resources/</directory>
</resource>
</resources>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution> <!-- Create the helper library and put it in the target class directory to be embedded inside the jar -->
<id>create-helper-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>helper</finalName>
<classifier>lib</classifier>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<includes>
<include>helper/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<excludes>
<exclude>helper/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>add-source</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<sources>
<source>src/3rdparty/java</source>
<source>src/3rdparty/resources</source>
<source>src/helper/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<sourceDirectories>${project.build.sourceDirectory}</sourceDirectories>
</configuration>
</plugin> -->
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ch.obermuhlner.scriptengine.java;

/**
* The isolation levels of the script at execution time.
*/
public enum Isolation {
/**
* The caller {@link ClassLoader} is visible to the script during execution.
*
* This allows to see all classes from the script that are visible in the calling application.
*/
CallerClassLoader,

/**
* The script executes in an isolated {@link ClassLoader}.
*
* This hides all classes of the calling application.
*/
IsolatedClassLoader
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package ch.obermuhlner.scriptengine.java;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

import ch.obermuhlner.scriptengine.java.bindings.BindingStrategy;
import ch.obermuhlner.scriptengine.java.execution.ExecutionStrategy;

/**
* The compiled Java script created by a {@link JavaScriptEngine}.
*/
public class JavaCompiledScript extends CompiledScript {
private final JavaScriptEngine engine;
private final Class<?> compiledClass;
private final Object compiledInstance;
private ExecutionStrategy executionStrategy;
private BindingStrategy bindingStrategy;

/**
* Construct a {@link JavaCompiledScript}.
*
* @param engine the {@link JavaScriptEngine} that compiled this script
* @param compiledClass the compiled {@link Class}
* @param compiledInstance the instance of the compiled {@link Class} or {@code null}
* if no instance was created and only static methods will be called
* by the the {@link ExecutionStrategy}.
* @param executionStrategy the {@link ExecutionStrategy}
*/
public JavaCompiledScript(JavaScriptEngine engine, Class<?> compiledClass, Object compiledInstance,
ExecutionStrategy executionStrategy, BindingStrategy bindingStrategy) {
this.engine = engine;
this.compiledClass = compiledClass;
this.compiledInstance = compiledInstance;
this.executionStrategy = executionStrategy;
this.bindingStrategy = bindingStrategy;
}

/**
* Returns the compiled {@link Class}.
*
* @return the compiled {@link Class}.
*/
public Class<?> getCompiledClass() {
return compiledClass;
}

/**
* Returns the instance of the compiled {@link Class}.
*
* @return the instance of the compiled {@link Class} or {@code null}
* if no instance was created and only static methods will be called
* by the the {@link ExecutionStrategy}.
*/
public Object getCompiledInstance() {
return compiledInstance;
}

/**
* Returns the compiled {@link Class}.
*
* @return the compiled {@link Class}.
* @deprecated in release 1.1.0 this method was deprecated,
* use {@link #getCompiledClass()} instead.
*/
@Deprecated
public Class<?> getInstanceClass() {
return getCompiledClass();
}

/**
* Returns the instance of the compiled {@link Class}.
*
* @return the instance of the compiled {@link Class} or {@code null}
* if no instance was created and only static methods will be called
* by the the {@link ExecutionStrategy}.
* @deprecated in release 1.1.0 this method was deprecated,
* use {@link #getCompiledInstance()} instead.
*/
@Deprecated
public Object getInstance() {
return getCompiledInstance();
}

/**
* Sets the {@link ExecutionStrategy} to be used when evaluating the compiled class instance.
*
* @param executionStrategy the {@link ExecutionStrategy}
*/
public void setExecutionStrategy(ExecutionStrategy executionStrategy) {
this.executionStrategy = executionStrategy;
}

@Override
public ScriptEngine getEngine() {
return engine;
}

@Override
public Object eval(ScriptContext context) throws ScriptException {
Bindings globalBindings = context.getBindings(ScriptContext.GLOBAL_SCOPE);
Bindings engineBindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

pushVariables(globalBindings, engineBindings);
Object result = executionStrategy.execute(compiledInstance);
pullVariables(globalBindings, engineBindings);

return result;
}

private void pushVariables(Bindings globalBindings, Bindings engineBindings) throws ScriptException {
Map<String, Object> mergedBindings = mergeBindings(globalBindings, engineBindings);

if (bindingStrategy != null) {
bindingStrategy.associateBindings(compiledClass, compiledInstance, mergedBindings);
return;
}

for (Map.Entry<String, Object> entry : mergedBindings.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();

try {
Field field = compiledClass.getField(name);
field.set(compiledInstance, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new ScriptException(e);
}
}
}

private void pullVariables(Bindings globalBindings, Bindings engineBindings) throws ScriptException {

if (bindingStrategy != null) {
Map<String, Object> retrievedBindings = bindingStrategy.retrieveBindings(compiledClass, compiledInstance);

for (Map.Entry<String, Object> entry : retrievedBindings.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();

setBindingsValue(globalBindings, engineBindings, name, value);
}

return;
}

for (Field field : compiledClass.getFields()) {
try {
String name = field.getName();
Object value = field.get(compiledInstance);
setBindingsValue(globalBindings, engineBindings, name, value);
} catch (IllegalAccessException e) {
throw new ScriptException(e);
}
}
}

private void setBindingsValue(Bindings globalBindings, Bindings engineBindings, String name, Object value) {
if (!engineBindings.containsKey(name) && globalBindings.containsKey(name)) {
globalBindings.put(name, value);
} else {
engineBindings.put(name, value);
}
}

private Map<String, Object> mergeBindings(Bindings... bindingsToMerge) {
Map<String, Object> variables = new HashMap<>();

for (Bindings bindings : bindingsToMerge) {
if (bindings != null) {
for (Map.Entry<String, Object> globalEntry : bindings.entrySet()) {
variables.put(globalEntry.getKey(), globalEntry.getValue());
}
}
}

return variables;
}
}
Loading

0 comments on commit 4f6b6a3

Please sign in to comment.