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))); // Convert the list to a sorted array for use in the selection dialog 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()); }}); // Present the list of queries to the user and allow the user to select one 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); // If the query executed properly, save the data and prepare it for display if (results.hasNext()) { // Column information accessed from the viewer g_columns = results.getColumnLabels(); g_cell = new CqRowData[(int)results.getRowCount()]; for (CqRowData row: results) (g_cell[(int)row.getRowNumber()-1] = row).getValues(); // Display the query result data showResults(query.location().string(), viewer); } } /** The result set made accessible to the GUI components for display */ static CqRowData[] g_cell; /** The column headings made accessible to the GUI components for display */ static String[] g_columns; /** * Displays the result set (in g_cell) in a table. * * @param title The title string for the result set window * @param viewer A Viewer instance to be used for a detailed display of a * single resource of the result set. May be null, in which case * the option to display a single resource is not presented. */ static void showResults(String title, final Viewer viewer) { // Define the table model for the JTable window; one column for each // query display field and one row for each row of the query result set. 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]; } }; // Construct the query result window with an optional button for // displaying the record in a selected row (used in the View Record and // Modify Record examples) 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; } /** * A simple interface for an object that will display a Record resource. * (Used by extensions to the ExecuteQuery example.) */ static interface Viewer { /** * Displays a Record resource * @param resource The Record proxy for the record to be displayed. * @return TODO */ JFrame view(CqRecord resource); } /** * The main program for the ExecuteQuery example. * @param args Not used. * @throws Exception If a provider cannot be instantiated. */ 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); } }
이 예제에서, 사용 가능한 데이터베이스 목록은 이전 레슨에서와 같이 생성됩니다. 그리고 목록은 사용자가 로그인하기 위해 단일 데이터베이스를 선택할 수 있도록 표시됩니다.
사용자가 사용자 데이터베이스를 선택하면 해당 데이터베이스의 ALL_QUERIES 특성이 애플리케이션으로 읽혀집니다. 이 특성의 값은 CqQuery 프록시의 ResourceList입니다. 이 목록은 조회 위치에서 정렬되며 사용자가 실행할 단일 조회를 선택하도록 제시됩니다.
데이터베이스 선택 및 조회 선택을 위해 동일한 범용 Swing 메소드인 JOptionPane.showInputDialog가 사용됩니다. 입력은 그 중에서 선택할 프록시 배열이고 결과는 선택된 프록시입니다. 프록시 toString() 메소드를 사용하여 사용자에게 표시될 목록을 생성합니다. 프록시의 toString() 메소드는 프록시의 위치 필드 이미지(즉, Resource.location().string())를 생성합니다.
프록시의 위치가 표시되므로, 프록시의 위치가 사용자에게 친숙한(즉, 데이터베이스 ID 대신 세그먼트화된 경로 이름으로 구성되는) 위치인지 확인해야 합니다. 서버는 리턴하는 프록시에서 어떤 양식의 위치도 사용할 수 있습니다. 일반적으로, 프록시가 서버로 다시 가져가기 위해 사용되는 경우 가장 효율적으로 처리되는 형식을 선택합니다. 가장 효율적인 형식은 좀처럼 사용자에게 친숙하지 않습니다. 어느 경우에는 클라이언트가 사용되는 위치 양식을 가정하면 안됩니다. 따라서 데이터베이스 목록과 조회 목록을 요청할 때 목록에 있는 각 항목의 USER_FRIENDLY_LOCATION 특성도 요청합니다. 그런 다음 setUserFriendlyLocation 메소드에서 각 프록시의 위치를 해당되는 사용자에 친숙한 버전으로 수정합니다.
이 애플리케이션은 선택된 조회가 동적 필터(조회 매개변수라고도 함)를 정의할 가능성을 무시하므로, 선택된 조회에 동적 필터가 있는 경우 실패하거나 이상한 동작을 금지합니다. 더 강력한 구현은 서버에서 조회의 DYNAMIC_FILTERS 특성을 요청하고 조회를 실행하기 전에 사용자로부터 누락된 데이터를 얻는 것입니다. 이는 리더를 위한 연습용으로 남겨집니다.
CqRowData.getValues()는 CqRowData 오브젝트가 표시를 위해 배열에 놓일 때 각 행에서 호출된다는 점에 유의하십시오. 이는 CqResultSet 반복기가 해제(끝에 도달할 때 자동으로 발생함)된 후 Java™ 오브젝트를 사용할 수 없어서 행 데이터 값을 계산하기 위해 필요한 정보로 인해 필요합니다.
ExecuteQuery.showResults에 대한 두 번째 매개변수(viewer라고 함)는 이 샘플에서 사용되지 않지만, 사용자가 결과 세트 행을 선택하고 연관된 레코드를 표시할 수 있도록 하기 위해 다음 예제에서 사용됩니다.