Bump spotless and fix formatting (#3469)

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K 2023-03-20 23:14:59 +01:00 committed by GitHub
parent 7bad9baa85
commit 9289fd5a78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 1274 additions and 1310 deletions

View File

@ -177,7 +177,7 @@ public class ScriptTransformationService
// compile the script here _after_ setting context attributes, so that the script engine
// can bind the attributes as variables during compilation. This primarily affects jruby.
if (compiledScript == null
&& scriptEngineContainer.getScriptEngine()instanceof Compilable scriptEngine) {
&& scriptEngineContainer.getScriptEngine() instanceof Compilable scriptEngine) {
// no compiled script available but compiling is supported
compiledScript = scriptEngine.compile(scriptRecord.script);
scriptRecord.compiledScript = compiledScript;

View File

@ -61,9 +61,9 @@ public final class ConfigParser {
*
* <pre>
* {@code
* public void modified(Map<String, Object> properties) {
* public void modified(Map<String, Object> properties) {
* YourConfig config = ConfigParser.configurationAs(properties, YourConfig.class);
* }
* }
* }
* </pre>
*

View File

@ -54,18 +54,19 @@ import com.igormaznitsa.jbbp.model.JBBPFieldUShort;
*
* Parser rules follows Java Binary Block Parser syntax.
*
* <p>
* <p />
*
* See details from <a href=
* "https://github.com/raydac/java-binary-block-parser">https://github.com/raydac/java-binary-block-parser</a>
*
* <p>
* <p />
* Usage example:
*
* <pre>
* {@code
* JsonObject json = new Bin2Json("byte a; byte b; ubyte c;").convert("03FAFF");
* json.toString() = {"a":3,"b":-6,"c":255}
* }
* </pre>
*
* @author Pauli Anttila - Initial contribution

View File

@ -53,7 +53,7 @@ public class ItemConsoleCommandCompleter implements ConsoleCommandCompleter {
if (cursorArgumentIndex <= 0) {
return new StringsCompleter(
itemRegistry.getAll().stream().map(i -> i.getName()).collect(Collectors.toList()), true)
.complete(args, cursorArgumentIndex, cursorPosition, candidates);
.complete(args, cursorArgumentIndex, cursorPosition, candidates);
}
var localDataTypeGetter = dataTypeGetter;
if (cursorArgumentIndex == 1 && localDataTypeGetter != null) {

View File

@ -505,7 +505,7 @@ public class ThingResource implements RESTResource {
thingRegistry.updateConfiguration(thingUIDObject,
new Configuration(
normalizeConfiguration(configurationParameters, thing.getThingTypeUID(), thing.getUID()))
.getProperties());
.getProperties());
} catch (ConfigValidationException ex) {
logger.debug("Config description validation exception occurred for thingUID {} - Messages: {}", thingUID,
ex.getValidationMessages());

View File

@ -38,5 +38,4 @@ public class ItemRuntimeActivator implements ModelParser {
public String getExtension() {
return "items";
}
}

View File

@ -1,37 +1,36 @@
/**
* Copyright (c) 2010-2023 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.model.internal.valueconverter;
import org.openhab.core.model.core.valueconverter.ValueTypeToStringConverter;
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import com.google.inject.Inject;
/**
* Registers {@link IValueConverter}s for the items language.
*
* @author Simon Kaufmann - Initial contribution
*/
public class ItemValueConverters extends DefaultTerminalConverters {
@Inject
private ValueTypeToStringConverter valueTypeToStringConverter;
@ValueConverter(rule = "ValueType")
public IValueConverter<Object> ValueType() {
return valueTypeToStringConverter;
}
}
/**
* Copyright (c) 2010-2023 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.model.internal.valueconverter;
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import org.openhab.core.model.core.valueconverter.ValueTypeToStringConverter;
import com.google.inject.Inject;
/**
* Registers {@link IValueConverter}s for the items language.
*
* @author Simon Kaufmann - Initial contribution
*/
public class ItemValueConverters extends DefaultTerminalConverters {
@Inject
private ValueTypeToStringConverter valueTypeToStringConverter;
@ValueConverter(rule = "ValueType")
public IValueConverter<Object> ValueType() {
return valueTypeToStringConverter;
}
}

View File

@ -28,5 +28,4 @@ public class BindingConfigParseException extends Exception {
public BindingConfigParseException(String msg, Exception e) {
super(msg, e);
}
}

View File

@ -517,5 +517,4 @@ public class GenericItemProvider extends AbstractProvider<Item>
public @Nullable StateDescriptionFragment getStateDescriptionFragment(String itemName, @Nullable Locale locale) {
return stateDescriptionFragments.get(itemName);
}
}

View File

@ -88,7 +88,8 @@ public class GenericMetadataProvider extends AbstractProvider<Metadata> implemen
* Removes all meta-data for a given item
*
* @param itemName the item name
*/public void removeMetadataByItemName(String itemName) {
*/
public void removeMetadataByItemName(String itemName) {
Set<Metadata> toBeRemoved;
try {
lock.writeLock().lock();
@ -101,6 +102,7 @@ public class GenericMetadataProvider extends AbstractProvider<Metadata> implemen
notifyListenersAboutRemovedElement(m);
}
}
@Override
public Collection<Metadata> getAll() {
try {
@ -110,5 +112,4 @@ public class GenericMetadataProvider extends AbstractProvider<Metadata> implemen
lock.readLock().unlock();
}
}
}

View File

@ -38,5 +38,4 @@ public class PersistenceRuntimeActivator implements ModelParser {
public String getExtension() {
return "persist";
}
}

View File

@ -16,17 +16,6 @@ import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.openhab.core.persistence.PersistenceManager;
import org.openhab.core.persistence.PersistenceService;
import org.openhab.core.persistence.PersistenceServiceConfiguration;
import org.openhab.core.persistence.PersistenceFilter;
import org.openhab.core.persistence.PersistenceItemConfiguration;
import org.openhab.core.persistence.config.PersistenceAllConfig;
import org.openhab.core.persistence.config.PersistenceConfig;
import org.openhab.core.persistence.config.PersistenceGroupConfig;
import org.openhab.core.persistence.config.PersistenceItemConfig;
import org.openhab.core.persistence.strategy.PersistenceCronStrategy;
import org.openhab.core.persistence.strategy.PersistenceStrategy;
import org.openhab.core.model.core.EventType;
import org.openhab.core.model.core.ModelRepository;
import org.openhab.core.model.core.ModelRepositoryChangeListener;
@ -38,6 +27,17 @@ import org.openhab.core.model.persistence.persistence.ItemConfig;
import org.openhab.core.model.persistence.persistence.PersistenceConfiguration;
import org.openhab.core.model.persistence.persistence.PersistenceModel;
import org.openhab.core.model.persistence.persistence.Strategy;
import org.openhab.core.persistence.PersistenceFilter;
import org.openhab.core.persistence.PersistenceItemConfiguration;
import org.openhab.core.persistence.PersistenceManager;
import org.openhab.core.persistence.PersistenceService;
import org.openhab.core.persistence.PersistenceServiceConfiguration;
import org.openhab.core.persistence.config.PersistenceAllConfig;
import org.openhab.core.persistence.config.PersistenceConfig;
import org.openhab.core.persistence.config.PersistenceGroupConfig;
import org.openhab.core.persistence.config.PersistenceItemConfig;
import org.openhab.core.persistence.strategy.PersistenceCronStrategy;
import org.openhab.core.persistence.strategy.PersistenceStrategy;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@ -170,5 +170,4 @@ public class PersistenceModelManager implements ModelRepositoryChangeListener {
private PersistenceFilter mapFilter(Filter filter) {
return new PersistenceFilter();
}
}

View File

@ -20,12 +20,12 @@ import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.openhab.core.model.persistence.persistence.Strategy;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractGlobalScopeProvider;
import org.eclipse.xtext.scoping.impl.SimpleScope;
import org.openhab.core.model.persistence.persistence.Strategy;
import com.google.common.base.Predicate;
@ -53,5 +53,4 @@ public class PersistenceGlobalScopeProvider extends AbstractGlobalScopeProvider
}
return new SimpleScope(parentScope, descs);
}
}

View File

@ -94,7 +94,5 @@ public class RuleContextHelper {
public IEvaluationContext getContext() {
return context;
}
}
}

View File

@ -49,5 +49,4 @@ public class RuleEvaluationContext extends DefaultEvaluationContext {
}
}
}
}

View File

@ -56,12 +56,10 @@ public class RulesClassFinder extends ClassFinder {
cache.put(name, NULL_CLASS);
throw e;
}
}
@Override
protected Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException {
return Class.forName(name, false, classLoader);
}
}

View File

@ -165,7 +165,8 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
}
}
Map<String, Object> cachePreset = scriptExtensionAccessor.findPreset("cache", (String) context.getAttribute("oh.engine-identifier", ScriptContext.ENGINE_SCOPE));
Map<String, Object> cachePreset = scriptExtensionAccessor.findPreset("cache",
(String) context.getAttribute("oh.engine-identifier", ScriptContext.ENGINE_SCOPE));
evalContext.newValue(QualifiedName.create("sharedCache"), cachePreset.get("sharedCache"));
evalContext.newValue(QualifiedName.create("privateCache"), cachePreset.get("privateCache"));
// now add specific implicit vars, where we have to map the right content
@ -211,7 +212,6 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
@Override
public void put(String key, Object value) {
}
@Override
@ -240,7 +240,6 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
@Override
public void setContext(ScriptContext context) {
}
@Override
@ -308,5 +307,4 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
}
};
}
}

View File

@ -45,7 +45,8 @@ public class DSLScriptEngineFactory implements ScriptEngineFactory {
protected @Nullable DSLScriptContextProvider contextProvider;
@Activate
public DSLScriptEngineFactory(@Reference ScriptEngine scriptEngine, @Reference ScriptExtensionAccessor scriptExtensionAccessor) {
public DSLScriptEngineFactory(@Reference ScriptEngine scriptEngine,
@Reference ScriptExtensionAccessor scriptExtensionAccessor) {
this.scriptEngine = scriptEngine;
this.scriptExtensionAccessor = scriptExtensionAccessor;
}
@ -63,5 +64,4 @@ public class DSLScriptEngineFactory implements ScriptEngineFactory {
public javax.script.@Nullable ScriptEngine createScriptEngine(String scriptType) {
return new DSLScriptEngine(scriptEngine, contextProvider, scriptExtensionAccessor);
}
}

View File

@ -1,103 +1,103 @@
/**
* Copyright (c) 2010-2023 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.model.script.runtime.internal.engine;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.interpreter.IEvaluationContext;
import org.eclipse.xtext.xbase.interpreter.IEvaluationResult;
import org.eclipse.xtext.xbase.interpreter.IExpressionInterpreter;
import org.openhab.core.model.script.engine.Script;
import org.openhab.core.model.script.engine.ScriptExecutionException;
import com.google.inject.Inject;
/**
* This is the default implementation of a {@link Script}.
*
* @author Kai Kreuzer - Initial contribution
*/
public class ScriptImpl implements Script {
private XExpression xExpression;
@Inject
public ScriptImpl() {
}
/* package-local */
void setXExpression(XExpression xExpression) {
this.xExpression = xExpression;
}
/* package-local */
XExpression getXExpression() {
return xExpression;
}
@Override
public Object execute() throws ScriptExecutionException {
if (xExpression != null) {
Resource resource = xExpression.eResource();
IEvaluationContext evaluationContext = null;
if (resource instanceof XtextResource) {
IResourceServiceProvider provider = ((XtextResource) resource).getResourceServiceProvider();
evaluationContext = provider.get(IEvaluationContext.class);
}
return execute(evaluationContext);
} else {
throw new ScriptExecutionException("Script does not contain any expression");
}
}
@Override
public Object execute(final IEvaluationContext evaluationContext) throws ScriptExecutionException {
if (xExpression != null) {
Resource resource = xExpression.eResource();
IExpressionInterpreter interpreter = null;
if (resource instanceof XtextResource) {
IResourceServiceProvider provider = ((XtextResource) resource).getResourceServiceProvider();
interpreter = provider.get(IExpressionInterpreter.class);
}
if (interpreter == null) {
throw new ScriptExecutionException("Script interpreter couldn't be obtained");
}
try {
IEvaluationResult result = interpreter.evaluate(xExpression, evaluationContext,
CancelIndicator.NullImpl);
if (result == null) {
// this can only happen on an InterpreterCancelledException,
// i.e. NEVER ;-)
return null;
}
if (result.getException() != null) {
throw new ScriptExecutionException(result.getException().getMessage(), result.getException());
}
return result.getResult();
} catch (Throwable e) {
if (e instanceof ScriptExecutionException) {
throw (ScriptExecutionException) e;
} else {
throw new ScriptExecutionException(
"An error occurred during the script execution: " + e.getMessage(), e);
}
}
} else {
throw new ScriptExecutionException("Script does not contain any expression");
}
}
}
/**
* Copyright (c) 2010-2023 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.model.script.runtime.internal.engine;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.interpreter.IEvaluationContext;
import org.eclipse.xtext.xbase.interpreter.IEvaluationResult;
import org.eclipse.xtext.xbase.interpreter.IExpressionInterpreter;
import org.openhab.core.model.script.engine.Script;
import org.openhab.core.model.script.engine.ScriptExecutionException;
import com.google.inject.Inject;
/**
* This is the default implementation of a {@link Script}.
*
* @author Kai Kreuzer - Initial contribution
*/
public class ScriptImpl implements Script {
private XExpression xExpression;
@Inject
public ScriptImpl() {
}
/* package-local */
void setXExpression(XExpression xExpression) {
this.xExpression = xExpression;
}
/* package-local */
XExpression getXExpression() {
return xExpression;
}
@Override
public Object execute() throws ScriptExecutionException {
if (xExpression != null) {
Resource resource = xExpression.eResource();
IEvaluationContext evaluationContext = null;
if (resource instanceof XtextResource) {
IResourceServiceProvider provider = ((XtextResource) resource).getResourceServiceProvider();
evaluationContext = provider.get(IEvaluationContext.class);
}
return execute(evaluationContext);
} else {
throw new ScriptExecutionException("Script does not contain any expression");
}
}
@Override
public Object execute(final IEvaluationContext evaluationContext) throws ScriptExecutionException {
if (xExpression != null) {
Resource resource = xExpression.eResource();
IExpressionInterpreter interpreter = null;
if (resource instanceof XtextResource) {
IResourceServiceProvider provider = ((XtextResource) resource).getResourceServiceProvider();
interpreter = provider.get(IExpressionInterpreter.class);
}
if (interpreter == null) {
throw new ScriptExecutionException("Script interpreter couldn't be obtained");
}
try {
IEvaluationResult result = interpreter.evaluate(xExpression, evaluationContext,
CancelIndicator.NullImpl);
if (result == null) {
// this can only happen on an InterpreterCancelledException,
// i.e. NEVER ;-)
return null;
}
if (result.getException() != null) {
throw new ScriptExecutionException(result.getException().getMessage(), result.getException());
}
return result.getResult();
} catch (Throwable e) {
if (e instanceof ScriptExecutionException) {
throw (ScriptExecutionException) e;
} else {
throw new ScriptExecutionException(
"An error occurred during the script execution: " + e.getMessage(), e);
}
}
} else {
throw new ScriptExecutionException("Script does not contain any expression");
}
}
}

View File

@ -31,8 +31,8 @@ import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.library.CoreItemFactory;
import org.openhab.core.model.script.internal.engine.action.SemanticsActionService;
import org.openhab.core.semantics.model.equipment.CleaningRobot;
import org.openhab.core.semantics.model.equipment.Battery;
import org.openhab.core.semantics.model.equipment.CleaningRobot;
import org.openhab.core.semantics.model.location.Bathroom;
import org.openhab.core.semantics.model.location.Indoor;

View File

@ -31,5 +31,4 @@ public class OptimizingFeatureScopeTrackerProvider2 extends OptimizingFeatureSco
return new FeatureScopeTracker() {
};
}
}

View File

@ -162,5 +162,4 @@ public class ScriptServiceUtil {
// uninjected as a callback from the script engine, not via DS as it is a circular dependency...
this.scriptEngine.compareAndSet(scriptEngine, null);
}
}

View File

@ -13,7 +13,6 @@
package org.openhab.core.model.script;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.model.core.ModelRepository;
import org.openhab.core.model.script.engine.IActionServiceProvider;
import org.openhab.core.model.script.engine.IThingActionsProvider;
@ -22,6 +21,7 @@ import org.openhab.core.model.script.internal.engine.ServiceTrackerActionService
import org.openhab.core.model.script.internal.engine.ServiceTrackerThingActionsProvider;
import org.openhab.core.model.script.script.Script;
import org.openhab.core.model.script.script.impl.ScriptImpl;
import org.openhab.core.thing.ThingRegistry;
import com.google.inject.Binder;
import com.google.inject.Module;
@ -52,5 +52,4 @@ public class ServiceModule implements Module {
binder.bind(IThingActionsProvider.class).toInstance(new ServiceTrackerThingActionsProvider(scriptServiceUtil));
binder.bind(Script.class).to(ScriptImpl.class);
}
}

View File

@ -47,7 +47,7 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the default sink")
public static void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
try {
AudioActionService.audioManager.playFile(filename, volume);
} catch (AudioException e) {
@ -57,13 +57,13 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the default sink")
public static void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
playSound(filename, floatVolumeToPercentType(volume));
}
@ActionDoc(text = "plays a sound from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
try {
AudioActionService.audioManager.playFile(filename, sink);
} catch (AudioException e) {
@ -73,8 +73,8 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
try {
AudioActionService.audioManager.playFile(filename, sink, volume);
} catch (AudioException e) {
@ -84,8 +84,8 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
playSound(sink, filename, floatVolumeToPercentType(volume));
}
@ -167,6 +167,7 @@ public class Audio {
/**
* Converts a float volume to a {@link PercentType} volume and checks if float volume is in the [0;1] range.
*
* @param volume
* @return
*/

View File

@ -24,10 +24,10 @@ import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.items.events.ItemEventFactory;
import org.openhab.core.model.script.ScriptServiceUtil;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.TypeParser;
import org.openhab.core.model.script.ScriptServiceUtil;
import org.slf4j.LoggerFactory;
/**

View File

@ -194,5 +194,4 @@ public class Ephemeris {
return -1;
}
}
}

View File

@ -56,5 +56,4 @@ public class Exec {
public static String executeCommandLine(Duration timeout, String... commandLine) {
return ExecUtil.executeCommandLineAndWaitResponse(timeout, commandLine);
}
}

View File

@ -1,301 +1,301 @@
/**
* Copyright (c) 2010-2023 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.model.script.actions;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
import org.eclipse.jetty.http.HttpMethod;
import org.openhab.core.io.net.http.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provides static methods that can be used in automation rules
* for sending HTTP requests
*
* @author Kai Kreuzer - Initial contribution
* @author Jan N. Klug - add timeout methods
*/
public class HTTP {
/** Constant which represents the content type <code>application/json</code> */
public static final String CONTENT_TYPE_JSON = "application/json";
private static Logger logger = LoggerFactory.getLogger(HTTP.class);
/**
* Send out a GET-HTTP request. Errors will be logged, success returns response
*
* @param url the URL to be used for the GET request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpGetRequest(String url) {
return sendHttpGetRequest(url, 5000);
}
/**
* Send out a GET-HTTP request. Errors will be logged, success returns response
*
* @param url the URL to be used for the GET request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpGetRequest(String url, int timeout) {
String response = null;
try {
return HttpUtil.executeUrl(HttpMethod.GET.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a GET-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the GET request.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
public static String sendHttpGetRequest(String url, Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.GET.name(), url, headerProperties, null, null, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url) {
return sendHttpPutRequest(url, 1000);
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.PUT.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content) {
return sendHttpPutRequest(url, contentType, content, 1000);
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.PUT.name(), url,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* sent.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content, Map<String, String> headers,
int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.PUT.name(), url, headerProperties,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url) {
return sendHttpPostRequest(url, 1000);
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.POST.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, String contentType, String content) {
return sendHttpPostRequest(url, contentType, content, 1000);
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, String contentType, String content, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.POST.name(), url,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the GET request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* sent.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
public static String sendHttpPostRequest(String url, String contentType, String content,
Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.POST.name(), url, headerProperties,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url) {
return sendHttpDeleteRequest(url, 1000);
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.DELETE.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url, Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.DELETE.name(), url, headerProperties, null, null, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
}
/**
* Copyright (c) 2010-2023 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.model.script.actions;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
import org.eclipse.jetty.http.HttpMethod;
import org.openhab.core.io.net.http.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provides static methods that can be used in automation rules
* for sending HTTP requests
*
* @author Kai Kreuzer - Initial contribution
* @author Jan N. Klug - add timeout methods
*/
public class HTTP {
/** Constant which represents the content type <code>application/json</code> */
public static final String CONTENT_TYPE_JSON = "application/json";
private static Logger logger = LoggerFactory.getLogger(HTTP.class);
/**
* Send out a GET-HTTP request. Errors will be logged, success returns response
*
* @param url the URL to be used for the GET request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpGetRequest(String url) {
return sendHttpGetRequest(url, 5000);
}
/**
* Send out a GET-HTTP request. Errors will be logged, success returns response
*
* @param url the URL to be used for the GET request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpGetRequest(String url, int timeout) {
String response = null;
try {
return HttpUtil.executeUrl(HttpMethod.GET.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a GET-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the GET request.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
public static String sendHttpGetRequest(String url, Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.GET.name(), url, headerProperties, null, null, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url) {
return sendHttpPutRequest(url, 1000);
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.PUT.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content) {
return sendHttpPutRequest(url, contentType, content, 1000);
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.PUT.name(), url,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the PUT request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* sent.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPutRequest(String url, String contentType, String content, Map<String, String> headers,
int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.PUT.name(), url, headerProperties,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url) {
return sendHttpPostRequest(url, 1000);
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.POST.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, String contentType, String content) {
return sendHttpPostRequest(url, contentType, content, 1000);
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the POST request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* send.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpPostRequest(String url, String contentType, String content, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.POST.name(), url,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the GET request.
* @param contentType the content type of the given <code>content</code>
* @param content the content to be send to the given <code>url</code> or <code>null</code> if no content should be
* sent.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
public static String sendHttpPostRequest(String url, String contentType, String content,
Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.POST.name(), url, headerProperties,
new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), contentType, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url) {
return sendHttpDeleteRequest(url, 1000);
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url, int timeout) {
String response = null;
try {
response = HttpUtil.executeUrl(HttpMethod.DELETE.name(), url, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return response;
}
/**
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
*
* @param url the URL to be used for the DELETE request.
* @param headers the HTTP headers to be sent in the request.
* @param timeout timeout in ms
* @return the response body or <code>NULL</code> when the request went wrong
*/
static public String sendHttpDeleteRequest(String url, Map<String, String> headers, int timeout) {
try {
Properties headerProperties = new Properties();
headerProperties.putAll(headers);
return HttpUtil.executeUrl(HttpMethod.DELETE.name(), url, headerProperties, null, null, timeout);
} catch (IOException e) {
logger.error("Fatal transport error: {}", e.getMessage());
}
return null;
}
}

View File

@ -80,5 +80,4 @@ public class Log {
static public void logError(String loggerName, String format, Object... args) {
LoggerFactory.getLogger(LOGGER_NAME_PREFIX.concat(loggerName)).error(format, args);
}
}

View File

@ -62,5 +62,4 @@ public class Ping {
return success;
}
}

View File

@ -12,6 +12,8 @@
*/
package org.openhab.core.model.script.actions;
import java.time.ZonedDateTime;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.xtext.xbase.XExpression;
@ -26,8 +28,6 @@ import org.openhab.core.model.script.internal.engine.action.ScriptExecutionActio
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.ZonedDateTime;
/**
* The {@link ScriptExecution} is a wrapper for the ScriptExecution actions
*
@ -78,17 +78,23 @@ public class ScriptExecution {
}
@ActionDoc(text = "create an identifiable timer ")
public static Timer createTimer(@Nullable String identifier, ZonedDateTime zonedDateTime, Procedures.Procedure0 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimer(identifier, zonedDateTime, closure::apply));
public static Timer createTimer(@Nullable String identifier, ZonedDateTime zonedDateTime,
Procedures.Procedure0 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimer(identifier, zonedDateTime,
closure::apply));
}
@ActionDoc(text = "create a timer with argument")
public static Timer createTimerWithArgument(ZonedDateTime zonedDateTime, Object arg1, Procedures.Procedure1 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(zonedDateTime, arg1, closure::apply));
public static Timer createTimerWithArgument(ZonedDateTime zonedDateTime, Object arg1,
Procedures.Procedure1 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(zonedDateTime, arg1,
closure::apply));
}
@ActionDoc(text = "create an identifiable timer with argument")
public static Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime zonedDateTime, Object arg1, Procedures.Procedure1 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(identifier, zonedDateTime, arg1, closure::apply));
public static Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime zonedDateTime, Object arg1,
Procedures.Procedure1 closure) {
return new Timer(ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(identifier,
zonedDateTime, arg1, closure::apply));
}
}

View File

@ -110,7 +110,6 @@ public class Semantics {
public static @Nullable Class<? extends Equipment> getEquipmentType(Item item) {
Item equipmentItem = isEquipment(item) ? item : getEquipment(item);
return equipmentItem != null ? SemanticTags.getEquipment(equipmentItem) : null;
}
/**

View File

@ -12,9 +12,9 @@
*/
package org.openhab.core.model.script.actions;
import org.openhab.core.model.script.internal.engine.action.ThingActionService;
import org.openhab.core.thing.ThingStatusInfo;
import org.openhab.core.thing.binding.ThingActions;
import org.openhab.core.model.script.internal.engine.action.ThingActionService;
/**
* This class provides static methods that can be used in automation rules for

View File

@ -12,11 +12,11 @@
*/
package org.openhab.core.model.script.actions;
import java.time.ZonedDateTime;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import java.time.ZonedDateTime;
/**
* The {@link Timer} is a wrapper for the {@link org.openhab.core.automation.module.script.action.Timer}
* interface. This is necessary because the implementation methods of an interface can't be called from

View File

@ -33,5 +33,4 @@ public class TransformationException extends Exception {
public TransformationException(@Nullable String message, @Nullable Throwable cause) {
super(message, cause);
}
}

View File

@ -67,13 +67,13 @@ public class Voice {
*/
@ActionDoc(text = "says a given text with the default voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
say(text, null, null, volume);
}
@ActionDoc(text = "says a given text with the default voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, null, null, floatVolumeToPercentType(volume));
}
@ -104,16 +104,14 @@ public class Voice {
* @param volume The volume to be used
*/
@ActionDoc(text = "says a given text with a given voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
say(text, voice, null, volume);
}
@ActionDoc(text = "says a given text with a given voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, voice, null, floatVolumeToPercentType(volume));
}
@ -128,9 +126,8 @@ public class Voice {
* be used
*/
@ActionDoc(text = "says a given text with a given voice through the given sink")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink) {
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink) {
say(text, voice, sink, null);
}
@ -147,8 +144,8 @@ public class Voice {
*/
@ActionDoc(text = "says a given text with a given voice and the given volume through the given sink")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
String output = text.toString();
if (!output.isBlank()) {
VoiceActionService.voiceManager.say(output, voice, sink, volume);
@ -157,8 +154,8 @@ public class Voice {
@ActionDoc(text = "says a given text with a given voice and the given volume through the given sink")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, voice, sink, floatVolumeToPercentType(volume));
}
@ -185,7 +182,7 @@ public class Voice {
*/
@ActionDoc(text = "interprets a given text by given human language interpreter(s)", returns = "human language response")
public static String interpret(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "interpreters") @Nullable String interpreters) {
@ParamDoc(name = "interpreters") @Nullable String interpreters) {
String response;
try {
response = VoiceActionService.voiceManager.interpret(text.toString(), interpreters);
@ -209,8 +206,7 @@ public class Voice {
*/
@ActionDoc(text = "interprets a given text by given human language interpreter(s) and using the given sink", returns = "human language response")
public static String interpret(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "interpreters") String interpreters,
@ParamDoc(name = "sink") @Nullable String sink) {
@ParamDoc(name = "interpreters") String interpreters, @ParamDoc(name = "sink") @Nullable String sink) {
String response;
try {
response = VoiceActionService.voiceManager.interpret(text.toString(), interpreters);
@ -233,7 +229,7 @@ public class Voice {
*/
@ActionDoc(text = "starts dialog processing for a given audio source")
public static void startDialog(@ParamDoc(name = "source") @Nullable String source,
@ParamDoc(name = "sink") @Nullable String sink) {
@ParamDoc(name = "sink") @Nullable String sink) {
startDialog(null, null, null, null, null, source, sink, null, null, null);
}
@ -476,6 +472,7 @@ public class Voice {
/**
* Converts a float volume to a {@link PercentType} volume and checks if float volume is in the [0;1] range.
*
* @param volume
* @return
*/

View File

@ -19,5 +19,4 @@ import org.openhab.core.model.script.engine.action.ActionService;
public interface IActionServiceProvider {
List<ActionService> get();
}

View File

@ -19,5 +19,4 @@ import org.openhab.core.thing.binding.ThingActions;
public interface IThingActionsProvider {
List<ThingActions> get();
}

View File

@ -53,11 +53,9 @@ public class ScriptParsingException extends ScriptException {
public ScriptParsingException addValidationIssues(Iterable<Issue> validationErrors) {
for (Issue validationError : validationErrors) {
this.getErrors().add(
new ScriptError(validationError.getMessage(), validationError.getLineNumber(), validationError
.getOffset(), validationError.getLength()));
this.getErrors().add(new ScriptError(validationError.getMessage(), validationError.getLineNumber(),
validationError.getOffset(), validationError.getLength()));
}
return this;
}
}

View File

@ -37,5 +37,4 @@ public interface ActionService {
* @return the action class
*/
Class<?> getActionClass();
}

View File

@ -112,5 +112,4 @@ public class RuleHumanLanguageInterpreter implements HumanLanguageInterpreter {
public Set<String> getSupportedGrammarFormats() {
return Collections.emptySet();
}
}

View File

@ -35,5 +35,4 @@ public class ScriptEncodingProvider implements IEncodingProvider {
}
return Charset.defaultCharset().name();
}
}

View File

@ -12,6 +12,8 @@
*/
package org.openhab.core.model.script.internal.engine.action;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.module.script.action.ScriptExecution;
@ -20,8 +22,6 @@ import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import java.util.Objects;
/**
* This class registers an OSGi service for the ScriptExecution action.
*

View File

@ -113,4 +113,4 @@ public class SemanticsActionService implements ActionService {
}
return null;
}
}
}

View File

@ -116,5 +116,4 @@ public class ThingActionService implements ActionService {
ThingActionsScope scopeAnnotation = actions.getClass().getAnnotation(ThingActionsScope.class);
return scopeAnnotation.name();
}
}

View File

@ -97,7 +97,6 @@ public class ScriptItemRefresher implements ItemRegistryChangeListener {
@Override
public void updated(Item oldElement, Item element) {
}
@Override

View File

@ -12,15 +12,15 @@
*/
package org.openhab.core.model.script.jvmmodel;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.model.script.script.QuantityLiteral;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.typesystem.computation.ITypeComputationState;
import org.eclipse.xtext.xbase.typesystem.computation.ITypeExpectation;
import org.eclipse.xtext.xbase.typesystem.computation.XbaseTypeComputer;
import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.model.script.script.QuantityLiteral;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
/**
* Calculates the type information used by Xbase to select the correct method during script execution.
@ -61,5 +61,4 @@ public class ScriptTypeComputer extends XbaseTypeComputer {
}
state.acceptActualType(qt);
}
}

View File

@ -1,399 +1,398 @@
/**
* Copyright (c) 2010-2023 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.model.script.lib;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.measure.quantity.Dimensionless;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.types.Type;
/**
* This class contains all kinds of extensions to be used by scripts and not
* provided by Xbase. These include things like number handling and comparisons.
*
* @author Kai Kreuzer - Initial contribution
*/
public class NumberExtensions {
/**
* It is the definition of Java null pointer for the rules language.
* Actually its value is 0 (rules variables are number) but we can use
* the null pointer and throws an NPE when a null value is used.
* I think this concept should not exist for those who writes the rules.
*/
public static final BigDecimal NULL_DEFINITION = new BigDecimal(0);
// Calculation operators for numbers
public static BigDecimal operator_plus(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return yValue;
} else if (yValue == null) {
return xValue;
} else {
return xValue.add(yValue);
}
}
public static BigDecimal operator_minus(Number x) {
BigDecimal xValue = numberToBigDecimal(x);
if (xValue == null) {
return xValue;
} else {
return xValue.negate();
}
}
public static BigDecimal operator_minus(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return operator_minus(yValue);
} else if (yValue == null) {
return xValue;
} else {
return xValue.subtract(yValue);
}
}
public static BigDecimal operator_multiply(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return NULL_DEFINITION;
} else if (yValue == null) {
return NULL_DEFINITION;
} else {
return xValue.multiply(yValue);
}
}
public static BigDecimal operator_divide(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
return xValue.divide(yValue, 8, RoundingMode.HALF_UP);
}
// Comparison operations between numbers
public static boolean operator_equals(Number left, Number right) {
// in case one of the Number instances is of type QuantityType they are never equal (except for
// Units.ONE).
// for both instances being QuantityTypes the specific method
// operator_equals(QuantityType<?> left, QuantityType<?> right) is called by the script engine.
if (oneIsQuantity(left, right)) {
return false;
}
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return rightValue == null;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) == 0;
}
}
public static boolean operator_notEquals(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return rightValue != null;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) != 0;
}
}
public static boolean operator_lessThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return true;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) < 0;
}
}
public static boolean operator_greaterThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return false;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) > 0;
}
}
public static boolean operator_lessEqualsThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return true;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) <= 0;
}
}
public static boolean operator_greaterEqualsThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return (rightValue != null) ? false : true;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) >= 0;
}
}
// Comparison operators between types and numbers
public static boolean operator_equals(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_equals((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) == 0;
} else {
return type == x; // both might be null, then we should return true
}
}
public static boolean operator_notEquals(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_notEquals((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) != 0;
} else {
return type != x; // both might be null, then we should return
// false, otherwise true
}
}
public static boolean operator_greaterThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_greaterThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) > 0;
} else {
return false;
}
}
public static boolean operator_greaterEqualsThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_greaterEqualsThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) >= 0;
} else {
return false;
}
}
public static boolean operator_lessThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_lessThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) < 0;
} else {
return false;
}
}
public static boolean operator_lessEqualsThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_lessEqualsThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) <= 0;
} else {
return false;
}
}
// QuantityType support
@SuppressWarnings({ "unchecked", "rawtypes" })
public static QuantityType<?> operator_plus(QuantityType<?> x, QuantityType<?> y) {
return x == null ? y : y == null ? x : x.add((QuantityType) y);
}
public static QuantityType<?> operator_minus(QuantityType<?> x) {
return x == null ? null : x.negate();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static QuantityType<?> operator_minus(QuantityType<?> x, QuantityType<?> y) {
return x == null ? operator_minus(y) : y == null ? x : x.subtract((QuantityType) y);
}
public static QuantityType<?> operator_multiply(Number x, QuantityType<?> y) {
BigDecimal xValue = numberToBigDecimal(x);
if (xValue == null) {
return QuantityType.ZERO;
} else if (y == null) {
return QuantityType.ZERO;
} else {
return y.multiply(xValue);
}
}
public static QuantityType<?> operator_multiply(QuantityType<?> x, Number y) {
return operator_multiply(y, x);
}
public static QuantityType<?> operator_multiply(QuantityType<?> x, QuantityType<?> y) {
return x == null || y == null ? QuantityType.ZERO : x.multiply(y);
}
public static QuantityType<?> operator_divide(QuantityType<?> x, Number y) {
BigDecimal yValue = numberToBigDecimal(y);
return x.divide(yValue);
}
public static QuantityType<?> operator_divide(Number x, QuantityType<?> y) {
QuantityType<Dimensionless> xQuantity = new QuantityType<>(x, Units.ONE);
return operator_divide(xQuantity, y);
}
public static QuantityType<?> operator_divide(QuantityType<?> x, QuantityType<?> y) {
return x.divide(y);
}
public static boolean operator_equals(QuantityType<?> left, QuantityType<?> right) {
return left.equals(right);
}
// support Units.ONE as Number representation
public static boolean operator_equals(QuantityType<?> left, Number right) {
return operator_equals((Number) left, right);
}
public static boolean operator_notEquals(QuantityType<?> left, QuantityType<?> right) {
return !operator_equals(left, right);
}
// support Units.ONE as Number representation
public static boolean operator_notEquals(QuantityType<?> left, Number right) {
return operator_notEquals((Number) left, right);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_lessThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) < 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_lessThan(QuantityType<?> x, Number y) {
return operator_lessThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_lessEqualsThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) <= 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_lessEqualsThan(QuantityType<?> x, Number y) {
return operator_lessEqualsThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_greaterThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) > 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_greaterThan(QuantityType<?> x, Number y) {
return operator_greaterThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_greaterEqualsThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) >= 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_greaterEqualsThan(QuantityType<?> x, Number y) {
return operator_greaterEqualsThan((Number) x, y);
}
/**
* Convert the given number into a BigDecimal
*
* @param number
* the number to convert
* @return the given number as BigDecimal or null if number is null
*/
public static BigDecimal numberToBigDecimal(Number number) {
if (number instanceof QuantityType) {
QuantityType<?> state = ((QuantityType<?>) number)
.toInvertibleUnit(((QuantityType<?>) number).getUnit().getSystemUnit());
if (state != null) {
return state.toBigDecimal();
}
return null;
}
if (number != null) {
return new BigDecimal(number.toString());
} else {
return null;
}
}
private static boolean oneIsQuantity(Number left, Number right) {
return (left instanceof QuantityType && !isAbstractUnitOne((QuantityType<?>) left))
|| (right instanceof QuantityType && !isAbstractUnitOne((QuantityType<?>) right));
}
private static boolean isAbstractUnitOne(QuantityType<?> left) {
return Units.ONE.equals(left.getUnit());
}
}
/**
* Copyright (c) 2010-2023 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.model.script.lib;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.measure.quantity.Dimensionless;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.types.Type;
/**
* This class contains all kinds of extensions to be used by scripts and not
* provided by Xbase. These include things like number handling and comparisons.
*
* @author Kai Kreuzer - Initial contribution
*/
public class NumberExtensions {
/**
* It is the definition of Java null pointer for the rules language.
* Actually its value is 0 (rules variables are number) but we can use
* the null pointer and throws an NPE when a null value is used.
* I think this concept should not exist for those who writes the rules.
*/
public static final BigDecimal NULL_DEFINITION = new BigDecimal(0);
// Calculation operators for numbers
public static BigDecimal operator_plus(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return yValue;
} else if (yValue == null) {
return xValue;
} else {
return xValue.add(yValue);
}
}
public static BigDecimal operator_minus(Number x) {
BigDecimal xValue = numberToBigDecimal(x);
if (xValue == null) {
return xValue;
} else {
return xValue.negate();
}
}
public static BigDecimal operator_minus(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return operator_minus(yValue);
} else if (yValue == null) {
return xValue;
} else {
return xValue.subtract(yValue);
}
}
public static BigDecimal operator_multiply(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
if (xValue == null) {
return NULL_DEFINITION;
} else if (yValue == null) {
return NULL_DEFINITION;
} else {
return xValue.multiply(yValue);
}
}
public static BigDecimal operator_divide(Number x, Number y) {
BigDecimal xValue = numberToBigDecimal(x);
BigDecimal yValue = numberToBigDecimal(y);
return xValue.divide(yValue, 8, RoundingMode.HALF_UP);
}
// Comparison operations between numbers
public static boolean operator_equals(Number left, Number right) {
// in case one of the Number instances is of type QuantityType they are never equal (except for
// Units.ONE).
// for both instances being QuantityTypes the specific method
// operator_equals(QuantityType<?> left, QuantityType<?> right) is called by the script engine.
if (oneIsQuantity(left, right)) {
return false;
}
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return rightValue == null;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) == 0;
}
}
public static boolean operator_notEquals(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return rightValue != null;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) != 0;
}
}
public static boolean operator_lessThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return true;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) < 0;
}
}
public static boolean operator_greaterThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return false;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) > 0;
}
}
public static boolean operator_lessEqualsThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return true;
} else if (rightValue == null) {
return false;
} else {
return leftValue.compareTo(rightValue) <= 0;
}
}
public static boolean operator_greaterEqualsThan(Number left, Number right) {
BigDecimal leftValue = numberToBigDecimal(left);
BigDecimal rightValue = numberToBigDecimal(right);
if (leftValue == null) {
return (rightValue != null) ? false : true;
} else if (rightValue == null) {
return true;
} else {
return leftValue.compareTo(rightValue) >= 0;
}
}
// Comparison operators between types and numbers
public static boolean operator_equals(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_equals((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) == 0;
} else {
return type == x; // both might be null, then we should return true
}
}
public static boolean operator_notEquals(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_notEquals((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) != 0;
} else {
return type != x; // both might be null, then we should return
// false, otherwise true
}
}
public static boolean operator_greaterThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_greaterThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) > 0;
} else {
return false;
}
}
public static boolean operator_greaterEqualsThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_greaterEqualsThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) >= 0;
} else {
return false;
}
}
public static boolean operator_lessThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_lessThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) < 0;
} else {
return false;
}
}
public static boolean operator_lessEqualsThan(Type type, Number x) {
if (type instanceof QuantityType && x instanceof QuantityType) {
return operator_lessEqualsThan((QuantityType<?>) type, (QuantityType<?>) x);
}
if (type != null && type instanceof DecimalType && x != null) {
return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) <= 0;
} else {
return false;
}
}
// QuantityType support
@SuppressWarnings({ "unchecked", "rawtypes" })
public static QuantityType<?> operator_plus(QuantityType<?> x, QuantityType<?> y) {
return x == null ? y : y == null ? x : x.add((QuantityType) y);
}
public static QuantityType<?> operator_minus(QuantityType<?> x) {
return x == null ? null : x.negate();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static QuantityType<?> operator_minus(QuantityType<?> x, QuantityType<?> y) {
return x == null ? operator_minus(y) : y == null ? x : x.subtract((QuantityType) y);
}
public static QuantityType<?> operator_multiply(Number x, QuantityType<?> y) {
BigDecimal xValue = numberToBigDecimal(x);
if (xValue == null) {
return QuantityType.ZERO;
} else if (y == null) {
return QuantityType.ZERO;
} else {
return y.multiply(xValue);
}
}
public static QuantityType<?> operator_multiply(QuantityType<?> x, Number y) {
return operator_multiply(y, x);
}
public static QuantityType<?> operator_multiply(QuantityType<?> x, QuantityType<?> y) {
return x == null || y == null ? QuantityType.ZERO : x.multiply(y);
}
public static QuantityType<?> operator_divide(QuantityType<?> x, Number y) {
BigDecimal yValue = numberToBigDecimal(y);
return x.divide(yValue);
}
public static QuantityType<?> operator_divide(Number x, QuantityType<?> y) {
QuantityType<Dimensionless> xQuantity = new QuantityType<>(x, Units.ONE);
return operator_divide(xQuantity, y);
}
public static QuantityType<?> operator_divide(QuantityType<?> x, QuantityType<?> y) {
return x.divide(y);
}
public static boolean operator_equals(QuantityType<?> left, QuantityType<?> right) {
return left.equals(right);
}
// support Units.ONE as Number representation
public static boolean operator_equals(QuantityType<?> left, Number right) {
return operator_equals((Number) left, right);
}
public static boolean operator_notEquals(QuantityType<?> left, QuantityType<?> right) {
return !operator_equals(left, right);
}
// support Units.ONE as Number representation
public static boolean operator_notEquals(QuantityType<?> left, Number right) {
return operator_notEquals((Number) left, right);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_lessThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) < 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_lessThan(QuantityType<?> x, Number y) {
return operator_lessThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_lessEqualsThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) <= 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_lessEqualsThan(QuantityType<?> x, Number y) {
return operator_lessEqualsThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_greaterThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) > 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_greaterThan(QuantityType<?> x, Number y) {
return operator_greaterThan((Number) x, y);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean operator_greaterEqualsThan(QuantityType<?> x, QuantityType<?> y) {
if (x != null && y != null) {
return x.compareTo((QuantityType) y) >= 0;
} else {
return false;
}
}
// support Units.ONE as Number representation
public static boolean operator_greaterEqualsThan(QuantityType<?> x, Number y) {
return operator_greaterEqualsThan((Number) x, y);
}
/**
* Convert the given number into a BigDecimal
*
* @param number
* the number to convert
* @return the given number as BigDecimal or null if number is null
*/
public static BigDecimal numberToBigDecimal(Number number) {
if (number instanceof QuantityType) {
QuantityType<?> state = ((QuantityType<?>) number)
.toInvertibleUnit(((QuantityType<?>) number).getUnit().getSystemUnit());
if (state != null) {
return state.toBigDecimal();
}
return null;
}
if (number != null) {
return new BigDecimal(number.toString());
} else {
return null;
}
}
private static boolean oneIsQuantity(Number left, Number right) {
return (left instanceof QuantityType && !isAbstractUnitOne((QuantityType<?>) left))
|| (right instanceof QuantityType && !isAbstractUnitOne((QuantityType<?>) right));
}
private static boolean isAbstractUnitOne(QuantityType<?> left) {
return Units.ONE.equals(left.getUnit());
}
}

View File

@ -50,5 +50,4 @@ public class ScriptImportSectionNamespaceScopeProvider extends XImportSectionNam
implicitImports.add(doCreateImportNormalizer(QUANTITY_PACKAGE, true, false));
return implicitImports;
}
}

View File

@ -90,5 +90,4 @@ public class StateAndCommandProvider {
public Iterable<State> getAllStates() {
return STATES;
}
}

View File

@ -38,5 +38,4 @@ public class SitemapRuntimeActivator implements ModelParser {
public String getExtension() {
return "sitemap";
}
}

View File

@ -1,56 +1,54 @@
/**
* Copyright (c) 2010-2023 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.model.sitemap;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.model.core.ModelRepositoryChangeListener;
import org.openhab.core.model.sitemap.sitemap.Sitemap;
@NonNullByDefault
public interface SitemapProvider {
/**
* This method provides access to sitemap model files, loads them and returns the object model tree.
*
* @param sitemapName the name of the sitemap to load
* @return the object model tree, null if it is not found
*/
@Nullable
Sitemap getSitemap(String sitemapName);
/**
* Returns the names of all available sitemaps
*
* @return names of provided sitemaps
*/
Set<String> getSitemapNames();
/**
* Add a listener which will be informed subsequently once a model has changed
*
* @param listener
*/
void addModelChangeListener(ModelRepositoryChangeListener listener);
/**
* Remove a model change listener again
*
* @param listener
*/
void removeModelChangeListener(ModelRepositoryChangeListener listener);
}
/**
* Copyright (c) 2010-2023 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.model.sitemap;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.model.core.ModelRepositoryChangeListener;
import org.openhab.core.model.sitemap.sitemap.Sitemap;
@NonNullByDefault
public interface SitemapProvider {
/**
* This method provides access to sitemap model files, loads them and returns the object model tree.
*
* @param sitemapName the name of the sitemap to load
* @return the object model tree, null if it is not found
*/
@Nullable
Sitemap getSitemap(String sitemapName);
/**
* Returns the names of all available sitemaps
*
* @return names of provided sitemaps
*/
Set<String> getSitemapNames();
/**
* Add a listener which will be informed subsequently once a model has changed
*
* @param listener
*/
void addModelChangeListener(ModelRepositoryChangeListener listener);
/**
* Remove a model change listener again
*
* @param listener
*/
void removeModelChangeListener(ModelRepositoryChangeListener listener);
}

View File

@ -1,131 +1,130 @@
/**
* Copyright (c) 2010-2023 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.model.sitemap.internal;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.model.core.EventType;
import org.openhab.core.model.core.ModelRepository;
import org.openhab.core.model.core.ModelRepositoryChangeListener;
import org.openhab.core.model.sitemap.SitemapProvider;
import org.openhab.core.model.sitemap.sitemap.Sitemap;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provides access to the sitemap model files.
*
* @author Kai Kreuzer - Initial contribution
*/
@NonNullByDefault
@Component(service = SitemapProvider.class)
public class SitemapProviderImpl implements SitemapProvider, ModelRepositoryChangeListener {
private static final String SITEMAP_MODEL_NAME = "sitemap";
protected static final String SITEMAP_FILEEXT = "." + SITEMAP_MODEL_NAME;
private final Logger logger = LoggerFactory.getLogger(SitemapProviderImpl.class);
private final ModelRepository modelRepo;
private final Map<String, Sitemap> sitemapModelCache = new ConcurrentHashMap<>();
private final Set<ModelRepositoryChangeListener> modelChangeListeners = new CopyOnWriteArraySet<>();
@Activate
public SitemapProviderImpl(final @Reference ModelRepository modelRepo) {
this.modelRepo = modelRepo;
refreshSitemapModels();
modelRepo.addModelRepositoryChangeListener(this);
}
@Deactivate
protected void deactivate() {
modelRepo.removeModelRepositoryChangeListener(this);
sitemapModelCache.clear();
}
@Override
public @Nullable Sitemap getSitemap(String sitemapName) {
String filename = sitemapName + SITEMAP_FILEEXT;
Sitemap sitemap = sitemapModelCache.get(filename);
if (sitemap == null) {
logger.trace("Sitemap {} cannot be found", sitemapName);
return null;
}
if (!sitemap.getName().equals(sitemapName)) {
logger.warn(
"Filename `{}` does not match the name `{}` of the sitemap - please fix this as you might see unexpected behavior otherwise.",
filename, sitemap.getName());
}
return sitemap;
}
@Override
public Set<String> getSitemapNames() {
return sitemapModelCache.keySet().stream()
.map(name -> name.substring(0, name.length() - SITEMAP_FILEEXT.length())).collect(Collectors.toSet());
}
@Override
public void modelChanged(String modelName, EventType type) {
if (modelName.endsWith(SITEMAP_FILEEXT)) {
if (type == EventType.REMOVED) {
sitemapModelCache.remove(modelName);
} else {
EObject sitemap = modelRepo.getModel(modelName);
// if the sitemap file is empty it will not be in the repo and thus there is no need to cache it here
if (sitemap instanceof Sitemap) {
sitemapModelCache.put(modelName, (Sitemap) sitemap);
}
}
}
for (ModelRepositoryChangeListener listener : modelChangeListeners) {
listener.modelChanged(modelName, type);
}
}
private void refreshSitemapModels() {
sitemapModelCache.clear();
Iterable<String> sitemapNames = modelRepo.getAllModelNamesOfType(SITEMAP_MODEL_NAME);
for (String sitemapName : sitemapNames) {
Sitemap sitemap = (Sitemap) modelRepo.getModel(sitemapName);
if (sitemap != null) {
sitemapModelCache.put(sitemapName, sitemap);
}
}
}
@Override
public void addModelChangeListener(ModelRepositoryChangeListener listener) {
modelChangeListeners.add(listener);
}
@Override
public void removeModelChangeListener(ModelRepositoryChangeListener listener) {
modelChangeListeners.remove(listener);
}
}
/**
* Copyright (c) 2010-2023 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.model.sitemap.internal;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.model.core.EventType;
import org.openhab.core.model.core.ModelRepository;
import org.openhab.core.model.core.ModelRepositoryChangeListener;
import org.openhab.core.model.sitemap.SitemapProvider;
import org.openhab.core.model.sitemap.sitemap.Sitemap;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provides access to the sitemap model files.
*
* @author Kai Kreuzer - Initial contribution
*/
@NonNullByDefault
@Component(service = SitemapProvider.class)
public class SitemapProviderImpl implements SitemapProvider, ModelRepositoryChangeListener {
private static final String SITEMAP_MODEL_NAME = "sitemap";
protected static final String SITEMAP_FILEEXT = "." + SITEMAP_MODEL_NAME;
private final Logger logger = LoggerFactory.getLogger(SitemapProviderImpl.class);
private final ModelRepository modelRepo;
private final Map<String, Sitemap> sitemapModelCache = new ConcurrentHashMap<>();
private final Set<ModelRepositoryChangeListener> modelChangeListeners = new CopyOnWriteArraySet<>();
@Activate
public SitemapProviderImpl(final @Reference ModelRepository modelRepo) {
this.modelRepo = modelRepo;
refreshSitemapModels();
modelRepo.addModelRepositoryChangeListener(this);
}
@Deactivate
protected void deactivate() {
modelRepo.removeModelRepositoryChangeListener(this);
sitemapModelCache.clear();
}
@Override
public @Nullable Sitemap getSitemap(String sitemapName) {
String filename = sitemapName + SITEMAP_FILEEXT;
Sitemap sitemap = sitemapModelCache.get(filename);
if (sitemap == null) {
logger.trace("Sitemap {} cannot be found", sitemapName);
return null;
}
if (!sitemap.getName().equals(sitemapName)) {
logger.warn(
"Filename `{}` does not match the name `{}` of the sitemap - please fix this as you might see unexpected behavior otherwise.",
filename, sitemap.getName());
}
return sitemap;
}
@Override
public Set<String> getSitemapNames() {
return sitemapModelCache.keySet().stream()
.map(name -> name.substring(0, name.length() - SITEMAP_FILEEXT.length())).collect(Collectors.toSet());
}
@Override
public void modelChanged(String modelName, EventType type) {
if (modelName.endsWith(SITEMAP_FILEEXT)) {
if (type == EventType.REMOVED) {
sitemapModelCache.remove(modelName);
} else {
EObject sitemap = modelRepo.getModel(modelName);
// if the sitemap file is empty it will not be in the repo and thus there is no need to cache it here
if (sitemap instanceof Sitemap) {
sitemapModelCache.put(modelName, (Sitemap) sitemap);
}
}
}
for (ModelRepositoryChangeListener listener : modelChangeListeners) {
listener.modelChanged(modelName, type);
}
}
private void refreshSitemapModels() {
sitemapModelCache.clear();
Iterable<String> sitemapNames = modelRepo.getAllModelNamesOfType(SITEMAP_MODEL_NAME);
for (String sitemapName : sitemapNames) {
Sitemap sitemap = (Sitemap) modelRepo.getModel(sitemapName);
if (sitemap != null) {
sitemapModelCache.put(sitemapName, sitemap);
}
}
}
@Override
public void addModelChangeListener(ModelRepositoryChangeListener listener) {
modelChangeListeners.add(listener);
}
@Override
public void removeModelChangeListener(ModelRepositoryChangeListener listener) {
modelChangeListeners.remove(listener);
}
}

View File

@ -45,7 +45,6 @@ public class SitemapConverters extends DefaultTerminalConverters {
}
return value;
}
};
}

View File

@ -38,5 +38,4 @@ public class ThingRuntimeActivator implements ModelParser {
public String getExtension() {
return "things";
}
}

View File

@ -141,5 +141,4 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
public Collection<ItemChannelLink> getAll() {
return itemChannelLinkMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
}
}

View File

@ -1,38 +1,39 @@
/**
* Copyright (c) 2010-2023 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.model.thing.serializer;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.ISynNavigable;
/**
*
* @author Alex Tugarev - Initial contribution
*/
@SuppressWarnings("restriction")
public class ThingSyntacticSequencerExtension extends ThingSyntacticSequencer {
@Override
protected void emit_ModelThing_ThingKeyword_0_q(EObject semanticObject, ISynNavigable transition, List<INode> nodes) {
ILeafNode node = nodes != null && nodes.size() == 1 && nodes.get(0) instanceof ILeafNode ? (ILeafNode) nodes
.get(0) : null;
Keyword keyword = grammarAccess.getModelThingAccess().getThingKeyword_0();
acceptUnassignedKeyword(keyword, keyword.getValue(), node);
}
}
/**
* Copyright (c) 2010-2023 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.model.thing.serializer;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.ISynNavigable;
/**
*
* @author Alex Tugarev - Initial contribution
*/
@SuppressWarnings("restriction")
public class ThingSyntacticSequencerExtension extends ThingSyntacticSequencer {
@Override
protected void emit_ModelThing_ThingKeyword_0_q(EObject semanticObject, ISynNavigable transition,
List<INode> nodes) {
ILeafNode node = nodes != null && nodes.size() == 1 && nodes.get(0) instanceof ILeafNode
? (ILeafNode) nodes.get(0)
: null;
Keyword keyword = grammarAccess.getModelThingAccess().getThingKeyword_0();
acceptUnassignedKeyword(keyword, keyword.getValue(), node);
}
}

View File

@ -1,40 +1,39 @@
/**
* Copyright (c) 2010-2023 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.model.thing.valueconverter;
import org.openhab.core.model.core.valueconverter.ValueTypeToStringConverter;
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import com.google.inject.Inject;
public class ThingValueConverters extends DefaultTerminalConverters {
@Inject
private ValueTypeToStringConverter valueTypeToStringConverter;
@Inject
private UIDtoStringConverter uidToStringConverter;
@ValueConverter(rule = "ValueType")
public IValueConverter<Object> ValueType() {
return valueTypeToStringConverter;
}
@ValueConverter(rule = "UID")
public IValueConverter<String> UID() {
return uidToStringConverter;
}
}
/**
* Copyright (c) 2010-2023 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.model.thing.valueconverter;
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import org.openhab.core.model.core.valueconverter.ValueTypeToStringConverter;
import com.google.inject.Inject;
public class ThingValueConverters extends DefaultTerminalConverters {
@Inject
private ValueTypeToStringConverter valueTypeToStringConverter;
@Inject
private UIDtoStringConverter uidToStringConverter;
@ValueConverter(rule = "ValueType")
public IValueConverter<Object> ValueType() {
return valueTypeToStringConverter;
}
@ValueConverter(rule = "UID")
public IValueConverter<String> UID() {
return uidToStringConverter;
}
}

View File

@ -1,74 +1,74 @@
/**
* Copyright (c) 2010-2023 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.model.thing.valueconverter;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.openhab.core.thing.UID;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.util.Strings;
/**
* A {@link UIDtoStringConverter} is used to create {@link UID} string
* representations from an input string and vice versa. If a segment of the
* parsed {@link UID} string doesn't match the ID rule, it will be escaped.
*
* @author Alex Tugarev - Initial contribution
*/
public class UIDtoStringConverter implements IValueConverter<String> {
private static final String SEPERATOR = ":";
@Override
public String toValue(final String string, INode node) throws ValueConverterException {
if (string == null) {
return null;
}
String[] ids = string.split(SEPERATOR);
for (int i = 0; i < ids.length; i++) {
String id = ids[i];
if (id != null && id.startsWith("\"") && id.endsWith("\"")) {
try {
ids[i] = Strings.convertFromJavaString(id.substring(1, id.length() - 1), true);
} catch (IllegalArgumentException e) {
throw new ValueConverterException(e.getMessage(), node, e);
}
}
}
return Arrays.stream(ids).collect(Collectors.joining(SEPERATOR));
}
@Override
public String toString(String value) throws ValueConverterException {
if (value == null) {
throw new ValueConverterException("Value may not be null.", null, null);
}
String[] ids = value.split(SEPERATOR);
for (int i = 0; i < ids.length; i++) {
String id = ids[i];
if (id != null && !id.matches("[A-Za-z0-9_]*")) {
// string escapes each segment which doesn't match:
// terminal ID: '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;
ids[i] = toEscapedString(id);
}
}
return Arrays.stream(ids).collect(Collectors.joining(SEPERATOR));
}
protected String toEscapedString(String value) {
return '"' + Strings.convertToJavaString(value, false) + '"';
}
}
/**
* Copyright (c) 2010-2023 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.model.thing.valueconverter;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.util.Strings;
import org.openhab.core.thing.UID;
/**
* A {@link UIDtoStringConverter} is used to create {@link UID} string
* representations from an input string and vice versa. If a segment of the
* parsed {@link UID} string doesn't match the ID rule, it will be escaped.
*
* @author Alex Tugarev - Initial contribution
*/
public class UIDtoStringConverter implements IValueConverter<String> {
private static final String SEPERATOR = ":";
@Override
public String toValue(final String string, INode node) throws ValueConverterException {
if (string == null) {
return null;
}
String[] ids = string.split(SEPERATOR);
for (int i = 0; i < ids.length; i++) {
String id = ids[i];
if (id != null && id.startsWith("\"") && id.endsWith("\"")) {
try {
ids[i] = Strings.convertFromJavaString(id.substring(1, id.length() - 1), true);
} catch (IllegalArgumentException e) {
throw new ValueConverterException(e.getMessage(), node, e);
}
}
}
return Arrays.stream(ids).collect(Collectors.joining(SEPERATOR));
}
@Override
public String toString(String value) throws ValueConverterException {
if (value == null) {
throw new ValueConverterException("Value may not be null.", null, null);
}
String[] ids = value.split(SEPERATOR);
for (int i = 0; i < ids.length; i++) {
String id = ids[i];
if (id != null && !id.matches("[A-Za-z0-9_]*")) {
// string escapes each segment which doesn't match:
// terminal ID: '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;
ids[i] = toEscapedString(id);
}
}
return Arrays.stream(ids).collect(Collectors.joining(SEPERATOR));
}
protected String toEscapedString(String value) {
return '"' + Strings.convertToJavaString(value, false) + '"';
}
}

View File

@ -209,7 +209,7 @@ public class JsonStorageTest extends JavaTest {
orderedMap.getAsJsonObject("DummyObject").getAsJsonObject("value")
.getAsJsonObject("innerMapWithComparableKeys"),
TypeToken.getParameterized(LinkedHashMap.class, Integer.class, Object.class).getType()))
.keySet().toArray());
.keySet().toArray());
}
private static class DummyObject {

View File

@ -96,7 +96,7 @@ public class ItemChannelLinkRegistry extends AbstractLinkRegistry<ItemChannelLin
public Set<Thing> getBoundThings(final String itemName) {
return ((Stream<Thing>) getBoundChannels(itemName).stream()
.map(channelUID -> thingRegistry.get(channelUID.getThingUID())).filter(Objects::nonNull))
.collect(Collectors.toSet());
.collect(Collectors.toSet());
}
@Reference

View File

@ -119,7 +119,7 @@ public class TTSLRUCacheImpl implements TTSCache {
}
});
} catch (RuntimeException re) {
if (re.getCause() != null && re.getCause()instanceof TTSException ttse) {
if (re.getCause() != null && re.getCause() instanceof TTSException ttse) {
throw ttse;
} else {
throw re;

View File

@ -370,8 +370,8 @@ public class ItemRegistryImpl extends AbstractRegistry<Item, String, ItemProvide
@Override
public @Nullable Item remove(String itemName, boolean recursive) {
return ((ManagedItemProvider) getManagedProvider()
.orElseThrow(() -> new IllegalStateException("ManagedProvider is not available"))).remove(itemName,
recursive);
.orElseThrow(() -> new IllegalStateException("ManagedProvider is not available")))
.remove(itemName, recursive);
}
@Override

View File

@ -70,15 +70,15 @@ public class ConfigDescriptionI18nTest extends JavaOSGiTest {
Objects.requireNonNull(config);
String expected = "location.label = Ort\n" + //
"location.description = Ort der Wetterinformation.\n" + //
"unit.label = Einheit\n" + //
"unit.description = Spezifiziert die Einheit der Daten. Valide Werte sind 'us' und 'metric'\n" + //
"refresh.label = Aktualisierungsintervall\n" + //
"refresh.description = Spezifiziert das Aktualisierungsintervall in Sekunden\n" + //
"question.pattern = Wie ist das Wetter in [\\w]*?\n" + //
"question.options = München, Köln\n" + //
"group.label = Group 1 German Label\n" + //
"group.description = Group 1 German Description";
"location.description = Ort der Wetterinformation.\n" + //
"unit.label = Einheit\n" + //
"unit.description = Spezifiziert die Einheit der Daten. Valide Werte sind 'us' und 'metric'\n" + //
"refresh.label = Aktualisierungsintervall\n" + //
"refresh.description = Spezifiziert das Aktualisierungsintervall in Sekunden\n" + //
"question.pattern = Wie ist das Wetter in [\\w]*?\n" + //
"question.options = München, Köln\n" + //
"group.label = Group 1 German Label\n" + //
"group.description = Group 1 German Description";
assertEquals(expected, asString(config));
});

11
pom.xml
View File

@ -77,8 +77,9 @@
<sat.version>0.13.0</sat.version>
<slf4j.version>1.7.32</slf4j.version>
<xtext.version>2.29.0</xtext.version>
<spotless.version>2.28.0</spotless.version>
<spotless.eclipse.version>4.21.0</spotless.eclipse.version>
<spotless.version>2.35.0</spotless.version>
<spotless.eclipse.version>4.26</spotless.eclipse.version>
<spotless.eclipse.wtp.version>4.21.0</spotless.eclipse.wtp.version>
</properties>
<dependencyManagement>
@ -561,7 +562,7 @@ Import-Package: \\
<files>
<file>openhab_wst_xml_files.prefs</file>
</files>
<version>${spotless.eclipse.version}</version>
<version>${spotless.eclipse.wtp.version}</version>
</eclipseWtp>
<trimTrailingWhitespace/>
<endWithNewline/>
@ -576,7 +577,7 @@ Import-Package: \\
<files>
<file>openhab_wst_feature_file.prefs</file>
</files>
<version>${spotless.eclipse.version}</version>
<version>${spotless.eclipse.wtp.version}</version>
</eclipseWtp>
<trimTrailingWhitespace/>
<endWithNewline/>
@ -591,7 +592,7 @@ Import-Package: \\
<files>
<file>openhab_wst_pom_file.prefs</file>
</files>
<version>${spotless.eclipse.version}</version>
<version>${spotless.eclipse.wtp.version}</version>
</eclipseWtp>
<trimTrailingWhitespace/>
<endWithNewline/>