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