added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.transform.jsonpath/.classpath
Normal file
32
bundles/org.openhab.transform.jsonpath/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.transform.jsonpath/.project
Normal file
23
bundles/org.openhab.transform.jsonpath/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.transform.jsonpath</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
31
bundles/org.openhab.transform.jsonpath/NOTICE
Normal file
31
bundles/org.openhab.transform.jsonpath/NOTICE
Normal file
@@ -0,0 +1,31 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
|
||||
== Third-party Content
|
||||
|
||||
json-path
|
||||
* License: Apache 2.0
|
||||
* Project: https://github.com/jayway/JsonPath
|
||||
* Source: https://github.com/jayway/JsonPath
|
||||
|
||||
json-smart, accessors-smart
|
||||
* License: Apache 2.0
|
||||
* Project: https://github.com/netplex/json-smart-v2
|
||||
* Source: https://github.com/netplex/json-smart-v2
|
||||
|
||||
asm
|
||||
* License: BSD
|
||||
* Project: https://asm.ow2.io/index.html
|
||||
* Source: https://gitlab.ow2.org/asm/asm
|
||||
|
||||
68
bundles/org.openhab.transform.jsonpath/README.md
Normal file
68
bundles/org.openhab.transform.jsonpath/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# JsonPath Transformation Service
|
||||
|
||||
Extracts values from a JSON string using a [JsonPath](https://github.com/jayway/JsonPath#jayway-jsonpath) expression.
|
||||
|
||||
Given the following JSON string:
|
||||
|
||||
```
|
||||
[{ "device": { "location": "Outside", "status": { "temperature": 23.2 }}}]
|
||||
```
|
||||
|
||||
The expression `$.device.location` extracts the string `Outside`.
|
||||
The JsonPath expression `$.device.status.temperature` extracts the string `23.2`.
|
||||
|
||||
## Examples
|
||||
|
||||
### Items
|
||||
|
||||
```
|
||||
String Temperature_json "Temperature [JSONPATH($.device.status.temperature):%s °C]" {...}
|
||||
Number Temperature "Temperature [%.1f °C]"
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
```php
|
||||
rule "Convert JSON to Item Type Number"
|
||||
when
|
||||
Item Temperature_json changed
|
||||
then
|
||||
// use the transformation service to retrieve the value
|
||||
val newValue = transform("JSONPATH", "$.device.status.temperature", Temperature_json.state.toString)
|
||||
|
||||
// post the new value to the Number Item
|
||||
Temperature.postUpdate( newValue )
|
||||
end
|
||||
```
|
||||
|
||||
Now the resulting Number can also be used in the label to [change the color](https://docs.openhab.org/configuration/sitemaps.html#label-and-value-colors) or in a rule as a value to compare.
|
||||
|
||||
|
||||
## Differences to standard JsonPath
|
||||
|
||||
Compared to standard JsonPath, the transformation returns single values instead of arrays.
|
||||
The transformation also will not ever return `null`.
|
||||
This makes it possible to use the transform in labels or output channels of Things.
|
||||
|
||||
If the JsonPath expression provided results in no matches, the transformation will return the entire original JSON string.
|
||||
|
||||
## Usage as a Profile
|
||||
|
||||
The transformation can be used in a `Profile` on an `ItemChannelLink` too.
|
||||
|
||||
One example for configuring it in the `.items` file:
|
||||
|
||||
```java
|
||||
String <itemName> { channel="<channelUID>"[profile="transform:JSONPATH", function="<jsonPath>", sourceFormat="<valueFormat>"]}
|
||||
```
|
||||
|
||||
The JsonPath expression to be used has to be set in the `function` parameter.
|
||||
The parameter `sourceFormat` is optional and can be used to format the input value **before** the transformation, i.e. `%.3f`.
|
||||
If omitted, the default is `%s`, so the input value will be returned from the transformation without any format changes.
|
||||
|
||||
This profile is a one-way transformation; only values from a device toward the item are changed.
|
||||
|
||||
## Further Reading
|
||||
|
||||
* An extended [introduction](https://www.w3schools.com/js/js_json_intro.asp) can be found at W3School.
|
||||
* As JsonPath transformation is based on [Jayway](https://github.com/json-path/JsonPath), using an [online validator](https://jsonpath.herokuapp.com/) which also uses Jayway will give the most similar results.
|
||||
48
bundles/org.openhab.transform.jsonpath/pom.xml
Normal file
48
bundles/org.openhab.transform.jsonpath/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.transform.jsonpath</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Transformation Service :: JSonPath</name>
|
||||
|
||||
<properties>
|
||||
<bnd.importpackage>!org.apache.tapestry5.json.*,!org.codehaus.jettison.json.*,!org.json.*,!com.fasterxml.jackson.*</bnd.importpackage>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>5.0.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.minidev</groupId>
|
||||
<artifactId>accessors-smart</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.minidev</groupId>
|
||||
<artifactId>json-smart</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.transform.jsonpath-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-transformation-jsonpath" description="JSONPath Transformation" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="75">mvn:org.openhab.addons.bundles/org.openhab.transform.jsonpath/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.jsonpath.internal;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.jayway.jsonpath.InvalidJsonException;
|
||||
import com.jayway.jsonpath.InvalidPathException;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import com.jayway.jsonpath.PathNotFoundException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The implementation of {@link TransformationService} which transforms the input by JSonPath Expressions.
|
||||
*
|
||||
* @author Gaël L'hopital
|
||||
* @author Sebastian Janzen
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, property = { "smarthome.transform=JSONPATH" })
|
||||
public class JSonPathTransformationService implements TransformationService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(JSonPathTransformationService.class);
|
||||
|
||||
/**
|
||||
* Transforms the input <code>source</code> by JSonPath expression.
|
||||
*
|
||||
* @param function JsonPath expression
|
||||
* @param source String which contains JSON
|
||||
* @throws TransformationException If the JsonPath expression is invalid, a {@link InvalidPathException} is thrown,
|
||||
* which is encapsulated in a {@link TransformationException}.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable String transform(String jsonPathExpression, String source) throws TransformationException {
|
||||
if (jsonPathExpression == null || source == null) {
|
||||
throw new TransformationException("the given parameters 'JSonPath' and 'source' must not be null");
|
||||
}
|
||||
|
||||
logger.debug("about to transform '{}' by the function '{}'", source, jsonPathExpression);
|
||||
|
||||
try {
|
||||
Object transformationResult = JsonPath.read(source, jsonPathExpression);
|
||||
logger.debug("transformation resulted in '{}'", transformationResult);
|
||||
if (transformationResult == null) {
|
||||
return null;
|
||||
} else if (transformationResult instanceof List) {
|
||||
return flattenList((List<?>) transformationResult);
|
||||
} else {
|
||||
return transformationResult.toString();
|
||||
}
|
||||
} catch (PathNotFoundException e) {
|
||||
throw new TransformationException("Invalid path '" + jsonPathExpression + "' in '" + source + "'");
|
||||
} catch (InvalidPathException | InvalidJsonException e) {
|
||||
throw new TransformationException("An error occurred while transforming JSON expression.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String flattenList(List<?> list) {
|
||||
if (list.size() == 1) {
|
||||
return list.get(0).toString();
|
||||
}
|
||||
if (list.size() > 1) {
|
||||
if (list.get(0) instanceof Number || list.get(0) instanceof Boolean) {
|
||||
return createNumberList(list);
|
||||
} else if (list.get(0) instanceof String) {
|
||||
return createStringList(list);
|
||||
}
|
||||
logger.warn(
|
||||
"JsonPath expressions with more than one result are only supported for Boolean, Number and String data types, please adapt your selector. Result: {}",
|
||||
list);
|
||||
}
|
||||
return UnDefType.NULL.toFullString();
|
||||
}
|
||||
|
||||
private String createNumberList(List<?> list) {
|
||||
return list.stream().map(n -> String.valueOf(n)).collect(Collectors.joining(", ", "[", "]"));
|
||||
}
|
||||
|
||||
private String createStringList(List<?> list) {
|
||||
return list.stream().map(n -> "\"" + String.valueOf(n) + "\"").collect(Collectors.joining(", ", "[", "]"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.jsonpath.internal.profiles;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.thing.profiles.StateProfile;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationHelper;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Profile to offer the JSonPathTransformationservice on a ItemChannelLink
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class JSonPathTransformationProfile implements StateProfile {
|
||||
|
||||
public static final ProfileTypeUID PROFILE_TYPE_UID = new ProfileTypeUID(
|
||||
TransformationService.TRANSFORM_PROFILE_SCOPE, "JSONPATH");
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(JSonPathTransformationProfile.class);
|
||||
|
||||
private final TransformationService service;
|
||||
private final ProfileCallback callback;
|
||||
|
||||
private static final String FUNCTION_PARAM = "function";
|
||||
private static final String SOURCE_FORMAT_PARAM = "sourceFormat";
|
||||
|
||||
@NonNullByDefault({})
|
||||
private final String function;
|
||||
@NonNullByDefault({})
|
||||
private final String sourceFormat;
|
||||
|
||||
public JSonPathTransformationProfile(ProfileCallback callback, ProfileContext context,
|
||||
TransformationService service) {
|
||||
this.service = service;
|
||||
this.callback = callback;
|
||||
|
||||
Object paramFunction = context.getConfiguration().get(FUNCTION_PARAM);
|
||||
Object paramSource = context.getConfiguration().get(SOURCE_FORMAT_PARAM);
|
||||
|
||||
logger.debug("Profile configured with '{}'='{}', '{}'={}", FUNCTION_PARAM, paramFunction, SOURCE_FORMAT_PARAM,
|
||||
paramSource);
|
||||
// SOURCE_FORMAT_PARAM is an advanced parameter and we assume "%s" if it is not set
|
||||
if (paramSource == null) {
|
||||
paramSource = "%s";
|
||||
}
|
||||
if (paramFunction instanceof String && paramSource instanceof String) {
|
||||
function = (String) paramFunction;
|
||||
sourceFormat = (String) paramSource;
|
||||
} else {
|
||||
logger.error("Parameter '{}' and '{}' have to be Strings. Profile will be inactive.", FUNCTION_PARAM,
|
||||
SOURCE_FORMAT_PARAM);
|
||||
function = null;
|
||||
sourceFormat = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileTypeUID getProfileTypeUID() {
|
||||
return PROFILE_TYPE_UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromItem(State state) {
|
||||
callback.handleUpdate(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandFromItem(Command command) {
|
||||
callback.handleCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandFromHandler(Command command) {
|
||||
if (function == null || sourceFormat == null) {
|
||||
logger.warn(
|
||||
"Please specify a function and a source format for this Profile in the '{}', and '{}' parameters. Returning the original command now.",
|
||||
FUNCTION_PARAM, SOURCE_FORMAT_PARAM);
|
||||
callback.sendCommand(command);
|
||||
return;
|
||||
}
|
||||
callback.sendCommand((Command) transformState(command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromHandler(State state) {
|
||||
if (function == null || sourceFormat == null) {
|
||||
logger.warn(
|
||||
"Please specify a function and a source format for this Profile in the '{}' and '{}' parameters. Returning the original state now.",
|
||||
FUNCTION_PARAM, SOURCE_FORMAT_PARAM);
|
||||
callback.sendUpdate(state);
|
||||
return;
|
||||
}
|
||||
callback.sendUpdate((State) transformState(state));
|
||||
}
|
||||
|
||||
private Type transformState(Type state) {
|
||||
String result = state.toFullString();
|
||||
try {
|
||||
result = TransformationHelper.transform(service, function, sourceFormat, state.toFullString());
|
||||
} catch (TransformationException e) {
|
||||
logger.warn("Could not transform state '{}' with function '{}' and format '{}'", state, function,
|
||||
sourceFormat);
|
||||
}
|
||||
StringType resultType = new StringType(result);
|
||||
logger.debug("Transformed '{}' into '{}'", state, resultType);
|
||||
return resultType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.jsonpath.internal.profiles;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.profiles.Profile;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileFactory;
|
||||
import org.openhab.core.thing.profiles.ProfileType;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeBuilder;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeProvider;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* Profilefactory that creates the transformation profile for the jsonpath transformation service
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { ProfileFactory.class, ProfileTypeProvider.class })
|
||||
public class JSonPathTransformationProfileFactory implements ProfileFactory, ProfileTypeProvider {
|
||||
|
||||
@NonNullByDefault({})
|
||||
private TransformationService service;
|
||||
|
||||
@Override
|
||||
public Collection<ProfileType> getProfileTypes(@Nullable Locale locale) {
|
||||
return Arrays.asList(ProfileTypeBuilder.newState(JSonPathTransformationProfile.PROFILE_TYPE_UID,
|
||||
JSonPathTransformationProfile.PROFILE_TYPE_UID.getId()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Profile createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback,
|
||||
ProfileContext profileContext) {
|
||||
return new JSonPathTransformationProfile(callback, profileContext, service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProfileTypeUID> getSupportedProfileTypeUIDs() {
|
||||
return Arrays.asList(JSonPathTransformationProfile.PROFILE_TYPE_UID);
|
||||
}
|
||||
|
||||
@Reference(target = "(smarthome.transform=JSONPATH)")
|
||||
public void addTransformationService(TransformationService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void removeTransformationService(TransformationService service) {
|
||||
this.service = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config-description:config-descriptions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||
|
||||
<config-description uri="profile:transform:JSONPATH">
|
||||
<parameter name="function" type="text" required="true">
|
||||
<label>JSONPath Expression</label>
|
||||
<description>Expression to be applied on the state. For example: $.device.status.temperature</description>
|
||||
</parameter>
|
||||
<parameter name="sourceFormat" type="text" required="false">
|
||||
<label>State Formatter</label>
|
||||
<description>How to format the state on the channel before transforming it, i.e. %s or %.1f °C (default is %s)</description>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</config-description:config-descriptions>
|
||||
@@ -0,0 +1 @@
|
||||
Bundle resources go in here!
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.jsonpath.internal;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital
|
||||
*/
|
||||
public class JSonPathTransformationServiceTest {
|
||||
|
||||
private JSonPathTransformationService processor;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
processor = new JSonPathTransformationService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByJSon() throws TransformationException {
|
||||
String json = "{'store':{'book':[{'category':'reference','author':'Nigel Rees','title': 'Sayings of the Century', 'price': 8.95 } ], 'bicycle': { 'color': 'red', 'price': 19.95} }}";
|
||||
// method under test
|
||||
String transformedResponse = processor.transform("$.store.book[0].author", json);
|
||||
|
||||
// Asserts
|
||||
Assert.assertEquals("Nigel Rees", transformedResponse);
|
||||
}
|
||||
|
||||
private static final String jsonArray = "[" + //
|
||||
"{ \"id\":1, \"name\":\"bob\", \"empty\":null }," + //
|
||||
"{ \"id\":2, \"name\":\"alice\" }" + //
|
||||
"]";
|
||||
|
||||
@Test
|
||||
public void testValidPath1() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$[0].name", jsonArray);
|
||||
assertEquals("bob", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidPath2() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$[1].id", jsonArray);
|
||||
assertEquals("2", transformedResponse);
|
||||
}
|
||||
|
||||
@Test(expected = TransformationException.class)
|
||||
public void testInvalidPathThrowsException() throws TransformationException {
|
||||
processor.transform("$$", jsonArray);
|
||||
}
|
||||
|
||||
@Test(expected = TransformationException.class)
|
||||
public void testPathMismatchReturnNull() throws TransformationException {
|
||||
processor.transform("$[5].id", jsonArray);
|
||||
}
|
||||
|
||||
@Test(expected = TransformationException.class)
|
||||
public void testInvalidJsonReturnNull() throws TransformationException {
|
||||
processor.transform("$", "{id:");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullValue() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$[0].empty", jsonArray);
|
||||
assertEquals(null, transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndefinite_filteredToSingle() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$.*[?(@.name=='bob')].id", jsonArray);
|
||||
assertEquals("1", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndefinite_notFiltered() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$.*.id", jsonArray);
|
||||
assertEquals("[1, 2]", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndefinite_noMatch() throws TransformationException {
|
||||
String transformedResponse = processor.transform("$.*[?(@.name=='unknown')].id", jsonArray);
|
||||
assertEquals("NULL", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanList() throws TransformationException {
|
||||
final String list = "[true, false, true, true, false]";
|
||||
final String json = "{\"data\":" + list + "}";
|
||||
String transformedResponse = processor.transform("$.data", json);
|
||||
assertEquals(list, transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumberList() throws TransformationException {
|
||||
final String list = "[0, 160, 253, -9, 21]";
|
||||
final String json = "{\"data\":" + list + "}";
|
||||
String transformedResponse = processor.transform("$.data", json);
|
||||
assertEquals(list, transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleList() throws TransformationException {
|
||||
final String list = "[1.0, 2.16, 5.253, -3.9, 21.21]";
|
||||
final String json = "{\"data\":" + list + "}";
|
||||
String transformedResponse = processor.transform("$.data", json);
|
||||
assertEquals(list, transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringList() throws TransformationException {
|
||||
final String list = "[\"test1\", \"test2\", \"test3\", \"test4\"]";
|
||||
final String json = "{\"data\":" + list + "}";
|
||||
String transformedResponse = processor.transform("$.data", json);
|
||||
assertEquals(list, transformedResponse);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user