Class Naftah.NaftahCommand.ManualCommand

java.lang.Object
org.daiitech.naftah.Naftah.NaftahCommand
org.daiitech.naftah.Naftah.NaftahCommand.ManualCommand
Enclosing class:
Naftah.NaftahCommand

private static final class Naftah.NaftahCommand.ManualCommand extends Naftah.NaftahCommand
The 'man' subcommand for Naftah.

This command loads and displays documentation topics related to Naftah usage. It provides help pages for classes, accessible classes, instantiable classes, built-in functions, JVM functions, and other runtime information.

The command supports both English and Arabic aliases for flexibility in multi-language environments.

Usage:


 naftah man [options] [filename] [args]
 

The ManualCommand maintains lists of:

It also keeps track of filtered results in filteredClassesOrFunctions and uses a LineReader for interactive input, if needed.

  • Field Details

    • NAME

      private static final String NAME
      The name of this command.
      See Also:
    • START_TIME

      private static final Instant START_TIME
      The start time when the command was initialized.
    • SKIP

      private static final String SKIP
      Marker value to skip processing certain entries.
      See Also:
    • PAGE_SIZE

      private static final int PAGE_SIZE
      Number of items to display per page in paginated output.
      See Also:
    • manualDir

      private final Path manualDir
      Path to the manual directory relative to the JAR.
    • classes

      private final List<String> classes
      List of all classes known to the manual.
    • accessibleClasses

      private final List<String> accessibleClasses
      List of classes accessible in the current context.
    • instantiableClasses

      private final List<String> instantiableClasses
      List of classes that can be instantiated.
    • builtinFunctions

      private final List<String> builtinFunctions
      List of all built-in functions available.
    • jvmFunctions

      private final List<String> jvmFunctions
      List of JVM/Java functions available.
    • filteredClassesOrFunctions

      private final List<String> filteredClassesOrFunctions
      Filtered results for classes or functions after applying user input.
    • reader

      private org.jline.reader.LineReader reader
      Interactive line reader for user input.
    • topics

      private Map<String,Path> topics
      Mapping of topic names to their corresponding documentation paths.
  • Constructor Details

    • ManualCommand

      private ManualCommand()
  • Method Details

    • run

      protected void run(Naftah main, boolean bootstrapAsync) throws Exception
      Runs the command.
      Overrides:
      run in class Naftah.NaftahCommand
      Parameters:
      main - the main Naftah instance
      bootstrapAsync - whether to bootstrap asynchronously
      Throws:
      Exception - if any error occurs
    • getSearchTextFromCommand

      private String getSearchTextFromCommand(String[] commandParts)
      Extracts and normalizes the search text from a tokenized command line.

      This method skips the first element of commandParts (the command keyword) and concatenates the remaining parts without any separator, then trims leading and trailing whitespace from the resulting string.

      For example:

       ["classes", "java", "util"] → "javautil"
       ["الأصناف", "نص", "بحث"] → "نصبحث"
       

      Parameters:
      commandParts - the command line split into parts, where the first element represents the command keyword
      Returns:
      the concatenated search text derived from the remaining command parts, or an empty string if no search text is provided
    • checkManagementCommands

      private boolean checkManagementCommands(String line, org.jline.reader.History history) throws IOException
      Processes and executes management (meta) commands entered by the user in the interactive Naftah manual.

      This method parses the given input line and determines if it corresponds to a supported management command. Supported commands allow the user to:

      • Display usage/help instructions
      • List available topics
      • List Java classes, accessible classes, or instantiable classes
      • List builtin (Naftah) functions or JVM functions
      • Filter any of the above lists by a search text
      • View or manage command history
      • Exit the program

      Commands may be entered in either English or Arabic. Some commands optionally accept a search text argument, in which case only entries matching the search text are displayed.

      When a recognized command is matched, this method executes the corresponding action (e.g., printing paginated results, filtering lists, or updating the command history) and returns true. If the input does not match any known management command, no action is taken and false is returned.

      Examples of supported commands:

      • usage / مساعدة – Display detailed instructions for the interactive manual
      • list / المواضيع – List all available documentation topics
      • classes <search> / الأصناف <نص البحث> – Show Java classes optionally filtered by a search term
      • accessible-classes / الأصناف-المتاحة – Show accessible classes
      • instantiable-classes / الأصناف-القابلة-للتهيئة – Show classes that can be instantiated
      • builtin-functions / الدوال-المدمجة – List Naftah builtin functions
      • jvm-functions / دوال-جافا – List available JVM/Java functions
      • history / الأوامر-المحفوظة – Display all saved REPL commands
      • exit / خروج – Exit the interactive session

      Commands that accept search text (e.g., classes or functions) will filter results and display them in a paginated format. The filtering uses the filteredClassesOrFunctions list, and paginated output is handled by printPaginated(Target, List).

      Parameters:
      line - the raw input command line provided by the user
      history - the REPL command history used for displaying, sanitizing, or purging entries
      Returns:
      true if the input matched a known management command and an action was executed; false if the input did not match any known command
      Throws:
      org.jline.reader.UserInterruptException - if the input corresponds to an exit command (for example "exit" or "خروج"), signaling that the interactive session should be terminated
      IOException - if an I/O error occurs during reading, filtering, or paginated output
      See Also:
    • loadClassesAndFunctions

      private void loadClassesAndFunctions()
      Loads detailed metadata for classes and functions from the DefaultContext in parallel using a fixed thread pool executor.

      This method asynchronously populates multiple collections with formatted, readable representations of:

      • All classes available in the context
      • Accessible classes (e.g., public classes)
      • Instantiable classes (i.e., non-abstract, non-interface)
      • Built-in functions
      • JVM functions

      Each task formats the content using classToDetailedString(...) or toDetailedString() methods, and surrounds each entry with visual dividers for terminal output.

      If a function group contains more than one overload or variant, each one is numbered and printed with its own separator.

      The method uses a fixed thread pool of 5 threads for concurrent execution and ensures proper shutdown of the executor.

    • loadBuiltinFunction

      private String loadBuiltinFunction(Map.Entry<String,List<BuiltinFunction>> builtinFunction)
      Builds a detailed textual representation of a single built-in function entry.

      The output includes the function group name (key) and a formatted list of one or more BuiltinFunction details separated by visual dividers for clarity.

      Parameters:
      builtinFunction - a map entry containing the function group name as key and a list of BuiltinFunction instances as value
      Returns:
      a formatted string containing a detailed description of the built-in functions
    • loadJvmFunction

      private String loadJvmFunction(Map.Entry<String,List<JvmFunction>> jvmFunction)
      Builds a detailed textual representation of a single JVM function entry.

      The output includes the function group name (key) and a formatted list of one or more JvmFunction details separated by visual dividers for readability.

      Parameters:
      jvmFunction - a map entry containing the function group name as key and a list of JvmFunction instances as value
      Returns:
      a formatted string containing a detailed description of the JVM functions
    • getTotal

      private int getTotal(Naftah.NaftahCommand.ManualCommand.Target target, int total)
      Computes the effective total number of elements for a given Naftah.NaftahCommand.ManualCommand.Target by comparing the provided total with the size of the corresponding collection in DefaultContext.

      The returned value is always the maximum of:

      • the supplied total value (typically derived from a cached or partially populated list), and
      • the size of the runtime collection associated with the specified target.
      This ensures pagination and indexed access remain consistent even when the target list has not yet been fully populated.

      Parameters:
      target - the target type whose backing context collection should be used for comparison
      total - the current known total (for example, the size of a cached list)
      Returns:
      the maximum of total and the size of the corresponding DefaultContext collection for the given target
    • loadClassOrFunction

      private String loadClassOrFunction(int index, Naftah.NaftahCommand.ManualCommand.Target target, List<String> targetList, String classOrFunctionFilter)
      Resolves, loads, and formats the detailed representation of a class or function at the specified index for the given target category.

      This method first attempts to return a previously loaded (cached) entry from targetList. If the requested index is not yet available in that list, it performs a lazy lookup against the corresponding collection in DefaultContext, based on the provided Naftah.NaftahCommand.ManualCommand.Target.

      Depending on the target type, the lookup is delegated to one of the following detail loaders:

      • loadDetailedClass(Map.Entry) for class-based targets
      • loadBuiltinFunction(Map.Entry) for builtin functions
      • loadJvmFunction(Map.Entry) for JVM functions

      If a classOrFunctionFilter is provided, the resolved element must match the filter (by name or related metadata, depending on the target). If the element at the given index does not satisfy the filter, the lookup is considered invalid and null is returned.

      Successfully resolved elements are formatted, appended to targetList for caching purposes, and then returned.

      Parameters:
      index - the zero-based index of the element to resolve
      target - the target category indicating which context collection should be queried
      targetList - the cache of already loaded and formatted entries for the given target
      classOrFunctionFilter - an optional search filter used to restrict results; may be null or blank
      Returns:
      the formatted detailed representation of the resolved element, or null if the index exists but does not satisfy the filter
      Throws:
      NaftahBugError - if the index is valid but the element cannot be resolved or formatted due to an unexpected internal error
    • printPaginated

      private void printPaginated(Naftah.NaftahCommand.ManualCommand.Target target, List<String> lines)
      Prints elements of the specified target to the terminal in a paginated manner.

      This is a convenience overload that delegates to printPaginated(Target, List, String) without applying any search filter.

      Parameters:
      target - the target category whose elements are being displayed
      lines - the cache of already loaded and formatted elements; additional elements may be lazily loaded during pagination
    • printPaginated

      private void printPaginated(Naftah.NaftahCommand.ManualCommand.Target target, List<String> lines, String classOrFunctionFilter)
      Prints elements of the specified target to the terminal in a paginated manner, with optional filtering applied during lazy loading.

      Elements are resolved on demand using loadClassOrFunction(int, Target, List, String). Already loaded entries are reused from lines, while missing entries are fetched, formatted, and appended as needed.

      Output is constrained by both a logical page size (PAGE_SIZE) and the effective terminal height. Multi-line entries are split as necessary to avoid overflowing the terminal viewport.

      Between pages, and whenever the terminal height limit is reached, the user is prompted to continue browsing. Pagination can be terminated early if the user enters any quit command recognized by REPLHelper.shouldQuit(LineReader).

      Parameters:
      target - the target category indicating which context collection is being paginated
      lines - the cache of already loaded and formatted elements; this list may be mutated during execution
      classOrFunctionFilter - an optional search filter applied during element resolution; may be null or blank
    • loadAvailableTopics

      private Map<String,Path> loadAvailableTopics() throws IOException
      Loads all available manual topics from the manualDir directory and returns them as a map of topic keys to their corresponding file paths.

      Each file in the directory is assumed to follow a naming convention like:

       001_topic-name.md
       
      The method:
      • Lists all files in the manualDir directory
      • Strips the file extension
      • Splits the name by underscore (_)
      • Skips the numeric prefix (e.g. 001)
      • Joins the remaining parts using hyphens (-) to form the topic key
      For example, 002_getting_started.md becomes getting-started. The resulting map allows easy lookup of topics by normalized key.
      Returns:
      a map of topic keys (e.g., getting-started) to Path objects representing their files
      Throws:
      IOException - if an I/O error occurs while accessing the manualDir
    • showManualTopic

      private void showManualTopic(String topic) throws IOException
      Displays the content of a manual topic in the terminal, formatted from Markdown.

      This method retrieves the file path for the given topic from the topics map, reads its content, parses it using a Markdown parser (such as commonmark), and then prints the parsed output to the terminal in a readable format.

      The output includes:

      • A header showing the topic name
      • A visual separator
      • The formatted content of the manual topic
      Parameters:
      topic - the name of the manual topic to display
      Throws:
      IOException - if the file for the given topic cannot be read
    • loadDetailedClasses

      private void loadDetailedClasses(Map<String,Class<?>> classes, List<String> target)
      Loads detailed string representations of the provided classes and appends them to the given target list.

      Each class is formatted using ClassUtils.classToDetailedString(Class) and prefixed with a visual separator and its associated key from the provided map. The final string for each class follows the structure:

       ---------------------------------------------------
       [Class Key]
       [Detailed Class Info]
       ---------------------------------------------------
       

      This method is useful for debugging, documentation, or logging purposes where a full breakdown of multiple classes is required in an easily readable form.

      Parameters:
      classes - a map of string keys (e.g., class labels or names) to Class objects
      target - the list to which the formatted, detailed string representations will be added
    • loadDetailedClass

      private String loadDetailedClass(Map.Entry<String,Class<?>> JvmFunction)