/** * Copyright (c) 2011-2014, OpenIoT * * This file is part of OpenIoT. * * OpenIoT is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * OpenIoT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with OpenIoT. If not, see <http://www.gnu.org/licenses/>. * * Contact: OpenIoT mailto: info@openiot.eu */ package org.openiot.cupus.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openiot.cupus.artefact.Announcement; import org.openiot.cupus.artefact.HashtablePublication; import org.openiot.cupus.artefact.Publication; import org.openiot.cupus.artefact.Subscription; import org.openiot.cupus.artefact.TripletAnnouncement; import org.openiot.cupus.artefact.TripletSubscription; import org.openiot.cupus.common.Triplet; import org.openiot.cupus.common.enums.Operator; /** * This class is used for inputing publication and subscription information from * XML document or string containing XML document content. * */ public class ReadingWritingXML { private String fileName; private String type; private String pubSupType; private String inputString; private long validity; private HashMap<String, Object> propertiesMap = new HashMap<String, Object>(); private HashMap<String, Operator> operatorMap = new HashMap<String, Operator>(); private boolean testing = false; private boolean fileWriting = false; // true ako se koristi samo pub-sub, a // ako se koristi za dostavu rpid // sadrzaja onda false /** * Constructor - only one string is given to the constructor, other has to * be empty string (not null) * * @param fileName * Input file * @param inputString * Input String */ public ReadingWritingXML(String fileName, String inputString) { this.fileName = fileName; this.inputString = inputString; new File("out").mkdir(); } /** * Used for reading input document or string Depending what string was * given, different reader method is called */ public void read() { if (fileName.isEmpty()) { fileWriting = false; if (inputString.isEmpty()) { System.err .println("ERROR (ReadingWritingXML): Both inputs are empty"); } else { readString(); } } else if (inputString.isEmpty()) { if (fileName.isEmpty()) { System.err .println("ERROR (ReadingWritingXML): Both inputs are empty"); } else { fileWriting = true; readFile(); } } else { System.err .println("ERROR (ReadingWritingXML): Both inputs are full"); } } /** * method used for reading input string stream */ public void readString() { BufferedReader in = new BufferedReader(new StringReader(inputString)); readBuffer(in); } /** * method used for reading input XML file */ public void readFile() { try { // BufferedReader in = new BufferedReader(new FileReader("in" // + System.getProperty("file.separator") + this.fileName)); BufferedReader in = new BufferedReader(new FileReader( this.fileName)); readBuffer(in); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * method that reads XML format and captures elements necessary for * publication/subscription construction * * @param in * Buffered reader wrapping input document or input string */ public void readBuffer(BufferedReader in) { try { String line; Pattern p1 = Pattern.compile("<\\?xml version.+>"); Pattern p2 = Pattern.compile("<subscription type=\"(.+)\">"); Pattern p3 = Pattern.compile("<publication type=\"(.+)\">"); Pattern p4 = Pattern.compile("^[ \t]<validity>([-]*\\d+)<.+"); Pattern p5 = Pattern .compile("^[ \t]<attribute name=\"(.+)\" operator=\"(.+)\" type=\"(.+)\">(.+)<.+"); Pattern p6 = Pattern.compile("<announcement type=\"(.+)\">"); while ((line = in.readLine()) != null) { Matcher m1 = p1.matcher(line); Matcher m2 = p2.matcher(line); Matcher m3 = p3.matcher(line); Matcher m4 = p4.matcher(line); Matcher m5 = p5.matcher(line); Matcher m6 = p6.matcher(line); boolean b1 = m1.matches(); boolean b2 = m2.matches(); boolean b3 = m3.matches(); boolean b4 = m4.matches(); boolean b5 = m5.matches(); boolean b6 = m6.matches(); if (testing) { System.out.println(line + " " + b1 + " " + b2 + " " + b3 + " " + b4 + " " + b5); } if (b1) { continue; // skip first line. this is just to check if // everything is ok } else if (b2) { type = "subscription"; pubSupType = m2.group(1); if (testing) { System.out.println("Type = subscription " + pubSupType); } } else if (b3) { type = "publication"; pubSupType = m3.group(1); if (testing) { System.out.println("Type = publication " + pubSupType); } } else if (b4) { validity = Long.parseLong(m4.group(1)); if (testing) { System.out.println("Validity = " + m4.group(1)); } } else if (b5) { if (!propertiesMap.containsKey(m5.group(1))) { if (m5.group(3).equals("string")) { propertiesMap.put(m5.group(1), m5.group(4)); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else if (m5.group(3).equals("integer")) { propertiesMap.put(m5.group(1), Integer.parseInt(m5.group(4))); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else if (m5.group(3).equals("long")) { propertiesMap.put(m5.group(1), Long.parseLong(m5.group(4))); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else if (m5.group(3).equals("double")) { propertiesMap.put(m5.group(1), Double.parseDouble(m5.group(4))); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else if (m5.group(3).equals("boolean")) { propertiesMap.put(m5.group(1), Boolean.parseBoolean(m5.group(4))); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else if (m5.group(3).equals("float")) { propertiesMap.put(m5.group(1), Float.parseFloat(m5.group(4))); operatorMap.put(m5.group(1), Operator.valueOf(m5.group(2))); } else { System.err .println("ERROR attribute type not supported: " + m5.group(3)); } if (testing) { System.out.println(m5.group(1) + " " + m5.group(2) + " " + m5.group(4) + " Type: " + m5.group(3)); } } } else if (b6) { type = "announcement"; pubSupType = m6.group(1); if (testing) { System.out.println("Type = announcement " + pubSupType); } } } } catch (IOException e) { e.printStackTrace(); } } public Subscription createSubscription() { if (pubSupType.equals("booleanHashtable")) { System.out .println("ERROR Subscription type not supported anymore!"); return null; } else if (pubSupType.equals("booleanTriplet")) { TripletSubscription sub = null; long now = System.currentTimeMillis(); if (validity == -1) { sub = new TripletSubscription(-1, now); } else { sub = new TripletSubscription(now + validity, now); } if (!type.equals("subscription")) { System.out.println("ERROR wrong method call!"); return null; } Iterator<String> it = propertiesMap.keySet().iterator(); while (it.hasNext()) { String key = it.next(); sub.addPredicate(new Triplet(key, propertiesMap.get(key), operatorMap.get(key))); if (testing) { System.out.println(key + " " + operatorMap.get(key) + " " + propertiesMap.get(key)); } } return sub; } else { System.err.println("ERROR Subscription type not supported!"); return null; } } public Publication createPublication() { if (pubSupType.equals("booleanHashtable")) { HashtablePublication pub = null; long now = System.currentTimeMillis(); if (validity == -1) { pub = new HashtablePublication(-1, now); } else { pub = new HashtablePublication(now + validity, now); } if (!type.equals("publication")) { System.out.println("ERROR wrong method call!"); return null; } Iterator<String> it = propertiesMap.keySet().iterator(); while (it.hasNext()) { String key = it.next(); pub.setProperty(key, propertiesMap.get(key)); if (testing) { System.out.println(key + " = " + propertiesMap.get(key)); } } return pub; } else if (pubSupType.equals("booleanTriplet")) { // TODO drugi tip return null; } else { System.err.println("ERROR Subscription type not supported!"); return null; } } public Announcement createAnnouncement() { if (pubSupType.equals("booleanHashtable")) { System.out .println("ERROR Announcement type not supported anymore!"); return null; } else if (pubSupType.equals("booleanTriplet")) { TripletAnnouncement ann = null; long now = System.currentTimeMillis(); if (validity == -1) { ann = new TripletAnnouncement(-1, now); } else { ann = new TripletAnnouncement(now + validity, now); } if (!type.equals("announcement")) { System.out.println("ERROR wrong method call!"); return null; } Iterator<String> it = propertiesMap.keySet().iterator(); while (it.hasNext()) { String key = it.next(); if (propertiesMap.get(key) instanceof String) { //if the resource is in the String format ann.addTextualPdredicate(key, (String) propertiesMap.get(key), operatorMap.get(key)); } else { //else it is a numerical predicate ann.addNumericalPdredicate(key, (Double) propertiesMap.get(key), operatorMap.get(key)); } if (testing) { System.out.println(key + " " + operatorMap.get(key) + " " + propertiesMap.get(key)); } } return ann; } else { System.err.println("ERROR Subscription type not supported!"); return null; } } /** * this method is used for writing output xml file * * @param publication * Publication to be written * @return String representing publication */ public String writeXML(Publication publication) { String oneLine = "<?xml version=\"1.0\" encoding='UTF-8'?>"; String outputString = oneLine + "\r\n"; try { BufferedWriter out = null; if (this.fileWriting) { out = new BufferedWriter(new FileWriter("out" + System.getProperty("file.separator") + this.fileName)); out.write(oneLine + "\r\n"); } if (publication instanceof HashtablePublication) { HashtablePublication pub = (HashtablePublication) publication; oneLine = "<publication type=\"Hashtable\" id=\"" + publication.getId() + "\">"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } oneLine = "\t<validity>" + pub.getValidity() + "</validity>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } Iterator<String> it = pub.getProperties().keySet().iterator(); while (it.hasNext()) { String key = it.next(); if (pub.getProperties().get(key) instanceof String) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"string\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else if (pub.getProperties().get(key) instanceof Integer) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"integer\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else if (pub.getProperties().get(key) instanceof Long) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"long\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else if (pub.getProperties().get(key) instanceof Double) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"double\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else if (pub.getProperties().get(key) instanceof Boolean) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"boolean\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else if (pub.getProperties().get(key) instanceof Float) { oneLine = "\t<attribute name=\"" + key + "\" operator=\"==\" type=\"float\">" + pub.getProperties().get(key) + "</attribute>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); } } else { System.err .println("ERROR attribute type not recognized"); } } oneLine = "</publication>"; outputString = outputString + oneLine + "\r\n"; if (this.fileWriting) { out.write(oneLine + "\r\n"); out.flush(); out.close(); } return outputString; } else { return "error turning publication with ID=" + publication.getId() + " to XML!"; } } catch (IOException e) { e.printStackTrace(); } return null; } public boolean isFileWriting() { return fileWriting; } public boolean isTesting() { return testing; } public void setFileWriting(boolean fileWriting) { this.fileWriting = fileWriting; } public void setTesting(boolean testing) { this.testing = testing; } }