/** @inheritDoc */
 @Override
 public void startUp(IngestJobContext context) throws IngestModuleException {
   this.context = context;
   synchronized (FilesIdentifierIngestModule.sharedResourcesLock) {
     if (FilesIdentifierIngestModule.refCounter.incrementAndGet(context.getJobId()) == 1) {
       // Starting up the first instance of this module for this ingest
       // job, so get the interesting file sets definitions snapshot
       // for the job. Note that getting this snapshot atomically via a
       // synchronized definitions manager method eliminates the need
       // to disable the interesting files set definition UI during ingest.
       List<FilesSet> filesSets = new ArrayList<>();
       try {
         for (FilesSet set :
             InterestingItemDefsManager.getInstance().getInterestingFilesSets().values()) {
           if (settings.interestingFilesSetIsEnabled(set.getName())) {
             filesSets.add(set);
           }
         }
       } catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
         throw new IngestModuleException(Bundle.FilesIdentifierIngestModule_getFilesError(), ex);
       }
       FilesIdentifierIngestModule.interestingFileSetsByJob.put(context.getJobId(), filesSets);
     }
   }
 }
  /** @inheritDoc */
  @Override
  @Messages({
    "FilesIdentifierIngestModule.indexError.message=Failed to index interesting file hit artifact for keyword search."
  })
  public ProcessResult process(AbstractFile file) {
    blackboard = Case.getCurrentCase().getServices().getBlackboard();

    // See if the file belongs to any defined interesting files set.
    List<FilesSet> filesSets =
        FilesIdentifierIngestModule.interestingFileSetsByJob.get(this.context.getJobId());
    for (FilesSet filesSet : filesSets) {
      String ruleSatisfied = filesSet.fileIsMemberOf(file);
      if (ruleSatisfied != null) {
        try {
          // Post an interesting files set hit artifact to the
          // blackboard.
          String moduleName = InterestingItemsIngestModuleFactory.getModuleName();
          BlackboardArtifact artifact =
              file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);

          // Add a set name attribute to the artifact. This adds a
          // fair amount of redundant data to the attributes table
          // (i.e., rows that differ only in artifact id), but doing
          // otherwise would requires reworking the interesting files
          // set hit artifact.
          BlackboardAttribute setNameAttribute =
              new BlackboardAttribute(
                  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, moduleName, filesSet.getName());
          artifact.addAttribute(setNameAttribute);

          // Add a category attribute to the artifact to record the
          // interesting files set membership rule that was satisfied.
          BlackboardAttribute ruleNameAttribute =
              new BlackboardAttribute(
                  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, moduleName, ruleSatisfied);
          artifact.addAttribute(ruleNameAttribute);

          try {
            // index the artifact for keyword search
            blackboard.indexArtifact(artifact);
          } catch (Blackboard.BlackboardException ex) {
            logger.log(
                Level.SEVERE,
                "Unable to index blackboard artifact " + artifact.getArtifactID(),
                ex); // NON-NLS
            MessageNotifyUtil.Notify.error(
                Bundle.FilesIdentifierIngestModule_indexError_message(), artifact.getDisplayName());
          }

          IngestServices.getInstance()
              .fireModuleDataEvent(
                  new ModuleDataEvent(
                      moduleName,
                      BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT,
                      Collections.singletonList(artifact)));

        } catch (TskCoreException ex) {
          FilesIdentifierIngestModule.logger.log(
              Level.SEVERE, "Error posting to the blackboard", ex); // NOI18N NON-NLS
        }
      }
    }
    return ProcessResult.OK;
  }