/** * Copyright (c) 2010-2016 by the respective copyright holders. * * 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.openhab.binding.zwave.internal.protocol.initialization; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import org.openhab.binding.zwave.internal.protocol.ZWaveDeviceClass; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMeterCommandClass.MeterScale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.StaxDriver; /** * ZWaveNodeSerializer class. Serializes nodes to XML and back again. * * @author Jan-Willem Spuij * @since 1.4.0 */ public class ZWaveNodeSerializer { private static final Logger logger = LoggerFactory.getLogger(ZWaveNodeSerializer.class); private final XStream stream = new XStream(new StaxDriver()); private String folderName = "etc/zwave"; /** * Constructor. Creates a new instance of the {@link ZWaveNodeSerializer} * class. */ public ZWaveNodeSerializer() { logger.trace("Initializing ZWaveNodeSerializer."); // Change the folder for OH2 // ConfigConstants.getUserDataFolder(); final String USERDATA_DIR_PROG_ARGUMENT = "smarthome.userdata"; final String eshUserDataFolder = System.getProperty(USERDATA_DIR_PROG_ARGUMENT); if (eshUserDataFolder != null) { folderName = eshUserDataFolder + "/zwave"; } final File folder = new File(folderName); // create path for serialization. if (!folder.exists()) { logger.debug("Creating directory {}", folderName); folder.mkdirs(); } stream.processAnnotations(ZWaveNode.class); stream.processAnnotations(ZWaveEndpoint.class); stream.processAnnotations(ZWaveDeviceClass.class); stream.processAnnotations(ZWaveCommandClass.class); stream.processAnnotations(CommandClass.class); for (CommandClass commandClass : CommandClass.values()) { Class<? extends ZWaveCommandClass> cc = commandClass.getCommandClassClass(); if (cc == null) { continue; } stream.processAnnotations(cc); for (Class<?> inner : cc.getDeclaredClasses()) { stream.processAnnotations(inner); } } stream.processAnnotations(MeterScale.class); logger.trace("Initialized ZWaveNodeSerializer."); } /** * Serializes an XML tree of a {@link ZWaveNode} * * @param node * the node to serialize */ public void SerializeNode(ZWaveNode node) { synchronized (stream) { // Don't serialise if the stage is not at least finished static // If we do serialise when we haven't completed the static stages // then when the binding starts it will have incomplete information! if (node.getNodeInitializationStage().isStaticComplete() == false) { logger.debug("NODE {}: Serialise aborted as static stages not complete", node.getNodeId()); return; } File file = new File(this.folderName, String.format("node%d.xml", node.getNodeId())); BufferedWriter writer = null; logger.debug("NODE {}: Serializing to file {}", node.getNodeId(), file.getPath()); try { writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); stream.marshal(node, new PrettyPrintWriter(writer)); writer.flush(); } catch (IOException e) { logger.error("NODE {}: Error serializing to file: {}", node.getNodeId(), e.getMessage()); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { } } } } } /** * Deserializes an XML tree of a {@link ZWaveNode} * * @param nodeId * the number of the node to deserialize * @return returns the Node or null in case Serialization failed. */ public ZWaveNode DeserializeNode(int nodeId) { synchronized (stream) { File file = new File(this.folderName, String.format("node%d.xml", nodeId)); BufferedReader reader = null; logger.debug("NODE {}: Serializing from file {}", nodeId, file.getPath()); if (!file.exists()) { logger.debug("NODE {}: Error serializing from file: file does not exist.", nodeId); return null; } try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); return (ZWaveNode) stream.fromXML(reader); } catch (IOException e) { logger.error("NODE {}: Error serializing from file: {}", nodeId, e.getMessage()); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { } } } return null; } } /** * Deletes the persistence store for the specified node. * * @param nodeId The node ID to remove * @return true if the file was deleted */ public boolean DeleteNode(int nodeId) { synchronized (stream) { File file = new File(this.folderName, String.format("node%d.xml", nodeId)); return file.delete(); } } }