< Zurück | Weiter >

Abfrage ausführen und Ergebnismenge anzeigen

Das folgende Codebeispiel ist eine Swing-Anwendung, die folgende Operationen ausführt: Auswahl und Ausführung der Abfrage finden in der Methode run statt. Die Ergebnismenge wird mit der Methode showResults angezeigt. Nachfolgend ist das vollständige Beispiel aufgeführt:
static void run(String title, CqProvider provider, Viewer viewer)
    throws WvcmException
    {
        ResourceList<CqUserDb> databases =
            setUserFriendlyLocation(Utilities
                .getUserDbList(provider,
                               new PropertyRequest(CqUserDb.USER_FRIENDLY_LOCATION)));
        CqUserDb userDb = (CqUserDb)JOptionPane.showInputDialog
            (null, "Choose a Database to Explore", title, 
             JOptionPane.INFORMATION_MESSAGE, 
             null, databases.toArray(), databases.get(0));
    
        if (userDb == null) System.exit(0);
        
        userDb = (CqUserDb)userDb.doReadProperties
            (new PropertyRequest(CqUserDb.ALL_QUERIES.nest(CqQuery.USER_FRIENDLY_LOCATION)));
    
        // Liste in eine sortierte Tabelle umwandeln, die im Auswahldialog verwendet werden kann
        CqQuery[] queries = 
            setUserFriendlyLocation(userDb.getAllQueries()).toArray(new CqQuery[]{});
    
        Arrays.sort(queries, new Comparator<CqQuery>(){
                public int compare(CqQuery arg0, CqQuery arg1)
                { return arg0.toString().compareTo(arg1.toString()); }});
    
        // Die Liste der Abfragen für den Benutzer anzeigen und dem Benutzer
        // ermöglichen, eine Abfrage auszuwählen
        CqQuery query = (CqQuery)JOptionPane.showInputDialog
                    (null, "Choose a Query to Execute", 
                     "All Queries in " + userDb.location().string(), 
                     JOptionPane.INFORMATION_MESSAGE, null, 
                     queries, queries[0]);
        
        if (query == null) System.exit(0);
        
        CqResultSet results = 
            query.doExecute(1, Long.MAX_VALUE, CqQuery.COUNT_ROWS);
        
        // Wenn die Abfrage ordnungsgemäß ausgeführt wurde, die Daten
       // speichern und für die Anzeige vorbereiten
        if (results.hasNext()) {
            // Spalteninformationen, die über den Viewer zugänglich sind
            g_columns = results.getColumnLabels();
            g_cell = new CqRowData[(int)results.getRowCount()];
    
            for (CqRowData row: results)
                (g_cell[(int)row.getRowNumber()-1] = row).getValues();
            
            // Daten des Abfrageergebnisses anzeigen
            showResults(query.location().string(), viewer);
        }
    }
    
    /** Die Ergebnismenge, die zur Anzeige durch die Komponenten der grafischen */
    /** Benutzerschnittstelle bereitgestellt wird */
    static CqRowData[] g_cell;
    /** Die Spaltenüberschriften, die zur Anzeige durch die Komponenten der grafischen */
    /** Benutzerschnittstelle bereitgestellt werden */
    static String[] g_columns;
    
    /**
     * Ergebnismenge (in g_cell) in einer Tabelle anzeigen.
     * 
     * @param title - Die Titelzeichenfolge für das Fenster mit der Ergebnismenge.
     * @param viewer - Eine Viewer-Instanz, die für eine detaillierte Anzeige einer
     *                 einzelnen Ressource der Ergebnismenge verwendet werden soll. *                 Wenn null verwendet wird, wird die Option zum Anzeigen einer
     *                 einzelnen Ressource nicht bereitgestellt.
          */
    static void showResults(String title, final Viewer viewer) {
        // Definition des Tabellenmodells für das JTable-Fenster; eine Spalte für jedes
        // Anzeigefeld der Abfrage und eine Zeile für jede Zeile in der Abfrageergebnismenge.
                TableModel dataModel = new AbstractTableModel() {
    		 		 private static final long serialVersionUID = -3764643269044024406L;
    		 		 public int getColumnCount() { return g_columns.length; }
            public int getRowCount() { return g_cell.length;}
            public Object getValueAt(int row, int col) 
                { return g_cell[row].getValues()[col]; }
            public String getColumnName(int col)
                { return g_columns[col]; }
        };
        
        // Abfrageergebnisfenster mit einer optionalen Schaltfläche zum
        // Anzeigen des Datensatzes in einer ausgewählten Zeile erstellen
        // (in den Beispielen "Datensatz anzeigen" und "Datensatz ändern"
        // verwendet)
                final JFrame frame = new JFrame(title);
        final JTable table = new JTable(dataModel);
        JPanel panel = new JPanel(new BorderLayout());
        
        if (viewer != null) {
            JButton button = new JButton("Open");
    
            panel.add(button, BorderLayout.SOUTH);
            button.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent arg0)
                    {
                        int[] selected = table.getSelectedRows();
                        
                        for (int i = 0; i < selected.length; ++i)
                            try {
                                viewer.view((CqRecord) g_cell[selected[i]]
                                    .getRecord());
                            } catch (WvcmException e) {
                                Utilities.exception(frame, "View Record", e);
                            }
                    }
                });
        }
        
        panel.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.setBounds(300, 300, 600, 300);
        frame.setVisible(true);
    }
    
    static <U extends=""> ResourceList<U> 
    setUserFriendlyLocation(ResourceList<U> list)
    throws WvcmException
    {
        for (U res: list)
            res.modifyLocation(res.getUserFriendlyLocation());
    
        return list;
    }
    
    /**
     * Eine einfache Schnittstelle für ein Objekt, das eine Datensatzressource anzeigen soll.
     * (Wird von Erweiterungen des Beispiels ExecuteQuery (Abfrage ausführen) verwendet.)
     */
    static interface Viewer {
        /**
         * Zeigt eine Datensatzressource an
         * @param resource - Der Datensatz-Proxy für den Datensatz, der angezeigt werden soll.
         * @return TODO
         */
        JFrame view(CqRecord resource);
    }
    
    /**
     * Das Hauptprogramm für das Beispiel ExecuteQuery (Abfrage ausführen).
     * @param args - Nicht verwendet.
     * @throws Exception - Wenn ein Provider nicht instanziiert werden kann.
     */
    public static void main(String[] args) throws Exception
    {
        try {
            run("Execute Query", Utilities.getProvider().cqProvider(), null);
        } catch(Throwable ex) {
            Utilities.exception(null, "Execute Query", ex);
            System.exit(0);
        }
    }

In diesem Beispiel wird die Liste der verfügbaren Datenbanken wie in der vorherigen Lerneinheit erstellt. Die Liste wird dem Benutzer bereitgestellt, damit er eine einzelne Datenbank auswählt, an der er sich anmelden möchte.

Nach Auswahl einer Benutzerdatenbank durch den Benutzer wird die Eigenschaft ALL_QUERIES dieser Datenbank in die Anwendung gelesen. Der Wert dieser Eigenschaft ist eine Ressourcenliste (ResourceList) von CqQuery-Proxys. Diese Liste wird an der Position der Abfrage sortiert und dem Benutzer zur Auswahl einer einzelnen Abfrage, die ausgeführt werden soll, angezeigt.

Zur Auswahl der Datenbank und zur Auswahl der Abfrage wird dieselbe vielseitig einsetzbare Swing-Methode, JOptionPane.showInputDialog, verwendet. Die Eingabe ist der Array der Proxys, aus dem ausgewählt werden kann, und das Ergebnis ist der ausgewählte Proxy. Die Proxy-Methode toString() wird verwendet, um die Liste zu generieren, die dem Benutzer angezeigt wird. Die Methode toString() eines Proxy generiert ein Image des Positionsfelds des Proxy, z. B. Resource.location().string().

Weil die Position des Proxy angezeigt wird, muss sichergestellt werden, dass diese Position benutzerfreundlich ist, d. h., dass sie sich aus segmentierten Pfadnamen zusammensetzt anstatt aus Datenbankkennungen. Server können in den Proxys, die sie zurückgeben, ein beliebiges Format zur Angabe der Position verwenden. Normalerweise wählen sie das Format aus, das am effizientesten verarbeitet werden kann, wenn der Proxy verwendet wird, um zum Server zurückzukehren. Das effizienteste Format ist selten benutzerfreundlich. In jedem Fall sollte ein Client kein bestimmtes Format für die Position voraussetzen. Wenn also die Datenbankliste und die Abfrageliste angefordert werden, dann wird auch die Eigenschaft USER_FRIENDLY_LOCATION jedes Elements in der Liste angefordert. Anschließend wird in der Methode setUserFriendlyLocation die Position jedes Proxys in seine benutzerfreundliche Version geändert.

Die Anwendung ignoriert die Möglichkeit, dass die ausgewählte Abfrage dynamische Filter (auch Abfrageparameter genannt) definiert und ein abweichendes Verhalten aufweisen oder sogar scheitern kann, wenn die ausgewählte Abfrage über dynamische Filter verfügt. Eine stabilere Implementierung würde die Eigenschaft DYNAMIC_FILTERS der Abfrage vom Server anfordern und die fehlenden Daten vom Benutzer anfordern, bevor die Abfrage ausgeführt wird. Dies wird dem Leser als Übung überlassen.

Beachten Sie, dass CqRowData.getValues() für jede Zeile aufgerufen wird, wenn das Objekt CqRowData zur Anzeige in den Array gestellt wird. Dies ist erforderlich, weil die Informationen, die benötigt werden, um die Zeilendatenwerte als Java-Objekte zu berechnen, nicht mehr verfügbar sind, nachdem der CqResultSet-Iterator freigegeben wurde, und dies geschieht automatisch, wenn er das Ende erreicht hat.

Der zweite Parameter zur Ausführung von ExecuteQuery.showResults (Viewer genannt) wird in diesem Beispiel zwar nicht verwendet, aber er wird im nächsten Beispiel eingesetzt, damit der Benutzer eine Zeile der Ergebnismenge auswählen und den zugehörigen Datensatz anzeigen kann.

Prüfpunkt der Lerneinheit

Nachdem Sie gelernt haben, wie Sie mithilfe der ClearQuest CM-API eine Abfrage ausführen, können Sie selbstständig die verfügbaren API-Schnittstellen prüfen und herausfinden, wie Sie Abfragen schreiben oder vorhandene Abfragen ändern können.
In dieser Lerneinheit haben Sie gelernt, wie Sie mithilfe der ClearQuest CM-API eine Abfrage ausführen. Dabei haben Sie folgende Kenntnisse erworben:
  • Sie haben gelernt, welche ClearQuest CM-API-Objekte erforderlich sind, um eine Rational ClearQuest-Abfrage auszuführen.
  • Sie haben gelernt, wie eine Ergebnismenge iteriert wird.
  • Sie haben gelernt, wie eine Clientanwendung zur Ausführung einer Abfrage erstellt wird.
< Zurück | Weiter >

Feedback