Class Projects

All Implemented Interfaces:
PropertyChangeListener, EventListener, ContextProvider, PropertyChangeSource, Rebindable

public class Projects extends AnahataToolkit implements PropertyChangeListener
A toolkit for interacting with the NetBeans Project APIs.

This toolkit acts as a global ContextProvider that manages a hierarchy of ProjectContextProviders, one for each open project in the IDE. It uses Canonical Paths for all registrations and lookups to ensure consistency across physical and virtual (MasterFS) FileObject proxies.

Author:
anahata
  • Field Details

    • listening

      private transient boolean listening
      Flag indicating if the toolkit is currently listening for global IDE project changes.
  • Constructor Details

    • Projects

      public Projects()
  • Method Details

    • initialize

      public void initialize()
      Performs initial setup for a newly created toolkit instance.

      This method is called exactly once by the ToolManager after the toolkit has been instantiated and registered. It provides a clean hook for toolkits to perform one-time initialization logic that requires the tool environment to be fully configured, such as scanning for project instructions or registering default resources.

      Registers project providers and ensures the hierarchical context is synchronized with the current IDE state.

      Overrides:
      initialize in class AnahataToolkit
    • rebind

      public void rebind()
      Rebinds the toolkit after deserialization.

      This method is called by the framework during session activation to restore transient state, reconnect listeners, or refresh cached project instances. It ensures the propertyChangeSupport is re-initialized.

      Overrides the base rebind logic to trigger a lazy initialization of all project child providers and fires a UI refresh for all open projects. This ensures that IDE annotations and context status are correctly reflected immediately upon session start or restoration.

      Specified by:
      rebind in interface Rebindable
      Overrides:
      rebind in class AnahataToolkit
    • getSystemInstructions

      public List<String> getSystemInstructions() throws Exception
      Gets a list of system instruction strings provided by this context provider. These are typically prepended to the conversation as high-level guidance.

      Provides a Markdown-formatted guide on how to handle Compile On Save (CoS) project property overrides, explaining the priority of IDE configuration over POM properties and detailing FQN/path resolution strategies for loading java types by fqn or path.

      Specified by:
      getSystemInstructions in interface ContextProvider
      Returns:
      A list containing the project management instructions.
      Throws:
      Exception - on internal error.
    • populateMessage

      public void populateMessage(RagMessage ragMessage)
      Populates the given RagMessage with dynamic, just-in-time context parts. These parts are appended to the end of the user's prompt (RAG).

      Populates the RAG message with a high-level overview of the IDE environment, including project folders, open projects, and the main project selection.

      Specified by:
      populateMessage in interface ContextProvider
      Parameters:
      ragMessage - The target RAG message.
    • ensureAnahataMdExists

      public static org.openide.filesystems.FileObject ensureAnahataMdExists(org.netbeans.api.project.Project project) throws IOException
      Ensures that the anahata.md file exists in the project root.

      If the file is missing, it creates a default template. The template logic is aware of Maven multi-module structures and injects appropriate architectural notes for parent and sub-module projects.

      Parameters:
      project - The project to check.
      Returns:
      The FileObject for anahata.md.
      Throws:
      IOException - if creation fails.
    • listAvailableProjectFolders

      public List<String> listAvailableProjectFolders()
      Lists all directories within the user's NetBeansProjects folder.

      Scans the system's project folder and returns a sorted list of names for all subdirectories.

      Returns:
      A list of directory names.
    • findOpenProject

      public static org.netbeans.api.project.Project findOpenProject(String projectDirectoryPath) throws Exception
      Locates an open project instance by its directory path.

      Performs a lookup across all currently open projects in the IDE using canonical path comparison to avoid issues with symlinks or virtual file proxies.

      Parameters:
      projectDirectoryPath - The absolute path to the project.
      Returns:
      The Project instance.
      Throws:
      Exception - if the project is not found or is closed.
    • getOpenProjects

      public List<String> getOpenProjects()
      Returns a list of absolute paths for all projects currently open in the IDE.

      Iterates through the IDE's open project list and captures the canonical path for each project's root directory.

      Returns:
      A list of canonical project paths.
    • getMainProject

      public String getMainProject()
      Returns the canonical path of the current NetBeans Main Project.

      Queries the IDE for the main project and resolves its directory to an absolute canonical path.

      Returns:
      The main project path, or null if none is set.
    • setMainProject

      public void setMainProject(String projectPath) throws Exception
      Sets the specified open project as the IDE's 'Main Project'.

      Resolves the project by its path and updates the NetBeans project management UI state.

      Parameters:
      projectPath - The absolute path of the project to set as main.
      Throws:
      Exception - if the project is not open.
    • closeProjects

      public void closeProjects(List<String> projectPaths) throws Exception
      Closes the specified projects in the IDE.

      Resolves multiple paths to project instances and performs a bulk close operation through the IDE controller.

      Parameters:
      projectPaths - A list of absolute paths of the projects to close.
      Throws:
      Exception - if any path does not resolve to an open project.
    • openProject

      public String openProject(String projectPath, boolean openSubprojects) throws Exception
      Opens a NetBeans project and optionally its subprojects.

      Handles both absolute and relative paths. It uses a CountDownLatch and an IDE property listener to synchronize the asynchronous open operation with the tool execution, ensuring the project is fully loaded before returning.

      Parameters:
      projectPath - The path to the project directory.
      openSubprojects - Whether to automatically open all subprojects.
      Returns:
      A status message indicating success or timeout.
      Throws:
      Exception - on internal error or directory failure.
    • openSubprojects

      public String openSubprojects(String projectPath) throws Exception
      Opens all sub-modules for a given parent project.

      Queries the project's SubprojectProvider and initiates the opening of all discovered subprojects in a single batch.

      Parameters:
      projectPath - The absolute path of the parent project.
      Returns:
      A status message summarizing the subprojects open request status.
      Throws:
      Exception - if the parent project is not open.
    • getOverview

      public ProjectOverview getOverview(String projectPath) throws Exception
      Generates a structured overview of a project's metadata and environment.

      Collects comprehensive data including packaging type, supported actions, Java versions, source encoding, and 'Compile on Save' status. It also fetches a list of declared Maven dependencies.

      Parameters:
      projectPath - The absolute path of the project.
      Returns:
      A ProjectOverview DTO.
      Throws:
      Exception - if the project is not found or is closed.
    • isCompileOnSaveEnabled

      public String isCompileOnSaveEnabled(org.netbeans.api.project.Project project)
      Determines the effective 'Compile on Save' status for a project.

      Follows the NetBeans priority hierarchy: 1. IDE Configuration overrides, 2. Maven properties in the POM, 3. Maven default settings.

      Parameters:
      project - The project to check.
      Returns:
      A status string indicating the value and its source.
    • setCompileOnSaveOverride

      public void setCompileOnSaveOverride(String projectPath, boolean enabled) throws Exception
      Configures a permanent 'Compile on Save' override for a project.

      Writes the netbeans.compile.on.save property to the project's nb-configuration.xml file. This ensures the setting persists across IDE restarts and takes precedence over POM properties.

      Parameters:
      projectPath - The absolute path of the project.
      enabled - Whether to enable ('all') or disable ('none') Compile on Save.
      Throws:
      Exception - on internal write error.
    • getProjectFiles

      public ProjectFiles getProjectFiles(String projectPath) throws Exception
      Generates a structural overview of all files and source folders in a project.

      Scans the project root for files and traverses all registered Java and Resource source groups to build a detailed DTO tree.

      Parameters:
      projectPath - The absolute path of the project.
      Returns:
      A ProjectFiles DTO.
      Throws:
      Exception - if project not open.
    • getProjectAlerts

      public ProjectDiagnostics getProjectAlerts(String projectPath) throws Exception
      Performs a comprehensive diagnostic scan of a project.

      Aggregates compilation errors from the NetBeans ErrorsCache and high-level IDE project problems (like missing SDKs or broken dependencies) into a single diagnostic report.

      Parameters:
      projectPath - The absolute path of the project to scan.
      Returns:
      A ProjectDiagnostics report.
      Throws:
      Exception - if project not open.
    • findFilesInError

      public static List<org.openide.filesystems.FileObject> findFilesInError(org.netbeans.api.project.Project project)
      Locates all Java source files with compilation errors in the project.

      Scans all Java source groups and uses the parsing cache to identify files currently flagged with errors.

      Parameters:
      project - The target project.
      Returns:
      A list of FileObjects in error.
    • setProjectProviderEnabled

      public void setProjectProviderEnabled(String projectPath, boolean enabled)
      Toggles the context provider state for a specific project.

      Locates the appropriate provider by its canonical path and updates its activation state. Triggers a recursive visual refresh of project icons in the NetBeans UI.

      Parameters:
      projectPath - The absolute path of the project.
      enabled - Whether to enable the context provider.
    • invokeAction

      public void invokeAction(String projectPath, String action) throws Exception
      Executes a project-level action.

      Uses the project's action provider to trigger an asynchronous task. This is suitable for actions like 'run', 'clean', or 'build'.

      Parameters:
      projectPath - The absolute path of the project.
      action - The action to invoke.
      Throws:
      Exception - if the project is not open or the action is unsupported.
    • getChildrenProviders

      public List<ContextProvider> getChildrenProviders()
      Gets the list of immediate child context providers.

      Returns the list of active project child providers, implementing a lazy-initialization pattern that registers a global IDE project state listener on the first call.

      Specified by:
      getChildrenProviders in interface ContextProvider
      Overrides:
      getChildrenProviders in class AnahataToolkit
      Returns:
      A list of context providers.
    • syncProjects

      private void syncProjects()
      Synchronizes project context providers with currently open IDE projects.

      Uses canonical paths to detect newly opened projects and stale providers for closed projects. It maintains the hierarchical context structure by adding or pruning providers as needed.

    • getProjectProvider

      public Optional<ProjectContextProvider> getProjectProvider(String projectPath)
      Returns a project context provider by path.

      Filters the active provider hierarchy for a project context provider that matches the specified canonical path.

      Parameters:
      projectPath - The canonical path.
      Returns:
      An Optional containing the provider.
    • getCanonicalPath

      public static String getCanonicalPath(org.openide.filesystems.FileObject fo)
      Resolves a FileObject to its canonical physical path.

      Attempts to normalize the file and resolve it via standard Java NIO canonical path resolution. Falls back to the standard path string if the resolution fails.

      Parameters:
      fo - The FileObject.
      Returns:
      The canonical path string.
    • propertyChange

      public void propertyChange(PropertyChangeEvent evt)

      Listens for IDE global project state changes and triggers a synchronization of the context provider hierarchy whenever projects are opened or closed.

      Specified by:
      propertyChange in interface PropertyChangeListener
      Parameters:
      evt - The property change event from the IDE.
    • buildSourceFolderTree

      private SourceFolder buildSourceFolderTree(org.openide.filesystems.FileObject folder, String displayName) throws org.openide.filesystems.FileStateInvalidException
      Recursively builds a structural tree for a source folder.

      Traverses children, classifying subfolders as SourceFolders and files as ProjectFiles, while calculating the recursive directory size.

      Parameters:
      folder - The target folder.
      displayName - The display name (from SourceGroup).
      Returns:
      A SourceFolder DTO.
      Throws:
      org.openide.filesystems.FileStateInvalidException - if the filesystem is invalid.
    • createProjectFile

      private ProjectFile createProjectFile(org.openide.filesystems.FileObject fo) throws org.openide.filesystems.FileStateInvalidException
      Creates a ProjectFile DTO with IDE-specific name annotations.

      Captures file metadata and attempts to extract HTML display names from the IDE's node delegate, stripping HTML tags to provide a clean annotated name.

      Parameters:
      fo - The target file.
      Returns:
      A ProjectFile DTO.
      Throws:
      org.openide.filesystems.FileStateInvalidException - if the filesystem is invalid.
    • getNetBeansProjectsFolder

      private String getNetBeansProjectsFolder()
      Returns the root NetBeansProjects directory.

      Queries the NetBeans project chooser for the standardized projects folder location, falling back to a default folder in the user's home directory.

      Returns:
      Absolute path to the projects folder.