001    package nl.cwi.sen1.visplugin.graphplugin;
002    
003    import java.awt.BorderLayout;
004    import java.awt.event.MouseEvent;
005    
006    import javax.swing.JPanel;
007    
008    import nl.cwi.sen1.gui.plugin.prefusedot.DotAdapter;
009    import nl.cwi.sen1.relationstores.Factory;
010    import nl.cwi.sen1.relationstores.types.Location;
011    import nl.cwi.sen1.relationstores.types.RTuple;
012    import nl.cwi.sen1.relationstores.types.RType;
013    import nl.cwi.sen1.relationstores.types.idcon.IdCon;
014    import nl.cwi.sen1.visplugin.VisualizationPluginWindow;
015    import prefuse.Display;
016    import prefuse.controls.ControlAdapter;
017    import prefuse.data.Graph;
018    import prefuse.visual.VisualItem;
019    
020    /**
021     * Graph Plugin VisualisationWindow. Shows a graph.
022     * 
023     * @author Anton Gerdessen (reviewer)
024     * @date 07-3-2007
025     */
026    public class GraphVisualizationWindow extends VisualizationPluginWindow {
027    
028        private static final int DOUBLE_CLICK = 2;
029    
030        private GraphBuilder graphBuilder;
031    
032        /**
033         * @todo Needs better implementation needs to be resolved reflection,
034         *       dynamic dispatch... in a the base or utility class for all plugins,
035         *       remark by Anton G.
036         */
037        private final String m_relationGraph = "relation([str,str])";
038    
039        private final String m_relationGraphTuple = "relation([tuple([str,loc]),tuple([str,loc])])";
040    
041            private final String m_attributedGraphTuple = "relation([tuple([str,relation([str,str])]),str])";
042    
043        /**
044         * This method is the respondant for a double click on an graph node and
045         * then signals to open the location
046         * 
047         * @param nodeId
048         *            This is the identifier of the double clicked node
049         * 
050         * @author Renze de Vries
051         * @date 14-03-2007
052         */
053        public void doLocationClick(String nodeId) {
054            // This retrieves the location and gives null if no Location was present
055            // for the node
056            Location loc = graphBuilder.getOrCreateLocation(nodeId, null);
057    
058            // check if this graph node really has a Location bound to the node
059            // and then open it
060            if (loc != null) {
061                openLocationInEditor(loc);
062            }
063        }
064    
065        /**
066         * Render the RTuple in a graph chart.
067         * 
068         * @param fact
069         *            RTuple with the information.
070         * @return JPanel holding the pie chart.
071         * @author A. Belgraver
072         * @author Anton Gerdessen (reviewer)
073         * @date 07-3-2007
074         */
075        public JPanel render(RTuple fact) {
076            // If the type issupported
077            if (!isTypeSupported(fact)) {
078                return new JPanel();
079            }
080    
081            // Create graph from rtuple
082            graphBuilder = new GraphBuilder(m_factory);
083            Graph graph = graphBuilder.buildGraphFromRTuple(fact);
084            GraphDisplayBuilder gvizBuilder = new GraphDisplayBuilder();
085            Display d = gvizBuilder.createDisplayFromGraph(graph);
086           
087    
088            d.addControlListener(new ControlAdapter() {
089                @Override
090                public void itemClicked(VisualItem item, MouseEvent e) {
091                    if (e.getClickCount() == DOUBLE_CLICK) {
092                        String nodeId = item.getString(DotAdapter.DOT_ID);
093    
094                        doLocationClick(nodeId);
095                    }
096                }
097            });
098    
099            // Create and return the panel with the graph
100            JPanel panel = new JPanel();
101            BorderLayout layout = new BorderLayout();
102            panel.setLayout(layout);
103            panel.add(d, BorderLayout.CENTER);
104    
105            return panel;
106        }
107    
108        /**
109         * Set a new Factory object, for testing purposes.
110         * 
111         * @param factory
112         *            Factory to use.
113         * @author A. Belgraver
114         * @author Anton Gerdessen (reviewer)
115         * @date 07-3-2007
116         */
117        public void setFactory(Factory factory) {
118            m_factory = factory;
119        }
120    
121        /**
122         * Check to see if the RTuple is indeed a <str,str> relation.
123         * 
124         * @param fact
125         *            RTuple to test.
126         * @return True if it is the correct str,str type.
127         * @author A. Belgraver
128         * @author Anton Gerdessen (reviewer)
129         * @date 07-3-2007
130         * @todo Needs better implementation needs to be resolved reflection,
131         *       dynamic dispatch... in a the base or utility class for all plugins,
132         *       remark by Anton G. *
133         */
134        public boolean isRelStrStr(RTuple fact) {
135            RType rType = m_factory.RTypeFromString(m_relationGraph);
136            return rType.equals(fact.getRtype());
137        }
138    
139        /**
140         * Check to see if the RTuple is indeed a tuple([str,loc]),tuple([str,loc])
141         * relation.
142         * 
143         * @param fact
144         *            RTuple to test.
145         * @return True if it is the correct tuple[str,loc],tuple[str,loc] type.
146         * @author Renze de Vries
147         * @date 13-3-2007
148         */
149        public boolean isRelTupleTuple(RTuple fact) {
150            RType rType = m_factory.RTypeFromString(m_relationGraphTuple);
151            return rType.equals(fact.getRtype());
152        }
153    
154        public boolean isAttributedGraphType(RTuple fact) {
155            RType rType = m_factory.RTypeFromString(m_attributedGraphTuple);
156            return rType.equals(fact.getRtype());
157        }
158    
159        /**
160         * Check if a given RType is supported by this visualisation.
161         * 
162         * @param fact
163         *            The facts for which to verify if the type is supported
164         * @return True if it itype is supported
165         * @author Anton Gerdessen
166         * 
167         * @date 07-3-2007
168         */
169        public boolean isTypeSupported(RTuple fact) {
170            return isRelStrStr(fact) || isRelTupleTuple(fact) || isAttributedGraphType(fact);
171        }
172    
173        /**
174         * Get the name of the RTuple.
175         * 
176         * @param fact
177         *            RTuple holding information
178         * @return String holding the name of the tuple
179         * @author A. Belgraver
180         * @author R. van Remortel
181         * @author Aldert Boerhoop (reviewer)
182         * @author Anton Gerdessen (reviewer)
183         * @date 07-3-2007
184         * @todo Needs better implementation needs to be resolved reflection,
185         *       dynamic dispatch... in a the base or utility class for all plugins,
186         *       remark by Anton G.
187         */
188        public String getRTupleName(RTuple fact) {
189            IdCon idCon = (IdCon) fact.getVariable();
190            return idCon.getString();
191        }
192    }