package org.ugate.resources;
import gnu.io.CommPortIdentifier;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javafx.application.Platform;
import javafx.scene.CacheHint;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.media.AudioClip;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ugate.UGateUtil;
import org.ugate.service.entity.RemoteNodeReadingType;
import org.ugate.service.entity.RemoteNodeType;
public class RS {
private static final Logger log = LoggerFactory.getLogger(RS.class);
public static final String PACKAGE_CHECK_EXTENSION = ".jar";
public static final String RXTX_JAR_FILE_NAME = "RXTXcomm.jar";
public static final String RXTX_DLL_PARALLEL_FILE_NAME = "rxtxParallel.dll";
public static final String RXTX_DLL_SERIAL_FILE_NAME = "rxtxSerial.dll";
public static final String RXTX_MAC_SERIAL_FILE_NAME = "librxtxSerial.jnilib";
public static final String RXTX_LINUX_PARALLEL_FILE_NAME = "librxtxParallel.so";
public static final String RXTX_LINUX_SERIAL_FILE_NAME = "librxtxSerial.so";
public static final String CSS_MAIN = "main.css";
public static final String CSS_DISPLAY_SHELF = "displayshelf.css";
public static final String IMG_LOGO_128 = "logo128x128x32.png";
public static final String IMG_LOGO_48 = "logo48x48x32.png";
public static final String IMG_LOGO_32 = "logo32x32x32.png";
public static final String IMG_LOGO_16 = "logo16x16x32.png";
public static final String IMG_SKIN_MIN = "ugskin-btn-min32x10.png";
public static final String IMG_SKIN_MAX = "ugskin-btn-max25x10.png";
public static final String IMG_SKIN_RESTORE = "ugskin-btn-res25x10.png";
public static final String IMG_SKIN_CLOSE = "ugskin-btn-close32x10.png";
public static final String IMG_HELP = "help.png";
public static final String IMG_CONNECT = "power-red.png";
public static final String IMG_PICS = "pics.png";
public static final String IMG_WIRELESS = "wireless-globe.png";
public static final String IMG_WIRELESS_ICON = "wireless-icon.png";
public static final String IMG_WEB_ICON = "web-icon.png";
public static final String IMG_GRAPH = "graph.png";
public static final String IMG_WEB = "web.png";
public static final String IMG_CAM_VGA = "cam-vga.png";
public static final String IMG_CAM_QVGA = "cam-qvga.png";
public static final String IMG_CAM_TOGGLE_VGA = "cam-toggle-vga.png";
public static final String IMG_CAM_TOGGLE_QVGA = "cam-toggle-qvga.png";
public static final String IMG_SENSOR_ARM = "camera.png";
public static final String IMG_EMAIL_NOTIFY_ON = "email-notify-on.png";
public static final String IMG_EMAIL_NOTIFY_OFF = "email-notify-off.png";
public static final String IMG_EMAIL_ICON = "email-icon.png";
public static final String IMG_GATE_ON = "gate-on.png";
public static final String IMG_GATE_OFF = "gate-off.png";
public static final String IMG_GATE_CLOSED = "gate-closed.png";
public static final String IMG_GATE_OPENED = "gate-opened.png";
public static final String IMG_RULER = "ruler.png";
public static final String IMG_STOPWATCH = "stopwatch.png";
public static final String IMG_SONAR_ALARM_MULTI = "sonar-alarm-multi.png";
public static final String IMG_SONAR_ALARM_ANY = "sonar-alarm-any.png";
public static final String IMG_SONAR_ALARM_OFF = "sonar-alarm-off.png";
public static final String IMG_PIR_ALARM_MULTI = "pir-alarm-multi.png";
public static final String IMG_PIR_ALARM_ANY = "pir-alarm-any.png";
public static final String IMG_PIR_ALARM_OFF = "pir-alarm-off.png";
public static final String IMG_MICROWAVE_ALARM_MULTI = "mw-alarm-multi.png";
public static final String IMG_MICROWAVE_ALARM_ANY = "mw-alarm-any.png";
public static final String IMG_MICROWAVE_ALARM_OFF = "mw-alarm-off.png";
public static final String IMG_LASER_ALARM_MULTI = "laser-alarm-multi.png";
public static final String IMG_LASER_ALARM_ANY = "laser-alarm-any.png";
public static final String IMG_LASER_ALARM_OFF = "laser-alarm-off.png";
public static final String IMG_LASER_CALIBRATE = "laser-calibrate.png";
public static final String IMG_SPEEDOMETER = "speedometer.png";
public static final String IMG_PAN = "pan.png";
public static final String IMG_READINGS_GET = "readings-get48x48.png";
public static final String IMG_SETTINGS_SET = "settings-set48x48.png";
public static final String IMG_SETTINGS_GET = "settings-get48x48.png";
public static final String IMG_SONAR = "sonar32x32.png";
public static final String IMG_PIR = "pir32x32.png";
public static final String IMG_LASER = "laser32x32.png";
public static final String IMG_MICROWAVE = "mw32x32.png";
public static final String IMG_SOUND_ON = "sound-on.png";
public static final String IMG_SOUND_OFF = "sound-off.png";
public static final String IMG_SYNC_ON = "sync-on.png";
public static final String IMG_SYNC_OFF = "sync-off.png";
public static final String IMG_UNIVERSAL_REMOTE_ON = "universal-remote-on.png";
public static final String IMG_UNIVERSAL_REMOTE_OFF = "universal-remote-off.png";
public static final String IMG_CORNER_RESIZE = "ugskin-resize11x11.png";
public static final String IMG_DB_SAVE = "db-save.png";
public static final String IMG_LOCK = "pad-lock.png";
public static final String IMG_UNLOCK = "pad-unlock.png";
private static final String RB_GUI = "LabelsBundle";
public static final AudioClip mediaPlayerConfirm = RS.audioClip("x_confirm.wav");
public static final AudioClip mediaPlayerDoorBell = RS.audioClip("x_doorbell.wav");
public static final AudioClip mediaPlayerCam = RS.audioClip("x_cam.wav");
public static final AudioClip mediaPlayerComplete = RS.audioClip("x_complete.wav");
public static final AudioClip mediaPlayerError = RS.audioClip("x_error.wav");
public static final AudioClip mediaPlayerBlip = RS.audioClip("x_blip.wav");
private static final Map<String, Image> IMGS = new HashMap<String, Image>();
private static final Pattern htmlBodyRegex = Pattern.compile("(.*)<body([^>]*)>(.*)</body>(.*)", Pattern.DOTALL);
/**
* Constructor
*/
private RS() {
}
/**
* Creates an {@linkplain ImageView} from a set of cached {@linkplain Image}
* s
*
* @param fileName
* the {@linkplain Image} file name
* @return the {@linkplain ImageView}
*/
public static ImageView imgView(final String fileName) {
return imgView(img(fileName), false);
}
/**
* Creates an {@linkplain ImageView} from a set of cached {@linkplain Image}
* s
*
* @param fileName
* the {@linkplain Image} file name
* @param requestedWidth
* {@linkplain Image#getRequestedWidth()}
* @param requestedHeight
* {@linkplain Image#getRequestedHeight()}
* @param preserveRatio
* {@linkplain Image#isPreserveRatio()}
* @param smooth
* {@linkplain Image#isSmooth()}
* @return the {@linkplain ImageView}
*/
public static ImageView imgView(final String fileName,
double requestedWidth, double requestedHeight,
boolean preserveRatio, boolean smooth) {
return imgView(img(fileName, requestedWidth, requestedHeight,
preserveRatio, smooth), smooth);
}
/**
* Creates an {@linkplain ImageView}
*
* @param image
* the {@linkplain Image}
* @param smooth
* {@linkplain Image#isSmooth()}
* @return the {@linkplain ImageView}
*/
public static ImageView imgView(final Image image, final boolean smooth) {
final ImageView node = new ImageView(image);
node.setSmooth(smooth);
node.setCache(true);
node.setCacheHint(CacheHint.SPEED);
return node;
}
/**
* Gets an {@linkplain Image} from a set of cached {@linkplain Image}s
*
* @param fileName
* the image file name
* @return the {@linkplain Image}
*/
public static Image img(final String fileName) {
return img(fileName, 0, 0, false, false);
}
/**
* Gets an {@linkplain Image} from a set of cached {@linkplain Image}s
*
* @param fileName
* the image file name
* @param requestedWidth
* {@linkplain Image#getRequestedWidth()}
* @param requestedHeight
* {@linkplain Image#getRequestedHeight()}
* @param preserveRatio
* {@linkplain Image#isPreserveRatio()}
* @param smooth
* {@linkplain Image#isSmooth()}
* @return the {@linkplain Image}
*/
public static Image img(final String fileName, double requestedWidth,
double requestedHeight, boolean preserveRatio, boolean smooth) {
final String key = fileName + requestedWidth + 'x' + requestedHeight;
if (IMGS.containsKey(key)) {
return IMGS.get(key);
} else {
final Image img = requestedWidth <= 0 || requestedHeight <= 0 ? new Image(
path(fileName)) : new Image(path(fileName), requestedWidth,
requestedHeight, preserveRatio, smooth);
IMGS.put(key, img);
return img;
}
}
/**
* Adds the application icon {@link Image}(s) to the specified {@link Stage}
*
* @param stage
* the {@link Stage}
*/
public static void img(final Stage stage) {
stage.getIcons().add(img(RS.IMG_LOGO_128));
}
/**
* Gets a resource stream
*
* @param fileName the resource file name
* @return the resource stream
*/
public static InputStream stream(final String fileName) {
return RS.class.getResourceAsStream(fileName);
}
/**
* Gets a resource path
*
* @param fileName the resource file name
* @return the resource path
*/
public static String path(final String fileName) {
return RS.class.getResource(fileName).toExternalForm();
}
/**
* Gets the content of an HTML {@linkplain String}
*
* @param html
* the HTML
* @return the HTML content
*/
public static String getHtmlBodyContent(final String html) {
String content = null;
try {
final Matcher matcher = htmlBodyRegex.matcher(html);
if (matcher.find() && matcher.groupCount() >= 3) {
content = matcher.group(3);
}
} catch (final Throwable t) {
log.debug("Unable to extract HTML conent for: " + html, t);
}
return content == null || content.isEmpty() ? html : content;
}
/**
* Creates an audio clip based on the file path
*
* @param fileName
* the file path with file name
* @return the audio clip
*/
public static AudioClip audioClip(final String fileName) {
try {
return new AudioClip(RS.class.getResource(fileName).toExternalForm());
} catch (final Throwable t) {
log.error("Unable to get audio clip for resource named: " + fileName);
}
return null;
}
/**
* Gets the image format name from a file
*
* @param f
* the file
* @return null if the format is not a known image format
*/
public static String imgFormatInFile(final File f) {
return imgFormatName(f);
}
/**
* Gets the image format name from an input stream
*
* @param is
* the input stream
* @return null if the format is not a known image format
*/
public static String imgFormatFromStream(final InputStream is) {
return imgFormatName(is);
}
/**
* Returns the format name of the image in the object
*
* @param o
* can be either a File or InputStream object
* @return null if the format is not a known image format
*/
private static String imgFormatName(final Object o) {
try {
// Create an image input stream on the image
final ImageInputStream iis = ImageIO.createImageInputStream(o);
// Find all image readers that recognize the image format
final Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
if (!iter.hasNext()) {
// No readers found
return null;
}
// Use the first reader
final ImageReader reader = iter.next();
// Close stream
iis.close();
// Return the format name
return reader.getFormatName();
} catch (final Exception e) {
}
// The image could not be read
return null;
}
/**
* <p>
* Ensures that the needed RXTX is loaded/installed. If RXTX cannot be
* detected an attempt will be made to load/install it.
* </p>
* <p>
* <code>Ubuntu {@linkplain https://launchpad.net/ubuntu/+search?text=rxtx},
* Debian {@linkplain http://packages.debian.org/lenny/librxtx-java}, and
* Fedora {@linkplain https://admin.fedoraproject.org/pkgdb/acls/name/rxtx?_csrf_token=f10460d886559c3a4e824f14b13302dff6cb1511}
* </code>
* all should have RXTX already installed from the distributions
* </p>
*
* @return true when RXTX was installed and the application needs to be
* restarted
*/
public static boolean initComm() {
log.info(String.format("Checking for RXTX native libs for JVM %1$s",
ManagementFactory.getRuntimeMXBean().getName()));
try {
getSerialPorts();
} catch (final NoClassDefFoundError e) {
// ClassNotFoundException
log.warn(String.format("RXTX not installed/loaded... attempting to install/load (from %1$s)",
e.getClass().getName()), e);
loadComm();
// return installComm();
} catch (final UnsatisfiedLinkError e) {
log.warn(String.format("RXTX not installed/loaded... attempting to install/load (from %1$s)",
e.getClass().getName()), e);
loadComm();
// return installComm();
}
return false;
}
/**
* {@link System#loadLibrary(String)} the native RXTX library.
*/
protected static void loadComm() {
try {
String rxtxFileName = rbLabel(KEY.RXTX_FILE_PREFIX);
String libName = null;
String suffix = "";
if (UGateUtil.isWindows()) {
libName = "rxtxSerial";
suffix = ".dll";
rxtxFileName += (".windows." + UGateUtil.getBitness() + suffix);
} else if (UGateUtil.isMac()) {
libName = "librxtxSerial";
suffix = ".jnilib";
rxtxFileName += (".mac." + UGateUtil.getBitness() + suffix);
} else if (UGateUtil.isLinux()) {
libName = "librxtxSerial";
suffix = ".so";
rxtxFileName += (".linux." + UGateUtil.getBitness() + suffix);
}
log.info(String
.format("Loading RXTX native libary %1$s for file %2$s", libName, rxtxFileName));
final Path commLibPath = Paths.get(RS.class.getProtectionDomain().getCodeSource().getLocation().getPath(),
rxtxFileName);
final Path tempLibPath = Files.createTempFile(libName, suffix);
try {
Files.copy(commLibPath, tempLibPath, StandardCopyOption.REPLACE_EXISTING);
System.load(tempLibPath.toAbsolutePath().toString());
System.loadLibrary(libName);
// test
getSerialPorts();
} finally {
try {
Files.deleteIfExists(tempLibPath);
} catch (final Throwable t) {
// ignore
}
}
} catch (final Throwable t) {
throw new IllegalStateException("Unable to dynamically load Serial COM support. " +
"RXTX needs to be installed in bundled JVM under the application's installation directory. " +
"See http://rxtx.qbang.org/wiki/index.php/Installation", t);
}
}
/**
* Installs RXTX to the working JVM
*
* @return true when the install was successful
*/
protected static boolean installComm() {
Path tempZip = null;
FileSystem fs = null;
FileSystem zipFs = null;
try {
if (!UGateUtil.isWindows() && !UGateUtil.isMac() && !UGateUtil.isLinux() && !UGateUtil.isSolaris()) {
throw new UnsupportedOperationException(
String.format("RXTX Install: %1$s is not a supported operating system",
UGateUtil.os()));
}
final String rxtxVersion = rbLabel(KEY.RXTX_VERSION);
final String rxtxFileName = rbLabel(KEY.RXTX_FILE_NAME);
final String jvmPath = System.getProperties().getProperty("java.home");
log.info(String.format("RXTX Install: Installing version %1$s from %2$s for JVM %3$s",
rxtxVersion, rxtxFileName, jvmPath));
// copy the ZIP to a temporary file and create a ZIP file system to install RXTX
final Path appPath = new File(applicationUri()).toPath();
Path rxtxFilePath;
if (Files.isDirectory(appPath)) {
fs = FileSystems.getDefault();
rxtxFilePath = fs.getPath(appPath.toAbsolutePath().toString(), rxtxFileName);
} else {
fs = FileSystems.newFileSystem(appPath, null);;
rxtxFilePath = fs.getPath(rxtxFileName);
}
tempZip = Files.createTempFile(null, ".zip");
Files.copy(rxtxFilePath, tempZip, StandardCopyOption.REPLACE_EXISTING);
zipFs = FileSystems.newFileSystem(tempZip.toAbsolutePath(), null);
final Path rxtxPath = zipFs.getPath("/");
// TODO : verify Mac x64/Linux x64 works using embedded files... see http://blog.iharder.net/2009/08/18/rxtx-java-6-and-librxtxserial-jnilib-on-intel-mac-os-x/
final String winArch32 = "Windows";
final String linuxArch32 = "Linux";
final String macArch32 = "Mac_OS_X";
final String winArch64 = "Windows-x64";
final String linuxArch64 = "Linux-x64";
final String macArch64 = "Mac_OS_X-x64";
// install files
Files.walkFileTree(rxtxPath, new java.nio.file.SimpleFileVisitor<Path>() {
/** {@inheritDoc} */
@Override
public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) {
try {
if ((UGateUtil.isWindows() && skipCommPath(dir, winArch32, winArch64)) ||
(UGateUtil.isMac() && skipCommPath(dir, macArch32, macArch64)) ||
(UGateUtil.isLinux() && skipCommPath(dir, linuxArch32, linuxArch64)) ||
(!UGateUtil.isSolaris() && dir.toAbsolutePath().toString().contains("Solaris"))) {
return FileVisitResult.SKIP_SUBTREE;
}
} catch (final Throwable t) {
log.error(String.format("RXTX Install: Error filtering RXTX directory %1$s", dir), t);
return FileVisitResult.TERMINATE;
}
log.debug(String.format("RXTX Install: Searching directory: %1$s", dir));
return FileVisitResult.CONTINUE;
}
/** {@inheritDoc} */
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) {
Path newPath = null;
try {
if (UGateUtil.isWindows()) {
if (file.getFileName().endsWith(RXTX_JAR_FILE_NAME)) {
// copy JAR to install path
newPath = Paths.get(jvmPath, "lib", "ext", file.getFileName().toString());
} else if (file.getFileName().endsWith(RXTX_DLL_PARALLEL_FILE_NAME)
|| file.getFileName().endsWith(RXTX_DLL_SERIAL_FILE_NAME)) {
// copy DLLs to the DLL directory
newPath = Paths.get(jvmPath, "bin", file.getFileName().toString());
}
} else if (UGateUtil.isMac()) {
if (file.getFileName().endsWith(RXTX_JAR_FILE_NAME)
|| file.getFileName().endsWith(RXTX_MAC_SERIAL_FILE_NAME)) {
// copy JAR/JNI LIB to java extensions
newPath = Paths.get("Library", "Java", "Extensions", file.getFileName().toString());
}
} else if (UGateUtil.isLinux()) {
if (file.getFileName().endsWith(RXTX_JAR_FILE_NAME)) {
// copy JAR to install path
newPath = Paths.get(jvmPath, "lib", "ext", file.getFileName().toString());
} else if ((file.getFileName().endsWith(RXTX_LINUX_PARALLEL_FILE_NAME) ||
file.getFileName().endsWith(RXTX_LINUX_SERIAL_FILE_NAME)) &&
UGateUtil.getBitness() == 32 && file.toAbsolutePath().toString().contains("i686")) {
newPath = Paths.get(jvmPath, "lib", "i386", file.getFileName().toString());
} else if (file.getFileName().endsWith(RXTX_LINUX_SERIAL_FILE_NAME) &&
UGateUtil.getBitness() == 64 && file.toAbsolutePath().toString().contains("ia64")) {
// TODO : should the 64 bit RXTX be in a different path other than i386 for Linux?
newPath = Paths.get(jvmPath, "lib", "i386", file.getFileName().toString());
}
}
if (newPath != null) {
final Path cpyToPath = newPath;
final Path cpyFromPath = file.toAbsolutePath();
new Thread(new Runnable() {
@Override
public void run() {
log.info(String.format("RXTX Install: Attempting to copy %1$s to %2$s", cpyFromPath, cpyToPath));
try {
Files.copy(cpyFromPath, cpyToPath, StandardCopyOption.REPLACE_EXISTING);
} catch (final Throwable t) {
log.error(String.format("RXTX Install: Attempting to copy %1$s to %2$s failed!", cpyFromPath, cpyToPath), t);
}
}
}).start();
}
} catch (final Throwable t) {
log.error(String.format("RXTX Install: Error installing the required file %1$s to %2$s", file, newPath), t);
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
}
});
Files.deleteIfExists(tempZip);
//restartApplication();
return true;
} catch (final Throwable t) {
throw new IllegalStateException("RXTX Install: Unable to install the required files needed for " +
"Serial/Parallel communications! To install manually goto " +
"http://rxtx.qbang.org/wiki/index.php/Installation", t);
} finally {
closeFileSystem(fs);
closeFileSystem(zipFs);
}
}
/**
* Determines if a {@linkplain Path} should be skipped for
* {@linkplain #installComm()}
*
* @param dir
* the {@linkplain Path}
* @param osArch32
* the OS 32-bit architecture folder name
* @param osArch64
* the OS 64-bit architecture folder name
* @return true to skip
*/
protected static boolean skipCommPath(final Path dir, final String osArch32, final String osArch64) {
final boolean is64 = !System.getProperties().getProperty("os.arch").equalsIgnoreCase("x86");
final String absp = dir.toAbsolutePath().toString();
return (is64 && absp.contains(osArch32 + '/')) ||
(!is64 && absp.contains(osArch64));
}
/**
* Restarts the application
*/
protected static void restartApplication(final String... args) {
// Sun property pointing the main class and its arguments.
// Might not be defined on non Hotspot VM implementations.
final String mcmd = System.getProperty("sun.java.command");
final StringBuilder cmd = new StringBuilder();
final String[] mainCommand = mcmd != null && !mcmd.isEmpty() ? mcmd.split(" ") : new String[] { rbLabel(KEY.MAIN_CLASS) };
log.info(String.format("Restarting application at entry point: %1$s", mainCommand[0]));
cmd.append('"');
cmd.append(Paths.get(System.getProperty("java.home"), "bin", "java").toAbsolutePath().toString());
cmd.append("\" ");
for (final String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
if (!jvmArg.contains("-agentlib")) {
cmd.append(jvmArg);
cmd.append(' ');
}
}
if (mainCommand[0].endsWith(".jar")) {
// if it's a jar, add -jar mainJar
cmd.append("-jar ");
cmd.append(new File(mainCommand[0]).getPath());
} else {
// else it's a .class, add the class path and mainClass
cmd.append("-cp \"").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append("\" ");
cmd.append(mainCommand[0]);
}
// finally add program arguments
for (int i = 1; i < mainCommand.length; i++) {
cmd.append(' ');
cmd.append(mainCommand[i]);
}
// execute the command in a shutdown hook, to be sure that all the
// resources have been disposed before restarting the application
// Runtime.getRuntime().addShutdownHook(new Thread() {
// @Override
// public void run() {
// }
// });
try {
//final ProcessBuilder processBuilder
Runtime.getRuntime().exec(cmd.toString());
} catch (final IOException e) {
log.error(String.format("Unable to restart the application at entry point: %1$s", cmd.toString()), e);
}
Platform.exit();
//System.exit(0);
}
/**
* Attempts to close a {@linkplain FileSystem}
*
* @param fs the {@linkplain FileSystem}
*/
private static void closeFileSystem(final FileSystem fs) {
if (fs != null && fs != FileSystems.getDefault()) {
try {
fs.close();
} catch (final Throwable t) {
}
}
}
/**
* This method is used to get a list of all the available Serial ports (note: only Serial ports are considered).
* Any one of the elements contained in the returned {@link List} can be used as a parameter in
* {@link #wirelessBtn(String)} or {@link #wirelessBtn(String, int)} to open a Serial connection.
*
* @return A {@link List} containing {@link String}s showing all available Serial ports.
*/
@SuppressWarnings("unchecked")
public static List<String> getSerialPorts() {
log.debug("Loading available COM ports");
Enumeration<CommPortIdentifier> portList;
List<String> ports = new ArrayList<String>();
portList = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId;
while (portList.hasMoreElements()) {
portId = portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
ports.add(portId.getName());
}
}
if (log.isDebugEnabled()) {
final StringBuilder sb = new StringBuilder("Found the following ports: ");
for (int i = 0; i < ports.size(); i++) {
sb.append(ports.get(i));
sb.append(' ');
}
log.error(sb.toString());
}
return ports;
}
/**
* @return the {@linkplain URI} that the application is running in
*/
public static URI applicationUri() {
try {
final URI appUri = RS.class.getProtectionDomain().getCodeSource().getLocation().toURI();
log.debug("Application URI: " + appUri);
return appUri;
} catch (final Throwable e) {
log.error("Unable to get application URI", e);
}
return null;
}
/**
* @return the {@linkplain FileSystems#getDefault()} when running within a directory or a
* new {@linkplain FileSystems#newFileSystem(Path, ClassLoader)} when running within an archive
*/
public static FileSystem applicationFileSystem() {
Path appPath = new File(applicationUri()).toPath();
try {
return Files.isDirectory(appPath) ? FileSystems.getDefault() : FileSystems.newFileSystem(appPath, null);
} catch (final IOException e) {
throw new RuntimeException(String.format("An %1$s occurred while trying to create a new %2$s",
e.getClass().getName(), FileSystem.class.getName()), e);
}
}
/**
* Gets the resource path
*
* @param validate
* true to validate that the resource exists
* @param resourceName
* the name of the resource to get a {@linkplain Path} to
* @param closeFileSystem
* true to close the {@linkplain FileSystem}
* @return the {@linkplain Path} to the resource
*/
public static Path resourcePath(final boolean validate, final String resourceName, final boolean closeFileSystem) {
try {
final Path resourcePath = Paths.get(RS.class.getResource(resourceName).toURI());
log.debug("Extracting application resource path: " + resourcePath);
return resourcePath;
} catch (final Throwable e) {
if (e instanceof FileSystemNotFoundException) {
// must be running from within a JAR- get the resource from within the archive
FileSystem fs = null;
try {
final Path appPath = new File(applicationUri()).toPath();
fs = FileSystems.newFileSystem(appPath, null);
final Path resourcePath = fs.getPath(RS.class.getPackage().getName().replace(".", fs.getSeparator()), resourceName);
if (resourcePath != null && validate && Files.notExists(resourcePath)) {
return null;
}
log.debug(String.format("Extracting application resource from ZIP path %1$s in %2$s", resourcePath.toAbsolutePath(),
appPath.toAbsolutePath()));
return resourcePath;
} catch (final Throwable e2) {
log.error("Unable to get application path (ZIP source)", e2);
} finally {
if (closeFileSystem) {
try {
fs.close();
} catch (final Exception e2) {
}
}
}
} else {
log.error("Unable to get application path", e);
}
}
return null;
}
/**
* Gets the working directory {@linkplain Path}. When a valid node index is specified a directory is created within
* the applications execution directory. When a valid file name is passed it will be appended to the path. When the
* node index and file name are null the path returned will be the path where the application is running.
*
* @param subDirectory the sub directory to append to the working directory
* @param fileName the name of the file (optional)
* @return the {@linkplain Path} to the remote nodes working directory (or the application path when
* the file name and node index are null)
*/
public static Path workingDirectoryPath(final Path subDirectory, final String fileName) {
Path workingPath = null;
try {
Path appPath = new File(applicationUri()).toPath();
if (Files.isDirectory(appPath)) {
workingPath = Files.createDirectories(appPath.toAbsolutePath());
} else {
// must be running from within a JAR- get the working directory excluding the file name of the archive
workingPath = appPath.getParent();
workingPath = workingPath == null ? appPath.subpath(0, 1).toAbsolutePath() :
workingPath.toAbsolutePath();
log.debug(String.format("Extracted working directory %1$s from application path %2$s", workingPath, appPath));
appPath = workingPath;
}
if (subDirectory != null) {
workingPath = workingPath.resolve(subDirectory);
log.debug(String.format("Creating working directory %1$s in %2$s", workingPath, appPath));
workingPath = Files.createDirectories(workingPath);
}
if (fileName != null && !fileName.isEmpty()) {
workingPath = workingPath.resolve(fileName);
}
return workingPath;
} catch (final Throwable t) {
throw new RuntimeException(String.format(
"Unable to initialize the working directory path. " +
"%1$s (with optional sub directory: %2$s) must be an accessible/writable directory (optional file name: %3$s)",
workingPath, subDirectory, fileName), t);
}
}
/**
* Gets the first available locale and the label resource bundles value for
* the specified key
*
* @param key
* the {@linkplain KEY} of the resource bundle value
* @param formatArguments
* the {@linkplain String#format(Locale, String, Object...)}
* arguments
* @return the resource bundle value
*/
public static String rbLabel(final KEY key, final Object... formatArguments) {
return rbLabel(Locale.getAvailableLocales()[0], key, formatArguments);
}
/**
* Gets the first available locale and the label resource bundles value for
* the specified key and generates a {@link URI} from it
*
* @param key
* the {@linkplain KEY} of the resource bundle value
* @param formatArguments
* the {@linkplain String#format(Locale, String, Object...)}
* arguments
* @return the {@link URI}
*/
public static URI rbURI(final KEY key, final Object... formatArguments) {
try {
return new URI(rbLabel(Locale.getAvailableLocales()[0], key, formatArguments));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Gets the a label resource bundles value for the specified key
*
* @param locale
* the locale of the resource bundle
* @param key
* the {@linkplain KEY} of the resource bundle value
* @param formatArguments
* the {@linkplain String#format(Locale, String, Object...)}
* arguments
* @return the resource bundle value
*/
public static String rbLabel(final Locale locale, final KEY key, final Object... formatArguments) {
return rbValue(RB_GUI, locale, key, formatArguments);
}
/**
* Gets the a resource bundles value for the specified key
*
* @param rb
* the resource bundle name
* @param locale
* the locale of the resource bundle
* @param key
* the {@linkplain KEY} of the resource bundle value
* @param formatArguments
* the {@linkplain String#format(Locale, String, Object...)}
* arguments
* @return the resource bundle value
*/
private static String rbValue(final String rb, final Locale locale, final KEY key, final Object... formatArguments) {
final String rbStr = ResourceBundle.getBundle(rb, locale).getString(key.getKey());
return formatArguments != null && formatArguments.length > 0 ? String.format(locale, rbStr, formatArguments) : rbStr;
}
/**
* {@linkplain RS} bundle keys
*/
public enum KEY {
MAIN_CLASS("main.class"),
RXTX_VERSION("rxtx.version"),
RXTX_FILE_PREFIX("rxtx.file.prefix"),
RXTX_FILE_NAME("rxtx.file.name"),
APP_ID("app.id"),
APP_VERSION("app.version"),
APP_LOGGER_NAME("app.logger.name"),
APP_LOGGER_LEVEL("app.logger.level"),
APP_DESC("app.desc"),
APP_TITLE("app.title"),
APP_TITLE_USER("app.title.user", 1),
APP_TITLE_ACTION_REQUIRED("app.title.action.required"),
APP_TITLE_ERROR("app.title.error"),
APP_FOOTER_UPDATES_INDICATOR("app.footer.updates.inidcator"),
APP_SERVICE_COM_RESTART_REQUIRED("app.service.com.restart.required"),
APP_SERVICE_INIT_ERROR("app.service.init.error"),
APP_GATE_KEEPER_ERROR("app.gatekeeper.init.error"),
APP_CONNECTION_DESC("app.connection.desc"),
APP_CONTROLS_DESC("app.controls.desc"),
APP_CAPTURE_DESC("app.capture.desc"),
APP_WEB_TOOL_DESC("app.web.tool.desc"),
APP_DIALOG_SETUP("app.dialog.setup"),
APP_DIALOG_SETUP_LINK("app.dialog.setup.link"),
APP_DIALOG_SETUP_ERROR("app.dialog.setup.error", 1),
APP_DIALOG_SETUP_ERROR_PWD_MISMATCH(
"app.dialog.setup.error.password.mismatch"),
APP_DIALOG_AUTH("app.dialog.auth"),
APP_DIALOG_AUTH_ERROR("app.dialog.auth.error", 1),
APP_DIALOG_USERNAME("app.dialog.username"),
APP_DIALOG_PWD("app.dialog.password"),
APP_DIALOG_PWD_VERIFY("app.dialog.password.verify"),
APP_DIALOG_PASS_PHRASE("app.dialog.passphrase"),
APP_DIALOG_REQUIRED("app.dialog.required", 1),
APP_DIALOG_DEFAULT_USER("app.dialog.defaultuser"),
APP_SERVICE_STARTUP_DESC("app.service.startup.desc"),
APP_SERVICE_HOST_STARTUP_DESC("app.service.host.startup.desc"),
APP_SERVICE_STARTUP_AUTO("app.service.startup.auto"),
APP_SERVICE_STARTUP_MANUAL("app.service.startup.manual"),
APP_HELP_DEFAULT("help.text.default"),
APP_WIN_SYSTRAY_MIN_INFO("win.systray.minimize.info"),
APP_WIN_SYSTRAY("win.systray.tooltip"),
LOADING("loading"),
LOGIN("login"),
LOGOUT("logout"),
SELECT("select"),
TODAY("today"),
RELOAD("reload"),
OPEN("open"),
CLOSE("close"),
ALL("all"),
ALL_OFF("all.off"),
ON("on"),
OFF("off"),
UPDATE("update"),
SUBMIT("submit"),
ERROR("error"),
INVALID("invalid", 1),
FEET("feet"),
INCHES("inches"),
METERS("meters"),
SENDING("sending"),
ALARM_SETTINGS("alarm.settings"),
ALARM_THRESHOLDS("alarm.thres"),
ALARM_POSITIONING("alarm.positioning"),
ALARM_NOTIFICATION("alarm.notify"),
SONAR("sonar"),
SONAR_PIR_POSITIONING("sonar.pir.pos"),
PIR("pir"),
MW("mw"),
MW_POSITIONING("mw.pos"),
LASER("laser"),
CAM("cam"),
CAM_POSITIONING("cam.pos"),
CAM_PAN(RemoteNodeType.CAM_ANGLE_PAN.getKey()),
CAM_PAN_DESC(RemoteNodeType.CAM_ANGLE_PAN.getKey() + ".desc"),
CAM_TILT(RemoteNodeType.CAM_ANGLE_TILT.getKey()),
CAM_TILT_DESC(RemoteNodeType.CAM_ANGLE_TILT.getKey() + ".desc"),
CAM_RES(RemoteNodeType.CAM_RESOLUTION.getKey()),
CAM_RES_DESC(RemoteNodeType.CAM_RESOLUTION.getKey() + ".desc"),
CAM_RES_VGA(RemoteNodeType.CAM_RESOLUTION.getKey() + ".vga"),
CAM_RES_QVGA(RemoteNodeType.CAM_RESOLUTION.getKey() + ".qvga"),
CAM_TRIP_ANGLE_PRIORITY_DESC("cam.trip.angle.priority.desc", 1),
CAM_SONAR_TRIP_ANGLE_PRIORITY(
RemoteNodeType.CAM_SONAR_TRIP_ANGLE_PRIORITY.getKey()),
CAM_PIR_TRIP_ANGLE_PRIORITY(RemoteNodeType.CAM_PIR_TRIP_ANGLE_PRIORITY
.getKey()),
CAM_MW_TRIP_ANGLE_PRIORITY(RemoteNodeType.CAM_MW_TRIP_ANGLE_PRIORITY
.getKey()),
CAM_LASER_TRIP_ANGLE_PRIORITY(
RemoteNodeType.CAM_LASER_TRIP_ANGLE_PRIORITY.getKey()),
CAM_PAN_SONAR(RemoteNodeType.CAM_SONAR_TRIP_ANGLE_PAN.getKey()),
CAM_TILT_SONAR(RemoteNodeType.CAM_SONAR_TRIP_ANGLE_TILT.getKey()),
CAM_PAN_SONAR_DESC(RemoteNodeType.CAM_SONAR_TRIP_ANGLE_PAN.getKey()
+ ".desc"),
CAM_TILT_SONAR_DESC(RemoteNodeType.CAM_SONAR_TRIP_ANGLE_TILT.getKey()
+ ".desc"),
CAM_PAN_PIR(RemoteNodeType.CAM_PIR_TRIP_ANGLE_PAN.getKey()),
CAM_TILT_PIR(RemoteNodeType.CAM_PIR_TRIP_ANGLE_TILT.getKey()),
CAM_PAN_PIR_DESC(RemoteNodeType.CAM_PIR_TRIP_ANGLE_PAN.getKey()
+ ".desc"),
CAM_TILT_PIR_DESC(RemoteNodeType.CAM_PIR_TRIP_ANGLE_TILT.getKey()
+ ".desc"),
CAM_PAN_MW(RemoteNodeType.CAM_MW_TRIP_ANGLE_PAN.getKey()),
CAM_TILT_MW(RemoteNodeType.CAM_MW_TRIP_ANGLE_TILT.getKey()),
CAM_PAN_MW_DESC(RemoteNodeType.CAM_MW_TRIP_ANGLE_PAN.getKey() + ".desc"),
CAM_TILT_MW_DESC(RemoteNodeType.CAM_MW_TRIP_ANGLE_TILT.getKey()
+ ".desc"),
CAM_PAN_LASER(RemoteNodeType.CAM_LASER_TRIP_ANGLE_PAN.getKey()),
CAM_TILT_LASER(RemoteNodeType.CAM_LASER_TRIP_ANGLE_TILT.getKey()),
CAM_PAN_LASER_DESC(RemoteNodeType.CAM_LASER_TRIP_ANGLE_PAN.getKey()
+ ".desc"),
CAM_TILT_LASER_DESC(RemoteNodeType.CAM_LASER_TRIP_ANGLE_TILT.getKey()
+ ".desc"),
CAM_ACTION_QVGA("cam.take.qvga"),
CAM_ACTION_VGA("cam.take.vga"),
USER_SAVE_FAILED("user.save.failed", 1),
SETTINGS_SAVE("settings.save"),
SETTINGS_SAVE_FAILED("settings.save.failed", 1),
SETTINGS_SEND("settings.send"),
SETTINGS_RECEIVE("settings.receive"),
SETTINGS_SEND_FAILED("settings.send.failed", 1),
SENSOR_READINGS_GET("sensors.readings.get"),
SENSOR_READINGS_GET_DESC("sensors.readings.get.desc"),
SENSOR_TRIP_MULTI("sensors.trip.multi"),
SENSOR_TRIP_MULTI_BINARY(RemoteNodeType.MULTI_ALARM_TRIP_STATE.getKey()),
SENSOR_TRIP_MULTI_DESC(RemoteNodeType.MULTI_ALARM_TRIP_STATE.getKey()
+ ".desc"),
SENSOR_READINGS("sensors.readings"),
SENSOR_LAST_READING("sensors.readings.last"),
SENSOR_READINGS_FAILED("sensors.readings.failed", 1),
GATE_CONFIG("gate.conf"),
GATE_ACCESS(RemoteNodeType.GATE_ACCESS_ON.getKey()),
GATE_ACCESS_DESC(RemoteNodeType.GATE_ACCESS_ON.getKey() + ".desc"),
GATE_TOGGLE("gate.toggle"),
GATE_TOGGLE_FAILED("gate.toggle.failed"),
GATE_TOGGLE_DESC("gate.toggle.desc"),
LABEL_GRAPH_DESC("app.graph.desc"),
LABEL_GRAPH_AXIS_X("graph.axis.x"),
LABEL_DISPLAYSHELF_FULLSIZE_DESC("displayshelf.fullsize.tooltip"),
LABEL_TOGGLE_SWITCH_ON("toggleswitch.on"),
LABEL_TOGGLE_SWITCH_OFF("toggleswitch.off"),
SERVICE_TX_RESPONSE_INVALID("service.tx.response.unrecognized", 2),
SERVICE_TX_RESPONSE_SUCCESS("service.tx.response.success", 2),
SERVICE_TX_RESPONSE_ERROR("service.tx.response.error", 2),
SERVICE_RX_READINGS("service.rx.readings", 1),
SERVICE_RX_SETTINGS("service.rx.settings", 1),
SERVICE_RX_KEYCODES("service.rx.keycodes", 1),
SERVICE_RX_IMAGE_MULTPART("service.rx.image.multipart", 1),
SERVICE_RX_IMAGE_SUCCESS("service.rx.image.success", 1),
SERVICE_RX_IMAGE_LOST_PACKETS("service.rx.image.lostpackets"),
SERVICE_RX_IMAGE_LOST_PACKETS_RETRY(
"service.rx.image.lostpackets.retry", 3),
SERVICE_RX_IMAGE_TIMEOUT("service.rx.image.timeout", 2),
SERVICE_CMD_SOUNDS(RemoteNodeType.DEVICE_SOUNDS_ON.getKey()),
SERVICE_CMD_SOUNDS_TOGGLE(RemoteNodeType.DEVICE_SOUNDS_ON.getKey()
+ ".desc"),
SERVICE_CMD_FAILED("service.command.failed"),
SERVICE_WIRELESS_SEND_ADDY_UNDEFINED("service.wireless.source.undefined"),
SERVICE_WIRELESS_CONNECTION_REQUIRED(
"service.wireless.connection.required"),
SERVICE_WIRELESS_FAILED("service.wireless.failed"),
SERVICE_WIRELESS_WEB_FAILED("service.wireless.web.failed"),
SERVICE_WIRELESS_ACK_SUCCESS("service.wireless.ack.success", 3),
SERVICE_WIRELESS_ACK_FAILED("service.wireless.ack.failed", 3),
SERVICE_WIRELESS_SENDING("service.wireless.sending", 2),
SERVICE_WIRELESS_TX_TIMEOUT("service.wireless.tx.timeout", 1),
SERVICE_WIRELESS_TX_FAILED("service.wireless.tx.failed", 1),
SERVICE_WIRELESS_SETTINGS_FAILED("service.wireless.settings.failed", 1),
SERVICE_EMAIL_FAILED("service.email.failed"),
SERVICE_EMAIL_CMD_EXEC("service.email.commandexec", 3),
SERVICE_EMAIL_CMD_EXEC_FAILED("service.email.commandexec.failed", 4),
LABEL_GRAPH_AXIS_Y("graph.axis.y"),
LABEL_GRAPH_SERIES_ALARM_LASER("graph.series.alarm.laser"),
LABEL_GRAPH_SERIES_ALARM_SONAR("graph.series.alarm.sonar"),
LABEL_GRAPH_SERIES_ALARM_MICROWAVE("graph.series.alarm.microwave"),
LABEL_GRAPH_SERIES_ALARM_PIR("graph.series.alarm.pir"),
LABEL_GRAPH_SERIES_ACTIVITY_READS("graph.series.activity.reads"),
MAIL_CONNECT_FAILED("mail.connect.failed", 1),
MAIL_CONNECT("mail.connect"),
MAIL_CONNECT_DESC("mail.connect.desc"),
MAIL_CONNECTED("mail.connected", 1),
MAIL_CONNECTING("mail.connecting"),
MAIL_DISCONNECTING("mail.disconnecting"),
MAIL_DISCONNECTED("mail.disconnected", 1),
MAIL_CLOSED("mail.closed", 1),
MAIL_AUTH_FAILED("mail.auth.failed", 1),
MAIL_SMTP_HOST("mail.smtp.host"),
MAIL_SMTP_HOST_DESC("mail.smtp.host.desc"),
MAIL_SMTP_PORT("mail.smtp.port"),
MAIL_SMTP_PORT_DESC("mail.smtp.port.desc"),
MAIL_IMAP_HOST("mail.imap.host"),
MAIL_IMAP_HOST_DESC("mail.imap.host.desc"),
MAIL_IMAP_PORT("mail.imap.port"),
MAIL_IMAP_PORT_DESC("mail.imap.port.desc"),
MAIL_USERNAME("mail.username"),
MAIL_USERNAME_DESC("mail.username.desc"),
MAIL_PASSWORD("mail.password"),
MAIL_PASSWORD_DESC("mail.password.desc"),
MAIL_FOLDER_NAME("mail.folder"),
MAIL_FOLDER_DESC("mail.folder.desc"),
MAIL_USE_SSL_ON("mail.ssl.on"),
MAIL_USE_SSL_OFF("mail.ssl.off"),
MAIL_USE_SSL_DESC("mail.ssl.desc"),
MAIL_USE_TLS_ON("mail.tls.on"),
MAIL_USE_TLS_OFF("mail.tls.off"),
MAIL_USE_TLS_DESC("mail.tls.desc"),
SONAR_THRESHOLD("sonar.threshold", 1),
SONAR_THRESHOLD_DESC("sonar.threshold.desc", 1),
SONAR_FEET(RemoteNodeReadingType.SONAR_FEET.getKey()),
SONAR_INCHES(RemoteNodeReadingType.SONAR_INCHES.getKey()),
SONAR_THRESHOLD_FEET(RemoteNodeType.SONAR_DISTANCE_THRES_FEET.getKey()),
SONAR_THRESHOLD_INCHES(RemoteNodeType.SONAR_DISTANCE_THRES_INCHES
.getKey()),
SONAR_PIR_PAN(RemoteNodeType.SONAR_PIR_ANGLE_PAN.getKey()),
SONAR_PIR_PAN_DESC(RemoteNodeType.SONAR_PIR_ANGLE_PAN.getKey()
+ ".desc"),
SONAR_PIR_TILT(RemoteNodeType.SONAR_PIR_ANGLE_TILT.getKey()),
SONAR_PIR_TILT_DESC(RemoteNodeType.SONAR_PIR_ANGLE_TILT.getKey()
+ ".desc"),
SONAR_ALARM_DELAY(RemoteNodeType.SONAR_DELAY_BTWN_TRIPS.getKey()),
SONAR_ALARM_DELAY_DESC(RemoteNodeType.SONAR_DELAY_BTWN_TRIPS.getKey()
+ ".desc"),
PIR_INTENSITY(RemoteNodeReadingType.PIR_INTENSITY.getKey()),
PIR_ALARM_DELAY(RemoteNodeType.PIR_DELAY_BTWN_TRIPS.getKey()),
PIR_ALARM_DELAY_DESC(RemoteNodeType.PIR_DELAY_BTWN_TRIPS.getKey()
+ ".desc"),
MW_CYCLE_COUNT(RemoteNodeReadingType.MICROWAVE_CYCLE_COUNT.getKey()),
MW_THRESHOLD(RemoteNodeType.MW_SPEED_THRES_CYCLES_PER_SEC.getKey()),
MW_THRESHOLD_DESC(RemoteNodeType.MW_SPEED_THRES_CYCLES_PER_SEC.getKey()
+ ".desc"),
MW_ALARM_DELAY(RemoteNodeType.MW_DELAY_BTWN_TRIPS.getKey()),
MW_ALARM_DELAY_DESC(RemoteNodeType.MW_DELAY_BTWN_TRIPS.getKey()
+ ".desc"),
MW_PAN(RemoteNodeType.MW_ANGLE_PAN.getKey()),
MW_PAN_DESC(RemoteNodeType.MW_ANGLE_PAN.getKey() + ".desc"),
LASER_THRESHOLD("laser.threshold", 1),
LASER_THRESHOLD_DESC("laser.threshold.desc", 1),
LASER_CALIBRATED_ANGLE_PAN(
RemoteNodeReadingType.LASER_CALIBRATED_ANGLE_PAN.getKey()),
LASER_CALIBRATED_ANGLE_TILT(
RemoteNodeReadingType.LASER_CALIBRATED_ANGLE_TILT.getKey()),
LASER_FEET(RemoteNodeReadingType.LASER_FEET.getKey()),
LASER_INCHES(RemoteNodeReadingType.LASER_INCHES.getKey()),
LASER_THRESHOLD_FEET(RemoteNodeType.LASER_DISTANCE_THRES_FEET.getKey()),
LASER_THRESHOLD_INCHES(RemoteNodeType.LASER_DISTANCE_THRES_INCHES
.getKey()),
LASER_ALARM_DELAY(RemoteNodeType.LASER_DELAY_BTWN_TRIPS.getKey()),
LASER_ALARM_DELAY_DESC(RemoteNodeType.LASER_DELAY_BTWN_TRIPS.getKey()
+ ".desc"),
LASER_CALIBRATION("laser.calibration"),
LASER_CALIBRATION_DESC("laser.calibration.desc"),
LASER_CALIBRATION_SUCCESS("laser.calibration.success"),
LASER_CALIBRATION_FAILED("laser.calibration.failed"),
GATE_STATE(RemoteNodeReadingType.GATE_STATE.getKey()),
FROM_MULTI_ALARM_TRIP_STATE(
RemoteNodeReadingType.FROM_MULTI_ALARM_TRIP_STATE.getKey()),
SIGNAL_STRENGTH(RemoteNodeReadingType.SIGNAL_STRENGTH.getKey()),
READ_DATE(RemoteNodeReadingType.READ_DATE.getKey()),
WIRELESS_WEB_START_STOP("wireless.web.startstop"),
WIRELESS_WEB_START_STOP_DESC("wireless.web.startstop.desc"),
WIRELESS_WEB_COMMANDS("wireless.web.commands"),
WIRELESS_WEB_COMMAND_EXECUTE("wireless.web.command.execute", 1),
WIRELESS_NODE_CONNECT("wireless.node.connect", 1),
WIRELESS_NODE_CONNECT_FAILED("wireless.node.connect.failed", 1),
WIRELESS_NODE_REMOTE_NODE("wireless.node.remote.node", 1),
WIRELESS_NODE_REMOTE_ADDY("wireless.node.remote"),
WIRELESS_NODE_REMOTE_ADDY_DESC("wireless.node.remote.desc"),
WIRELESS_NODE_REMOTE_PROMPT("wireless.node.remote.prompt"),
WIRELESS_NODE_REMOTE_STATUS("wireless.node.remote.status", 2),
WIRELESS_NODE_REMOTE_CHANGING("wireless.node.remote.changing", 2),
WIRELESS_NODE_REMOTE_REMOVE("wireless.node.remote.remove"),
WIRELESS_NODE_REMOTE_REMOVE_DESC("wireless.node.remote.remove.desc"),
WIRELESS_NODE_REMOVE_FAILED("wireless.node.remote.remove.failed", 1),
WIRELESS_NODE_REMOTE_ADD("wireless.node.remote.add", 1),
WIRELESS_NODE_REMOTE_ADD_DESC("wireless.node.remote.add.desc"),
WIRELESS_NODE_ADD_FAILED("wireless.node.remote.add.failed", 1),
WIRELESS_NODE_REMOTE_SELECT_FAILED(
"wireless.node.remote.select.failed", 1),
WIRELESS_NODE_REMOTE_SAVED_LOCAL("wireless.node.remote.local.saved", 1),
WIRELESS_REMOTE_SYNC(RemoteNodeType.DEVICE_AUTO_SYNCHRONIZE.getKey()),
WIRELESS_REMOTE_SYNC_DESC(RemoteNodeType.DEVICE_AUTO_SYNCHRONIZE
.getKey() + ".desc"),
WIRELESS_REMOTE_SYNCD("wireless.node.remote.syncd", 1),
WIRELESS_REMOTE_OUT_OF_SYNC("wireless.node.remote.outofsync", 1),
WIRELESS_REMOTE_READINGS_TIME("wireless.node.remote.readings.time"),
WIRELESS_REMOTE_READINGS_SENSOR("wireless.node.remote.readings.sensor"),
WIRELESS_REMOTE_READINGS_REPORT("wireless.node.remote.readings.report"),
WIRELESS_REMOTE_UNIVERSAL("universal.remote"),
WIRELESS_REMOTE_UNIVERSAL_TOGGLE(
RemoteNodeType.UNIVERSAL_REMOTE_ACCESS_ON.getKey()),
WIRELESS_REMOTE_UNIVERSAL_DESC(
RemoteNodeType.UNIVERSAL_REMOTE_ACCESS_ON.getKey() + ".desc"),
WIRELESS_PORT("wireless.port"),
WIRELESS_PORT_DESC("wireless.port.desc"),
WIRELESS_SPEED("wireless.speed"),
WIRELESS_SPEED_DESC("wireless.speed.desc"),
WIRELESS_ACCESS_KEY("wireless.access.key", 1),
WIRELESS_ACCESS_KEY_DESC("wireless.access.key.desc", 1),
WIRELESS_HOST_ADDY("wireless.host"),
WIRELESS_HOST_ADDY_DESC("wireless.host.desc"),
WIRELESS_CONNECT("wireless.connect"),
WIRELESS_CONNECT_DESC("wireless.connect.desc"),
WIRELESS_CONNECTING("wireless.connecting"),
WIRELESS_RECONNECT("wireless.reconnect"),
WIRELESS_DISCONNECTING("wireless.disconnecting"),
WIRELESS_SYNC("wireless.synchronizing"),
WIRELESS_WORKING_DIR("wireless.workingdir"),
WIRELESS_WORKING_DIR_DESC("wireless.workingdir.desc"),
WEB_HOST("wireless.web.host"),
WEB_HOST_DESC("wireless.web.host.desc"),
WEB_PORT("wireless.web.port"),
WEB_PORT_DESC("wireless.web.port.desc"),
WEB_HOST_LOCAL("wireless.web.host.local"),
WEB_HOST_LOCAL_DESC("wireless.web.host.local.desc"),
WEB_PORT_LOCAL("wireless.web.port.local"),
WEB_PORT_LOCAL_DESC("wireless.web.port.local.desc"),
MAIL_ALARM_NOTIFY(RemoteNodeType.MAIL_ALERT_ON.getKey()),
MAIL_ALARM_NOTIFY_DESC(RemoteNodeType.MAIL_ALERT_ON.getKey() + ".desc"),
MAIL_ALARM_NOFITY_SUBJECT("mail.alarm.notify.subject", 1),
MAIL_ALARM_NOFITY_BODY("mail.alarm.notify.body", 2),
MAIL_ALARM_NOFITY_EMAILS("mail.alarm.notify.emails"),
MAIL_ALARM_NOTIFY_EMAILS_DESC("mail.alarm.notify.emails.desc"),
MAIL_ALARM_NOTIFY_EMAILS_REMOVE("mail.alarm.notify.emails.remove"),
MAIL_ALARM_NOTIFY_EMAILS_ADD("mail.alarm.notify.emails.add"),
MAIL_ALARM_NOTIFY_EMAILS_ADD_DESC("mail.alarm.notify.emails.add.desc"),
MAIL_ALARM_NOTIFY_EMAILS_ADD_FAILED(
"mail.alarm.notify.emails.add.failed"),
MAIL_ALARM_NOTIFY_EMAILS_REMOVE_FAILED(
"mail.alarm.notify.emails.remove.failed");
private final String key;
private final int numberOfArguments;
/**
* Constructor
*
* @param key
* the key to the {@linkplain RS}
*/
private KEY(final String key) {
this.key = key;
this.numberOfArguments = 0;
}
/**
* Constructor
*
* @param key
* the key to the {@linkplain RS}
* @param numberOfArguments
* the {@link #getNumberOfArguments()}
*/
private KEY(final String key, final int numberOfArguments) {
this.key = key;
this.numberOfArguments = numberOfArguments >= 0 ? numberOfArguments
: 0;
}
/**
* Gets a {@link KEY} based upon a {@link #getKey()}
*
* @param key
* the {@link #getKey()}
* @return the {@link KEY}
*/
public static KEY keyValueOf(final String key) {
if (key != null && !key.isEmpty()) {
for (final KEY ke : values()) {
if (key.equals(ke.getKey())) {
return ke;
}
}
}
return null;
}
/**
* @return the key to the {@linkplain RS}
*/
public String getKey() {
return key;
}
/**
* @return the number of arguments that the {@link KEY} expects
*/
public int getNumberOfArguments() {
return numberOfArguments;
}
}
}