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