Exemple #1
0
  private void performNewSearch(final ErlangExternalFunctionCallRef ref) {

    final ErlSearchQuery query =
        new ErlSearchQuery(
            ref, IErlSearchConstants.REFERENCES, IErlSearchConstants.FUNCTION, getScope());
    if (query.canRunInBackground()) {
      /*
       * This indirection with Object as parameter is needed to prevent
       * the loading of the Search plug-in: the VM verifies the method
       * call and hence loads the types used in the method signature,
       * eventually triggering the loading of a plug-in (in this case
       * ISearchQuery results in Search plug-in being loaded).
       */
      SearchUtil.runQueryInBackground(query);
    } else {
      final IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
      /*
       * This indirection with Object as parameter is needed to prevent
       * the loading of the Search plug-in: the VM verifies the method
       * call and hence loads the types used in the method signature,
       * eventually triggering the loading of a plug-in (in this case it
       * would be ISearchQuery).
       */
      final IStatus status = SearchUtil.runQueryInForeground(progressService, query);
      if (status.matches(IStatus.ERROR | IStatus.INFO | IStatus.WARNING)) {
        ErrorDialog.openError(
            getShell(),
            "SearchMessages.Search_Error_search_title",
            "SearchMessages.Search_Error_search_message",
            status);
      }
    }
  }
 public void doit(SearchingCodeVisitor visitor, MethodCallExpression call) {
   // Recognize and handle <methodName>(..., <argName>: "<oldName>", ...)
   MapEntryExpression arg = SearchUtil.getNamedArgument(call, argName);
   if (arg != null) {
     final Expression valueExpression = arg.getValueExpression();
     String argValue = SearchUtil.getStringValue(valueExpression);
     if (oldValue.equals(argValue)) {
       matchFound(visitor, call, valueExpression);
     }
   }
 }
 private boolean performNewSearch() throws CoreException {
   final SearchPatternData data = getPatternData();
   final int includeMask = getIncludeMask();
   // Setup search scope
   ErlSearchScope scope = EMPTY_SCOPE;
   String scopeDescription = null;
   final boolean searchSources = (includeMask & SearchUtil.SEARCH_IN_SOURCES) != 0;
   final boolean searchExternals = (includeMask & SearchUtil.SEARCH_IN_EXTERNALS) != 0;
   final boolean searchOtp = (includeMask & SearchUtil.SEARCH_IN_OTP_LIBRARIES) != 0;
   final int selectedScope = getContainer().getSelectedScope();
   switch (selectedScope) {
     case ISearchPageContainer.WORKSPACE_SCOPE:
       if (searchSources) {
         scope = SearchCoreUtil.getWorkspaceScope(searchExternals, searchOtp);
       }
       scopeDescription = SearchUtil.getWorkspaceScopeDescription();
       break;
     case ISearchPageContainer.SELECTED_PROJECTS_SCOPE:
       final String[] projectNames = getContainer().getSelectedProjectNames();
       if (searchSources) {
         scope =
             SearchCoreUtil.getProjectsScope(
                 SearchCoreUtil.getProjects(projectNames), searchExternals, searchOtp);
       }
       scopeDescription =
           SearchUtil.getProjectScopeDescription(SearchCoreUtil.getProjects(projectNames));
       break;
     case ISearchPageContainer.SELECTION_SCOPE:
       if (searchSources) {
         scope =
             SearchUtil.getSelectionScope(
                 getContainer().getSelection(), searchExternals, searchOtp);
       }
       scopeDescription = SearchUtil.getSelectionScopeDescription(getContainer().getSelection());
       break;
     case ISearchPageContainer.WORKING_SET_SCOPE:
       {
         final IWorkingSet[] workingSets = getContainer().getSelectedWorkingSets();
         // should not happen - just to be sure
         if (workingSets == null || workingSets.length < 1) {
           return false;
         }
         scopeDescription = SearchUtil.getWorkingSetsScopeDescription(workingSets);
         if (searchSources) {
           scope = SearchUtil.getWorkingSetsScope(workingSets, searchExternals, searchOtp);
         }
         SearchUtil.updateLRUWorkingSets(workingSets);
       }
   }
   final ErlangSearchPattern searchPattern =
       SearchUtil.getSearchPattern(
           null, data.getSearchFor(), data.getPattern(), data.getLimitTo());
   SearchUtil.runQuery(searchPattern, scope, scopeDescription, getShell());
   return true;
 }
Exemple #4
0
  /**
   * 按照属性查找对象,匹配方式为"in"
   *
   * @param propertyName 属性名称
   * @param value 属性值
   * @param orderByProperty 排序属性名称
   * @param isDesc true:降序,false:升序
   * @return
   */
  @SuppressWarnings("unchecked")
  public List<T> findByPropertyAndOrderWithParams(
      final Class<T> entityClass,
      final String propertyName,
      final Collection<?> values,
      final String orderByProperty,
      boolean isDesc) {
    Assert.hasText(propertyName, "propertyName不能为空");

    Search search = new Search(entityClass);
    SearchUtil.addFilterIn(search, propertyName, values);
    SearchUtil.addSort(search, orderByProperty, isDesc);

    return searchProcessor.search(this.getEntityManager().getPersistEntityManager(), search);
  }
Exemple #5
0
  /*
   * Method declared on SelectionChangedAction.
   */
  @Override
  public void run(final ITextSelection selection) {
    // if (!ActionUtil.isProcessable(fEditor)) {
    // return;
    // }
    IErlModule module = fEditor.getModule();
    if (module == null) {
      return;
    }
    final Backend b = ErlangCore.getBackendManager().getIdeBackend();
    final ISelection sel = getSelection();
    final ITextSelection textSel = (ITextSelection) sel;
    final int offset = textSel.getOffset();
    try {
      String scannerModuleName = ErlangToolkit.createScannerModuleName(module);
      final OpenResult res =
          ErlideOpen.open(b, scannerModuleName, offset, "", ErlangCore.getModel().getPathVars());
      ErlLogger.debug("open " + res);

      // final String title =
      // "SearchMessages.SearchElementSelectionDialog_title";
      // final String message =
      // "SearchMessages.SearchElementSelectionDialog_message";

      if (res.isExternalCall()) {
        performNewSearch(SearchUtil.getRefFromOpenRes(res));
      }
    } catch (final Exception e) {
      // final String title = "SearchMessages.Search_Error_search_title";
      // final String message = "SearchMessages.Search_Error_codeResolve";
      // ExceptionHandler.handle(e, getShell(), title, message);
      ErlLogger.debug(e);
    }
  }
  private String addQueryParams(String apiUrlCall) {
    if (!SearchUtil.isNullOrEmpty(advanceSettings.getColorFilter())) {
      apiUrlCall = apiUrlCall + "&imgcolor=" + advanceSettings.getColorFilter();
    }
    if (!SearchUtil.isNullOrEmpty(advanceSettings.getImageSize())) {
      apiUrlCall = apiUrlCall + "&imgsz=" + advanceSettings.getImageSize();
    }
    if (!SearchUtil.isNullOrEmpty(advanceSettings.getImageType())) {
      apiUrlCall = apiUrlCall + "&imgtype=" + advanceSettings.getImageType();
    }
    if (!SearchUtil.isNullOrEmpty(advanceSettings.getSiteFilter())) {
      apiUrlCall = apiUrlCall + "&as_sitesearch=" + advanceSettings.getSiteFilter();
    }

    return apiUrlCall;
  }
  @Test
  public void testSearch() throws IOException {
    String key = "tomcat";
    Sort sort = new Sort();
    sort.setSort(new SortField("name", SortField.SCORE));
    List<String> list =
        SearchUtil.searchUseIK(
            key,
            path,
            new String[] {
              "name",
            },
            sort,
            0,
            2,
            new ResultMapper<String>() {

              @Override
              public String mapRow(Document doc) {
                String v = doc.get("name");
                return v;
              }
            });
    for (String s : list) {
      P.println(s);
    }
  }
  @Test
  public void testIndexDoc() throws IOException {
    DataUtil.mkdir(path);
    List<String> list = new ArrayList<String>();
    list.add("中国上海天安门手机购买");
    list.add("美国北京纽约手机e71电池购买");
    list.add(
        "也能启动tomcat6的,我的环境下不包含任何tomcat的信息哦。"
            + " 重命名了jdk的文件夹,记住修改jdk的环境变量哈。"
            + "你安装的6.0 myeclipse下不能启动,就去查下myeclipse下tomcat的配置,"
            + "和你jdk的配置是否正确。tomcat的启动");
    list.add("不错啊");
    list.add("我手机不错,哈哈");
    list.add("我的tomcat不能启动,大家帮我看看");
    list.add("tom and lily");
    SearchUtil.indexDocUseIK(
        true,
        path,
        list,
        new AddDocProc<String>() {

          @Override
          public Document buildDoc(String t) {
            Document doc = new Document();
            doc.add(new Field("name", t, Store.YES, Index.ANALYZED));
            return doc;
          }
        });
  }
Exemple #9
0
 /**
  * 按照属性查找对象,匹配方式为"="
  *
  * @param propertyName 属性名称
  * @param value 属性值
  * @return
  */
 @SuppressWarnings("unchecked")
 public List<T> findByProperty(
     final Class<T> entityClass, final String propertyName, final Object value) {
   Assert.hasText(propertyName, "propertyName不能为空");
   Search search = new Search(entityClass);
   SearchUtil.addFilterEqual(search, propertyName, value);
   return searchProcessor.search(this.getEntityManager().getPersistEntityManager(), search);
 }
 public Object execute(final ExecutionEvent event) throws ExecutionException {
   Object selection = HandlerUtil.getVariable(event, ISources.ACTIVE_CURRENT_SELECTION_NAME);
   Shell shell = (Shell) HandlerUtil.getVariable(event, ISources.ACTIVE_SHELL_NAME);
   if (selection instanceof IStructuredSelection) {
     Object firstElement = ((IStructuredSelection) selection).getFirstElement();
     if (firstElement instanceof IErlElement) {
       IErlElement element = (IErlElement) firstElement;
       final ErlangSearchPattern pattern =
           SearchUtil.getSearchPatternFromErlElementAndLimitTo(
               element, ErlangSearchPattern.REFERENCES);
       SearchUtil.runQuery(
           pattern,
           SearchUtil.getWorkspaceScope(),
           SearchUtil.getWorkspaceScopeDescription(),
           shell);
     }
   }
   return null;
 }
Exemple #11
0
  /** 按属性查找唯一对象, 匹配方式为相等. */
  @SuppressWarnings("unchecked")
  public T findUniqueByProperty(
      final Class<T> entityClass, final String propertyName, final Object value) {

    Search search = new Search(entityClass);
    search.setResultMode(Search.RESULT_SINGLE);
    SearchUtil.addFilterEqual(search, propertyName, value);

    return (T)
        searchProcessor.searchUnique(this.getEntityManager().getPersistEntityManager(), search);
  }
  public static void processExtreme(
      HttpServletRequest request, String searchName, Object criteriaObject) {
    String page = request.getParameter("page");
    // String searchName = SearchUtil.getSearchName(request);
    Map searchInfo = SearchUtil.getSearchInfo(request);

    Map criterias = null;
    if (page == null) {
      String method = request.getParameter("method");
      if (method != null && method.equals("delete")) {
        BeanUtil.copyProperties(criteriaObject, SearchUtil.getSearchModel(request));
        criterias = SearchUtil.processCriterias(criteriaObject);
      }
      criterias = SearchUtil.processCriterias(criteriaObject);
      request.getSession().setAttribute(SearchConstant.CRITERIA_OBJECT, criteriaObject);
    } else {
      BeanUtil.copyProperties(
          criteriaObject, request.getSession().getAttribute(SearchConstant.CRITERIA_OBJECT));
      criterias = SearchUtil.processCriterias(criteriaObject);
    }
    if (request.getAttribute(SearchConstant.COMPOSITE_ID) != null) {
      criterias.put(SearchConstant.ID, request.getAttribute(SearchConstant.COMPOSITE_ID));
    }
    Search search = (Search) searchInfo.get(searchName);
    String fixedParams = (String) request.getAttribute(SearchConstant.FIXED_PARAMETERS);
    if (fixedParams != null) {
      search.setFixedParams(fixedParams);
    }

    Map fixedCriterias = (Map) request.getAttribute(SearchConstant.FIXED_CRITERIAS);
    if (fixedCriterias != null && !fixedCriterias.isEmpty()) {
      for (Iterator it = fixedCriterias.keySet().iterator(); it.hasNext(); ) {
        Object key = it.next();
        criterias.put(key, fixedCriterias.get(key));
      }
    }
    processExtreme(request, search, criterias);
  }
Exemple #13
0
  /**
   * 根据id获取对象列表,并排序
   *
   * @param ids
   * @param orderByProperty
   * @param isDesc true 降序,false升序
   * @return
   */
  @SuppressWarnings("unchecked")
  public List<T> get(
      final Class<T> entityClass,
      final Collection<PK> ids,
      String orderByProperty,
      boolean isDesc) {
    Search search = new Search(entityClass);
    search.setResultMode(Search.RESULT_LIST);

    JPAAnnotationMetadataUtil metadataUtil = new JPAAnnotationMetadataUtil();
    T entity;
    try {
      entity = entityClass.newInstance();
    } catch (Exception e) {
      logger.error("根据主键集合查找对象 {}发生异常! ", entityClass.getClass());
      throw new RuntimeException("根据主键集合查找对象发生异常", e);
    }
    String propertyName = metadataUtil.getIdPropertyName(entity);

    SearchUtil.addFilterIn(search, propertyName, ids);
    SearchUtil.addSort(search, orderByProperty, isDesc);

    return searchProcessor.search(this.getEntityManager().getPersistEntityManager(), search);
  }
 private SearchPatternData determineInitValuesFrom(
     final IErlModule module, final int offset, final OpenResult res) throws ErlModelException {
   if (res == null) {
     return null;
   }
   final ErlangSearchPattern pattern =
       SearchUtil.getSearchPatternFromOpenResultAndLimitTo(
           module, offset, res, LimitTo.REFERENCES, true);
   final String patternString = pattern == null ? "" : pattern.patternString();
   final SearchFor searchFor = pattern == null ? SearchFor.FUNCTION : pattern.getSearchFor();
   final SearchPatternData searchPatternData =
       new SearchPatternData(
           patternString,
           ISearchPageContainer.WORKSPACE_SCOPE,
           LimitTo.REFERENCES,
           searchFor,
           null,
           SearchUtil.SEARCH_IN_SOURCES);
   return searchPatternData;
 }
  public static void processExtreme(HttpServletRequest request, Search search, Map criterias) {
    /* extreme component*/
    Map sortCriterias = ExtremeTableUtil.getSort(request);
    CommonSearch commonSearch = (CommonSearch) SpringUtil.getBean(request, "commonSearch");
    commonSearch.setClassName(search.getClazz());
    commonSearch.setCriterias(criterias);
    commonSearch.setSearch(search);
    commonSearch.setRowsPerPage(ExtremeTableUtil.getCurrentRows(request));
    commonSearch.setSortCriterias(SearchUtil.convertSort(search.getSort()));
    commonSearch.addSortCriterias(sortCriterias);
    commonSearch.addSortCriterias((Map) request.getAttribute(SearchConstant.SORT_CRITERIAS));

    int totalRows = commonSearch.getTotalRows();
    if (logger.isInfoEnabled()) {
      logger.info("Total Rows:" + new Integer(totalRows));
    }

    List currentPageList = commonSearch.getCurrentPageList(ExtremeTableUtil.getPage(request));

    request.setAttribute("list", currentPageList);
    request.setAttribute("totalRows", new Integer(totalRows));
  }
 /**
  * Transform <string of CJK> into characters separated by spaces. FIXME: I'm sure we could handle
  * this a lot better!
  */
 private static String fixCJK(String search) {
   StringBuffer sb = null;
   int offset = 0;
   boolean wasCJK = false;
   for (; offset < search.length(); ) {
     int character = search.codePointAt(offset);
     if (SearchUtil.isCJK(character)) {
       if (wasCJK) {
         sb.append(' '); // Delimit characters by whitespace so we do an && search.
       }
       if (sb == null) {
         sb = new StringBuffer();
         sb.append(search.substring(0, offset));
       }
       wasCJK = true;
     } else {
       wasCJK = false;
     }
     if (sb != null) sb.append(Character.toChars(character));
     offset += Character.charCount(character);
   }
   if (sb != null) return sb.toString();
   else return search;
 }
  /**
   * Splits query into multiple searches, will be used for advanced queries
   *
   * @param query search query, can use various different search conventions
   * @param indexuri uri for one index
   * @return single Search encompassing everything in the query or null if query is a stop word
   * @throws InvalidSearchException if search query is invalid
   */
  private static Search splitQuery(String query, String indexuri)
      throws InvalidSearchException, TaskAbortException {
    if (query.matches("\\A[\\p{L}\\d]*\\Z")
        || query.matches("\\A[\\p{L}\\d][\\p{L}'\\d]*[\\p{L}\\d]\\Z")) {
      // single search term
      // return null if stopword
      if (SearchUtil.isStopWord(query)) return null;
      Execution<Set<TermEntry>> request = library.getIndex(indexuri).getTermEntries(query);
      if (request == null)
        throw new InvalidSearchException(
            "Something wrong with query=\""
                + query
                + "\" or indexURI=\""
                + indexuri
                + "\", maybe something is wrong with the index or it's uri is wrong.");
      return new Search(query, indexuri, request);
    }

    // Make phrase search
    if (query.matches("\\A\"[^\"]*\"\\Z")) {
      ArrayList<Execution<Set<TermEntry>>> phrasesearches = new ArrayList();
      String[] phrase = query.replaceAll("\"(.*)\"", "$1").split("[^\\p{L}\\d]+");
      if (logMINOR) Logger.minor(Search.class, "Phrase split" + query);
      for (String subquery : phrase) {
        Search term = startSearch(subquery, indexuri);
        phrasesearches.add(term);
      }
      // Not really sure how stopwords should be handled in phrases
      // currently i'm thinking that they should be treated as blanks
      // between other words and ignored in other cases "jesus of nazareth"
      // is treated as "jesus <blank> nazareth". Whereas "the who" will be
      // treated as a stop query as just searching for "who" and purporting
      // that the results are representative of "the who" is misleading.

      // this makes sure there are no trailing nulls at the start
      while (phrasesearches.get(0) == null) phrasesearches.remove(0);
      // this makes sure there are no trailing nulls at the end
      while (phrasesearches.get(phrasesearches.size() - 1) == null)
        phrasesearches.remove(phrasesearches.size() - 1);

      if (phrasesearches.size() > 1)
        return new Search(query, indexuri, phrasesearches, ResultOperation.PHRASE);
      else return null;
    }

    if (logMINOR) Logger.minor(Search.class, "Splitting " + query);
    String formattedquery = "";
    // Remove phrases, place them in arraylist and replace tem with references to the arraylist
    ArrayList<String> phrases = new ArrayList();
    String[] phraseparts = query.split("\"");
    if (phraseparts.length > 1)
      for (int i = 0; i < phraseparts.length; i++) {
        String string = phraseparts[i];
        formattedquery += string;
        if (++i < phraseparts.length) {
          string = phraseparts[i];
          formattedquery += "$" + phrases.size() + "£";
          phrases.add(string);
        }
      }
    else formattedquery = query;

    if (logMINOR) Logger.minor(Search.class, "phrases removed query : " + formattedquery);

    // treat hyphens as phrases, as they are treated equivalently in spider so this is the most
    // effective way now
    query = query.replaceAll("((?:[\\d\\p{L}]+-)+[\\d\\p{L}]+)", "\"$1\"");
    if (logMINOR) Logger.minor(Search.class, "Treat hyphenated words as phrases");

    if (!query.contains(
        "\"")) { // dont do the other splitting operations as we need to put phrases back in and
                 // call self
      formattedquery = formattedquery.replaceAll("\\s+or\\s+", "||");
      formattedquery = formattedquery.replaceAll("\\s+(?:not\\s*|-)(\\S+)", "^^($1)");
      if (logMINOR) Logger.minor(Search.class, "not query : " + formattedquery);
      formattedquery = formattedquery.replaceAll("\\s+", "&&");
      if (logMINOR) Logger.minor(Search.class, "and query : " + formattedquery);
    }

    // Put phrases back in
    phraseparts = formattedquery.split("\\$");
    formattedquery = phraseparts[0];
    for (int i = 1; i < phraseparts.length; i++) {
      String string = phraseparts[i];
      if (logMINOR)
        Logger.minor(Search.class, "replacing phrase " + string.replaceFirst("(\\d+).*", "$1"));
      formattedquery +=
          "\""
              + phrases.get(Integer.parseInt(string.replaceFirst("(\\d+).*", "$1")))
              + "\""
              + string.replaceFirst("\\d+£(.*)", "$1");
    }
    if (logMINOR) Logger.minor(Search.class, "phrase back query : " + formattedquery);

    if (query.contains("\"")) // recall self to remove phrases
    return splitQuery(query, indexuri);

    // Make complement search
    if (formattedquery.contains("^^(")) {
      ArrayList<Execution<Set<TermEntry>>> complementsearches = new ArrayList();
      String[] splitup = formattedquery.split("(\\^\\^\\(|\\))", 3);
      Search add = startSearch(splitup[0] + splitup[2], indexuri);
      Search subtract = startSearch(splitup[1], indexuri);
      if (add == null || subtract == null)
        return null; // If 'and' is not to be searched for 'the -john' is not to be searched for,
                     // also 'john -the' wouldnt have shown many results anyway
      complementsearches.add(add);
      complementsearches.add(subtract);
      return new Search(query, indexuri, complementsearches, ResultOperation.REMOVE);
    }
    // Split intersections
    if (formattedquery.contains("&&")) {
      ArrayList<Search> intersectsearches = new ArrayList();
      String[] intersects = formattedquery.split("&&");
      for (String subquery : intersects) {
        Search subsearch = startSearch(subquery, indexuri);
        if (subsearch
            != null) // We will assume that searching for 'the big apple' will near enough show the
                     // same results as 'big apple', so just ignore 'the' in interseaction
        intersectsearches.add(subsearch);
      }
      switch (intersectsearches.size()) {
        case 0: // eg. 'the that'
          return null;
        case 1: // eg. 'cake that' will return a search for 'cake'
          return intersectsearches.get(0);
        default:
          return new Search(query, indexuri, intersectsearches, ResultOperation.INTERSECTION);
      }
    }
    // Split Unions
    if (formattedquery.contains("||")) {
      ArrayList<Execution<Set<TermEntry>>> unionsearches = new ArrayList();
      String[] unions = formattedquery.split("\\|\\|");
      for (String subquery : unions) {
        Search add = startSearch(subquery, indexuri);
        if (add
            == null) // eg a search for 'the or cake' would be almost the same as a search for 'the'
                     // and so should be treated as such
        return null;
        unionsearches.add(add);
      }
      return new Search(query, indexuri, unionsearches, ResultOperation.UNION);
    }

    Logger.error(Search.class, "No split made, " + formattedquery + query);
    return null;
  }
 public void clearFetches() {
   SearchUtil.clearFetches(this);
 }
 public void clear() {
   SearchUtil.clear(this);
 }
Exemple #20
0
 /**
  * 获取全部对象, 支持按属性行序
  *
  * @param orderByProperty 排序的属性名称
  * @param isDesc true:降序,false:升序
  * @return
  */
 @SuppressWarnings("unchecked")
 public List<T> getAll(final Class<T> entityClass, String orderByProperty, boolean isDesc) {
   Search search = new Search(entityClass);
   SearchUtil.addSort(search, orderByProperty, isDesc);
   return searchProcessor.search(this.getEntityManager().getPersistEntityManager(), search);
 }
 @Override
 public boolean equals(Object obj) {
   return SearchUtil.equals(this, obj);
 }
 /** Add a filter that uses the IN operator. */
 public Search addFilterIn(String property, Collection<?> value) {
   SearchUtil.addFilterIn(this, property, value);
   return this;
 }
 /** Add a filter that uses the > operator. */
 public Search addFilterGreaterThan(String property, Object value) {
   SearchUtil.addFilterGreaterThan(this, property, value);
   return this;
 }
 /** Add a filter that uses the == operator. */
 public Search addFilterEqual(String property, Object value) {
   SearchUtil.addFilterEqual(this, property, value);
   return this;
 }
 public Search addFilters(Filter... filters) {
   SearchUtil.addFilters(this, filters);
   return this;
 }
 // Filters
 public Search addFilter(Filter filter) {
   SearchUtil.addFilter(this, filter);
   return this;
 }
 public void clearPaging() {
   SearchUtil.clearPaging(this);
 }
 @Override
 public int hashCode() {
   return SearchUtil.hashCode(this);
 }
 @Override
 public String toString() {
   return SearchUtil.toString(this);
 }
 /**
  * Create a copy of this search. All collections are copied into new collections, but them items
  * in those collections are not duplicated; they still point to the same objects.
  */
 public Search copy() {
   Search dest = new Search(this.getSearchClass());
   SearchUtil.copy(this, dest);
   return dest;
 }