// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.trustosm.io; import java.io.BufferedWriter; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.io.XmlWriter; import org.openstreetmap.josm.plugins.trustosm.data.TrustNode; import org.openstreetmap.josm.plugins.trustosm.data.TrustOsmPrimitive; import org.openstreetmap.josm.plugins.trustosm.data.TrustRelation; import org.openstreetmap.josm.plugins.trustosm.data.TrustSignatures; import org.openstreetmap.josm.plugins.trustosm.data.TrustWay; public class SigWriter extends XmlWriter { private String indent = ""; public SigWriter(PrintWriter out) { super(out); } public SigWriter(OutputStream out) throws UnsupportedEncodingException { super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, "UTF-8")))); } public void write(Collection<TrustOsmPrimitive> items) { writeHeader(); indent = " "; writeItems(items); writeFooter(); out.flush(); } private void writeDTD() { out.println("<!DOCTYPE trustXML ["); out.println(" <!ELEMENT trustXML (trustnode|trustway|trustrelation)*>"); out.println(" <!ATTLIST trustXML version CDATA #IMPLIED creator CDATA #IMPLIED >"); out.println(" <!ELEMENT trustnode (tags?,node?)>"); out.println(" <!ELEMENT trustway (tags?,segmentlist?)>"); out.println(" <!ELEMENT trustrelation (tags?,memberlist?)>"); out.println(" <!ATTLIST trustnode osmid CDATA #IMPLIED >"); out.println(" <!ATTLIST trustway osmid CDATA #IMPLIED >"); out.println(" <!ATTLIST trustrelation osmid CDATA #IMPLIED >"); out.println(" <!ELEMENT tags (key)+>"); out.println(" <!ELEMENT key (openpgp)+>"); out.println(" <!ATTLIST key k CDATA #IMPLIED >"); out.println(" <!ELEMENT node (openpgp)>"); // out.println(" <!ATTLIST node id CDATA #REQUIRED >"); out.println(" <!ELEMENT segmentlist (segment)*>"); out.println(" <!ELEMENT segment (openpgp)+>"); out.println(" <!ELEMENT memberlist (member)*>"); out.println(" <!ELEMENT member (openpgp)+>"); out.println(" <!ELEMENT openpgp (#PCDATA)*>"); out.println("]>"); } private void writeHeader() { out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); writeDTD(); out.println("<trustXML version=\"0.1\" creator=\"JOSM Signature export\">"); } private void writeFooter() { out.println("</trustXML>"); } private void writeSigs(TrustSignatures tsigs) { for (String plain : tsigs.getAllPlainTexts()) { simpleTag("openpgp", tsigs.getArmoredFulltextSignatureAll(plain)); } } private void writeTags(TrustOsmPrimitive trust) { Map<String, TrustSignatures> tagsigs = trust.getTagSigs(); Set<String> signedKeys = tagsigs.keySet(); if (signedKeys.isEmpty()) return; openln("tags"); for (String key : signedKeys) { openAtt("key", "k=\""+key+"\""); writeSigs(tagsigs.get(key)); closeln("key"); } closeln("tags"); } private void writeNode(TrustNode tn) { TrustSignatures tsigs = tn.getNodeSigs(); if (tsigs == null) return; openln("node"); writeSigs(tsigs); closeln("node"); } private void writeSegments(TrustWay tw) { Map<List<Node>, TrustSignatures> segmentSig = tw.getSegmentSigs(); Set<List<Node>> signedSegments = segmentSig.keySet(); if (signedSegments.isEmpty()) return; openln("segmentlist"); for (List<Node> segment : signedSegments) { openln("segment"); writeSigs(segmentSig.get(segment)); closeln("segment"); } closeln("segmentlist"); } private void writeMembers(TrustRelation tr) { Map<String, TrustSignatures> memberSig = tr.getMemberSigs(); Set<String> signedMembers = memberSig.keySet(); if (signedMembers.isEmpty()) return; openln("memberlist"); for (String member : signedMembers) { openln("member"); writeSigs(memberSig.get(member)); closeln("member"); } closeln("memberlist"); } private void writeItems(Collection<TrustOsmPrimitive> items) { for (TrustOsmPrimitive trust : items) { OsmPrimitive osm = trust.getOsmPrimitive(); if (trust instanceof TrustNode) { TrustNode tn = (TrustNode) trust; openAtt("trustnode", "osmid=\""+String.valueOf(osm.getUniqueId())+"\""); writeTags(tn); writeNode(tn); closeln("trustnode"); } else if (trust instanceof TrustWay) { TrustWay tw = (TrustWay) trust; openAtt("trustway", "osmid=\""+String.valueOf(osm.getUniqueId())+"\""); writeTags(tw); writeSegments(tw); closeln("trustway"); } else if (trust instanceof TrustRelation) { TrustRelation tr = (TrustRelation) trust; openAtt("trustrelation", "osmid=\""+String.valueOf(osm.getUniqueId())+"\""); writeTags(tr); writeMembers(tr); closeln("trustrelation"); } // openAtt("trustitem", "osmid=\""+String.valueOf(osm.getUniqueId())+"\" type=\""+osm.getType().getAPIName()+"\""); } } private void openln(String tag) { open(tag); out.println(); } private void open(String tag) { out.print(indent + "<" + tag + ">"); indent += " "; } private void openAtt(String tag, String attributes) { out.println(indent + "<" + tag + " " + attributes + ">"); indent += " "; } /*private void inline(String tag, String attributes) { out.println(indent + "<" + tag + " " + attributes + " />"); }*/ private void close(String tag) { indent = indent.substring(2); out.print(indent + "</" + tag + ">"); } private void closeln(String tag) { close(tag); out.println(); } /** * if content not null, open tag, write encoded content, and close tag * else do nothing. */ private void simpleTag(String tag, String content) { if (content != null && content.length() > 0) { open(tag); out.print(encode(content)); //out.print(content); out.println("</" + tag + ">"); indent = indent.substring(2); } } }