зеркало из https://github.com/mozilla/smarthome.git
Adding Scale transformation service, without Localizable source file for scale and map
Signed-off-by: Gaël L'hopital <glhopital@gmail.com> My own code review Signed-off-by: Gaël L'hopital <glhopital@gmail.com> Corrections after CR Signed-off-by: Gaël L'hopital <glhopital@gmail.com> Removing test launch files Signed-off-by: Gaël L'hopital <glhopital@gmail.com>
This commit is contained in:
Родитель
93676abed4
Коммит
fe0ae37189
|
@ -7,7 +7,9 @@ Bundle-Version: 0.8.0.qualifier
|
|||
Bundle-Activator: org.eclipse.smarthome.core.transform.internal.TransformationActivator
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-License: http://www.eclipse.org/legal/epl-v10.html
|
||||
Import-Package: org.eclipse.smarthome.core.scriptengine.action;resolution:=optional,
|
||||
Import-Package: org.apache.commons.io,
|
||||
org.eclipse.smarthome.config.core,
|
||||
org.eclipse.smarthome.core.scriptengine.action;resolution:=optional,
|
||||
org.osgi.framework,
|
||||
org.slf4j
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.core.transform
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/**
|
||||
* Copyright (c) 2014-2015 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.smarthome.core.transform;
|
||||
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
|
||||
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.eclipse.smarthome.config.core.ConfigConstants;
|
||||
import org.eclipse.smarthome.core.transform.TransformationException;
|
||||
import org.eclipse.smarthome.core.transform.TransformationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Base class for cacheable and localizable file based transformation
|
||||
* {@link TransformationService}.
|
||||
* It expects the transformation to be applied to be read from a file stored
|
||||
* under the 'transform' folder within the configuration path. To organize the various
|
||||
* transformations one might use subfolders.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
* @author Kai Kreuzer - File caching mechanism
|
||||
*/
|
||||
public abstract class AbstractFileTransformationService<T> implements TransformationService {
|
||||
|
||||
private WatchService watchService = null;
|
||||
|
||||
protected final Map<String, T> cachedFiles = new ConcurrentHashMap<>();
|
||||
protected final List<String> watchedDirectories = new ArrayList<String>();
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AbstractFileTransformationService.class);
|
||||
private final String language = Locale.getDefault().getLanguage();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Transforms the input <code>source</code> by the according method defined in subclass to another string.
|
||||
* It expects the transformation to be read from a file which is stored
|
||||
* under the 'configurations/transform'
|
||||
* </p>
|
||||
*
|
||||
* @param filename
|
||||
* the name of the file which contains the transformation definition.
|
||||
* The name may contain subfoldernames
|
||||
* as well
|
||||
* @param source
|
||||
* the input to transform
|
||||
*
|
||||
* @{inheritDoc
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String transform(String filename, String source) throws TransformationException {
|
||||
|
||||
if (filename == null || source == null) {
|
||||
throw new TransformationException("the given parameters 'filename' and 'source' must not be null");
|
||||
}
|
||||
|
||||
if (watchService == null) {
|
||||
initializeWatchService();
|
||||
} else {
|
||||
processFolderEvents();
|
||||
}
|
||||
|
||||
String transformFile = getLocalizedProposedFilename(filename);
|
||||
T transform = cachedFiles.get(transformFile);
|
||||
if (transform == null) {
|
||||
transform = internalLoadTransform(transformFile);
|
||||
cachedFiles.put(transformFile, transform);
|
||||
}
|
||||
|
||||
String result = internalTransform(transform, source);
|
||||
|
||||
if (result == null) {
|
||||
logger.warn("Could not transform '{}' with the file '{}'.", source, filename);
|
||||
result = source;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract method defined by subclasses to effectively operate the
|
||||
* transformation according to its rules
|
||||
* </p>
|
||||
*
|
||||
* @param transform
|
||||
* transformation held by the file provided to <code>transform</code> method
|
||||
*
|
||||
* @param source
|
||||
* the input to transform
|
||||
*
|
||||
* @return the transformed result or null if the
|
||||
* transformation couldn't be completed for any reason.
|
||||
*
|
||||
*/
|
||||
protected abstract String internalTransform(T transform, String source) throws TransformationException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract method defined by subclasses to effectively read the transformation
|
||||
* source file according to their own needs.
|
||||
* </p>
|
||||
*
|
||||
* @param filename
|
||||
* Name of the file to be read. This filename may have been transposed
|
||||
* to a localized one
|
||||
*
|
||||
* @return
|
||||
* An object containing the source file
|
||||
*
|
||||
* @throws TransformationException
|
||||
* file couldn't be read for any reason
|
||||
*/
|
||||
protected abstract T internalLoadTransform(String filename) throws TransformationException;
|
||||
|
||||
|
||||
private void initializeWatchService() {
|
||||
try {
|
||||
watchService = FileSystems.getDefault().newWatchService();
|
||||
watchSubDirectory("");
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to start transformation directory monitoring");
|
||||
}
|
||||
}
|
||||
|
||||
private void watchSubDirectory(String subDirectory) {
|
||||
if (watchedDirectories.indexOf(subDirectory) == -1) {
|
||||
String watchedDirectory = getSourcePath() + subDirectory;
|
||||
Path transformFilePath = Paths.get(watchedDirectory);
|
||||
try {
|
||||
transformFilePath.register(watchService, ENTRY_DELETE, ENTRY_MODIFY);
|
||||
watchedDirectories.add(subDirectory);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Unable to watch transformation directory : {}", watchedDirectory);
|
||||
cachedFiles.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a modified or deleted cached files does not stay in the cache
|
||||
*/
|
||||
private void processFolderEvents() {
|
||||
WatchKey key = watchService.poll();
|
||||
if (key != null) {
|
||||
for (WatchEvent<?> e : key.pollEvents()) {
|
||||
if (e.kind() == OVERFLOW) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Context for directory entry event is the file name of entry
|
||||
@SuppressWarnings("unchecked")
|
||||
WatchEvent<Path> ev = (WatchEvent<Path>) e;
|
||||
Path path = ev.context();
|
||||
|
||||
logger.debug("Refreshing transformation file '{}'", path);
|
||||
|
||||
for (String fileEntry : cachedFiles.keySet()) {
|
||||
if (fileEntry.endsWith(path.toString())) {
|
||||
cachedFiles.remove(fileEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
key.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the localized transformation file
|
||||
* if it actually exists, keeps the original in the other case
|
||||
*
|
||||
* @param filename name of the requested transformation file
|
||||
* @return original or localized transformation file to use
|
||||
*/
|
||||
protected String getLocalizedProposedFilename(String filename) {
|
||||
String extension = FilenameUtils.getExtension(filename);
|
||||
String prefix = FilenameUtils.getPath(filename);
|
||||
String result = filename;
|
||||
|
||||
if (!prefix.isEmpty()) {
|
||||
watchSubDirectory(prefix);
|
||||
}
|
||||
|
||||
// the filename may already contain locale information
|
||||
if (!filename.matches(".*_[a-z]{2}." + extension +"$")) {
|
||||
String basename = FilenameUtils.getBaseName(filename);
|
||||
String alternateName = prefix + basename + "_" + language + "." + extension;
|
||||
String alternatePath = getSourcePath() + alternateName;
|
||||
|
||||
File f = new File(alternatePath);
|
||||
if (f.exists()) {
|
||||
result = alternateName;
|
||||
}
|
||||
}
|
||||
|
||||
result = getSourcePath() + result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the root of the transformation folder
|
||||
*/
|
||||
private String getSourcePath() {
|
||||
return ConfigConstants.getConfigFolder() + File.separator + TransformationService.TRANSFORM_FOLDER_NAME + File.separator;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/test/java"/>
|
||||
<classpathentry kind="output" path="target/test-classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.smarthome.transform.map.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,7 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,9 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Tests for the Map Transformation Service
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.transform.map.test
|
||||
Bundle-Version: 0.8.0.qualifier
|
||||
Bundle-Vendor: Eclipse.org/SmartHome
|
||||
Fragment-Host: org.eclipse.smarthome.transform.map
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: org.junit;bundle-version="4.8.1"
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body lang="EN-US">
|
||||
<h2>About This Content</h2>
|
||||
|
||||
<p>June 5, 2006</p>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||
indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/test/java/
|
||||
output.. = target/test-classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
about.html
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
#Fri Jun 19 12:42:17 CEST 2015
|
||||
OPEN=offen
|
||||
-=-
|
||||
undefined=undefiniert
|
||||
CLOSED=zu
|
|
@ -0,0 +1,4 @@
|
|||
CLOSED=closed
|
||||
OPEN=open
|
||||
undefined=unknown
|
||||
-=-
|
|
@ -0,0 +1,4 @@
|
|||
CLOSED=fermé
|
||||
OPEN=ouvert
|
||||
undefined=inconnu
|
||||
-=-
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>0.8.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>org.eclipse.smarthome.transform.map.test</artifactId>
|
||||
|
||||
<name>Eclipse SmartHome Map Transformation Service Tests</name>
|
||||
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
<artifactId>tycho-surefire-plugin</artifactId>
|
||||
<version>${tycho-version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* Copyright (c) 2014-2015 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.smarthome.transform.map.internal;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.smarthome.core.transform.TransformationException;
|
||||
import org.eclipse.smarthome.transform.map.internal.MapTransformationService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital
|
||||
*/
|
||||
public class MapTransformationServiceTest {
|
||||
|
||||
private MapTransformationService processor;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
processor = new MapTransformationService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByMap() throws TransformationException {
|
||||
|
||||
String existingGermanFilename = "map/doorstatus_de.map";
|
||||
String shouldBeLocalizedFilename = "map/doorstatus.map";
|
||||
String inexistingFilename = "map/de.map";
|
||||
|
||||
// Test that we find a translation in an existing file
|
||||
String source = "CLOSED";
|
||||
String transformedResponse = processor.transform(existingGermanFilename, source);
|
||||
Assert.assertEquals("zu", transformedResponse);
|
||||
|
||||
String usedfile = "conf/transform/" + existingGermanFilename;
|
||||
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(new FileReader(usedfile));
|
||||
properties.setProperty(source, "changevalue");
|
||||
properties.store(new FileWriter(usedfile), "");
|
||||
|
||||
// This tests that the requested transformation file has been removed from
|
||||
// the cache
|
||||
transformedResponse = processor.transform(existingGermanFilename, source);
|
||||
Assert.assertEquals("changevalue", transformedResponse);
|
||||
|
||||
properties.setProperty(source, "zu");
|
||||
properties.store(new FileWriter(usedfile), "");
|
||||
|
||||
transformedResponse = processor.transform(existingGermanFilename, source);
|
||||
Assert.assertEquals("zu", transformedResponse);
|
||||
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// Test that an unknown input in an existing file give the expected behaviour
|
||||
// transformed response shall be the same as source if not found in the file
|
||||
source = "UNKNOWN";
|
||||
transformedResponse = processor.transform(existingGermanFilename, source);
|
||||
Assert.assertEquals(source, transformedResponse);
|
||||
|
||||
// Test that an inexisting file raises correct exception as expected
|
||||
source = "CLOSED";
|
||||
try {
|
||||
transformedResponse = processor.transform(inexistingFilename, source);
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
// That's what we expect.
|
||||
}
|
||||
|
||||
// Test that we find a localized version of desired file
|
||||
source = "CLOSED";
|
||||
transformedResponse = processor.transform(shouldBeLocalizedFilename, source);
|
||||
// as we don't know the real locale at the moment the
|
||||
// test is run, we test that the string has actually been transformed
|
||||
Assert.assertNotEquals(source, transformedResponse);
|
||||
transformedResponse = processor.transform(shouldBeLocalizedFilename, source);
|
||||
Assert.assertNotEquals(source, transformedResponse);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,8 +4,7 @@ Bundle-Vendor: Eclipse.org/SmartHome
|
|||
Bundle-Version: 0.8.0.qualifier
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-License: http://www.eclipse.org/legal/epl-v10.html
|
||||
Import-Package: org.eclipse.smarthome.config.core,
|
||||
org.eclipse.smarthome.core.transform,
|
||||
Import-Package: org.eclipse.smarthome.core.transform,
|
||||
org.slf4j
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.transform.map
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
|
|
|
@ -7,27 +7,13 @@
|
|||
*/
|
||||
package org.eclipse.smarthome.transform.map.internal;
|
||||
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
|
||||
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.smarthome.config.core.ConfigConstants;
|
||||
import org.eclipse.smarthome.core.transform.TransformationException;
|
||||
import org.eclipse.smarthome.core.transform.TransformationService;
|
||||
import org.eclipse.smarthome.core.transform.AbstractFileTransformationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -35,29 +21,14 @@ import org.slf4j.LoggerFactory;
|
|||
* <p>
|
||||
* The implementation of {@link TransformationService} which simply maps strings to other strings
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution and API
|
||||
* @author Gaël L'hopital - Make it localizable
|
||||
*/
|
||||
public class MapTransformationService implements TransformationService {
|
||||
public class MapTransformationService extends AbstractFileTransformationService<Properties> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MapTransformationService.class);
|
||||
|
||||
protected WatchService watchService = null;
|
||||
|
||||
protected final Map<String, Properties> cachedProperties = new ConcurrentHashMap<>();
|
||||
|
||||
protected void deactivate() {
|
||||
cachedProperties.clear();
|
||||
if (watchService != null) {
|
||||
try {
|
||||
watchService.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Cannot cancel watch service for folder '{}'", getSourcePath());
|
||||
}
|
||||
watchService = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Transforms the input <code>source</code> by mapping it to another string. It expects the mappings to be read from
|
||||
|
@ -65,83 +36,32 @@ public class MapTransformationService implements TransformationService {
|
|||
* simple lines with "key=value" pairs. To organize the various transformations one might use subfolders.
|
||||
* </p>
|
||||
*
|
||||
* @param filename
|
||||
* the name of the file which contains the key value pairs for the mapping. The name may contain
|
||||
* subfoldernames
|
||||
* as well
|
||||
* @param properties
|
||||
* the list of properties which contains the key value pairs for the mapping.
|
||||
* @param source
|
||||
* the input to transform
|
||||
*
|
||||
* @{inheritDoc
|
||||
*
|
||||
*/
|
||||
*/
|
||||
@Override
|
||||
public String transform(String filename, String source) throws TransformationException {
|
||||
|
||||
if (filename == null || source == null) {
|
||||
throw new TransformationException("the given parameters 'filename' and 'source' must not be null");
|
||||
}
|
||||
|
||||
if (watchService == null) {
|
||||
try {
|
||||
initializeWatchService();
|
||||
} catch (IOException e) {
|
||||
// we cannot watch the folder, so let's at least clear the cache
|
||||
cachedProperties.clear();
|
||||
}
|
||||
} else {
|
||||
processFolderEvents();
|
||||
}
|
||||
Properties properties = cachedProperties.get(filename);
|
||||
if (properties == null) {
|
||||
String path = getSourcePath() + File.separator + filename;
|
||||
try (Reader reader = new FileReader(path)) {
|
||||
properties = new Properties();
|
||||
properties.load(reader);
|
||||
cachedProperties.put(filename, properties);
|
||||
} catch (IOException e) {
|
||||
String message = "opening file '" + filename + "' throws exception";
|
||||
logger.error(message, e);
|
||||
throw new TransformationException(message, e);
|
||||
}
|
||||
}
|
||||
protected String internalTransform(Properties properties, String source) throws TransformationException {
|
||||
String target = properties.getProperty(source);
|
||||
if (target != null) {
|
||||
logger.debug("transformation resulted in '{}'", target);
|
||||
return target;
|
||||
} else {
|
||||
logger.warn("Could not find a mapping for '{}' in the file '{}'.", source, filename);
|
||||
return "";
|
||||
logger.debug("transformation resulted in '{}'", target);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private void processFolderEvents() {
|
||||
WatchKey key = watchService.poll();
|
||||
if (key != null) {
|
||||
for (WatchEvent<?> e : key.pollEvents()) {
|
||||
if (e.kind() == OVERFLOW) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Context for directory entry event is the file name of entry
|
||||
@SuppressWarnings("unchecked")
|
||||
WatchEvent<Path> ev = (WatchEvent<Path>) e;
|
||||
Path path = ev.context();
|
||||
logger.debug("Refreshing transformation file '{}'", path);
|
||||
cachedProperties.remove(path.getFileName().toString());
|
||||
}
|
||||
key.reset();
|
||||
@Override
|
||||
protected Properties internalLoadTransform(String filename) throws TransformationException {
|
||||
try {
|
||||
Properties result = new Properties();
|
||||
result.load(new FileReader(filename));
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
throw new TransformationException("An error occured while opening file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeWatchService() throws IOException {
|
||||
watchService = FileSystems.getDefault().newWatchService();
|
||||
Path transformFilePath = Paths.get(getSourcePath());
|
||||
transformFilePath.register(watchService, ENTRY_DELETE, ENTRY_MODIFY);
|
||||
}
|
||||
|
||||
protected String getSourcePath() {
|
||||
return ConfigConstants.getConfigFolder() + File.separator + TransformationService.TRANSFORM_FOLDER_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/test/java"/>
|
||||
<classpathentry kind="output" path="target/test-classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.smarthome.transform.scale.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,7 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,9 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Tests for the Scale Transformation Service
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.transform.scale.test
|
||||
Bundle-Version: 0.8.0.qualifier
|
||||
Bundle-Vendor: Eclipse.org/SmartHome
|
||||
Fragment-Host: org.eclipse.smarthome.transform.scale
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: org.junit;bundle-version="4.8.1"
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body lang="EN-US">
|
||||
<h2>About This Content</h2>
|
||||
|
||||
<p>June 5, 2006</p>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||
indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/test/java/
|
||||
output.. = target/test-classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
about.html
|
|
@ -0,0 +1,5 @@
|
|||
]..10[=low
|
||||
[10..20[=middle
|
||||
[20..300[=high
|
||||
[300..]=extreme
|
||||
[..]=catchall
|
|
@ -0,0 +1,4 @@
|
|||
]..10[=low
|
||||
[1O..20[=middle
|
||||
[20..300[=high
|
||||
[300..]=extreme
|
|
@ -0,0 +1,6 @@
|
|||
[-40..20]=no significant
|
||||
[20..29]=comfortable
|
||||
[29..38]=some discomfort
|
||||
[38..45]=avoid exertion
|
||||
[45..54]=dangerous
|
||||
[54..100]=heat stroke imminent
|
|
@ -0,0 +1,6 @@
|
|||
[-40..20]=nicht wesentlich
|
||||
[20..29]=komfortabel
|
||||
[29..38]=etwas unannehmlich
|
||||
[38..45]=Anstrengung vermeiden
|
||||
[45..54]=gefährlich
|
||||
[54..100]=Hitzschlag bevorstehend
|
|
@ -0,0 +1,6 @@
|
|||
[-40..20]=non significatif
|
||||
[20..29]=confortable
|
||||
[29..38]=quelque inconfort
|
||||
[38..45]=éviter de s'exposer
|
||||
[45..54]=dangereux
|
||||
[54..100]=coup de soleil imminent
|
|
@ -0,0 +1,4 @@
|
|||
]..10[=low
|
||||
[10..20[=middle
|
||||
[20..300[=high
|
||||
[300..]=extreme
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>0.8.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>org.eclipse.smarthome.transform.scale.test</artifactId>
|
||||
|
||||
<name>Eclipse SmartHome Scale Transformation Service Tests</name>
|
||||
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
<artifactId>tycho-surefire-plugin</artifactId>
|
||||
<version>${tycho-version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* Copyright (c) 2014-2015 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.smarthome.transform.scale.internal;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.eclipse.smarthome.core.transform.TransformationException;
|
||||
import org.eclipse.smarthome.transform.scale.internal.ScaleTransformationService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital
|
||||
*/
|
||||
public class ScaleTransformServiceTest {
|
||||
private ScaleTransformationService processor;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
processor = new ScaleTransformationService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScale() throws TransformationException {
|
||||
|
||||
// need to be sur we'll have the german version
|
||||
String existingscale = "scale/humidex_de.scale";
|
||||
String source="10";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("nicht wesentlich", transformedResponse);
|
||||
|
||||
existingscale = "scale/limits.scale";
|
||||
source="10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("middle", transformedResponse);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleLimits() throws TransformationException {
|
||||
String existingscale = "scale/limits.scale";
|
||||
|
||||
// Testing upper bound opened range
|
||||
String source="500";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("extreme", transformedResponse);
|
||||
|
||||
// Testing lower bound opened range
|
||||
source="-10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("low", transformedResponse);
|
||||
|
||||
// Testing unfinite up and down range
|
||||
existingscale = "scale/catchall.scale";
|
||||
source="-10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("catchall", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleUndef() throws TransformationException {
|
||||
|
||||
// check that for undefined/non numeric value we return the original value
|
||||
String existingscale = "scale/humidex_fr.scale";
|
||||
String source="-";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("-", transformedResponse);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleErrorInBounds() throws TransformationException {
|
||||
|
||||
// the tested file contains inputs that generate a conversion error of the bounds
|
||||
// of range
|
||||
String existingscale = "scale/erroneous.scale";
|
||||
String source="15";
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
fail();
|
||||
} catch (TransformationException e) {
|
||||
// awaited result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.smarthome.transform.scale</name>
|
||||
<comment>This is the transformation bundle containing the Scale Transformation Service</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,8 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,9 @@
|
|||
#Fri Feb 19 20:28:11 CET 2010
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
fullBuildGoals=process-test-resources
|
||||
includeModules=false
|
||||
resolveWorkspaceProjects=true
|
||||
resourceFilterGoals=process-resources resources\:testResources
|
||||
skipCompilerPlugin=true
|
||||
version=1
|
|
@ -0,0 +1,14 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-Name: Eclipse SmartHome Scale Transformation Service
|
||||
Bundle-Vendor: Eclipse.org/SmartHome
|
||||
Bundle-Version: 0.8.0.qualifier
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-License: http://www.eclipse.org/legal/epl-v10.html
|
||||
Import-Package: com.google.common.collect,
|
||||
org.eclipse.smarthome.core.transform,
|
||||
org.slf4j
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.transform.scale
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Service-Component: OSGI-INF/scaleservice.xml
|
||||
Bundle-ClassPath: .
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2014-2015 openHAB UG (haftungsbeschraenkt) and others.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
-->
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.smarthome.transform.processor.scale">
|
||||
<implementation class="org.eclipse.smarthome.transform.scale.internal.ScaleTransformationService"/>
|
||||
|
||||
<service>
|
||||
<provide interface="org.eclipse.smarthome.core.transform.TransformationService"/>
|
||||
</service>
|
||||
<property name="smarthome.transform" type="String" value="SCALE"/>
|
||||
|
||||
</scr:component>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body lang="EN-US">
|
||||
<h2>About This Content</h2>
|
||||
|
||||
<p>June 5, 2006</p>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||
indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
output.. = target/classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
OSGI-INF/,\
|
||||
about.html
|
||||
source.. = src/main/java/,\
|
||||
src/main/resources/
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>0.8.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.eclipse.smarthome.transform</groupId>
|
||||
<artifactId>org.eclipse.smarthome.transform.sale</artifactId>
|
||||
|
||||
<name>Eclipse SmartHome Scale Transform Service</name>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* Copyright (c) 2014-2015 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.smarthome.transform.scale.internal;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.smarthome.core.transform.TransformationException;
|
||||
import org.eclipse.smarthome.core.transform.TransformationService;
|
||||
import org.eclipse.smarthome.core.transform.AbstractFileTransformationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.Ranges;
|
||||
|
||||
/**
|
||||
* The implementation of {@link TransformationService} which transforms the
|
||||
* input by matching it between limits of ranges in a scale file
|
||||
*
|
||||
* @author Gaël L'hopital
|
||||
*/
|
||||
public class ScaleTransformationService extends AbstractFileTransformationService<Map<Range<Double>, String>> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ScaleTransformationService.class);
|
||||
|
||||
/** RegEx to extract a scale definition */
|
||||
private static final Pattern limits_pattern = Pattern.compile("(\\[|\\])(.*)\\.\\.(.*)(\\[|\\])");
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Transforms the input <code>source</code> by matching searching the range where it fits
|
||||
* i.e. [min..max]=value or ]min..max]=value
|
||||
* </p>
|
||||
*
|
||||
* @param properties
|
||||
* the list of properties defining all the available ranges
|
||||
* @param source
|
||||
* the input to transform
|
||||
*
|
||||
* @{inheritDoc
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected String internalTransform(Map<Range<Double>, String> data, String source) throws TransformationException {
|
||||
|
||||
Double value = null;
|
||||
try {
|
||||
value = new Double(source);
|
||||
for (Range<Double> range : data.keySet()) {
|
||||
if (range.contains(value)) {
|
||||
return data.get(range);
|
||||
}
|
||||
}
|
||||
logger.debug("No matching range for '{}'", source);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Scale can not work with non numeric input");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Range<Double>, String> internalLoadTransform(String filename) throws TransformationException {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new FileReader(filename));
|
||||
Map<Range<Double>,String> data = new HashMap<Range<Double>,String>();
|
||||
|
||||
for (Entry<Object, Object> f : properties.entrySet()) {
|
||||
String key = (String) f.getKey();
|
||||
String value = properties.getProperty(key);
|
||||
Matcher matcher = limits_pattern.matcher(key);
|
||||
if (matcher.matches() && (matcher.groupCount() == 4)) {
|
||||
|
||||
BoundType lowBoundType = matcher.group(1).equals("]") ? BoundType.OPEN : BoundType.CLOSED;
|
||||
BoundType highBoundType = matcher.group(4).equals("[") ? BoundType.OPEN : BoundType.CLOSED;
|
||||
|
||||
String lowLimit = matcher.group(2);
|
||||
String highLimit = matcher.group(3);
|
||||
|
||||
Range<Double> range = null;
|
||||
|
||||
Double lowValue = null;
|
||||
Double highValue = null;
|
||||
|
||||
try {
|
||||
if (!lowLimit.isEmpty()) lowValue = new Double(lowLimit);
|
||||
if (!highLimit.isEmpty()) highValue = new Double(highLimit);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new TransformationException("Error parsing bounds : "+lowLimit+".."+highLimit);
|
||||
}
|
||||
|
||||
if (lowValue == null && highValue == null) {
|
||||
range = Ranges.all();
|
||||
} else if (lowValue == null) {
|
||||
range = Ranges.upTo(highValue, highBoundType);
|
||||
} else if (highValue == null) {
|
||||
range = Ranges.downTo(lowValue, lowBoundType);
|
||||
} else {
|
||||
range = Ranges.range(lowValue, lowBoundType, highValue, highBoundType);
|
||||
}
|
||||
|
||||
data.put(range, value);
|
||||
|
||||
} else {
|
||||
logger.warn("Scale transform entry does not comply with syntax : '{}', '{}'",key,value);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
} catch (IOException e) {
|
||||
throw new TransformationException("An error occured while opening file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Bundle resources go in here!
|
|
@ -19,6 +19,9 @@
|
|||
<module>org.eclipse.smarthome.transform.exec</module>
|
||||
<module>org.eclipse.smarthome.transform.javascript</module>
|
||||
<module>org.eclipse.smarthome.transform.map</module>
|
||||
<module>org.eclipse.smarthome.transform.map.test</module>
|
||||
<module>org.eclipse.smarthome.transform.scale</module>
|
||||
<module>org.eclipse.smarthome.transform.scale.test</module>
|
||||
<module>org.eclipse.smarthome.transform.regex</module>
|
||||
<module>org.eclipse.smarthome.transform.regex.test</module>
|
||||
<module>org.eclipse.smarthome.transform.xpath</module>
|
||||
|
|
|
@ -67,42 +67,42 @@
|
|||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.exec"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.javascript"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.map"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.regex"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.xpath"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.xslt"
|
||||
download-size="0"
|
||||
|
@ -215,4 +215,11 @@
|
|||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.smarthome.transform.scale"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
||||
|
|
Загрузка…
Ссылка в новой задаче