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))); // 선택사항 대화 상자에서 사용하기 위해 정렬된 배열로 목록을 변환 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()); }}); // 사용자에게 조회 목록을 표시하고 사용자가 선택할 수 있도록 허용 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 (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(); // 조회 결과 데이터 표시 showResults(query.location().string(), viewer); } } /** GUI 컴포넌트에 액세스하여 표시할 수 있는 결과 세트 */ static CqRowData[] g_cell; /** GUI 컴포넌트에 액세스하여 표시할 수 있는 열 표제 */ static String[] g_columns; /** * 테이블에 결과 세트(g_cell)를 표시합니다. * * @param title 결과 세트 창의 제목 문자열 * @param viewer 결과 세트의 단일 자원에 대한 세부사항 표시에 사용되는 뷰어 인스턴스. * 널(null)인 경우에 단일 자원을 표시하는 옵션이 * 표시되지 않습니다. */ 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]; } }; // 조회 결과 창에 선택한 행에 레코드를 표시하는 // 추가 단추 생성(예: 보기 레코드 및 수정 레코드) // 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; } /** * 레코드 자원을 표시하는 오브젝트의 단순 인터페이스. * (ExecuteQuery 예제 확장에 사용.) */ static interface Viewer { /** * 레코드 자원 표시 * @param resource 표시할 레코드의 레코드 프록시. * @return TODO */ JFrame view(CqRecord resource); } /** * ExecuteQuery 에제의 기본 프로그램. * @param args 사용 안함. * @throws Exception Provider를 인스턴스화할 수 없는 경우. */ 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 오브젝트가 표시를 위해 배열로 넣어질 때 각 행에서 CqRowData.getValues()가 호출됨에 유의하십시오. CqResultSet 반복기가 해제된 후에는 행 데이터 값을 Java™ 오브젝트로 계산하는데 필요한 정보를 사용할 수 없게 되므로(끝에 도달하면 자동으로 발생함) 이것은 필수입니다.
이 샘플에서는 ExecuteQuery.showResults에 대한 두 번째 매개변수(이름 지정된 뷰어)가 사용되지 않지만 사용자가 결과 세트 행을 선택하고 연관된 레코드를 표시할 수 있도록 다음 예제에서는 사용됩니다.