1 /*
   2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 package com.sun.hotspot.igv.view;
  25 
  26 import com.sun.hotspot.igv.data.InputNode;
  27 import com.sun.hotspot.igv.data.Properties;
  28 import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
  29 import com.sun.hotspot.igv.data.services.InputGraphProvider;
  30 import com.sun.hotspot.igv.util.LookupHistory;
  31 import java.util.HashSet;
  32 import java.util.List;
  33 import java.util.Set;
  34 import java.util.regex.Pattern;
  35 import org.netbeans.spi.quicksearch.SearchProvider;
  36 import org.netbeans.spi.quicksearch.SearchRequest;
  37 import org.netbeans.spi.quicksearch.SearchResponse;
  38 import org.openide.DialogDisplayer;
  39 import org.openide.NotifyDescriptor;
  40 import org.openide.NotifyDescriptor.Message;
  41 
  42 /**
  43  *
  44  * @author Thomas Wuerthinger
  45  */
  46 public class NodeQuickSearch implements SearchProvider {
  47 
  48     private static final String DEFAULT_PROPERTY = "name";
  49 
  50     /**
  51      * Method is called by infrastructure when search operation was requested.
  52      * Implementors should evaluate given request and fill response object with
  53      * apropriate results
  54      *
  55      * @param request Search request object that contains information what to search for
  56      * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
  57      */
  58     @Override
  59     public void evaluate(SearchRequest request, SearchResponse response) {
  60         String query = request.getText();
  61         if (query.trim().isEmpty()) {
  62             return;
  63         }
  64 
  65         final String[] parts = query.split("=", 2);
  66 
  67         String name;
  68         String value;
  69 
  70         if (parts.length == 1) {
  71             name = DEFAULT_PROPERTY;
  72             value = ".*" + Pattern.quote(parts[0]) + ".*";
  73         } else {
  74             name = parts[0];
  75             value = parts[1];
  76         }
  77 
  78         if (value.isEmpty()) {
  79             value = ".*";
  80         }
  81 
  82         final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
  83         if (p != null && p.getGraph() != null) {
  84             List<InputNode> matches = null;
  85             try {
  86                 RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
  87                 Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes());
  88 
  89                 matches = selector.selectMultiple(matcher);
  90             } catch (Exception e) {
  91                 final String msg = e.getMessage();
  92                 response.addResult(new Runnable() {
  93                     @Override
  94                         public void run() {
  95                             Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
  96                                     + "perhaps due to a malformed query string:\n" + msg,
  97                                     NotifyDescriptor.WARNING_MESSAGE);
  98                             DialogDisplayer.getDefault().notify(desc);
  99                         }
 100                     },
 101                     "(Error during search)"
 102                 );
 103             }
 104 
 105             if (matches != null) {
 106                 final Set<InputNode> set = new HashSet<>(matches);
 107                 response.addResult(new Runnable() {
 108                     @Override
 109                         public void run() {
 110                             final EditorTopComponent comp = EditorTopComponent.getActive();
 111                             if (comp != null) {
 112                                 comp.setSelectedNodes(set);
 113                                 comp.requestActive();
 114                             }
 115                         }
 116                     },
 117                     "All " + matches.size() + " matching nodes (" + name + "=" + value + ")"
 118                 );
 119 
 120                 // Single matches
 121                 for (final InputNode n : matches) {
 122                     response.addResult(new Runnable() {
 123                         @Override
 124                             public void run() {
 125                                 final EditorTopComponent comp = EditorTopComponent.getActive();
 126                                 if (comp != null) {
 127                                     final Set<InputNode> tmpSet = new HashSet<>();
 128                                     tmpSet.add(n);
 129                                     comp.setSelectedNodes(tmpSet);
 130                                     comp.requestActive();
 131                                 }
 132                             }
 133                         },
 134                         n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"
 135                     );
 136                 }
 137             }
 138         } else {
 139             System.out.println("no input graph provider!");
 140         }
 141     }
 142 }