1
28 package demo.view.mindmap;
29
30 import org.w3c.dom.NamedNodeMap;
31 import org.w3c.dom.Node;
32 import org.xml.sax.SAXException;
33 import y.base.EdgeCursor;
34 import y.io.IOHandler;
35 import y.view.Graph2D;
36 import y.view.LineType;
37 import y.view.NodeRealizer;
38
39 import java.awt.Color;
40 import java.io.BufferedWriter;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.OutputStream;
44 import java.io.OutputStreamWriter;
45 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.parsers.ParserConfigurationException;
47
48
53 public class FreeMindIOHandler extends IOHandler {
54 private static final String ENCODING = "UTF-8" ;
55 private static final String ATTRIBUTE_COLOR = "COLOR";
56 private static final String ATTRIBUTE_POSITION = "POSITION";
57 private static final String ATTRIBUTE_WIDTH = "WIDTH";
58 private static final String ATTRIBUTE_TEXT = "TEXT";
59 private static final String TAG_EDGE = "edge";
60 private static final String TAG_NODE = "node";
61
62
65 public void write( final Graph2D graph, final OutputStream out ) throws IOException {
66 final BufferedWriter bufferedWriter = new BufferedWriter(
67 new OutputStreamWriter(new OutputStreamGuardian(out), ENCODING));
68 try {
69 bufferedWriter.write("<map version=\"0.9.0\">");
70 bufferedWriter.newLine();
71 writeNode(graph, ViewModel.instance.getRoot(), bufferedWriter);
72 bufferedWriter.write("</map>");
73 bufferedWriter.flush();
74 } finally {
75 bufferedWriter.close();
76 }
77 }
78
79
86 private static void writeNode(
87 final Graph2D graph, final y.base.Node node, final BufferedWriter writer
88 ) throws IOException {
89
92 final NodeRealizer nodeRealizer = graph.getRealizer(node);
93 writer.write("<" + TAG_NODE + " " + ATTRIBUTE_TEXT + "=\"" + nodeRealizer.getLabelText() + "\"");
94
95 final boolean isSecondLevel = node.inDegree() > 0 && node.firstInEdge().source().inDegree() == 0;
96 final boolean isLeftSide = ViewModel.instance.isLeft(node);
97 if (isSecondLevel && isLeftSide) {
99 writer.write(" " + ATTRIBUTE_POSITION + "=\"left\" ");
100 }
101 writer.write(" >");
102 writer.newLine();
103 writeEdge(nodeRealizer, writer);
104
105 for (EdgeCursor ec = MindMapUtil.outEdges(node).edges(); ec.ok(); ec.next()) {
106 writeNode(graph, ec.edge().target(), writer);
107 }
108
109 writer.write("</" + TAG_NODE + ">");
110 writer.newLine();
111 }
112
113 private static void writeEdge(
114 final NodeRealizer target, final BufferedWriter writer
115 ) throws IOException {
116 writer.write("<" + TAG_EDGE + " ");
117 String value = Integer.toHexString(target.getFillColor().getRGB());
118 writer.write(ATTRIBUTE_COLOR + "=\"#" + value.substring(2, 8) + "\" ");
119 writer.write(ATTRIBUTE_WIDTH + "=\"" + ((int) target.getLineType().getLineWidth()) + "\"");
120 writer.write("/>");
121 writer.newLine();
122 }
123
124
125
128 public void read( final Graph2D graph, final InputStream in ) throws IOException {
129 try {
130 readNode(
131 DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in),
132 graph,
133 null);
134 } catch (SAXException e) {
135 final IOException ioe = new IOException();
136 ioe.initCause(ioe);
137 throw ioe;
138 } catch (ParserConfigurationException e) {
139 final IOException ioe = new IOException();
140 ioe.initCause(ioe);
141 throw ioe;
142 }
143 }
144
145
146
152 private static void readNode(final Node node, final Graph2D graph, final y.base.Node parent) {
153 final String nodeName = node.getNodeName();
154 y.base.Node n = parent;
155 if (nodeName.equals(TAG_NODE)) {
156 final NamedNodeMap attributes = node.getAttributes();
157 Node attr = attributes.getNamedItem(ATTRIBUTE_TEXT);
158 String name = "";
159 boolean side = false;
160 if (attr != null) {
161 name = attr.getNodeValue();
162 }
163 attr = attributes.getNamedItem(ATTRIBUTE_POSITION);
164 if (attr != null) {
165 side = attr.getNodeValue().equalsIgnoreCase("left");
166 }
167 if (parent == null) {
168 n = graph.createNode(0,0,name);
172 } else {
173 n = MindMapUtil.addNode(graph, parent, name, side);
175 }
176 if (parent != null && attr == null) {
177 MindMapUtil.updateVisuals(graph, n, ViewModel.instance.isLeft(parent));
178 } else {
179 MindMapUtil.updateVisuals(graph, n, side);
180 }
181 } else if (nodeName.equals(TAG_EDGE)) {
182 final NamedNodeMap attributes = node.getAttributes();
183 Node attr = attributes.getNamedItem(ATTRIBUTE_COLOR);
184 final NodeRealizer nodeRealizer = graph.getRealizer(parent);
187 if (attr != null) {
188 nodeRealizer.setFillColor(Color.decode(attr.getNodeValue()));
189 }
190 attr = attributes.getNamedItem(ATTRIBUTE_WIDTH);
191 if (attr != null) {
192 int lineWidth = Integer.parseInt(attr.getNodeValue());
193 if (lineWidth == 2) {
194 nodeRealizer.setLineType(LineType.LINE_3);
195 } else {
196 nodeRealizer.setLineType(LineType.LINE_6);
197 }
198 }
199 }
200
201 for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
203 readNode(child, graph, n);
204 }
205 }
206
207
208
212 public String getFileFormatString() {
213 return "FreeMind file";
214 }
215
216
220 public String getFileNameExtension() {
221 return "mm";
222 }
223
224
225
229 private static final class OutputStreamGuardian extends OutputStream {
230 private final OutputStream os;
231
232 OutputStreamGuardian( final OutputStream os ) {
233 this.os = os;
234 }
235
236 public void close() throws IOException {
237 }
239
240 public void flush() throws IOException {
241 os.flush();
242 }
243
244 public void write( final int b ) throws IOException {
245 os.write(b);
246 }
247
248 public void write( final byte[] b ) throws IOException {
249 os.write(b);
250 }
251
252 public void write( final byte[] b, final int off, final int len ) throws IOException {
253 os.write(b, off, len);
254 }
255 }
256 }
257