1 /***
2 * DependencyDialog.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 14.01.2003 pko modifications
9 * 17.07.2002 ctr creation
10 *
11 * Copyright 2003 ELCA Informatique SA
12 * Av. de la Harpe 22-24, 1000 Lausanne 13, Switzerland
13 * www.elca.ch
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public License
17 * as published by the Free Software Foundation; either version 2.1 of
18 * the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 */
30
31 package ch.elca.dependency.gui;
32
33 import att.grappa.*;
34
35 import ch.elca.dependency.core.DependencyModel;
36 import ch.elca.dependency.core.classinfo.ClassInfo;
37 import ch.elca.dependency.graph.Aggregator;
38 import ch.elca.dependency.view.GraphView;
39 import ch.elca.dependency.graph.Perspective;
40
41 import java.awt.*;
42 import java.awt.event.*;
43 import java.util.*;
44 import java.util.regex.Matcher;
45 import java.util.regex.Pattern;
46 import javax.swing.*;
47 import javax.swing.table.JTableHeader;
48 import javax.swing.table.TableColumnModel;
49
50 import org.apache.log4j.Logger;
51 import org.apache.regexp.RE;
52 import org.apache.regexp.RESyntaxException;
53
54 import info.clearthought.layout.TableLayout;
55
56 /***
57 * Dialog showing the classes involved in a package dependency (edge)
58 * and its type (uses, ext, impl). This class is responsible for the
59 * dialog appearing when the user does a double click on an edge in
60 * the graph representation.
61 *
62 * @author Christoph Trutmann
63 * @version 1.0-beta
64 */
65 public class DependencyDialog extends JDialog implements DependencyDetails {
66
67 private final static Logger LOG = Logger.getLogger(DependencyDialog.class);
68
69 /***
70 * Model for getting the class informations.
71 */
72 private DependencyModel m_model;
73
74 /***
75 * Model responsible for the data in the table.
76 */
77 private DependencyTableModel m_tableModel;
78
79 /***
80 * Current dependency edge.
81 */
82 private Edge m_currentEdge;
83
84 /***
85 * Constructor
86 *
87 * @param owner Sets the owner for this modal dialog.
88 * @param model Model for getting the class informations.
89 */
90 public DependencyDialog(Frame owner, DependencyModel model) {
91 super(owner, false);
92 m_model = model;
93 init();
94 }
95
96 /***
97 * Initialize the gui components of this dialog.
98 */
99 public void init(){
100
101 // add the window closing event
102 this.addWindowListener(new WindowAdapter() {
103 public void windowClosing(WindowEvent e) {
104 closeDialog();
105 }
106 });
107
108 double border = 10;
109 double fill = TableLayout.FILL;
110 double pref = TableLayout.PREFERRED;
111 double size[][] =
112 {{border, fill, pref, border}, // Columns
113 {border, fill, border, pref, border}}; // Rows
114
115 this.getContentPane().setLayout(new TableLayout(size));
116
117 // create dependency table
118 //
119 m_tableModel = new DependencyTableModel();
120 JTable depTable = new JTable(m_tableModel);
121
122 // the rows can't be selected
123 //
124 depTable.disable();
125
126 // set the columnwiths
127 //
128 depTable.getColumnModel().getColumn(0).setMinWidth(222);
129 depTable.getColumnModel().getColumn(1).setMinWidth(60);
130 depTable.getColumnModel().getColumn(2).setMinWidth(221);
131
132 // add mouse listener for sorting the rows of the table in order of the
133 // current selected column
134 JTableHeader header = depTable.getTableHeader();
135
136 // make columns not changable
137 header.setReorderingAllowed(false);
138
139 header.setUpdateTableInRealTime(true);
140 header.addMouseListener(new ColumnListener(depTable));
141
142 // set the resizing behavior of the columns
143 depTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
144
145 // Disable autoCreateColumnsFromModel otherwise all the
146 // column customizations and adjustments will be lost
147 // when the model data is sorted
148 depTable.setAutoCreateColumnsFromModel(false);
149
150 // make a scroll pane with the JTable inside
151 JScrollPane scrollpane = new JScrollPane(depTable);
152 scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
153 scrollpane.setPreferredSize(depTable.getPreferredSize());
154 scrollpane.setMinimumSize(depTable.getMinimumSize());
155
156 // add the dependency table to the content pane
157 this.getContentPane().add(scrollpane, "1, 1, 2, 1");
158
159 JPanel buttonPanel = new JPanel();
160
161 // ok button for closing the dialog
162 JButton okButton = new JButton("OK");
163 okButton.setMnemonic(KeyEvent.VK_O);
164 okButton.setPreferredSize(new Dimension(100,25));
165 okButton.addActionListener(new ActionListener() {
166 public void actionPerformed(ActionEvent e){
167 closeDialog();
168 }
169 });
170
171 // hide button for deleting the current edge
172 JButton hideButton = new JButton("Hide edge");
173 hideButton.setMnemonic(KeyEvent.VK_H);
174 hideButton.setPreferredSize(new Dimension(100, 25));
175 hideButton.addActionListener(new ActionListener(){
176 public void actionPerformed(ActionEvent e){
177 hideCurrentEdge();
178 }
179 });
180 buttonPanel.add(hideButton);
181 buttonPanel.add(okButton);
182
183 // add the dependency table to the content pane
184 getContentPane().add(buttonPanel, "1, 3, 2, 3");
185
186 // do the frame settings
187 setTitle("Edge dependency");
188 setSize(new Dimension(549, 200));
189 setLocation(400, 200);
190 setVisible(false);
191 setResizable(true);
192 }
193
194 /***
195 * Set the current dependency edge and show the informations.
196 *
197 * @param currentEdge Edge to set as current.
198 */
199 public void showDetails(Edge currentEdge){
200 m_currentEdge = currentEdge;
201 initializeTable();
202 setVisible(true);
203 }
204
205 /***
206 * Initilaizes the table with the data for the current edge.
207 */
208 private void initializeTable(){
209 m_tableModel.clear();
210
211 // head and tail nodes of this dependency edge
212 //
213 String headName = m_currentEdge.getHead().getName();
214 String tailName = m_currentEdge.getTail().getName();
215
216 // set the appropriate title
217 //
218 StringBuffer title = new StringBuffer("Dependency details from '");
219 title.append(tailName);
220 title.append("' to '");
221 title.append(headName);
222 title.append("'");
223 this.setTitle(title.toString());
224
225 // get the map with the filtered class informations
226 //
227 HashMap infos = m_model.getFilteredClassInfos();
228 ArrayList fromInfoList = null;
229 ArrayList keys = new ArrayList();
230
231 Perspective perspective = GraphView.singleton().getCurrentPerspective();
232 ArrayList aggregators = perspective.getAggregators();
233 Aggregator current = null;
234 String regexpString = "";
235
236 // find the regexp String used for this node
237 //
238 for (Iterator iter = aggregators.iterator(); iter.hasNext();) {
239 current = (Aggregator)iter.next();
240 if (current.getName().equals(tailName)) {
241 regexpString = current.getRegexp();
242 break;
243 }
244 }
245
246 if (!regexpString.equals("")) {
247 fromInfoList = new ArrayList();
248 RE regexp = null;
249 try {
250 regexp = new RE(regexpString);
251 } catch (RESyntaxException e) {
252 //
253 // this will not happen, as a Regexp is created previously
254 //
255 LOG.warn("An invalid regexp String used: " + regexpString);
256 //
257 }
258 String currentKey = "";
259
260 // Enumerate over all keys and get the keys which match the regexp
261 //
262 for (Iterator iter = infos.keySet().iterator(); iter.hasNext(); ) {
263 currentKey = (String)iter.next();
264 if (regexp.match(currentKey)) {
265 fromInfoList.addAll((ArrayList)infos.get(currentKey));
266 }
267 }
268 } else {
269 fromInfoList = (ArrayList)infos.get(tailName);
270 }
271
272
273 // perhaps head is an aggregate
274 //
275 ArrayList headz = new ArrayList();
276 if ((ArrayList)infos.get(headName) != null) {
277 headz.add(headName);
278 } else {
279 Aggregator aggregator = perspective.findAggregatorForName(headName);
280 Pattern regexp = aggregator.getPattern();
281 for (Iterator iter = infos.keySet().iterator(); iter.hasNext();) {
282 String keyString = (String)iter.next();
283 Matcher matcher = regexp.matcher(keyString);
284 if (matcher.matches()) {
285 headz.add(keyString);
286 }
287 }
288 }
289
290 // iterate over all headz
291 //
292 for (Iterator iter = headz.iterator(); iter.hasNext();) {
293 headName = (String)iter.next();
294
295 // iterate over the class infos of the from package
296 //
297 ListIterator fromListIter = fromInfoList.listIterator();
298 while ( fromListIter.hasNext() ) {
299 ClassInfo fromInfoTmp = (ClassInfo)fromListIter.next();
300
301 // check interfaces
302 Iterator interIter = fromInfoTmp.getImplInterfaces().iterator();
303 while ( interIter.hasNext() ) {
304 String interTmp = (String)interIter.next();
305 String interPack = interTmp.substring(0, interTmp.lastIndexOf("."));
306
307 // interface belongs to the target package
308 if ( interPack.equals(headName) ) {
309 String from = fromInfoTmp.getFullName().
310 substring(fromInfoTmp.getFullName().
311 lastIndexOf(".") + 1);
312 String to = interTmp.substring(interTmp.lastIndexOf(".") + 1);
313 m_tableModel.addDependency(from, "impl", to);
314 }
315 }
316
317 // check super class
318 //
319 String superClass = fromInfoTmp.getSuperClass();
320 String superPack = superClass.substring(0, superClass.lastIndexOf("."));
321 if ( ! superClass.equals("java.lang.Object") &&
322 superPack.equals(headName) ) {
323 String from = fromInfoTmp.getFullName().
324 substring(fromInfoTmp.getFullName().
325 lastIndexOf(".") + 1);
326 String to = superClass.substring(superClass.lastIndexOf(".") + 1);
327 m_tableModel.addDependency(from, "ext", to);
328 }
329
330 // check used classes
331 //
332 ListIterator usedIter
333 = fromInfoTmp.getNeededClasses().listIterator();
334 while ( usedIter.hasNext() ) {
335 String usedTmp = (String)usedIter.next();
336 String usedPack
337 = usedTmp.substring(0, usedTmp.lastIndexOf("."));
338
339 // used class belongs to the target package
340 //
341 if ( usedPack.equals(headName) ) {
342 String from = fromInfoTmp.getFullName().
343 substring(fromInfoTmp.getFullName().
344 lastIndexOf(".") + 1);
345 String to = usedTmp.substring(usedTmp.lastIndexOf(".") + 1);
346 m_tableModel.addDependency(from, "uses", to);
347 }
348 }
349 }
350 }
351
352 // sort the tabel according to the first row in ascending order
353 //
354 m_tableModel.sortAllRowsBy(0, true);
355 }
356
357 /***
358 * Helper method for closing the dialog.
359 */
360 private void closeDialog() {
361 this.setVisible(false);
362 }
363
364 /***
365 * Helper method for hiding the current edge.
366 */
367 private void hideCurrentEdge() {
368 if ( m_currentEdge == null ) {
369 return;
370 }
371 Graph graph = m_currentEdge.getGraph();
372 m_currentEdge.delete();
373 m_currentEdge = null;
374 this.hide();
375 }
376
377 /***
378 * Listener for the table column.
379 */
380 class ColumnListener extends MouseAdapter {
381
382 /***
383 * Table where the columns belong to.
384 */
385 protected JTable m_table;
386
387 /***
388 * Flag determining the order of the last sort.
389 */
390 protected boolean[] m_sortAsc = {false, true, true};
391
392 /***
393 * Constructor - Initialize the table.
394 */
395 public ColumnListener(JTable table) {
396 m_table = table;
397 }
398
399 /***
400 * Handling the mouse clicked events.
401 *
402 * @param e MouseEvents.
403 */
404 public void mouseClicked(MouseEvent e) {
405 TableColumnModel colModel = m_table.getColumnModel();
406 int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
407
408 if ( columnModelIndex < 0 ) {
409 return;
410 }
411
412 // sort the appropriate column in the specified order
413 //
414 m_tableModel.sortAllRowsBy(columnModelIndex, true);
415
416 // swap order for next time
417 //
418 m_sortAsc[columnModelIndex] = ! m_sortAsc[columnModelIndex];
419 }
420 }
421 }
This page was automatically generated by Maven