1   package demo.yext.graphml;
2   
3   import y.base.DataMap;
4   import y.base.Edge;
5   import y.base.EdgeCursor;
6   import y.base.Node;
7   import y.base.NodeCursor;
8   import y.util.DataProviderAdapter;
9   import y.util.Maps;
10  import y.util.YRandom;
11  import y.view.Graph2D;
12  import y.view.HitInfo;
13  import y.view.ViewMode;
14  
15  import javax.swing.Action;
16  import javax.swing.JMenu;
17  import java.awt.event.ActionEvent;
18  import java.util.HashSet;
19  import java.util.Set;
20  
21  /**
22   * This demo shows how to configure a GraphMLIOHandler to persist the value of GraphML core element IDs.
23   */
24  public class GraphMLIdDemo extends GraphMLDemo {
25  
26    /**
27     * This stores all ids of normal graph core elements, except for ids of nested graph
28     * (this demo only handles flat graphs correctly, to keep it simple
29     */
30    DataMap elementIdMap = Maps.createHashedDataMap();
31  
32    /**
33     * We use these sets to check that all id values are unique for the respective scope
34     */
35    Set nodeIds = new HashSet();
36    Set edgeIds = new HashSet();
37    Set graphIds = new HashSet();
38  
39    YRandom rnd = new YRandom();
40  
41    public GraphMLIdDemo() {
42      getGraphMLIOHandler().setIdDataAcceptor(elementIdMap);
43      //we wrap the original map, so that we can check for duplicate ids or generate ids for new elements
44      getGraphMLIOHandler().setIdDataProvider(new DataProviderAdapter() {
45        public Object get(Object dataHolder) {
46          Object origId = elementIdMap.get(dataHolder);
47          if (origId == null) {
48            //this is a new element which has no id that has been set previously, so generate one
49            String generatedId = null;
50            if (dataHolder instanceof Node) {
51              generatedId = generateId(nodeIds, "node_generated_");
52            } else if (dataHolder instanceof Edge) {
53              generatedId = generateId(edgeIds, "edge_generated_");
54            } else {
55              generatedId = generateId(graphIds, "graph_generated_");
56            }
57            elementIdMap.set(dataHolder, generatedId);
58            return generatedId;
59          } else {
60            return origId;
61          }
62        }
63  
64        private String generateId(Set ids, String prefix) {
65          String id;
66          do {
67            id = prefix + rnd.nextInt(0, Integer.MAX_VALUE);
68          }
69          while (ids.contains(id));
70          ids.add(id);
71          return id;
72        }
73      });
74      //define a view mode that displays the element's ID
75      ViewMode tooltipMode = new ViewMode() {
76        public void mouseMoved(double x, double y) {
77          HitInfo info = getHitInfo(x, y);
78          String id = "";
79          if (info.getHitNode() != null) {
80            id = (String) elementIdMap.get(info.getHitNode());
81          } else if (info.getHitEdge() != null) {
82            id = (String) elementIdMap.get(info.getHitEdge());
83          } else {
84            //retrieve the id of the view's root graph
85            id = (String) elementIdMap.get(view.getGraph2D());
86          }
87          view.setToolTipText("ID=" + id);
88        }
89      };
90  
91      //add the view mode to the view
92      view.addViewMode(tooltipMode);
93    }
94  
95    protected Action createSaveAction() {
96      return new SaveAction();
97    }
98  
99    /**
100    * Action that saves the current graph to a file in GraphML format.
101    */
102   class SaveAction extends GraphMLDemo.SaveAction {
103     public void actionPerformed(ActionEvent e) {
104       //we decorate the base class action, to clear the id sets before each write process
105       Graph2D graph = view.getGraph2D();
106       nodeIds.clear();
107       for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
108         Node node = nodeCursor.node();
109         Object o = elementIdMap.get(node);
110         if (o != null) {
111           nodeIds.add(o);
112         }
113       }
114 
115       edgeIds.clear();
116       for (EdgeCursor edgeCursor = graph.edges(); edgeCursor.ok(); edgeCursor.next()) {
117         Edge edge = edgeCursor.edge();
118         Object o = elementIdMap.get(edge);
119         if (o != null) {
120           edgeIds.add(o);
121         }
122       }
123       graphIds.clear();
124       graphIds.add(elementIdMap.get(graph));
125       super.actionPerformed(e);
126     }
127   }
128 
129   /**
130    * Add sample graphs to the menu.
131    */
132   protected JMenu createSampleGraphMenu() {
133     return createSampleGraphMenu(new String[]{"resources/simple/simple.graphml"});
134   }
135 
136   /**
137    * Launches this demo.
138    */
139   public static void main(String[] args) {
140     initLnF();
141     final GraphMLIdDemo demo = new GraphMLIdDemo();
142     demo.start();
143   }
144 }
145