# Project Scan Hook

**URL:** <https://forum.inductiveautomation.com/t/project-scan-hook/104304>\
**Category:** Module Development\
**Created:** [March 27, 2025, 1:22pm UTC](https://forum.inductiveautomation.com/t/project-scan-hook/104304 "2025-03-27T13:22:47Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [March 27, 2025, 1:22pm UTC](https://forum.inductiveautomation.com/t/project-scan-hook/104304/1 "2025-03-27T13:22:47Z")

</div>

Is there a hook present to fire actions on a project scan that identifies changes?

I have a module that is compiling some side-content in a gateway that depends on certain resources, and I dont really want to setup a custom thing to watch those resources, but ideally to just leverage a pre-existing hook that sees new resources.

Ideal state would be this:

1. Project Scan Starts
2. Project Scan identifies 3 new resources
3. Project Scan does whatever it needs to do to the resources
4. Project Scan finishes that, and fires said mystery `OnProjectScanCompleteHook`
5. Said hook gives me a list of resources that were just identified, and I can go on about my business with them.

I have dug around in the javadocs and haven't found anything yet that could mirror this setup.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [March 27, 2025, 1:32pm UTC](https://forum.inductiveautomation.com/t/project-scan-hook/104304/2 "2025-03-27T13:32:36Z")

</div>

Not exactly like you're asking for, but you'll probably want to look at 3 things:

1. `ProjectManagerBase::addProjectListener` and `::removeProjectListener` ([ProjectManagerBase](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.47/com/inductiveautomation/ignition/gateway/project/ProjectManagerBase.html#addProjectListener(com.inductiveautomation.ignition.common.project.ProjectListener)))
2. `Project::addProjectResourceListener` and `::removeProjectResourceListener` ([Project](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.47/com/inductiveautomation/ignition/common/project/Project.html#addProjectResourceListener(com.inductiveautomation.ignition.common.project.ProjectResourceListener)))
3. `ProjectLifecycle` and `ProjectLifecycleFactory`, which are things you can use to not deal with the "raw" listeners and instead just get notified when resources you're interested in get created/updated/deleted. ([ProjectLifecycle](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.47/com/inductiveautomation/ignition/gateway/project/ProjectLifecycle.html) and [ProjectLifecycleFactory](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.47/com/inductiveautomation/ignition/gateway/project/ProjectLifecycleFactory.html))

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [March 27, 2025, 1:38pm UTC](https://forum.inductiveautomation.com/t/project-scan-hook/104304/3 "2025-03-27T13:38:27Z")

</div>

Here's a fairly simple example of what implementing a ProjectLifecycle and ProjectLifecycleFactory look like:

```java
    private static final ResourceFilter PIPELINE_RESOURCE_FILTER = new ResourceFilter(
        ApplicationScope.GATEWAY,
        Collections.singletonList(PipelineDescriptor.RESOURCE_TYPE));

    private class PipelineLifecycleFactory extends ProjectLifecycleFactory<PipelineLifecycle> {

        PipelineLifecycleFactory(ProjectManager projectManager) {
            super(projectManager);
        }

        @Override
        public PipelineLifecycle createProjectLifecycle(RuntimeProject project) {
            return new PipelineLifecycle(project);
        }

        @Override
        protected ResourceFilter getResourceFilter() {
            return PIPELINE_RESOURCE_FILTER;
        }

        @Override
        public Predicate<RuntimeProject> getProjectFilter() {
            return project -> project.hasResourcesOfType(PipelineDescriptor.RESOURCE_TYPE);
        }

    }

    private class PipelineLifecycle extends ProjectLifecycle {

        PipelineLifecycle(RuntimeProject project) {
            super(project);
        }

        @Override
        protected void onStartup(List<ProjectResource> resources) {
            startPipelinesFromResources(resources);
        }

        @Override
        protected void onShutdown(List<ProjectResourceId> resourceIds) {
            retirePipelinesFromResources(resourceIds);
        }

        @Override
        protected void onResourcesCreated(List<ProjectResource> resources) {
            startPipelinesFromResources(resources);
        }

        @Override
        protected void onResourcesModified(List<ProjectResource> resources) {
            // Modifications to a pipeline are basically stop the old one and start a new one.
            // startPipelinesFromResources() will retire an existing pipeline before starting
            // an updated pipeline.
            startPipelinesFromResources(resources);
        }

        @Override
        protected void onResourcesDeleted(List<ProjectResourceId> resourceIds) {
            retirePipelinesFromResources(resourceIds);
        }

    }

```

Elsewhere the factory gets instantiated and `startup()` is called on it, then eventually `shutdown()`.

You may just want the listeners if you don't care about the lifecycle of the project as well as the resources.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [March 27, 2025, 1:40pm UTC](https://forum.inductiveautomation.com/t/project-scan-hook/104304/4 "2025-03-27T13:40:47Z")

</div>

This is perfect!

Thanks, I will try it out.
