Add JShell Accumulo Feature (#1910)

In response to apache/accumulo#1870, this commit includes
basic functionality to boot up JShell with default
Accumulo APIs and any user custom file(s).

Co-authored-by: Christopher Tubbs <ctubbsii@apache.org>
diff --git a/assemble/bin/accumulo b/assemble/bin/accumulo
index ba6c4a2..f82f848 100755
--- a/assemble/bin/accumulo
+++ b/assemble/bin/accumulo
@@ -59,6 +59,17 @@
     exit 0
   fi
 
+  # Start up JShell with Accumulo
+  local jShellPath="$conf/jshell-init.jsh"
+  if [[ $cmd == "jshell" ]]; then
+    shift
+    if [[ -f "$jShellPath" ]]; then
+      exec "$cmd" --startup DEFAULT --startup "$jShellPath" "$@"
+    else
+      exec "$cmd" "$@"
+    fi
+  fi
+
   if [[ -x "$JAVA_HOME/bin/java" ]]; then
     JAVA="$JAVA_HOME/bin/java"
   else
diff --git a/assemble/pom.xml b/assemble/pom.xml
index 45fdfc7..ee4fcda 100644
--- a/assemble/pom.xml
+++ b/assemble/pom.xml
@@ -503,6 +503,16 @@
               </arguments>
             </configuration>
           </execution>
+          <execution>
+            <id>create-jshell</id>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <phase>compile</phase>
+            <configuration>
+              <executable>src/main/scripts/create-jshell.sh</executable>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>
diff --git a/assemble/src/main/assemblies/component.xml b/assemble/src/main/assemblies/component.xml
index 2c738ec..630a2b7 100644
--- a/assemble/src/main/assemblies/component.xml
+++ b/assemble/src/main/assemblies/component.xml
@@ -130,6 +130,7 @@
       <fileMode>0644</fileMode>
       <includes>
         <include>accumulo-client.properties</include>
+        <include>jshell-init.jsh</include>
       </includes>
     </fileSet>
     <fileSet>
diff --git a/assemble/src/main/scripts/create-jshell.sh b/assemble/src/main/scripts/create-jshell.sh
new file mode 100755
index 0000000..6d58fee
--- /dev/null
+++ b/assemble/src/main/scripts/create-jshell.sh
@@ -0,0 +1,77 @@
+#! /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.
+#
+
+function addAccumuloAPI() {
+  local srcDir="$1" api apiPath
+  # Validate each source directory before populating JShell-Init file
+  if [[ ! -d "$srcDir" ]]; then
+    echo "$srcDir is not a valid directory. Please make sure it exists."
+    exit 1
+  fi
+
+  # Extract API info from provided source directory
+  mapfile -t api < <(find "$srcDir" -type f -name '*.java' -print0 | xargs -0 -n1 dirname | sort -u)
+
+  # Load in API and format source directory into Java import statements
+  for apiPath in "${api[@]}"; do
+    echo "import ${apiPath##*/java/}.*;" | tr / .
+  done
+  echo
+}
+
+function main() {
+  local SOURCE bin scriptPath mainBase corePath
+  # Establish Accumulo's main base directory
+  SOURCE="${BASH_SOURCE[0]}"
+  while [[ -h "${SOURCE}" ]]; do
+    bin="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
+    SOURCE="$(readlink "${SOURCE}")"
+    [[ "${SOURCE}" != /* ]] && SOURCE="${bin}/${SOURCE}"
+  done
+
+  # Establish file and folder paths for JShell config
+  scriptPath="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
+  mainBase="$( cd -P "${scriptPath}"/../../../.. && pwd )"
+  corePath="$mainBase/core/src/main/java/org/apache/accumulo/core"
+
+  # Create new jshell-init file
+  mkdir -p "$mainBase/assemble/target"
+  echo 'Generating JShell-Init file'
+  {
+    echo '// Accumulo Client API'
+    addAccumuloAPI "$corePath/client"
+    echo '// Accumulo Data API'
+    addAccumuloAPI "$corePath/data"
+    echo '// Accumulo Security API'
+    addAccumuloAPI "$corePath/security"
+    echo '// Accumulo MiniCluster API'
+    addAccumuloAPI "$mainBase/minicluster/src/main/java/org/apache/accumulo/minicluster"
+    echo '// Accumulo Hadoop API'
+    addAccumuloAPI "$mainBase/hadoop-mapreduce/src/main/java/org/apache/accumulo/hadoop/mapreduce"
+    echo '// Essential Hadoop API'
+    echo 'import org.apache.hadoop.io.Text;'
+    echo
+    echo '// Initialization code'
+    echo 'System.out.println("Preparing JShell for Apache Accumulo");'
+    echo
+  } > "$mainBase/assemble/target/jshell-init.jsh"
+}
+
+main "$@"