package dods.clients.importwizard.GCMD; // Import all of java... import dods.clients.importwizard.*; import dods.clients.importwizard.ECHO.*; import java.lang.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import java.util.*; import java.io.*; import java.net.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.swing.table.*; import gnu.regexp.*; /** * This class searches the GCMD database for datasets. */ public class FreeTextSearch extends SearchInterface implements ActionListener, ListSelectionListener { String url; DefaultHandler handler; Hashtable difs; Hashtable difPanels; Vector searchPanels; GridBagLayout gridbag; GridBagConstraints c; JPanel centerPanel; JPanel tempPanel; JTable idTable; JScrollPane idTableScroller; JPanel topPanel; JScrollPane topScroller; JPanel buttonPanel; JComboBox logicTypeBox; JButton searchButton; JButton showAllButton; JPanel bottomPanel; JPanel infoPanel; JButton returnButton; public FreeTextSearch(String baseURL) { url = baseURL; difs = new Hashtable(); difPanels = new Hashtable(); searchPanels = new Vector(); handler = new DifHandler(); initGUI(); } private void initGUI() { idTable = new JTable(); idTableScroller = new JScrollPane(idTable); topPanel = new JPanel(); topScroller = new JScrollPane(topPanel); infoPanel = new JPanel(); centerPanel = new JPanel(); buttonPanel = new JPanel(); String[] logicTypes = { "AND", "OR" }; logicTypeBox = new JComboBox(logicTypes); searchButton = new JButton("Search"); showAllButton = new JButton("Show All"); gridbag = new GridBagLayout(); c = new GridBagConstraints(); // // Setup the search panel // topScroller.setPreferredSize(new Dimension(600,97)); topScroller.setMinimumSize(new Dimension(600,97)); topPanel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); SearchPanel search = new SearchPanel(); search.addActionListener(this); search.setActionCommands("togglePanel", "search"); search.setMaximumSize(new Dimension(32768,30)); searchPanels.addElement(search); topPanel.add(search); search.setEnabled(true); search = new SearchPanel(); search.addActionListener(this); search.setActionCommands("togglePanel", "search"); search.setMaximumSize(new Dimension(32768,30)); searchPanels.addElement(search); topPanel.add(search); search.setEnabled(false); // // Setup the button panel // JPanel temp = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); buttonPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(2,2,2,2))); temp.add(new JLabel("Logic:")); temp.add(logicTypeBox); buttonPanel.add(temp); buttonPanel.add(Box.createVerticalGlue()); searchButton.addActionListener(this); searchButton.setActionCommand("search"); searchButton.setAlignmentX(JComponent.CENTER_ALIGNMENT); buttonPanel.add(searchButton); showAllButton.addActionListener(this); showAllButton.setActionCommand("showAll"); showAllButton.setAlignmentX(JComponent.CENTER_ALIGNMENT); buttonPanel.add(showAllButton); buttonPanel.add(Box.createVerticalGlue()); // // Setup the ID list // centerPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Matching Datasets")); centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS)); idTableScroller.setBackground(java.awt.Color.white); Object[] selected = { }; Object[] ids = { }; idTable.setPreferredScrollableViewportSize(new Dimension(600, 300)); idTable.setModel(new GCMDTableModel(selected, ids)); idTable.getColumnModel().getColumn(0).setMaxWidth(80); idTable.getSelectionModel().addListSelectionListener(this); centerPanel.add(idTableScroller); infoPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Dataset Information")); infoPanel.setPreferredSize(new Dimension(600,50)); // // Add the components into the main panel // setLayout(gridbag); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.weighty = 0; c.fill = GridBagConstraints.BOTH; gridbag.setConstraints(topScroller, c); add(topScroller); c.gridx = 1; c.gridy = 0; c.weightx = 0; c.weighty = 0; c.fill = GridBagConstraints.BOTH; gridbag.setConstraints(buttonPanel, c); add(buttonPanel); c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.weightx = 1; c.weighty = 1; gridbag.setConstraints(centerPanel, c); add(centerPanel); c.gridx = 0; c.gridy = 2; c.gridwidth = 2; c.weightx = 1; c.weighty = 0; gridbag.setConstraints(infoPanel, c); add(infoPanel); } protected Dif getDif(String difName, String sections) { //DefaultHandler handler = new DifHandler(); //SAXParserFactory factory = SAXParserFactory.newInstance(); /* Extracts info from Dif returned from the first query. No needs to make another query. try { //URL xmlFile = new URL(url + "/getdif.py?entry_id=" + difName URL xmlFile = new URL(url + "/getdifs.py?query=" + URLEncoder.encode("[Project:Short_Name='DODS']") + "&entry_id=" + difName + "&format=xml§ions=" + sections); System.out.println(url + "/getdifs.py?query=" + URLEncoder.encode("[Project:Short_Name='DODS']") + "&entry_id=" + difName + "&format=xml§ions=" + sections); //System.out.println(url + "/getdif.py?entry_id=" + difName // + "&format=xml§ions=" + sections); InputStream urlStream = xmlFile.openStream(); SAXParser saxParser = factory.newSAXParser(); saxParser.parse( urlStream, handler ); } catch(Throwable t) { t.printStackTrace(); } */ return (Dif)((DifHandler)handler).getDifs().elementAt(0); } /** * The function to handle action events. * @param e The event. */ public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); // This event is generated when the user clicks the checkbox next // to a search field. Enable the search panel if it's disabled and // if it's the last one, create a new disabled search panel. if(command.equals("togglePanel")) { if(searchPanels.lastElement().equals(e.getSource()) && ((SearchPanel)e.getSource()).isEnabled() == false) { SearchPanel search = new SearchPanel(); search.setEnabled(false); search.setMaximumSize(new Dimension(32768, 30)); search.addActionListener(this); search.setActionCommands("togglePanel", "search"); searchPanels.addElement(search); topPanel.add(search); validate(); } ((SearchPanel)e.getSource()).toggleEnabled(); } // From the show all button. Retrieve all the DODS datasets from // GCMD and show them. else if(command.equals("showAll")) { SearchThread search = new SearchThread(""); tempPanel = search.createTempPanel(); tempPanel.setMinimumSize(centerPanel.getSize()); tempPanel.setPreferredSize(centerPanel.getSize()); centerPanel.setVisible(false); c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.weightx = 1; c.weighty = 1; gridbag.setConstraints(tempPanel, c); remove(centerPanel); add(tempPanel); search.start(); } // Triggered by either the search button, or by hitting enter // inside one of the text fields. Build a search string from // the enabled search panels, and get all the datasets that match. else if(command.equals("search")) { String searchString = ""; String logicType = (String)logicTypeBox.getSelectedItem(); for(int i=0;i<searchPanels.size();i++) { if(((SearchPanel)searchPanels.elementAt(i)).isEnabled()) { if(!searchString.equals("")) searchString += " " + logicType + " "; searchString += ((SearchPanel)searchPanels.elementAt(i)).getSearchString(); } } //add spatial query JPanel spatial = ((GCMDSearch)getParent().getParent()).getSpatial(); if (((SpatialPanel)spatial).spatialIsSet()) { //southernmost String value = ((SpatialPanel)spatial).getSouthernmost().toUpperCase(); try { RE spaces = new RE(" "); value = spaces.substituteAll(value, "%20"); } catch(Exception ex) {} searchString += " AND " + "[Spatial_Coverage:Southernmost_Latitude='" + value + "',"; //northernmost value = ((SpatialPanel)spatial).getNorthernmost().toUpperCase(); try { RE spaces = new RE(" "); value = spaces.substituteAll(value, "%20"); } catch(Exception ex) {} searchString += "Northernmost_Latitude='" + value + "',"; //westernmost value = ((SpatialPanel)spatial).getWesternmost().toUpperCase(); try { RE spaces = new RE(" "); value = spaces.substituteAll(value, "%20"); } catch(Exception ex) {} searchString += "Westernmost_Longitude='" + value + "',"; //easternmost value = ((SpatialPanel)spatial).getEasternmost().toUpperCase(); try { RE spaces = new RE(" "); value = spaces.substituteAll(value, "%20"); } catch(Exception ex) {} searchString += "Easternmost_Longitude='" + value + "']"; } SearchThread search = new SearchThread(searchString); tempPanel = search.createTempPanel(); tempPanel.setMinimumSize(centerPanel.getSize()); tempPanel.setPreferredSize(centerPanel.getSize()); centerPanel.setVisible(false); c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.weightx = 1; c.weighty = 1; gridbag.setConstraints(tempPanel, c); remove(centerPanel); add(tempPanel); search.start(); } else if(command.equals("getSummary")) { JFrame summaryWindow = new JFrame(); JTextArea summaryText = new JTextArea(); JScrollPane summaryScroller = new JScrollPane(summaryText); int index = idTable.getSelectionModel().getMinSelectionIndex(); Dif dif = (Dif)idTable.getValueAt(index,1); summaryText.setEditable(false); if(dif.getSummary().equals("")) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) dif.setSummary("No Summary Available"); } summaryText.setText(dif.getSummary()); summaryWindow.setTitle(dif.getTitle()); summaryWindow.getContentPane().add(summaryScroller); summaryWindow.setSize(new Dimension(550,275)); summaryWindow.setVisible(true); } else if(command.equals("getGeneralInfo")) { JFrame infoWindow = new JFrame(); JTextArea infoText = new JTextArea(); JScrollPane infoScroller = new JScrollPane(infoText); int index = idTable.getSelectionModel().getMinSelectionIndex(); Dif dif = (Dif)idTable.getValueAt(index,1); infoText.setEditable(false); String generalInfo = ""; if(dif.getPersonnels() == null) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) generalInfo = generalInfo + "No Contact Infomation Available"; } else { generalInfo = generalInfo + "Contact Information"; for(int i=0; i<dif.getPersonnels().size(); i++) { generalInfo = generalInfo + "\n\nRole "; generalInfo = generalInfo + dif.getRole(i); generalInfo = generalInfo + "\nName "; generalInfo = generalInfo + dif.getName(i); generalInfo = generalInfo + "\nEmail "; generalInfo = generalInfo + dif.getEmail(i); generalInfo = generalInfo + "\nPhone "; generalInfo = generalInfo + dif.getPhone(i); generalInfo = generalInfo + "\nFax "; generalInfo = generalInfo + dif.getFax(i); generalInfo = generalInfo + "\nAddress "; generalInfo = generalInfo + dif.getAddress(i); } } if(dif.getParameters() == null) { generalInfo = generalInfo + "No Parameters Available"; } else { generalInfo = generalInfo + "\n\nParameters\n"; for(int i=0; i<dif.getParameters().size(); i++) { generalInfo = generalInfo + "\n"; generalInfo = generalInfo + dif.getCategory(i) + " > " + dif.getTopic(i) + " > " + dif.getTerm(i) + " > " + dif.getVariable(i); } } if(dif.getSpatialCoverage() == null) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) generalInfo = generalInfo + "No Spatial Coverage Infomation Available"; } else { generalInfo = generalInfo + "\n\nSpatial Coverage"; generalInfo = generalInfo + "\n\nSouthernmost Latitude: "; generalInfo = generalInfo + dif.getSouthernmost(); generalInfo = generalInfo + "\nNorthernmost Latitude: "; generalInfo = generalInfo + dif.getNorthernmost(); generalInfo = generalInfo + "\nWesternmost Longitude: "; generalInfo = generalInfo + dif.getWesternmost(); generalInfo = generalInfo + "\nEasternmost Longitude: "; generalInfo = generalInfo + dif.getEasternmost(); } if(dif.getTemporalCoverage() == null) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) generalInfo = generalInfo + "No Temporal Coverage Infomation Available"; } else { generalInfo = generalInfo + "\n\nTemporal Coverage"; generalInfo = generalInfo + "\n\nStart Date: "; generalInfo = generalInfo + dif.getStartDate(); generalInfo = generalInfo + "\nStop Date: "; generalInfo = generalInfo + dif.getStopDate(); } if(dif.getDataResolution() == null) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) generalInfo = generalInfo + "No Data Resolution Infomation Available"; } else { generalInfo = generalInfo + "\n\nData Resolution"; generalInfo = generalInfo + "\n\nLatitude Resolution: "; generalInfo = generalInfo + dif.getLatResolution(); generalInfo = generalInfo + "\nLongitude Resolution: "; generalInfo = generalInfo + dif.getLongResolution(); generalInfo = generalInfo + "\nTemporal Resolution: "; generalInfo = generalInfo + dif.getTemporalResolution(); } if(dif.getSummary().equals("")) { //Dif temp = getDif(dif.getID(), "Summary"); //dif.setSummary(temp.getSummary()); //if(dif.getSummary().equals("")) //dif.setSummary("No Summary Available"); generalInfo = generalInfo + "No Summary Infomation Available"; } else generalInfo = generalInfo + "\n\nSummary" + dif.getSummary(); infoText.setText(generalInfo); infoWindow.setTitle(dif.getTitle()); infoWindow.getContentPane().add(infoScroller); infoWindow.setSize(new Dimension(550,275)); infoWindow.setVisible(true); } } /** * The function to handle list selection events. * @param e The event. */ public void valueChanged(ListSelectionEvent e) { if(!e.getValueIsAdjusting()) { int index = ((ListSelectionModel)e.getSource()).getMinSelectionIndex(); if(index != -1) { JPanel difPanel; JPanel innerPanel; Dif dif = (Dif)idTable.getModel().getValueAt(index,1); if( (difPanel = (JPanel)difPanels.get(dif)) == null) { difPanel = new JPanel(); difPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Dataset Information")); difPanel.setLayout(new BoxLayout(difPanel, BoxLayout.Y_AXIS)); difPanel.add(new JLabel("<html><table style=\"color:black\"><tr><td valign=\"top\">Title:</td><td>" + dif.getTitle() + "</td></tr><tr><td>URL:</td><td>" + dif.getDodsURL().getBaseURL() + "</td></tr></table>")); innerPanel = new JPanel(); innerPanel.setBorder(BorderFactory.createEtchedBorder()); innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS)); JButton summary = new JButton("Get Summary"); summary.addActionListener(this); summary.setActionCommand("getSummary"); innerPanel.add(summary); JButton general = new JButton("Get General Info"); general.addActionListener(this); general.setActionCommand("getGeneralInfo"); innerPanel.add(general); innerPanel.setAlignmentX(LEFT_ALIGNMENT); difPanel.add(innerPanel); difPanels.put(dif, difPanel); } infoPanel.setVisible(false); difPanel.setVisible(true); remove(infoPanel); infoPanel = difPanel; c.gridx = 0; c.gridy = 2; c.weightx = 1; c.gridwidth = 2; c.weighty = 0; gridbag.setConstraints(infoPanel,c); add(infoPanel); } } } /** * Returns all the urls that have the "Download" box checked. * @return all the urls that have the "Download" box checked. */ public DodsURL[] getURLs() { int numURLs = 0; for(int i=0;i<idTable.getRowCount();i++) { if(((Boolean)idTable.getValueAt(i,0)).booleanValue()) numURLs++; } DodsURL[] urls = new DodsURL[numURLs]; int urlIndex = 0; for(int i=0;i<idTable.getRowCount();i++) { if(((Boolean)idTable.getValueAt(i,0)).booleanValue()) { Dif dif = (Dif)idTable.getValueAt(i,1); urls[urlIndex++] = dif.getDodsURL(); } } return urls; } /* public static void main(String args[]) { JFrame frame = new JFrame("GCMD"); frame.getContentPane().add(new GCMDSearch("http://128.183.164.60/servlets/md/")); frame.pack(); frame.setVisible(true); } */ /** * This class makes a request to the GCMD servlets and * displays the results when it's done. */ public class SearchThread extends Thread implements ActionListener { String query; boolean drawTable; public SearchThread(String queryString) { query = queryString; drawTable = true; } public void run() { handler = new DifHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); try { URL xmlFile; if(query.equals("")) xmlFile = new URL(url + "/getdifs.py?query=" + URLEncoder.encode("[Project:Short_Name='DODS']")); // + "§ions=Entry_ID+Entry_Title+Related_URL+Personnel+Spatial_Coverage+Summary"); else xmlFile = new URL(url + "/getdifs.py?query=" + URLEncoder.encode("[Project:Short_Name='DODS'] AND (" + query + ")"));// + "§ions=Entry_ID+Entry_Title+Related_URL+Personnel+Spatial_Coverage+Summary"); System.out.println(url + "/getdifs.py?query=" + URLEncoder.encode("[Project:Short_Name='DODS'] AND (" + query + ")")); // + "§ions=Entry_ID+Entry_Title+Related_URL+Summary"); InputStream urlStream = xmlFile.openStream(); SAXParser saxParser = factory.newSAXParser(); saxParser.parse( urlStream, handler ); // If the request has been canceled, drawTable will be false // at this point. if(drawTable) { Vector idVector = ((DifHandler)handler).getDifs(); Object[] selected = new Boolean[idVector.size()]; Object[] ids = new Object[idVector.size()]; idVector.copyInto(ids); for(int i=0;i<ids.length;i++) { selected[i] = new Boolean(false); } c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.weightx = 1; c.weighty = 1; gridbag.setConstraints(centerPanel, c); centerPanel.setMinimumSize(tempPanel.getSize()); centerPanel.setPreferredSize(tempPanel.getSize()); int size0=idTable.getColumnModel().getColumn(0).getWidth(); int size1=idTable.getColumnModel().getColumn(1).getWidth(); // This is a rather clunky way of doing things, but for // some reason JDK1.1 won't size the columns correctly // unless I create a new table. idTable = new JTable(); idTable.setModel(new GCMDTableModel(selected, ids)); idTable.getColumnModel().getColumn(0).setPreferredWidth(size0); idTable.getColumnModel().getColumn(0).setMaxWidth(80); idTable.getColumnModel().getColumn(1).setPreferredWidth(size1); idTableScroller.setViewportView(idTable); idTable.getSelectionModel().addListSelectionListener(FreeTextSearch.this); tempPanel.setVisible(false); add(centerPanel); centerPanel.setVisible(true); remove(tempPanel); getRootPane().getContentPane().validate(); } } catch(Throwable t) { t.printStackTrace(); } } /** * Create a temporary panel that can be used to cancel the search * request. * @return a temporary panel to show while searching. */ public JPanel createTempPanel() { JPanel temp = new JPanel(); JButton cancelButton = new JButton("Cancel"); temp.setLayout(new BoxLayout(temp, BoxLayout.Y_AXIS)); temp.setBorder(BorderFactory.createEmptyBorder(10,20,10,10)); temp.add(Box.createVerticalGlue()); JLabel text = new JLabel("Searching, please wait..."); text.setAlignmentX(Component.CENTER_ALIGNMENT); temp.add(text); cancelButton.addActionListener(this); cancelButton.setActionCommand("cancel"); cancelButton.setAlignmentX(Component.CENTER_ALIGNMENT); temp.add(cancelButton); temp.add(Box.createVerticalGlue()); return temp; } public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("cancel")) { drawTable = false; c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.weightx = 1; c.weighty = 1; gridbag.setConstraints(centerPanel, c); centerPanel.setVisible(true); centerPanel.setMinimumSize(tempPanel.getSize()); centerPanel.setPreferredSize(tempPanel.getSize()); tempPanel.setVisible(false); remove(tempPanel); add(centerPanel); } } } }