Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 49 additions & 142 deletions src/main/java/services/MeasurementValueReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,8 @@
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import javax.xml.parsers.*;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
Expand All @@ -29,61 +17,45 @@
import java.util.Date;


/**
* Die Klasse dient als Schnittstelle zur Datenhaltung der Messwerte.
* Je nach konfiguriertem Protokoll wird die entsprechende Methode aufgerufen.
*
* Created by Nett on 04.06.2017.
*/
public class MeasurementValueReader {


/**
* Dient als Weiche um die, gemaess Prokoll des Devices, passende Methode aufzurufen.
*
* @param deviceName
* @return
* @throws ReadWriteException
*/
public static MeasurementValueXml getActualValue(String deviceName)throws ReadWriteException{

String protocol = DeviceMapperJson.getMeasurementValueProtocol(deviceName);
switch (protocol){

case "xml-1":
return getActualValueFromXml(deviceName);
case "txt-1":
return getActualValueFromTxt(deviceName);
case "xml-2":
return getActualValueFromXmlSax(deviceName);
default:
throw new ReadWriteException("Not possible to read protocol-type: " + protocol);
public static MeasurementValueXml getActualValue(String deviceName) {

try {
String protocol = DeviceMapperJson.getMeasurementValueProtocol(deviceName);

assert protocol != null;
switch (protocol){

case "xml-1":
return getActualValueFromXml(deviceName);
case "txt-1":
return getActualValueFromTxt(deviceName);
case "xml-2":
return getActualValueFromXmlSax(deviceName);
default:
throw new ReadWriteException("Not possible to read protocol-type: " + protocol);
}

}catch (ParserConfigurationException | IOException | SAXException e) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die exceptions sollten so lokal, d.h. so nahe am Erzeuger wie möglich, catched werden. das war vor deinen changes eher der fall ... :)
weil: Jetzt hast du in einer abstrakten Methode getActualValue sehr technische Exceptions-Catches drin, die stark von der Implementierung der einzelnen Protokolle abhängig sind. Das ist nicht gut (eine Form von "mixed levels of abstraction" Code Smell, oder auch Verletzung von information hiding).

throw new ReadWriteException("Fehler beim Lesen von " /*+ path*/ + "\n" + e.getMessage());
} catch (ParseException e) {
throw new ReadWriteException("Der Name " + deviceName + " wurde nicht gefunden");
}catch (NumberFormatException e) {
throw new ReadWriteException("Kein gültiger Messwert für " + deviceName + " gefunden");
}
}

/**
* Gibt einen Messwert mit Zeitstempel in Form einer Instanz von MeasurementValueXml zurueck,
* wenn das Protokoll xml-1 konfiguriert wurde.
*
* Wirft im Fehlerfall eine ReadWriteException
*
* @param deviceName
* @return
* @throws ReadWriteException
*/
public static MeasurementValueXml getActualValueFromXml(String deviceName)throws ReadWriteException{

private static MeasurementValueXml getActualValueFromXml(String deviceName) throws ReadWriteException, ParserConfigurationException, SAXException, IOException{
MeasurementValueXml measurementValue = new MeasurementValueXml();
// Pfad der Messwerte-Files gemaess deviceName aus der Konfiguration lesen und ein File erstellen
String path = DeviceMapperJson.getMeasurementValuePath(deviceName);
InputStream xmlFile;
if(path != null){
xmlFile = MeasurementValueReader.class.getResourceAsStream(path);
}else{
throw new ReadWriteException("Path for DataSource from " + deviceName + " not found in configuration");
}
assert path != null;
InputStream xmlFile = MeasurementValueReader.class.getResourceAsStream(path);

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try {

DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
Expand All @@ -94,144 +66,79 @@ public static MeasurementValueXml getActualValueFromXml(String deviceName)throws
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String deviceId = eElement.getElementsByTagName("Id").item(0).getTextContent();
//Suchbegriff mit dem Wert des aktuellen Elements vergleichen
if(deviceId.equals(deviceName)){
// Messwert erstellen aus Xml-File
measurementValue.setId(deviceId);
measurementValue.setValue(eElement.getElementsByTagName("Value").item(0).getTextContent());
measurementValue.setTime(new File(path).lastModified());
break;
}
}
}
} catch (ParserConfigurationException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
} catch (SAXException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
} catch (IOException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
}
if(measurementValue == null){
throw new ReadWriteException("Der Name " + deviceName + " wurde in " + path +" nicht gefunden");
}
return measurementValue;
}

/**
* Gibt einen Messwert mit Zeitstempel in Form einer Instanz von MeasurementValueXml zurueck,
* wenn das Protokoll xml-2 konfiguriert wurde.
*
* Wirft im Fehlerfall eine ReadWriteException
*
* @param deviceName
* @return
* @throws ReadWriteException
*/
public static MeasurementValueXml getActualValueFromXmlSax(String deviceName)throws ReadWriteException {

// Pfad der Messwerte-Files gemaess deviceName aus der Konfiguration lesen und ein File erstellen

private static MeasurementValueXml getActualValueFromXmlSax(String deviceName) throws ReadWriteException, ParserConfigurationException, SAXException, IOException {

String path = DeviceMapperJson.getMeasurementValuePath(deviceName);
long time = 0;
MeasurementValueXml actualValue = null;
SaxHandler handler = new SaxHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
ArrayList<MeasurementValueXml> measurementValues = (ArrayList<MeasurementValueXml>) handler.getMeasurementValues();
try {
SAXParser saxParser = factory.newSAXParser();
assert path != null;
saxParser.parse(
new SequenceInputStream(
Collections.enumeration(Arrays.asList(
new InputStream[] {
new ByteArrayInputStream("<ChannelResult>".getBytes()),
new FileInputStream(path),
new ByteArrayInputStream("</ChannelResult>".getBytes()),
}))
new ByteArrayInputStream("<ChannelResult>".getBytes()),
new FileInputStream(path),
new ByteArrayInputStream("</ChannelResult>".getBytes())))
), handler);
} catch (ParserConfigurationException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
} catch (SAXException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
} catch (FileNotFoundException e) {
throw new ReadWriteException("Datei konnte nicht gefunden werden " + path + "\n" + e.getMessage());
} catch (IOException e) {
throw new ReadWriteException("Fehler beim Lesen von " + path + "\n" + e.getMessage());
}

// Aktuellster Messwert zuweisen
for (MeasurementValueXml value : measurementValues){
if(value.getTime() > time){
actualValue = value;
time = value.getTime();
}
}
if(actualValue == null){
throw new ReadWriteException("Der Name " + deviceName + " wurde in " + path +" nicht gefunden");
}
//Bei Abbruch des Bluetooth-Signals der Messuhr wird NaN (Not_A_Number) als Messwert eingelesen
if(actualValue.getValue().equals("NaN")){
throw new ReadWriteException("Kein gültiger Messwert in " + path +" für " + deviceName + " gefunden");
}
return actualValue;
}


/**
* Gibt einen Messwert mit Zeitstempel in Form einer Instanz von MeasurementValueXml zurueck,
* wenn das Protokoll txt-1 konfiguriert wurde.
*
* Wirft im Fehlerfall eine ReadWriteException
*
* @param deviceName
* @return
* @throws ReadWriteException
*/
public static MeasurementValueXml getActualValueFromTxt(String deviceName)throws ReadWriteException{

FileInputStream in = null;
BufferedReader br = null;
private static MeasurementValueXml getActualValueFromTxt(String deviceName) throws ReadWriteException, ParseException, IOException {

String strLine = null;
String line = null;
String lastLine = null;
String line;
MeasurementValueXml measurementValue = new MeasurementValueXml();
// Pfad der Messwerte-Files gemaess deviceName aus der Konfiguration lesen und ein File erstellen
String path = DeviceMapperJson.getMeasurementValuePath(deviceName);

try {
in = new FileInputStream(path);
br = new BufferedReader(new InputStreamReader(in));
assert path != null;
FileInputStream in = new FileInputStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(in));

while ((line = br.readLine()) != null)
{
strLine = line;
}
lastLine = strLine;
String lastLine = strLine;

System.out.println(lastLine);
in.close();

} catch (FileNotFoundException ex) {
throw new ReadWriteException(ex.getMessage());
} catch (IOException ex) {
throw new ReadWriteException(ex.getMessage());
}

assert lastLine != null;
String[] tokens = lastLine.split(";");
measurementValue.setId(tokens[0]);
measurementValue.setValue(tokens[1]);
tokens[2].split(" ");

String pattern = "dd.MM.yyyy HH:mm:ss";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date date = null;

try {
date = simpleDateFormat.parse(tokens[2]);
} catch (ParseException e) {
e.printStackTrace();
}
Date date = new SimpleDateFormat(pattern).parse(tokens[2]);

assert date != null;
measurementValue.setTime(date.getTime());

return measurementValue;
}

}