View Javadoc

1   /*
2    *  Licensed under the Apache License, Version 2.0 (the "License");
3    *  you may not use this file except in compliance with the License.
4    *  You may obtain a copy of the License at
5    *
6    *      http://www.apache.org/licenses/LICENSE-2.0
7    *
8    *  Unless required by applicable law or agreed to in writing, software
9    *  distributed under the License is distributed on an "AS IS" BASIS,
10   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   *  See the License for the specific language governing permissions and
12   *  limitations under the License.
13   */
14  /*
15   * This file has been modified by Chris Pheby in accordance with Section 4.2
16   * of the Apache Software License
17   */
18  package org.jadira.dependencynavigator.gui;
19  
20  /**********************************************************************you may not use this file except in compliance with the License. You may obtain a copy of the License at
21   * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
22   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
23   * either express or implied. See the License for the specific language governing permissions and limitations under the
24   * License. Contributors:
25   **********************************************************************/
26  import java.awt.Cursor;
27  import java.awt.Dimension;
28  import java.awt.FlowLayout;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import java.awt.event.MouseAdapter;
32  import java.awt.event.MouseEvent;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.util.Properties;
36  
37  import javax.swing.BoxLayout;
38  import javax.swing.JButton;
39  import javax.swing.JCheckBox;
40  import javax.swing.JFrame;
41  import javax.swing.JLabel;
42  import javax.swing.JPanel;
43  import javax.swing.JScrollPane;
44  import javax.swing.JSplitPane;
45  import javax.swing.JTable;
46  import javax.swing.JTree;
47  import javax.swing.ListSelectionModel;
48  import javax.swing.SwingUtilities;
49  import javax.swing.table.JTableHeader;
50  
51  import org.jadira.dependencynavigator.controller.ArtifactResolver;
52  import org.jadira.dependencynavigator.controller.Controller;
53  import org.jadira.dependencynavigator.controller.model.DuplicatesListManager;
54  import org.jadira.dependencynavigator.implementations.WorkspaceLoader;
55  import org.jadira.dependencynavigator.model.ArtifactInitialisationException;
56  import org.jadira.repositorysnapshot.RepositorySnapshotFactory;
57  
58  public class DependencyBrowserGui {
59  
60      public static final String ROLE = "org.jadira.dependencynavigator.gui.DependencyBrowserGui";
61  
62      private static final String PROPERTIES = "/META-INF/maven/org.jadira/maven-dependency-browser-swing-gui/pom.properties";
63  
64      private JTree tree;
65      private Controller controller;
66      private JFrame frame;
67      private JTable versions;
68      private JTable duplicates;
69      private WorkspaceLoader workspaceLoader;
70      private ArtifactResolver resolver;
71      private DuplicatesListManager duplicatesListManager;
72      private ProgressMeter progressMeter;
73      private RepositorySnapshotFactory repositorySnapshotFactory;
74  
75      public void open() {
76          frame.setTitle("Maven Dependency Navigator" + loadVersion());
77          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
78          frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
79  
80          JPanel topPanel = new JPanel();
81          topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
82  
83          topPanel.add(createLoadButton());
84          topPanel.add(createCheckBox("compile", controller.getCheckShowCompile()));
85          topPanel.add(createCheckBox("test", controller.getCheckShowTest()));
86          topPanel.add(createCheckBox("runtime", controller.getCheckShowRuntime()));
87          topPanel.add(createCheckBox("provided", controller.getCheckShowProvided()));
88          topPanel.add(createCheckBox("exclusions", controller.getResolveExclusions()));
89          topPanel.add(createSnapshotButton());
90  
91          JPanel bottomPanel = new JPanel();
92          bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
93          JLabel progressLabel = new JLabel();
94          bottomPanel.add(progressLabel);
95          progressMeter = new ProgressMeter(progressLabel);
96          progressMeter.ready();
97  
98          tree = new JTree(new DependencyTreeModel(workspaceLoader.getRoot()));
99          tree.setCellRenderer(new DependencyTreeRenderer());
100         versions = new JTable(new VersionsTableModel(duplicatesListManager));
101         versions.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
102         versions.setDefaultRenderer(String.class, new SelectableTableModelRenderer());
103         versions.addMouseListener(new MouseAdapter() {
104 
105             @Override
106             public void mouseClicked(MouseEvent e) {
107                 JTable table = (JTable) e.getComponent();
108                 duplicatesListManager.deselect();
109                 duplicatesListManager.getVersionsListManager().select(table.getSelectedRow());
110                 tree.repaint();
111                 versions.repaint();
112                 duplicates.repaint();
113             }
114 
115         });
116         versions.getTableHeader().addMouseListener(new MouseAdapter() {
117 
118             @Override
119             public void mouseClicked(MouseEvent e) {
120                 JTableHeader h = (JTableHeader) e.getSource();
121                 int vColIndex = h.getColumnModel().getColumnIndexAtX(e.getX());
122                 int mColIndex = h.getTable().convertColumnIndexToModel(vColIndex);
123                 duplicatesListManager.getVersionsListManager().setArtifactInstanceMapComparator(mColIndex);
124                 versions.repaint();
125             }
126 
127         });
128         duplicates = new JTable(new DuplicatesTableModel(duplicatesListManager));
129         duplicates.setDefaultRenderer(String.class, new SelectableTableModelRenderer());
130         duplicates.addMouseListener(new MouseAdapter() {
131 
132             @Override
133             public void mouseClicked(MouseEvent e) {
134                 JTable table = (JTable) e.getComponent();
135                 duplicatesListManager.select(table.getSelectedRow());
136                 tree.repaint();
137                 versions.repaint();
138                 duplicates.repaint();
139             }
140 
141         });
142         duplicates.getTableHeader().addMouseListener(new MouseAdapter() {
143             @Override
144             public void mouseClicked(MouseEvent e) {
145                 duplicatesListManager.setOrderByIdentifier();
146                 duplicates.repaint();
147             }
148         });
149 
150         JSplitPane versionsSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(versions), new JScrollPane(duplicates));
151         JPanel versionsPanel = new JPanel();
152         versionsPanel.setLayout(new BoxLayout(versionsPanel, BoxLayout.PAGE_AXIS));
153         versionsPanel.add(versionsSplit);
154 
155         JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(tree), versionsPanel);
156 
157         JPanel mainPanel = new JPanel();
158         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
159         mainPanel.add(mainSplitPane);
160 
161         mainPanel.setPreferredSize(new Dimension(800, 600));
162 
163         frame.getContentPane().add(topPanel);
164         frame.getContentPane().add(mainPanel);
165         frame.getContentPane().add(bottomPanel);
166         frame.pack();
167         frame.setVisible(true);
168 
169         mainSplitPane.setDividerLocation(0.5);
170         mainSplitPane.setResizeWeight(0.5);
171         versionsSplit.setDividerLocation(0.7);
172         versionsSplit.setResizeWeight(0.7);
173     }
174 
175     private JButton createLoadButton() {
176         JButton loadButton = new JButton("Load");
177         loadButton.addActionListener(new ActionListener() {
178 
179             public void actionPerformed(ActionEvent e) {
180                 frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
181                 PomLoaderThread pomLoader = new PomLoaderThread(workspaceLoader, "pom loader") {
182 
183                     public void run() {
184                         try {
185 
186                             duplicatesListManager.reset();
187                             duplicates.repaint();
188                             versions.repaint();
189 
190                             workspaceLoader.loadPom();
191                             if (workspaceLoader.getRoot() != null) {
192                                 workspaceLoader.getRoot().resolveDependencies(resolver, progressMeter);
193                             }
194                             progressMeter.ready();
195                         } catch (ArtifactInitialisationException e) {
196                             progressMeter.error(e);
197                             e.printStackTrace();
198                         } catch (RuntimeException e) {
199                             progressMeter.error(e);
200                             e.printStackTrace();
201                         }
202                         updateModel();
203                     }
204                 };
205                 pomLoader.start();
206             }
207 
208         });
209 
210         return loadButton;
211     }
212 
213     private JCheckBox createCheckBox(String label, final Controller.BooleanController bcontroller) {
214         JCheckBox checkBox = new JCheckBox(label, bcontroller.getValue());
215         checkBox.addActionListener(new ActionListener() {
216 
217             public void actionPerformed(ActionEvent e) {
218                 frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
219                 bcontroller.toggle();
220                 PomLoaderThread pomLoader = new PomLoaderThread(workspaceLoader, "pom loader") {
221 
222                     public void run() {
223                         try {
224                             duplicatesListManager.reset();
225                             workspaceLoader.reloadPom();
226                             workspaceLoader.getRoot().resolveDependencies(resolver, progressMeter);
227                             progressMeter.ready();
228                         } catch (ArtifactInitialisationException e) {
229                             progressMeter.error(e);
230                         } catch (RuntimeException e) {
231                             progressMeter.error(e);
232                         }
233                         updateModel();
234                     }
235                 };
236                 pomLoader.start();
237             }
238         });
239         return checkBox;
240     }
241 
242     private abstract class PomLoaderThread implements Runnable {
243 
244         protected WorkspaceLoader workspaceLoader;
245         private String name;
246 
247         public PomLoaderThread(WorkspaceLoader workspaceLoader, String name) {
248             this.workspaceLoader = workspaceLoader;
249             this.name = name;
250         }
251 
252         public void start() {
253             Thread thread = new Thread(this);
254             thread.setName(name);
255             thread.setDaemon(true);
256             thread.start();
257         }
258     }
259 
260     /**
261      * called by background thread to queue a gui model reload
262      */
263     public void updateModel() {
264         Runnable modelUpdate = new Runnable() {
265 
266             public void run() {
267                 tree.setModel(new DependencyTreeModel(workspaceLoader.getRoot()));
268                 versions.setModel(new VersionsTableModel(duplicatesListManager));
269                 duplicates.setModel(new DuplicatesTableModel(duplicatesListManager));
270                 frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
271             }
272         };
273         SwingUtilities.invokeLater(modelUpdate);
274     }
275 
276     /**
277      * extract the version number from the maven pom.properties file. fail silently if we can't find it as this
278      * functionality is optional.
279      */
280     private String loadVersion() {
281         InputStream resourceStream = DependencyBrowserGui.class.getResourceAsStream(PROPERTIES);
282         if (resourceStream == null) {
283             return "";
284         }
285         Properties properties = new Properties();
286         try {
287             properties.load(resourceStream);
288         } catch (IOException e) {
289             return "";
290         }
291         String version = properties.getProperty("version");
292         if (version == null || version.trim().length() == 0) {
293             return "";
294         }
295         return " " + version;
296     }
297 
298     private JButton createSnapshotButton() {
299         JButton snapshotButton = new JButton("Snapshot");
300         snapshotButton.setEnabled(repositorySnapshotFactory.isSnapshotEnabled());
301         snapshotButton.addActionListener(new ActionListener() {
302 
303             public void actionPerformed(ActionEvent e) {
304                 repositorySnapshotFactory.createSnapshot(progressMeter);
305             }
306         });
307         return snapshotButton;
308     }
309 }