1
14 package demo.io.graphml;
15
16 import org.w3c.dom.Element;
17 import org.w3c.dom.NodeList;
18
19 import y.base.DataMap;
20 import y.base.Edge;
21 import y.base.EdgeMap;
22 import y.base.Node;
23 import y.base.NodeMap;
24 import y.io.GraphMLIOHandler;
25 import y.io.graphml.GraphMLHandler;
26 import y.io.graphml.KeyScope;
27 import y.io.graphml.KeyType;
28 import y.io.graphml.input.AbstractDataAcceptorInputHandler;
29 import y.io.graphml.input.DeserializationEvent;
30 import y.io.graphml.input.DeserializationHandler;
31 import y.io.graphml.input.GraphMLParseContext;
32 import y.io.graphml.input.GraphMLParseException;
33 import y.io.graphml.input.InputHandlerProvider;
34 import y.io.graphml.input.NameBasedDeserializer;
35 import y.io.graphml.input.QueryInputHandlersEvent;
36 import y.io.graphml.output.AbstractOutputHandler;
37 import y.io.graphml.output.GraphMLWriteContext;
38 import y.io.graphml.output.GraphMLWriteException;
39 import y.io.graphml.output.SerializationEvent;
40 import y.io.graphml.output.SerializationHandler;
41 import y.io.graphml.output.TypeBasedSerializer;
42 import y.io.graphml.output.XmlWriter;
43 import y.option.OptionHandler;
44 import y.view.EditMode;
45 import y.view.PopupMode;
46 import y.view.TooltipMode;
47
48 import javax.swing.AbstractAction;
49 import javax.swing.JPopupMenu;
50 import java.awt.EventQueue;
51 import java.awt.event.ActionEvent;
52 import java.text.ParseException;
53 import java.text.SimpleDateFormat;
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.Date;
57 import java.util.Iterator;
58 import java.util.Locale;
59 import java.util.StringTokenizer;
60
61
70 public class ComplexExtensionGraphMLDemo extends GraphMLDemo {
71
72
75 private NodeMap nodeDataMap;
76 private EdgeMap edgeDataMap;
77
78 protected void loadInitialGraph() {
79 loadGraph("resources/custom/complexdemo.graphml");
80 }
81
82
86 protected GraphMLIOHandler createGraphMLIOHandler() {
87 if (nodeDataMap == null) {
88 nodeDataMap = view.getGraph2D().createNodeMap();
89 }
90 if (edgeDataMap == null) {
91 edgeDataMap = view.getGraph2D().createEdgeMap();
92 }
93
94
95 GraphMLIOHandler ioHandler = super.createGraphMLIOHandler();
96
97
98 ioHandler.getGraphMLHandler().addInputDataAcceptor("myNodeAttribute", nodeDataMap, KeyScope.NODE,
101 new ItemListDeserializer());
102
103 ioHandler.getGraphMLHandler().addOutputDataProvider("myNodeAttribute", nodeDataMap, KeyScope.NODE,
104 new ItemListSerializer());
105
106 ioHandler.getGraphMLHandler().addDeserializationHandler(new ItemDeserializer());
109 ioHandler.getGraphMLHandler().addSerializationHandler(new ItemSerializer());
110
111 ioHandler.getGraphMLHandler().addInputHandlerProvider(new InputHandlerProvider() {
113 public void onQueryInputHandler(QueryInputHandlersEvent event) throws GraphMLParseException {
114 Element keyDefinition = event.getKeyDefinition();
115 if (!event.isHandled()
116 && GraphMLHandler.matchesScope(keyDefinition, KeyScope.EDGE)
117 && GraphMLHandler.matchesName(keyDefinition, "myEdgeAttribute")) {
118 MyDateInputHandler handler = new MyDateInputHandler();
119 handler.setDataAcceptor(edgeDataMap);
120 handler.initializeFromKeyDefinition(event.getContext(), keyDefinition);
121 event.addInputHandler(handler);
122 }
123 }
124 });
125
126 ioHandler.getGraphMLHandler().addOutputHandlerProvider(
128 new AbstractOutputHandler("myEdgeAttribute", KeyScope.EDGE, KeyType.COMPLEX) {
129 protected void writeValueCore(GraphMLWriteContext context, Object data) throws GraphMLWriteException {
130 if (data instanceof Date) {
131 context.getWriter().writeText(dateFormat.format(data));
132 }
133 }
134
135 protected Object getValue(GraphMLWriteContext context, Object key) throws GraphMLWriteException {
136 return edgeDataMap.get(key);
137 }
138 });
139
140 return ioHandler;
141 }
142
143
144 public static final String DEMO_NS = "demo.io.graphml.complex";
145
146
149 public static class Item {
150 private String value;
151
152 public Item(String value) {
153 this.value = value;
154 }
155
156 public String getValue() {
157 return value;
158 }
159
160 public String toString() {
161 return value;
162 }
163 }
164
165
168 public static class ItemSerializer extends TypeBasedSerializer {
169 public void serializeItem(Object o, XmlWriter writer, GraphMLWriteContext context) throws GraphMLWriteException {
170 Item item = (Item) o;
171 writer.writeStartElement("Item", DEMO_NS).writeAttribute("value", item.getValue()).writeEndElement();
172 }
173
174 protected Class getSerializationType(GraphMLWriteContext context) {
175 return Item.class;
177 }
178 }
179
180
183 public static class ItemDeserializer extends NameBasedDeserializer {
184 public Object deserializeNode(org.w3c.dom.Node xmlNode, GraphMLParseContext context) throws GraphMLParseException {
185 if (xmlNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE
186 && DEMO_NS.equals(xmlNode.getNamespaceURI())
187 && "Item".equals(xmlNode.getLocalName())) {
188 return new Item(((Element) xmlNode).getAttribute("value"));
189 }
190 return null;
191 }
192
193
194 public String getNamespaceURI(GraphMLParseContext context) {
195 return DEMO_NS;
196 }
197
198 public String getNodeName(GraphMLParseContext context) {
199 return "Item";
200 }
201 }
202
203
206 public static class ItemListSerializer implements SerializationHandler {
207
208 public void onHandleSerialization(SerializationEvent event) throws GraphMLWriteException {
209 Object o = event.getItem();
210 if (o instanceof Collection) {
211 Collection coll = (Collection) o;
212 event.getWriter().writeStartElement("ItemList", DEMO_NS);
213 for (Iterator iterator = coll.iterator(); iterator.hasNext();) {
214 Object item = iterator.next();
215 event.getContext().serialize(item);
216 }
217 event.getWriter().writeEndElement();
218 }
219 }
220 }
221
222
225 public static class ItemListDeserializer implements DeserializationHandler {
226 public void onHandleDeserialization(DeserializationEvent event) throws GraphMLParseException {
227 org.w3c.dom.Node xmlNode = event.getXmlNode();
228 if (xmlNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE
229 && DEMO_NS.equals(xmlNode.getNamespaceURI())
230 && "ItemList".equals(xmlNode.getLocalName())) {
231 Collection retval = new ArrayList();
232 NodeList childNodes = xmlNode.getChildNodes();
233 for (int i = 0; i < childNodes.getLength(); ++i) {
234 org.w3c.dom.Node child = childNodes.item(i);
235 if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
236 Object o = event.getContext().deserialize(child);
237 retval.add(o);
238 }
239 }
240 event.setResult(retval);
241 }
242 }
243 }
244
245 private static SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy");
246
247
248 public static class MyDateInputHandler extends AbstractDataAcceptorInputHandler {
249 protected Object parseDataCore(GraphMLParseContext context, org.w3c.dom.Node node) throws GraphMLParseException {
250 if (node.getChildNodes().getLength() != 1) {
251 throw new GraphMLParseException("Invalid data format - single text node expected");
252 }
253 org.w3c.dom.Node n = node.getFirstChild();
254 if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
255 try {
256 return dateFormat.parse(n.getNodeValue());
257 } catch (ParseException e) {
258 throw new GraphMLParseException("Invalid date format: " + e.getMessage(), e);
259 }
260 } else {
261 throw new GraphMLParseException("Invalid data format - Text node expected");
262 }
263 }
264 }
265
266 protected String[] getExampleResources() {
267 return null;
268 }
269
270
274 protected EditMode createEditMode() {
275 EditMode editMode = super.createEditMode();
276
277 editMode.setPopupMode(new PopupMode() {
278 public JPopupMenu getNodePopup(Node v) {
279 JPopupMenu pm = new JPopupMenu();
280 pm.add(new EditAttributeAction("Edit Node Attribute...", v, nodeDataMap));
281 return pm;
282 }
283 });
284 return editMode;
285 }
286
287
291 protected TooltipMode createTooltipMode() {
292 TooltipMode tooltipMode = new TooltipMode() {
293
298 protected String getNodeTip(Node node) {
299 Collection items = (Collection) nodeDataMap.get(node);
300 String tipText = null;
301 if (items != null) {
302 tipText = "<html><body>Items:<table>";
303 for (Iterator iterator = items.iterator(); iterator.hasNext(); ) {
304 tipText += "</tr></td>" + iterator.next() + "</td></tr>";
305 }
306 tipText += "</table></body></html>";
307 }
308 return tipText;
309 }
310
311
316 protected String getEdgeTip(Edge edge) {
317 Object o = edgeDataMap.get(edge);
318 String tipText = null;
319 if (o instanceof Date) {
320 tipText = o.toString();
321 }
322 return tipText;
323 }
324 };
325
326 return tooltipMode;
327 }
328
329
332 class EditAttributeAction extends AbstractAction {
333 private Object object;
334 private DataMap dataMap;
335
336 private OptionHandler op;
337
338 EditAttributeAction(String name, Object object, DataMap dataMap) {
339 super(name);
340 this.object = object;
341 this.dataMap = dataMap;
342 op = new OptionHandler(name);
343 if (object instanceof Node) {
344 Object o = dataMap.get(object);
345 if (o instanceof Collection) {
346 Collection coll = (Collection) o;
347 String str = "";
348 for (Iterator iterator = coll.iterator(); iterator.hasNext();) {
349 str += iterator.next();
350 if (iterator.hasNext()) {
351 str += "\n";
352 }
353 }
354 op.addString("Node Items", str, 10);
355 } else {
356 op.addString("Node Items", "", 10);
357 }
358 }
359 }
360
361 public void actionPerformed(ActionEvent actionEvent) {
362 if (op.showEditor(view.getFrame())) {
363 if (object instanceof Node) {
364 Collection coll = new ArrayList();
365 String s = op.getString("Node Items");
366 StringTokenizer tokenizer = new StringTokenizer(s, "\n");
367 while (tokenizer.hasMoreElements()) {
368 String s1 = (String) tokenizer.nextElement();
369 coll.add(new Item(s1));
370 }
371 dataMap.set(object, coll);
372 }
373 graphMLPane.updateGraphMLText(view.getGraph2D());
374 }
375 }
376 }
377
378
381 public static void main(String[] args) {
382 EventQueue.invokeLater(new Runnable() {
383 public void run() {
384 Locale.setDefault(Locale.ENGLISH);
385 initLnF();
386 (new ComplexExtensionGraphMLDemo()).start();
387 }
388 });
389 }
390 }
391