Skip to content

Commit

Permalink
Added ScriptModuleTypeProvider
Browse files Browse the repository at this point in the history
Added ScriptModuleTypeProvider, which dynamically adds available script
languages to the the ParameterOptions.

Signed-off-by: Scott Rushworth <openhab@5iver.com>
  • Loading branch information
Scott Rushworth committed Mar 24, 2019
1 parent 790de9c commit 2e52513
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 314 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,49 @@
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.openhab.core.automation.module.script.internal.provider.ScriptModuleTypeProvider;

/**
* This class is used by the ScriptManager to load ScriptEngines.
* This is meant as a way to allow other OSGi bundles to provide custom Script-Languages with special needs (like
* Nashorn, Groovy, etc.)
* This class is used by the ScriptEngineManager to load ScriptEngines. This is meant as a way to allow other OSGi
* bundles to provide custom script-languages with special needs, e.g. Nashorn, Jython, Groovy, etc.
*
* @author Simon Merschjohann
*
* @author Scott Rushworth - added/changed methods and parameters when implementing {@link ScriptModuleTypeProvider}
*/
public interface ScriptEngineFactory {

final static ScriptEngineManager engineManager = new ScriptEngineManager();

/**
* @return the list of supported language endings e.g. py, jy
* This method logs details about the implementations of ScriptEngineFactory.
*
*/
List<String> getLanguages();
void logFactoryDetails();

/**
* "scopes" new values into the given ScriptEngine
* This method returns a list of file extensions and MimeTypes that are supported by the ScriptEngine, e.g. py,
* application/python, js, application/javascript, etc.
*
* @param scriptEngine
* @param scopeValues
* @return List of supported script types
*/
void scopeValues(ScriptEngine scriptEngine, Map<String, Object> scopeValues);
List<String> getScriptTypes();

/**
* created a new ScriptEngine
* This method "scopes" new values into the given ScriptEngine.
*
* @param fileExtension
* @return
* @param scriptEngine
* @param scopeValues
*/
ScriptEngine createScriptEngine(String fileExtension);
void scopeValues(ScriptEngine scriptEngine, Map<String, Object> scopeValues);

/**
* checks if the script is supported. Does not necessarily be equal to getLanguages()
* This method creates a new ScriptEngine based on the supplied file extension or MimeType.
*
* @param fileExtension
* @return
* @param scriptType a file extension (script) or MimeType (ScriptAction or ScriptCondition)
* @return ScriptEngine
*/
boolean isSupported(String fileExtension);
ScriptEngine createScriptEngine(String scriptType);

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,48 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.module.script.internal.provider.ScriptModuleTypeProvider;

/**
* The ScriptEngineManager provides the ability to load and unload scripts.
*
* @author Simon Merschjohann - Initial contribution
* @author Scott Rushworth - changed parameter names when implementing {@link ScriptModuleTypeProvider}
*/
@NonNullByDefault
public interface ScriptEngineManager {

/**
* Checks if a given fileExtension is supported
* Creates a new ScriptEngine used to execute scripts, ScriptActions or ScriptConditions
*
* @param fileExtension
* @return true if supported
* @param scriptType a file extension (script) or MimeType (ScriptAction or ScriptCondition)
* @param engineIdentifier the unique identifier for the ScriptEngine (script file path or UUID)
* @return ScriptEngineContainer or null
*/
boolean isSupported(String fileExtension);
@Nullable
ScriptEngineContainer createScriptEngine(String scriptType, String engineIdentifier);

/**
* Creates a new ScriptEngine based on the given fileExtension
* Loads a script and initializes its scope variables
*
* @param fileExtension
* @param scriptIdentifier
* @return
* @param engineIdentifier the unique identifier for the ScriptEngine (script file path or UUID)
* @param scriptData the content of the script
*/
@Nullable
ScriptEngineContainer createScriptEngine(String fileExtension, String scriptIdentifier);
void loadScript(String engineIdentifier, InputStreamReader scriptData);

/**
* Loads a script and initializes its scope variables
* Unloads the ScriptEngine loaded with the engineIdentifier
*
* @param fileExtension
* @param scriptIdentifier
* @param scriptData
* @return
* @param engineIdentifier the unique identifier for the ScriptEngine (script file path or UUID)
*/
void loadScript(String scriptIdentifier, InputStreamReader scriptData);
void removeEngine(String engineIdentifier);

/**
* Unloads the ScriptEngine loaded with the scriptIdentifer
* Checks if the supplied file extension or MimeType is supported by the existing ScriptEngineFactories
*
* @param scriptIdentifier
* @param scriptType a file extension (script) or MimeType (ScriptAction or ScriptCondition)
* @return boolean
*/
void removeEngine(String scriptIdentifier);
boolean isSupported(String scriptType);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright (c) 2010-2019 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.core.automation.module.script.internal;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.script.ScriptEngine;

import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is an abstract class for implementing {@link ScriptEngineFactory}s.
*
* @author Scott Rushworth - initial contribution
*/
public abstract class AbstractScriptEngineFactory implements ScriptEngineFactory {

protected final Logger logger = LoggerFactory.getLogger(this.getClass());

@Override
public void logFactoryDetails() {
for (javax.script.ScriptEngineFactory f : engineManager.getEngineFactories()) {
logger.info("Scripting support is available for {}", f.getLanguageName());
logger.debug(
"Scripting support is available for engine {} ({}) supporting {} ({}) with file extensions {}, names {}, and mimetypes {}",
f.getEngineName(), f.getEngineVersion(), f.getLanguageName(), f.getLanguageVersion(),
f.getExtensions(), f.getNames(), f.getMimeTypes());
}
}

@Override
public List<String> getScriptTypes() {
List<String> scriptTypes = new ArrayList<>();

for (javax.script.ScriptEngineFactory f : engineManager.getEngineFactories()) {
scriptTypes.addAll(f.getExtensions());
scriptTypes.addAll(f.getMimeTypes());
}
logger.trace("getScriptTypes(): {}", scriptTypes);
return scriptTypes;
}

@Override
public void scopeValues(ScriptEngine scriptEngine, Map<String, Object> scopeValues) {
for (Entry<String, Object> entry : scopeValues.entrySet()) {
scriptEngine.put(entry.getKey(), entry.getValue());
}
}

@Override
public ScriptEngine createScriptEngine(String scriptType) {
ScriptEngine scriptEngine = engineManager.getEngineByExtension(scriptType);
if (scriptEngine == null) {
scriptEngine = engineManager.getEngineByMimeType(scriptType);
}
if (scriptEngine == null) {
scriptEngine = engineManager.getEngineByName(scriptType);
}
return scriptEngine;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,78 +12,16 @@
*/
package org.openhab.core.automation.module.script.internal;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.osgi.service.component.annotations.Component;

/**
* An implementation of {@link ScriptEngineFactory} for ScriptEngines that do not require customizations.
*
* @author Simon Merschjohann - Initial contribution
* @author Scott Rushworth - added service and removed default methods provided by ScriptEngineFactory
*/
public class GenericScriptEngineFactory implements ScriptEngineFactory {
private ScriptEngineManager engineManager = new ScriptEngineManager();
private final Logger logger = LoggerFactory.getLogger(getClass());

public GenericScriptEngineFactory() {
for (javax.script.ScriptEngineFactory f : engineManager.getEngineFactories()) {
logger.info("Activated scripting support for {}", f.getLanguageName());
logger.debug(
"Activated scripting support with engine {}({}) for {}({}) with mimetypes {} and file extensions {}",
f.getEngineName(), f.getEngineVersion(), f.getLanguageName(), f.getLanguageVersion(),
f.getMimeTypes(), f.getExtensions());
}
}

@Override
public List<String> getLanguages() {
ArrayList<String> languages = new ArrayList<>();

for (javax.script.ScriptEngineFactory f : engineManager.getEngineFactories()) {
languages.addAll(f.getExtensions());
}

return languages;
}

@Override
public void scopeValues(ScriptEngine scriptEngine, Map<String, Object> scopeValues) {
for (Entry<String, Object> entry : scopeValues.entrySet()) {
scriptEngine.put(entry.getKey(), entry.getValue());
}
}

@Override
public ScriptEngine createScriptEngine(String fileExtension) {
ScriptEngine engine = engineManager.getEngineByExtension(fileExtension);

if (engine == null) {
engine = engineManager.getEngineByName(fileExtension);
}

if (engine == null) {
engine = engineManager.getEngineByMimeType(fileExtension);
}

return engine;
}

@Override
public boolean isSupported(String fileExtension) {
for (javax.script.ScriptEngineFactory f : engineManager.getEngineFactories()) {
if (f.getExtensions().contains(fileExtension)) {
return true;
}
}

return false;
}
@Component(service = ScriptEngineFactory.class)
public class GenericScriptEngineFactory extends AbstractScriptEngineFactory {

}
Loading

0 comments on commit 2e52513

Please sign in to comment.