001 /*
002 * file ExecuteQuery.java
003 *
004 * Licensed Materials - Property of IBM
005 * Restricted Materials of IBM - you are allowed to copy, modify and
006 * redistribute this file as part of any program that interfaces with
007 * IBM Rational CM API.
008 *
009 * com.ibm.rational.stp.client.samples.ExecuteQuery
010 *
011 * © Copyright IBM Corporation 2005, 2008. All Rights Reserved.
012 * Note to U.S. Government Users Restricted Rights: Use, duplication or
013 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
014 */
015 package com.ibm.rational.stp.client.samples;
016
017 import java.awt.BorderLayout;
018 import java.awt.event.ActionEvent;
019 import java.awt.event.ActionListener;
020 import java.util.Arrays;
021 import java.util.Comparator;
022
023 import javax.swing.JButton;
024 import javax.swing.JFrame;
025 import javax.swing.JOptionPane;
026 import javax.swing.JPanel;
027 import javax.swing.JScrollPane;
028 import javax.swing.JTable;
029 import javax.swing.table.AbstractTableModel;
030 import javax.swing.table.TableModel;
031 import javax.wvcm.ResourceList;
032 import javax.wvcm.WvcmException;
033 import javax.wvcm.PropertyRequestItem.PropertyRequest;
034
035 import com.ibm.rational.wvcm.stp.StpResource;
036 import com.ibm.rational.wvcm.stp.cq.CqProvider;
037 import com.ibm.rational.wvcm.stp.cq.CqQuery;
038 import com.ibm.rational.wvcm.stp.cq.CqRecord;
039 import com.ibm.rational.wvcm.stp.cq.CqResultSet;
040 import com.ibm.rational.wvcm.stp.cq.CqRowData;
041 import com.ibm.rational.wvcm.stp.cq.CqUserDb;
042
043 /**
044 * Pick a query from a list of those available in a database and execute it.
045 * Display the result in a table.
046 */
047 public class ExecuteQuery {
048
049 /**
050 * Asks the user to select a database and a query in that database and then
051 * executes the query, displaying the results in a table.
052 * @param title The title string used in the initial dialog
053 * @param provider A javax.wvcm provider for accessing ClearQuest
054 * @param viewer A Viewer instance for displaying an individual row of the
055 * results set. May be null.
056 * @throws WvcmException
057 */
058 static void run(String title, CqProvider provider, Viewer viewer)
059 throws WvcmException
060 {
061 ResourceList<CqUserDb> databases =
062 setUserFriendlyLocation(Utilities
063 .getUserDbList(provider,
064 new PropertyRequest(CqUserDb.USER_FRIENDLY_LOCATION)));
065 CqUserDb userDb = (CqUserDb)JOptionPane.showInputDialog
066 (null, "Choose a Database to Explore", title,
067 JOptionPane.INFORMATION_MESSAGE,
068 null, databases.toArray(), databases.get(0));
069
070 if (userDb == null) System.exit(0);
071
072 userDb = (CqUserDb)userDb.doReadProperties
073 (new PropertyRequest(CqUserDb.ALL_QUERIES.nest(CqQuery.USER_FRIENDLY_LOCATION)));
074
075 // Convert the list to a sorted array for use in the selection dialog
076 CqQuery[] queries =
077 setUserFriendlyLocation(userDb.getAllQueries()).toArray(new CqQuery[]{});
078
079 Arrays.sort(queries, new Comparator<CqQuery>(){
080 public int compare(CqQuery arg0, CqQuery arg1)
081 { return arg0.toString().compareTo(arg1.toString()); }});
082
083 // Present the list of queries to the user and allow the user to select one
084 CqQuery query = (CqQuery)JOptionPane.showInputDialog
085 (null, "Choose a Query to Execute",
086 "All Queries in " + userDb.location().string(),
087 JOptionPane.INFORMATION_MESSAGE, null,
088 queries, queries[0]);
089
090 if (query == null) System.exit(0);
091
092 CqResultSet results =
093 query.doExecute(1, Long.MAX_VALUE, CqQuery.COUNT_ROWS);
094
095 // If the query executed properly, internalize the data and prepare it for display
096 if (results.hasNext()) {
097 // Column information accessed from the viewer
098 g_columns = results.getColumnLabels();
099 g_cell = new CqRowData[(int)results.getRowCount()];
100
101 for (CqRowData row: results)
102 (g_cell[(int)row.getRowNumber()-1] = row).getValues();
103
104 // Display the query result data
105 showResults(query.location().string(), viewer);
106 }
107 }
108
109 /** The result set made accessible to the GUI components for display */
110 static CqRowData[] g_cell;
111 /** The column headings made accessible to the GUI components for display */
112 static String[] g_columns;
113
114 /**
115 * Displays the result set (in g_cell) in a table.
116 *
117 * @param title The title string for the result set window
118 * @param viewer A Viewer instance to be used for a detailed display of a
119 * single resource of the result set. May be null, in which case
120 * the option to display a single resource is not presented.
121 */
122 static void showResults(String title, final Viewer viewer) {
123 // Define the table model for the JTable window; one column for each
124 // query display field and one row for each row of the query result set.
125 TableModel dataModel = new AbstractTableModel() {
126 private static final long serialVersionUID = -3764643269044024406L;
127 public int getColumnCount() { return g_columns.length; }
128 public int getRowCount() { return g_cell.length;}
129 public Object getValueAt(int row, int col)
130 { return g_cell[row].getValues()[col]; }
131 public String getColumnName(int col)
132 { return g_columns[col]; }
133 };
134
135 // Construct the query result window with an optional button for
136 // displaying the record in a selected row (used in the View Record and
137 // Modify Record examples)
138 final JFrame frame = new JFrame(title);
139 final JTable table = new JTable(dataModel);
140 JPanel panel = new JPanel(new BorderLayout());
141
142 if (viewer != null) {
143 JButton button = new JButton("Open");
144
145 panel.add(button, BorderLayout.SOUTH);
146 button.addActionListener(new ActionListener(){
147 public void actionPerformed(ActionEvent arg0)
148 {
149 int[] selected = table.getSelectedRows();
150
151 for (int i = 0; i < selected.length; ++i)
152 try {
153 viewer.view((CqRecord) g_cell[selected[i]]
154 .getRecord());
155 } catch (WvcmException e) {
156 Utilities.exception(frame, "View Record", e);
157 }
158 }
159 });
160 }
161
162 panel.add(new JScrollPane(table), BorderLayout.CENTER);
163 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
164 frame.setContentPane(panel);
165 frame.setBounds(300, 300, 600, 300);
166 frame.setVisible(true);
167 }
168
169 static <U extends StpResource> ResourceList<U>
170 setUserFriendlyLocation(ResourceList<U> list)
171 throws WvcmException
172 {
173 for (U res: list)
174 res.modifyLocation(res.getUserFriendlyLocation());
175
176 return list;
177 }
178
179 /**
180 * A simple interface for an object that will display a Record resource.
181 * (Used by extensions to the ExecuteQuery example.)
182 */
183 static interface Viewer {
184 /**
185 * Displays a Record resource
186 * @param resource The Record proxy for the record to be displayed.
187 * @return TODO
188 */
189 JFrame view(CqRecord resource);
190 }
191
192 /**
193 * The main program for the ExecuteQuery example.
194 * @param args Not used.
195 * @throws Exception If a provider cannot be instantiated.
196 */
197 public static void main(String[] args) throws Exception
198 {
199 try {
200 run("Execute Query", Utilities.getProvider().cqProvider(), null);
201 } catch(Throwable ex) {
202 Utilities.exception(null, "Execute Query", ex);
203 System.exit(0);
204 }
205 }
206 }