This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hop.git


The following commit(s) were added to refs/heads/master by this push:
     new fb8ba5f  HOP-2662 : Add CLI search tool
     new 4f85936  Merge pull request #717 from mattcasters/master
fb8ba5f is described below

commit fb8ba5fe41cd25e8dedf9321002a85d5e1baf148
Author: Matt Casters <[email protected]>
AuthorDate: Mon Mar 29 13:13:51 2021 +0200

    HOP-2662 : Add CLI search tool
---
 assemblies/static/src/main/resources/hop-conf.bat  |   2 +-
 .../resources/{hop-conf.bat => hop-search.bat}     |   4 +-
 assemblies/static/src/main/resources/hop-search.sh |  82 +++++
 .../hop/core/config/plugin/ConfigPlugin.java       |   5 +-
 .../hop/core/search/ISearchablesLocation.java      |   4 +-
 .../core/search/SearchableAnalyserPluginType.java  |   4 +
 .../main/java/org/apache/hop/search/HopSearch.java | 374 +++++++++++++++++++++
 ...OptionPlugin.java => ProjectsOptionPlugin.java} |  32 +-
 .../projects/config/ProjectsRunOptionPlugin.java   | 119 +------
 .../config/ProjectsSearchOptionPlugin.java         |  55 +++
 .../search/ProjectSearchablesIterator.java         |  17 +-
 .../search/ProjectsSearchablesLocation.java        |  16 +-
 .../perspective/search/HopSearchPerspective.java   |   6 +-
 .../hop/ui/hopgui/search/HopGuiSearchLocation.java |   4 +-
 14 files changed, 564 insertions(+), 160 deletions(-)

diff --git a/assemblies/static/src/main/resources/hop-conf.bat 
b/assemblies/static/src/main/resources/hop-conf.bat
index 882fcab..5a7af10 100644
--- a/assemblies/static/src/main/resources/hop-conf.bat
+++ b/assemblies/static/src/main/resources/hop-conf.bat
@@ -62,7 +62,7 @@ if not "%HOP_AES_ENCODER_KEY%"=="" (
 )
 
 set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
+set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Conf
 
 set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
 
diff --git a/assemblies/static/src/main/resources/hop-conf.bat 
b/assemblies/static/src/main/resources/hop-search.bat
similarity index 96%
copy from assemblies/static/src/main/resources/hop-conf.bat
copy to assemblies/static/src/main/resources/hop-search.bat
index 882fcab..fed0948 100644
--- a/assemblies/static/src/main/resources/hop-conf.bat
+++ b/assemblies/static/src/main/resources/hop-search.bat
@@ -62,7 +62,7 @@ if not "%HOP_AES_ENCODER_KEY%"=="" (
 )
 
 set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
+set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Search
 
 set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
 
@@ -86,6 +86,6 @@ echo %_HOP_JAVA% -classpath %LIBSPATH%\*;%SWTJAR%\* 
-Djava.library.path=%LIBSPAT
 echo.
 echo ===[Starting 
HopConfig]=========================================================
 
-%_HOP_JAVA% -classpath %LIBSPATH%\*;%SWTJAR%\* -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
+%_HOP_JAVA% -classpath %LIBSPATH%\*;%SWTJAR%\* -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.search.HopSearch %_cmdline%
 @echo off
 :End
\ No newline at end of file
diff --git a/assemblies/static/src/main/resources/hop-search.sh 
b/assemblies/static/src/main/resources/hop-search.sh
new file mode 100755
index 0000000..4e84626
--- /dev/null
+++ b/assemblies/static/src/main/resources/hop-search.sh
@@ -0,0 +1,82 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+ORIGINDIR=$( pwd )
+BASEDIR=$( dirname $0 )
+cd $BASEDIR
+
+# set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java
+if [ -n "$HOP_JAVA_HOME" ]; then
+  _HOP_JAVA=$HOP_JAVA_HOME/bin/java
+elif [ -n "$JAVA_HOME" ]; then
+  _HOP_JAVA=$JAVA_HOME/bin/java
+else
+  _HOP_JAVA="java"
+fi
+
+# Settings for all OSses
+#
+if [ -z "$HOP_OPTIONS" ]; then
+  HOP_OPTIONS="-Xmx2048m"
+fi
+# optional line for attaching a debugger
+#
+#HOP_OPTIONS="${HOP_OPTIONS} -Xdebug -Xnoagent -Djava.compiler=NONE 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009"
+
+# Add HOP variables if they're set:
+#
+if [ -n "${HOP_AUDIT_FOLDER}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} -DHOP_AUDIT_FOLDER=${HOP_AUDIT_FOLDER}"
+fi
+if [ -n "${HOP_CONFIG_FOLDER}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} -DHOP_CONFIG_FOLDER=${HOP_CONFIG_FOLDER}"
+fi
+if [ -n "${HOP_SHARED_JDBC_FOLDER}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} 
-DHOP_SHARED_JDBC_FOLDER=${HOP_SHARED_JDBC_FOLDER}"
+fi
+if [ -n "${HOP_PLUGIN_BASE_FOLDERS}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} 
-DHOP_PLUGIN_BASE_FOLDERS=${HOP_PLUGIN_BASE_FOLDERS}"
+fi
+if [ -n "${HOP_PASSWORD_ENCODER_PLUGIN}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} 
-DHOP_PASSWORD_ENCODER_PLUGIN=${HOP_PASSWORD_ENCODER_PLUGIN}"
+fi
+if [ -n "${HOP_AES_ENCODER_KEY}" ]; then
+    HOP_OPTIONS="${HOP_OPTIONS} -DHOP_AES_ENCODER_KEY=${HOP_AES_ENCODER_KEY}"
+fi
+
+HOP_OPTIONS="${HOP_OPTIONS} -DHOP_PLATFORM_RUNTIME=Search 
-DHOP_AUTO_CREATE_CONFIG=Y -DHOP_PLATFORM_OS="$(uname -s)
+
+case $( uname -s ) in
+        Linux) 
+                CLASSPATH="lib/*:libswt/linux/$( uname -m )/*"
+                ;;
+        Darwin) 
+                CLASSPATH="lib/*:libswt/osx64/*" 
+                HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread"
+                ;;
+esac
+
+
+"$_HOP_JAVA" ${HOP_OPTIONS} -Djava.library.path=$LIBPATH  -classpath 
"${CLASSPATH}" org.apache.hop.search.HopSearch "$@"
+EXITCODE=$?
+
+cd ${ORIGINDIR}
+exit $EXITCODE
+
diff --git 
a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java 
b/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
index 8d09983..58cac14 100644
--- a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
+++ b/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
@@ -32,8 +32,9 @@ import java.lang.annotation.Target;
 @Retention( RetentionPolicy.RUNTIME )
 @Target( ElementType.TYPE )
 public @interface ConfigPlugin {
-  public static final String CATEGORY_CONFIG = "config";
-  public static final String CATEGORY_RUN = "run";
+  String CATEGORY_CONFIG = "config";
+  String CATEGORY_RUN = "run";
+  String CATEGORY_SEARCH = "search";
 
   String id();
   String description() default "";
diff --git 
a/core/src/main/java/org/apache/hop/core/search/ISearchablesLocation.java 
b/core/src/main/java/org/apache/hop/core/search/ISearchablesLocation.java
index 08f7c6b..f2f704d 100644
--- a/core/src/main/java/org/apache/hop/core/search/ISearchablesLocation.java
+++ b/core/src/main/java/org/apache/hop/core/search/ISearchablesLocation.java
@@ -18,6 +18,8 @@
 package org.apache.hop.core.search;
 
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
 
 import java.util.Iterator;
 
@@ -26,5 +28,5 @@ import java.util.Iterator;
  */
 public interface ISearchablesLocation {
   String getLocationDescription();
-  Iterator<ISearchable> getSearchables() throws HopException;
+  Iterator<ISearchable> getSearchables( IHopMetadataProvider metadataProvider, 
IVariables variables ) throws HopException;
 }
diff --git 
a/core/src/main/java/org/apache/hop/core/search/SearchableAnalyserPluginType.java
 
b/core/src/main/java/org/apache/hop/core/search/SearchableAnalyserPluginType.java
index 39cae7a..61fc7dc 100644
--- 
a/core/src/main/java/org/apache/hop/core/search/SearchableAnalyserPluginType.java
+++ 
b/core/src/main/java/org/apache/hop/core/search/SearchableAnalyserPluginType.java
@@ -18,9 +18,13 @@
 package org.apache.hop.core.search;
 
 import org.apache.hop.core.plugins.BasePluginType;
+import org.apache.hop.core.plugins.PluginAnnotationType;
+import org.apache.hop.core.plugins.PluginMainClassType;
 
 import java.util.Map;
 
+@PluginMainClassType( ISearchableAnalyser.class )
+@PluginAnnotationType( SearchableAnalyserPlugin.class )
 public class SearchableAnalyserPluginType extends 
BasePluginType<SearchableAnalyserPlugin> {
 
   private static SearchableAnalyserPluginType pluginType;
diff --git a/engine/src/main/java/org/apache/hop/search/HopSearch.java 
b/engine/src/main/java/org/apache/hop/search/HopSearch.java
new file mode 100644
index 0000000..53296fc
--- /dev/null
+++ b/engine/src/main/java/org/apache/hop/search/HopSearch.java
@@ -0,0 +1,374 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.search;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hop.core.Const;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.config.plugin.ConfigPlugin;
+import org.apache.hop.core.config.plugin.ConfigPluginType;
+import org.apache.hop.core.config.plugin.IConfigOptions;
+import org.apache.hop.core.encryption.Encr;
+import org.apache.hop.core.encryption.HopTwoWayPasswordEncoder;
+import org.apache.hop.core.encryption.ITwoWayPasswordEncoder;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.logging.LogChannel;
+import org.apache.hop.core.plugins.IPlugin;
+import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.core.search.ISearchResult;
+import org.apache.hop.core.search.ISearchable;
+import org.apache.hop.core.search.ISearchableAnalyser;
+import org.apache.hop.core.search.ISearchablesLocation;
+import org.apache.hop.core.search.SearchQuery;
+import org.apache.hop.core.search.SearchableAnalyserPluginType;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.metadata.api.IHasHopMetadataProvider;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.serializer.json.JsonMetadataProvider;
+import picocli.CommandLine;
+import picocli.CommandLine.ExecutionException;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ParameterException;
+import picocli.CommandLine.Parameters;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class HopSearch implements Runnable, IHasHopMetadataProvider {
+
+  @Option(
+      names = {"-h", "--help"},
+      usageHelp = true,
+      description = "Displays this help message and quits.")
+  private boolean helpRequested;
+
+  @Parameters(description = "The string to search for")
+  private String searchString;
+
+  @Option(
+      names = {"-i", "--case-insensitive"},
+      description = "Perform a case insensitive search")
+  private Boolean caseInsensitive;
+
+  @Option(
+      names = {"-x", "--regular-expression"},
+      description = "The specified search string is a regular expression")
+  private Boolean regularExpression;
+
+  @Option(
+      names = {"-l", "--print-locations"},
+      description = "Print which locations are being looked at")
+  private Boolean printLocations;
+
+  private CommandLine cmd;
+  private IVariables variables;
+  private IHopMetadataProvider metadataProvider;
+
+  protected List<ISearchablesLocation> searchablesLocations;
+
+  public HopSearch() {
+    searchablesLocations = new ArrayList<>();
+  }
+
+  public void run() {
+
+    try {
+      LogChannel logChannel = new LogChannel("hop-search");
+      logChannel.setSimplified(true);
+      ILogChannel log = logChannel;
+      variables = Variables.getADefaultVariableSpace();
+      buildMetadataProvider();
+
+      boolean actionTaken = false;
+
+      Map<String, Object> mixins = cmd.getMixins();
+      for (String key : mixins.keySet()) {
+        Object mixin = mixins.get(key);
+        if (mixin instanceof IConfigOptions) {
+          IConfigOptions configOptions = (IConfigOptions) mixin;
+
+          actionTaken = configOptions.handleOption(log, this, variables) || 
actionTaken;
+        }
+      }
+
+      if (!actionTaken || StringUtils.isEmpty(searchString)) {
+        cmd.usage(System.out);
+        System.exit(1);
+      }
+
+      if (searchablesLocations.isEmpty()) {
+        System.out.println(
+            "There were no locations found to search. Specify an option so 
that Hop knows where to look.");
+        System.exit(3);
+      }
+
+      boolean isCaseSensitive = caseInsensitive == null || !caseInsensitive;
+      boolean isRegularExpression = regularExpression != null && 
regularExpression;
+
+      SearchQuery searchQuery = new SearchQuery(searchString, isCaseSensitive, 
isRegularExpression);
+      System.out.println(
+          "Searching for ["
+              + searchString
+              + "]  Case sensitive? "
+              + isCaseSensitive
+              + "  Regular expression? "
+              + isRegularExpression);
+
+      // Get all the searchable analysers from the plugin registry...
+      //
+      Map<Class<ISearchableAnalyser>, ISearchableAnalyser> 
searchableAnalyserMap = new HashMap<>();
+      PluginRegistry registry = PluginRegistry.getInstance();
+      for (IPlugin analyserPlugin : 
registry.getPlugins(SearchableAnalyserPluginType.class)) {
+        ISearchableAnalyser searchableAnalyser =
+            (ISearchableAnalyser) registry.loadClass(analyserPlugin);
+        searchableAnalyserMap.put(searchableAnalyser.getSearchableClass(), 
searchableAnalyser);
+      }
+
+      // Search!
+      //
+      for (ISearchablesLocation searchablesLocation : searchablesLocations) {
+        System.out.println(
+            "Searching in location : " + 
searchablesLocation.getLocationDescription());
+        System.out.println(
+            
"-----------------------------------------------------------------------------------");
+
+        Iterator<ISearchable> iterator =
+            searchablesLocation.getSearchables(metadataProvider, variables);
+        while (iterator.hasNext()) {
+          // Load the next object
+          //
+          ISearchable searchable = iterator.next();
+
+          Object object = searchable.getSearchableObject();
+          if (object != null) {
+            if (printLocations != null && printLocations) {
+              System.out.println("Checking searchable: " + 
searchable.getName());
+            }
+            // Find an analyser...
+            //
+            ISearchableAnalyser searchableAnalyser = 
searchableAnalyserMap.get(object.getClass());
+            if (searchableAnalyser != null) {
+              List<ISearchResult> searchResults =
+                  searchableAnalyser.search(searchable, searchQuery);
+
+              // Print the results...
+              //
+              for (ISearchResult searchResult : searchResults) {
+                String filename = 
variables.resolve(searchResult.getMatchingSearchable().getFilename());
+                if (StringUtils.isNotEmpty(filename)) {
+                  System.out.print(filename + " : ");
+                }
+                System.out.print(
+                    searchResult.getComponent() + " : " + 
searchResult.getDescription());
+                System.out.println();
+              }
+            }
+          }
+        }
+      }
+
+    } catch (Exception e) {
+      throw new ExecutionException(cmd, "There was an error handling options", 
e);
+    }
+  }
+
+  private void buildMetadataProvider() throws HopException {
+    String folder = variables.getVariable(Const.HOP_METADATA_FOLDER);
+    if (StringUtils.isEmpty(folder)) {
+      metadataProvider = new JsonMetadataProvider();
+    } else {
+      ITwoWayPasswordEncoder passwordEncoder = Encr.getEncoder();
+      if (passwordEncoder == null) {
+        passwordEncoder = new HopTwoWayPasswordEncoder();
+      }
+      metadataProvider = new JsonMetadataProvider(passwordEncoder, folder, 
variables);
+    }
+  }
+
+  /**
+   * Gets cmd
+   *
+   * @return value of cmd
+   */
+  public CommandLine getCmd() {
+    return cmd;
+  }
+
+  /** @param cmd The cmd to set */
+  public void setCmd(CommandLine cmd) {
+    this.cmd = cmd;
+  }
+
+  /**
+   * Gets metadataProvider
+   *
+   * @return value of metadataProvider
+   */
+  @Override
+  public IHopMetadataProvider getMetadataProvider() {
+    return metadataProvider;
+  }
+
+  /** @param metadataProvider The metadataProvider to set */
+  @Override
+  public void setMetadataProvider(IHopMetadataProvider metadataProvider) {
+    this.metadataProvider = metadataProvider;
+  }
+
+  /**
+   * Gets helpRequested
+   *
+   * @return value of helpRequested
+   */
+  public boolean isHelpRequested() {
+    return helpRequested;
+  }
+
+  /** @param helpRequested The helpRequested to set */
+  public void setHelpRequested(boolean helpRequested) {
+    this.helpRequested = helpRequested;
+  }
+
+  /**
+   * Gets variables
+   *
+   * @return value of variables
+   */
+  public IVariables getVariables() {
+    return variables;
+  }
+
+  /** @param variables The variables to set */
+  public void setVariables(IVariables variables) {
+    this.variables = variables;
+  }
+
+  /**
+   * Gets searchablesLocations
+   *
+   * @return value of searchablesLocations
+   */
+  public List<ISearchablesLocation> getSearchablesLocations() {
+    return searchablesLocations;
+  }
+
+  /** @param searchablesLocations The searchablesLocations to set */
+  public void setSearchablesLocations(List<ISearchablesLocation> 
searchablesLocations) {
+    this.searchablesLocations = searchablesLocations;
+  }
+
+  /**
+   * Gets searchString
+   *
+   * @return value of searchString
+   */
+  public String getSearchString() {
+    return searchString;
+  }
+
+  /** @param searchString The searchString to set */
+  public void setSearchString(String searchString) {
+    this.searchString = searchString;
+  }
+
+  /**
+   * Gets caseInsensitive
+   *
+   * @return value of caseInsensitive
+   */
+  public Boolean getCaseInsensitive() {
+    return caseInsensitive;
+  }
+
+  /** @param caseInsensitive The caseInsensitive to set */
+  public void setCaseInsensitive(Boolean caseInsensitive) {
+    this.caseInsensitive = caseInsensitive;
+  }
+
+  /**
+   * Gets regularExpression
+   *
+   * @return value of regularExpression
+   */
+  public Boolean getRegularExpression() {
+    return regularExpression;
+  }
+
+  /** @param regularExpression The regularExpression to set */
+  public void setRegularExpression(Boolean regularExpression) {
+    this.regularExpression = regularExpression;
+  }
+
+  public static void main(String[] args) {
+
+    HopSearch hopSearch = new HopSearch();
+
+    try {
+      HopEnvironment.init();
+
+      // Also register the search plugin type (usually only done for the GUI)
+      // We don't want to load these in HopEnvironmnent.init() because for now 
it would
+      // only be useful in Hop GUI and Hop Search.  There is no need to slow 
down
+      // Hop Run or Hop Server with this.
+      //
+      PluginRegistry registry = PluginRegistry.getInstance();
+      SearchableAnalyserPluginType searchableAnalyserPluginType =
+          SearchableAnalyserPluginType.getInstance();
+      registry.addPluginType(searchableAnalyserPluginType);
+      searchableAnalyserPluginType.searchPlugins();
+
+      CommandLine cmd = new CommandLine(hopSearch);
+      List<IPlugin> configPlugins = 
registry.getPlugins(ConfigPluginType.class);
+      for (IPlugin configPlugin : configPlugins) {
+        // Load only the plugins of the "search" category
+        if (ConfigPlugin.CATEGORY_SEARCH.equals(configPlugin.getCategory())) {
+          IConfigOptions configOptions = registry.loadClass(configPlugin, 
IConfigOptions.class);
+          cmd.addMixin(configPlugin.getIds()[0], configOptions);
+        }
+      }
+
+      hopSearch.setCmd(cmd);
+      CommandLine.ParseResult parseResult = cmd.parseArgs(args);
+      if (CommandLine.printHelpIfRequested(parseResult)) {
+        System.exit(1);
+      } else {
+        hopSearch.run();
+        System.exit(0);
+      }
+    } catch (ParameterException e) {
+      System.err.println(e.getMessage());
+      hopSearch.cmd.usage(System.err);
+      System.exit(9);
+    } catch (ExecutionException e) {
+      System.err.println("Error found during execution!");
+      System.err.println(Const.getStackTracker(e));
+
+      System.exit(1);
+    } catch (Exception e) {
+      System.err.println("General error found, something went horribly 
wrong!");
+      System.err.println(Const.getStackTracker(e));
+
+      System.exit(2);
+    }
+  }
+}
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsOptionPlugin.java
similarity index 86%
copy from 
plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
copy to 
plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsOptionPlugin.java
index e117667..086699d 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsOptionPlugin.java
@@ -28,22 +28,12 @@ import 
org.apache.hop.projects.environment.LifecycleEnvironment;
 import org.apache.hop.projects.project.Project;
 import org.apache.hop.projects.project.ProjectConfig;
 import org.apache.hop.projects.util.ProjectsUtil;
-import org.apache.hop.ui.core.dialog.ErrorDialog;
-import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
-import org.apache.hop.ui.core.widget.TextVar;
-import org.apache.hop.ui.hopgui.HopGui;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Control;
 import picocli.CommandLine;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@ConfigPlugin(
-    id = "ProjectsRunOptionPlugin",
-    description = "Project and Environment configuration options for hop-run",
-    category = ConfigPlugin.CATEGORY_RUN)
-public class ProjectsRunOptionPlugin implements IConfigOptions {
+public class ProjectsOptionPlugin implements IConfigOptions {
 
   @CommandLine.Option(
       names = {"-e", "--environment"},
@@ -55,16 +45,24 @@ public class ProjectsRunOptionPlugin implements 
IConfigOptions {
       description = "The name of the project to use")
   private String projectOption = null;
 
+  protected ProjectsConfig config;
+  protected ProjectConfig projectConfig;
+  protected List<String> configurationFiles;
+  protected Project project;
+  protected String projectName;
+  protected String environmentName;
+  protected LifecycleEnvironment environment;
+
   @Override
   public boolean handleOption(
       ILogChannel log, IHasHopMetadataProvider hasHopMetadataProvider, 
IVariables variables)
       throws HopException {
 
-    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-    ProjectConfig projectConfig = null;
-    List<String> configurationFiles = new ArrayList<>();
-    String projectName = projectOption;
-    String environmentName = environmentOption;
+    config = ProjectsConfigSingleton.getConfig();
+    projectConfig = null;
+    configurationFiles = new ArrayList<>();
+    projectName = projectOption;
+    environmentName = environmentOption;
 
     // You can specify the project using -p (project) or -e (lifecycle 
environment)
     // The main difference is that the environment provides extra 
configuration files to consider.
@@ -97,7 +95,7 @@ public class ProjectsRunOptionPlugin implements 
IConfigOptions {
     if ( StringUtils.isNotEmpty(environmentName)) {
       // The environment contains extra configuration options we need to pass 
along...
       //
-      LifecycleEnvironment environment = 
config.findEnvironment(environmentName);
+      environment = config.findEnvironment(environmentName);
       if (environment == null) {
         throw new HopException(
           "Unable to find lifecycle environment '" + environmentName + "'");
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
index e117667..5a094bf 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsRunOptionPlugin.java
@@ -43,123 +43,6 @@ import java.util.List;
     id = "ProjectsRunOptionPlugin",
     description = "Project and Environment configuration options for hop-run",
     category = ConfigPlugin.CATEGORY_RUN)
-public class ProjectsRunOptionPlugin implements IConfigOptions {
+public class ProjectsRunOptionPlugin extends ProjectsOptionPlugin implements 
IConfigOptions {
 
-  @CommandLine.Option(
-      names = {"-e", "--environment"},
-      description = "The name of the lifecycle environment to use")
-  private String environmentOption = null;
-
-  @CommandLine.Option(
-      names = {"-j", "--project"},
-      description = "The name of the project to use")
-  private String projectOption = null;
-
-  @Override
-  public boolean handleOption(
-      ILogChannel log, IHasHopMetadataProvider hasHopMetadataProvider, 
IVariables variables)
-      throws HopException {
-
-    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-    ProjectConfig projectConfig = null;
-    List<String> configurationFiles = new ArrayList<>();
-    String projectName = projectOption;
-    String environmentName = environmentOption;
-
-    // You can specify the project using -p (project) or -e (lifecycle 
environment)
-    // The main difference is that the environment provides extra 
configuration files to consider.
-    //
-
-    // If there is no environment specified but we have a default set, take 
that one...
-    //
-    if (StringUtils.isEmpty( environmentName )) {
-      environmentName = config.getDefaultEnvironment();
-    }
-
-    // See if an environment is mandatory...
-    //
-    if (config.isEnvironmentMandatory() && StringUtils.isEmpty( 
environmentName )) {
-      throw new HopException("Use of an environment is configured to be 
mandatory and none was specified.");
-    }
-
-    // If there is no project specified but we have a default set, take that 
one...
-    //
-    if (StringUtils.isEmpty( projectName )) {
-      projectName = config.getDefaultProject();
-    }
-
-    // See if a project is mandatory...
-    //
-    if (config.isProjectMandatory() && StringUtils.isEmpty( projectName )) {
-      throw new HopException("Use of a project is configured to be mandatory 
and none was specified.");
-    }
-
-    if ( StringUtils.isNotEmpty(environmentName)) {
-      // The environment contains extra configuration options we need to pass 
along...
-      //
-      LifecycleEnvironment environment = 
config.findEnvironment(environmentName);
-      if (environment == null) {
-        throw new HopException(
-          "Unable to find lifecycle environment '" + environmentName + "'");
-      }
-      projectName = environment.getProjectName();
-
-      if (StringUtils.isEmpty(projectName)) {
-        throw new HopException(
-          "Lifecycle environment '"
-            + environmentOption
-            + "' is not referencing a project.");
-      }
-      projectConfig = config.findProjectConfig(projectName);
-      if (projectConfig == null) {
-        throw new HopException("Unable to find project '" + projectName + "' 
referenced in environment '"+environmentName);
-      }
-      configurationFiles.addAll(environment.getConfigurationFiles());
-
-      log.logBasic(
-        "Referencing environment '"
-          + environmentOption
-          + "' for project "
-          + projectName
-          + "' in "
-          + environment.getPurpose());
-    } else if (StringUtils.isNotEmpty(projectName)) {
-      // Simply reference the project directly without extra configuration 
files...
-      //
-      projectConfig = config.findProjectConfig(projectName);
-      if (projectConfig == null) {
-        throw new HopException("Unable to find project '" + projectName + "'");
-      }
-      projectName = projectConfig.getProjectName();
-    } else {
-        log.logDebug(
-          "No project or environment referenced.");
-        return false;
-      }
-
-
-    try {
-      Project project = projectConfig.loadProject(variables);
-      log.logBasic("Enabling project '" + projectName + "'");
-
-      if (project == null) {
-        throw new HopException("Project '" + projectName + "' couldn't be 
found");
-      }
-      // Now we just enable this project
-      //
-      ProjectsUtil.enableProject(
-        log,
-        projectName,
-        project,
-        variables,
-        configurationFiles,
-        environmentName,
-        hasHopMetadataProvider);
-
-      return true;
-
-    } catch (Exception e) {
-      throw new HopException("Error enabling project '" + projectName + "'", 
e);
-    }
-  }
 }
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsSearchOptionPlugin.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsSearchOptionPlugin.java
new file mode 100644
index 0000000..03d7602
--- /dev/null
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsSearchOptionPlugin.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.projects.config;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hop.core.config.plugin.ConfigPlugin;
+import org.apache.hop.core.config.plugin.IConfigOptions;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.metadata.api.IHasHopMetadataProvider;
+import org.apache.hop.projects.search.ProjectsSearchablesLocation;
+import org.apache.hop.search.HopSearch;
+import org.apache.hop.ui.core.gui.HopNamespace;
+
+@ConfigPlugin(
+    id = "ProjectsSearchOptionPlugin",
+    description = "Project and Environment configuration options for 
hop-search",
+    category = ConfigPlugin.CATEGORY_SEARCH)
+public class ProjectsSearchOptionPlugin extends ProjectsOptionPlugin 
implements IConfigOptions {
+
+  @Override public boolean handleOption( ILogChannel log, 
IHasHopMetadataProvider hasHopMetadataProvider, IVariables variables ) throws 
HopException {
+
+    // If a project or environment was set, pass it to HopSearch...
+    //
+    if (super.handleOption( log, hasHopMetadataProvider, variables )) {
+
+      String projectName = HopNamespace.getNamespace();
+      if ( StringUtils.isNotEmpty(projectName)) {
+        log.logBasic( "Searching in project : "+projectName );
+
+        ProjectsSearchablesLocation projectsSearchablesLocation = new 
ProjectsSearchablesLocation( projectConfig );
+        
((HopSearch)hasHopMetadataProvider).getSearchablesLocations().add(projectsSearchablesLocation);
+
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectSearchablesIterator.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectSearchablesIterator.java
index ff266c8..8b54f79 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectSearchablesIterator.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectSearchablesIterator.java
@@ -22,7 +22,9 @@ import org.apache.hop.core.config.DescribedVariable;
 import org.apache.hop.core.config.HopConfig;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.search.ISearchable;
+import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.metadata.api.IHopMetadata;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.projects.config.ProjectsConfig;
@@ -51,12 +53,11 @@ public class ProjectSearchablesIterator implements 
Iterator<ISearchable> {
   private List<ISearchable> searchables;
   private Iterator<ISearchable> iterator;
 
-  public ProjectSearchablesIterator( ProjectConfig projectConfig ) throws 
HopException {
+  public ProjectSearchablesIterator( IHopMetadataProvider metadataProvider, 
IVariables variables, ProjectConfig projectConfig ) throws HopException {
     this.projectConfig = projectConfig;
     this.searchables = new ArrayList<>();
 
     ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-    HopGui hopGui = HopGui.getInstance();
 
     try {
       List<String> configurationFiles = new ArrayList<>();
@@ -70,23 +71,23 @@ public class ProjectSearchablesIterator implements 
Iterator<ISearchable> {
       File homeFolderFile = new File(projectConfig.getProjectHome());
       Collection<File> pipelineFiles = FileUtils.listFiles( homeFolderFile, 
new String[] { "hpl" }, true );
       for (File pipelineFile : pipelineFiles) {
-        PipelineMeta pipelineMeta = new PipelineMeta(pipelineFile.getPath(), 
hopGui.getMetadataProvider(), true, hopGui.getVariables());
+        PipelineMeta pipelineMeta = new PipelineMeta(pipelineFile.getPath(), 
metadataProvider, true, variables);
         searchables.add(new HopGuiPipelineSearchable( "Project pipeline file", 
pipelineMeta ) );
       }
 
       Collection<File> workflowFiles = FileUtils.listFiles( homeFolderFile, 
new String[] { "hwf" }, true );
       for (File workflowFile : workflowFiles) {
-        WorkflowMeta workflowMeta = new WorkflowMeta(hopGui.getVariables(), 
workflowFile.getPath(), hopGui.getMetadataProvider() );
+        WorkflowMeta workflowMeta = new WorkflowMeta(variables, 
workflowFile.getPath(),metadataProvider );
         searchables.add(new HopGuiWorkflowSearchable( "Project workflow file", 
workflowMeta ) );
       }
 
       // Add the available metadata objects
       //
-      for ( Class<IHopMetadata> metadataClass : 
hopGui.getMetadataProvider().getMetadataClasses() ) {
-        IHopMetadataSerializer<IHopMetadata> serializer = 
hopGui.getMetadataProvider().getSerializer( metadataClass );
+      for ( Class<IHopMetadata> metadataClass : 
metadataProvider.getMetadataClasses() ) {
+        IHopMetadataSerializer<IHopMetadata> serializer = 
metadataProvider.getSerializer( metadataClass );
         for ( final String metadataName : serializer.listObjectNames() ) {
           IHopMetadata hopMetadata = serializer.load( metadataName );
-          HopGuiMetadataSearchable searchable = new HopGuiMetadataSearchable( 
hopGui.getMetadataProvider(), serializer, hopMetadata, 
serializer.getManagedClass() );
+          HopGuiMetadataSearchable searchable = new HopGuiMetadataSearchable( 
metadataProvider, serializer, hopMetadata, serializer.getManagedClass() );
           searchables.add( searchable );
         }
       }
@@ -101,7 +102,7 @@ public class ProjectSearchablesIterator implements 
Iterator<ISearchable> {
       // Now the described variables in the configuration files...
       //
       for (String configurationFile : configurationFiles) {
-        String realConfigurationFile = hopGui.getVariables().resolve( 
configurationFile );
+        String realConfigurationFile = variables.resolve( configurationFile );
 
         if (new File(realConfigurationFile).exists()) {
           DescribedVariablesConfigFile configFile = new 
DescribedVariablesConfigFile( realConfigurationFile );
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectsSearchablesLocation.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectsSearchablesLocation.java
index fcb1206..52eb566 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectsSearchablesLocation.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/search/ProjectsSearchablesLocation.java
@@ -20,6 +20,8 @@ package org.apache.hop.projects.search;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.search.ISearchable;
 import org.apache.hop.core.search.ISearchablesLocation;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.projects.project.ProjectConfig;
 
 import java.util.Iterator;
@@ -28,16 +30,18 @@ public class ProjectsSearchablesLocation implements 
ISearchablesLocation {
 
   private ProjectConfig projectConfig;
 
-  public ProjectsSearchablesLocation( ProjectConfig projectConfig ) {
+  public ProjectsSearchablesLocation(ProjectConfig projectConfig) {
     this.projectConfig = projectConfig;
   }
 
-  @Override public String getLocationDescription() {
-    return "Project "+projectConfig.getProjectName();
+  @Override
+  public String getLocationDescription() {
+    return "Project " + projectConfig.getProjectName();
   }
 
-  @Override public Iterator<ISearchable> getSearchables() throws HopException {
-    return new ProjectSearchablesIterator( projectConfig );
+  @Override
+  public Iterator<ISearchable> getSearchables(
+      IHopMetadataProvider metadataProvider, IVariables variables) throws 
HopException {
+    return new ProjectSearchablesIterator(metadataProvider, variables, 
projectConfig);
   }
-
 }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/search/HopSearchPerspective.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/search/HopSearchPerspective.java
index 6a65f07..524f07f 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/search/HopSearchPerspective.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/search/HopSearchPerspective.java
@@ -19,8 +19,6 @@ package org.apache.hop.ui.hopgui.perspective.search;
 
 import org.apache.hop.core.Const;
 import org.apache.hop.core.gui.plugin.GuiPlugin;
-import org.apache.hop.core.gui.plugin.key.GuiKeyboardShortcut;
-import org.apache.hop.core.gui.plugin.key.GuiOsxKeyboardShortcut;
 import org.apache.hop.core.plugins.IPlugin;
 import org.apache.hop.core.plugins.PluginRegistry;
 import org.apache.hop.core.search.ISearchResult;
@@ -35,7 +33,6 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.HopGui;
-import org.apache.hop.ui.hopgui.HopGuiKeyHandler;
 import org.apache.hop.ui.hopgui.context.IGuiContextHandler;
 import org.apache.hop.ui.hopgui.file.IHopFileType;
 import org.apache.hop.ui.hopgui.file.IHopFileTypeHandler;
@@ -368,7 +365,8 @@ public class HopSearchPerspective implements 
IHopPerspective {
       AuditManagerGuiUtil.addLastUsedValue( AUDIT_TYPE_SEARCH_LOCATION, 
searchablesLocation.getLocationDescription() );
       AuditManagerGuiUtil.addLastUsedValue( AUDIT_TYPE_SEARCH_STRING, 
wSearchString.getText() );
 
-      Iterator<ISearchable> iterator = searchablesLocation.getSearchables();
+      Iterator<ISearchable> iterator =
+          searchablesLocation.getSearchables(hopGui.getMetadataProvider(), 
hopGui.getVariables() );
       while ( iterator.hasNext() ) {
         // Load the next object
         //
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/search/HopGuiSearchLocation.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/search/HopGuiSearchLocation.java
index f9d1475..b123bdf 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/search/HopGuiSearchLocation.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/search/HopGuiSearchLocation.java
@@ -20,6 +20,8 @@ package org.apache.hop.ui.hopgui.search;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.search.ISearchable;
 import org.apache.hop.core.search.ISearchablesLocation;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.ui.hopgui.HopGui;
 
 import java.util.Iterator;
@@ -35,7 +37,7 @@ public class HopGuiSearchLocation implements 
ISearchablesLocation {
     return "Current objects loaded in the Hop GUI";
   }
 
-  @Override public Iterator<ISearchable> getSearchables() throws HopException {
+  @Override public Iterator<ISearchable> getSearchables( IHopMetadataProvider 
metadataProvider, IVariables variables ) throws HopException {
     return new HopGuiSearchLocationIterator( hopGui, this );
   }
 }

Reply via email to