/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package de.cismet.cids.search; import Sirius.navigator.connection.SessionManager; import Sirius.navigator.search.CidsSearchExecutor; import Sirius.navigator.search.dynamic.SearchControlPanel; import Sirius.navigator.ui.ComponentRegistry; import Sirius.server.middleware.types.Node; import org.apache.log4j.Logger; import org.jdesktop.swingx.JXErrorPane; import org.jdesktop.swingx.error.ErrorInfo; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.SwingWorker; import de.cismet.cids.server.search.MetaObjectNodeServerSearch; import de.cismet.cids.server.search.builtin.QueryEditorCountStatement; /** * DOCUMENT ME! * * @author therter * @version $Revision$, $Date$ */ @org.openide.util.lookup.ServiceProvider(service = QuerySearchMethod.class) public class SearchQuerySearchMethod implements QuerySearchMethod, PropertyChangeListener { //~ Static fields/initializers --------------------------------------------- private static final Logger LOG = Logger.getLogger(SearchQuerySearchMethod.class); //~ Instance fields -------------------------------------------------------- private QuerySearch querySearch; private boolean searching = false; private SwingWorker<Node[], Void> searchThread; private SwingWorker<Long, Void> searchCountThread; //~ Methods ---------------------------------------------------------------- @Override public void setQuerySearch(final QuerySearch querySearch) { this.querySearch = querySearch; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean isSearching() { return searching; } @Override public void actionPerformed(final Object layer, final String query) { if (LOG.isInfoEnabled()) { LOG.info((searching ? "Cancel" : "Search") + " button was clicked."); } if (searching) { if (searchThread != null) { searchThread.cancel(true); } if (searchCountThread != null) { searchCountThread.cancel(true); } ComponentRegistry.getRegistry().getSearchResultsTree().cancelNodeLoading(); } else { final MetaObjectNodeServerSearch search = querySearch.getServerSearch(); ComponentRegistry.getRegistry().getSearchResultsTree().addPropertyChangeListener("browse", this); searchThread = CidsSearchExecutor.searchAndDisplayResults( search, this, this, false, true); if (querySearch.getPanginationPanel().getParent() != null) { searchCountThread = new SwingWorker<Long, Void>() { @Override protected Long doInBackground() throws Exception { final List<Long> result = (List<Long>)SessionManager.getProxy() .customServerSearch( SessionManager.getSession().getUser(), new QueryEditorCountStatement( SessionManager.getSession().getUser().getDomain(), querySearch.getMetaClass().getTableName(), querySearch.getWhereCause())); return result.get(0); } @Override protected void done() { try { final Long count = get(); if (!isCancelled()) { querySearch.getPanginationPanel().setTotal(count); } } catch (final Exception ex) { LOG.error(ex, ex); } } }; searchCountThread.execute(); } searching = true; querySearch.setControlsAccordingToState(searching); } } @Override public void propertyChange(final PropertyChangeEvent evt) { if (!(evt.getSource() instanceof SwingWorker)) { LOG.warn("Listened object is not of type 'SwingWorker'. Skipping process of event: '" + evt + "'."); return; } if (!"state".equalsIgnoreCase(evt.getPropertyName())) { return; } final SwingWorker source = (SwingWorker)evt.getSource(); if (SwingWorker.StateValue.DONE.equals(evt.getNewValue())) { if (source.isCancelled()) { searching = false; querySearch.setControlsAccordingToState(searching); } else { int results = 0; try { final Object obj = source.get(); if (obj instanceof Node[]) { results = ((Node[])obj).length; } if (obj instanceof Collection) { results = ((Collection)obj).size(); } } catch (InterruptedException ex) { LOG.error("Search result can't be get().", ex); } catch (ExecutionException ex) { LOG.error("Search result can't be get().", ex); final ErrorInfo errorInfo = new ErrorInfo( org.openide.util.NbBundle.getMessage( SearchControlPanel.class, "SearchControlPanel.propertyChange(PropertyChangeEvent).JOptionPane_anon.title"), org.openide.util.NbBundle.getMessage( SearchControlPanel.class, "SearchControlPanel.propertyChange(PropertyChangeEvent).JOptionPane_anon.message"), null, "ERROR", ex.getCause(), Level.WARNING, null); JXErrorPane.showDialog(querySearch.getRootPane(), errorInfo); } // this class is used as listener of the search thread and as a listener for the thread which // refreshes the SearchResultsTree. So this point is reached by on of two conditions: // - The search thread is done. // - Refreshing the SearchResultsTree is done. // SearchControlPanel can display normal mode only if: // - Search is done and has no results (refreshing the SearchResultsTree is not started). // - Or refreshing SearchResultsTree is done. if ((source.equals(searchThread) && (results == 0)) || !source.equals(searchThread)) { searching = false; querySearch.setControlsAccordingToState(searching); } } } } @Override public String toString() { return NbBundle.getMessage(SearchQuerySearchMethod.class, "SearchQuerySearchMethod.toString"); } }