private IndexingHandler getHandler(RepositorySession repositorySession, String path) {
    org.sakaiproject.nakamura.api.lite.Session sparseSession =
        repositorySession.adaptTo(org.sakaiproject.nakamura.api.lite.Session.class);

    while (path != null) {
      if (!ignoreCache.containsKey(path)) {
        try {
          if (sparseSession != null) {
            ContentManager contentManager = sparseSession.getContentManager();
            Content c = contentManager.get(path);
            LOGGER.debug("Checking Content at {} got {} ", path, c);
            if (c != null) {
              if (c.hasProperty(SLING_RESOURCE_TYPE)) {
                String resourceType = (String) c.getProperty(SLING_RESOURCE_TYPE);
                IndexingHandler handler = indexers.get(resourceType);
                if (handler != null) {
                  LOGGER.debug(
                      "Handler of type {} found {} for {} from {} ",
                      new Object[] {resourceType, handler, path, indexers});
                  return handler;
                } else {
                  TelemetryCounter.incrementValue(
                      "solr", "SparseIndexingServiceImpl-ignoredPath", path);
                  LOGGER.debug("Ignored {} no handler for {} ", path, resourceType);
                  ignoreCache.put(path, path);
                }
              } else {
                LOGGER.debug("Ignored {} no resource type ", path);
              }
            }
          }
        } catch (StorageClientException e) {
          LOGGER.debug(e.getMessage(), e);
        } catch (AccessDeniedException e) {
          LOGGER.debug(e.getMessage(), e);
        }
      }
      if (StorageClientUtils.isRoot(path)) {
        break;
      }
      path = Utils.getParentPath(path);
    }
    TelemetryCounter.incrementValue("solr", "SparseIndexingServiceImpl", "useDefaultHandler");
    return defaultHandler;
  }
  private void addDefaultFields(SolrInputDocument doc, RepositorySession repositorySession)
      throws StorageClientException {
    Object o = doc.getFieldValue(_DOC_SOURCE_OBJECT);
    if (o instanceof Content) {
      Content content = (Content) o;
      boolean writeReaders = true;
      Object suppressReadersValue = doc.getFieldValue(FIELD_SUPPRESS_READERS);
      if (suppressReadersValue instanceof String) {
        if (FIELD_SUPPRESS_READERS.equals(suppressReadersValue)) {
          writeReaders = false;
          doc.removeField(FIELD_SUPPRESS_READERS);
        }
      }
      if (writeReaders) {
        String[] principals =
            getReadingPrincipals(repositorySession, Security.ZONE_CONTENT, content.getPath());
        for (String principal : principals) {
          doc.addField(FIELD_READERS, principal);
        }
      } else {
        doc.removeField(FIELD_READERS);
      }

      if (content.hasProperty(SLING_RESOURCE_TYPE)) {
        doc.setField(FIELD_RESOURCE_TYPE, content.getProperty(SLING_RESOURCE_TYPE));
      }
      String path = content.getPath();
      // we don't overwrite the id field if it has been provided
      if (!doc.getFieldNames().contains(FIELD_ID)) {
        doc.setField(FIELD_ID, path);
      }
      while (path != null) {
        doc.addField(FIELD_PATH, path);
        String newPath = Utils.getParentPath(path);
        if (path.equals(newPath)) {
          break;
        }
        path = newPath;
      }
      doc.removeField(_DOC_SOURCE_OBJECT);
    } else {
      TelemetryCounter.incrementValue("solr", "SparseIndexingServiceImpl", "docMissingSource");
      LOGGER.error(
          "Note to Developer: Indexer must add the _source fields so that the default fields can be set, please correct, SolrDoc was {} ",
          doc);
      throw new StorageClientException(
          _DOC_SOURCE_OBJECT
              + " fields was missing from Solr Document, please correct the handler implementation");
    }
  }
 public Collection<SolrInputDocument> getDocuments(
     RepositorySession repositorySession, Event event) {
   String topic = event.getTopic();
   if (topic.endsWith(StoreListener.UPDATED_TOPIC) || topic.endsWith(StoreListener.ADDED_TOPIC)) {
     final IndexingHandler indexingHandler = getHandler(repositorySession, event);
     if (indexingHandler != null) {
       LOGGER.debug(
           "Update action at path:{}  require on {} ", event.getProperty(FIELD_PATH), event);
       Collection<SolrInputDocument> docs = indexingHandler.getDocuments(repositorySession, event);
       List<SolrInputDocument> outputDocs = Lists.newArrayList();
       if (docs != null) {
         for (SolrInputDocument doc : docs) {
           boolean docAdded = false;
           for (String name : doc.getFieldNames()) {
             // loop through the fields of the returned docs to make sure they contain
             // atleast 1 field that is not a system property. this is not to filter out
             // any system properties but to make sure there are more things to index than
             // just system properties.
             if (!SYSTEM_PROPERTIES.contains(name)) {
               try {
                 addDefaultFields(doc, repositorySession);
                 outputDocs.add(doc);
                 docAdded = true;
               } catch (StorageClientException e) {
                 LOGGER.warn(
                     "Failed to index {} cause: {} ",
                     event.getProperty(FIELD_PATH),
                     e.getMessage());
               }
               break;
             }
           }
           if (!docAdded) {
             TelemetryCounter.incrementValue(
                 "solr", "SparseIndexingServiceImpl", "docHasOnlySysProps");
           }
         }
       }
       return outputDocs;
     } else {
       LOGGER.debug(
           "Ignored action at path:{}  require on {} ", event.getProperty(FIELD_PATH), event);
     }
   } else {
     LOGGER.debug("No update action require on {} ", event);
   }
   return ImmutableList.of();
 }
 private IndexingHandler getHandler(RepositorySession repositorySession, Event event) {
   String path = (String) event.getProperty(FIELD_PATH);
   if (!ignore(path)) {
     // The content might have been deleted by the event, or we might not
     // have been given a content session to work with, and so we first
     // check the resourceType cached in the event record itself.
     String resourceType = (String) event.getProperty("resourceType");
     if ((resourceType != null) && indexers.containsKey(resourceType)) {
       return indexers.get(resourceType);
     } else {
       if (repositorySession != null) {
         return getHandler(repositorySession, path);
       } else {
         // If there is no content system to walk, then we're done.
         TelemetryCounter.incrementValue("solr", "SparseIndexingServiceImpl", "useDefaultHandler");
         return defaultHandler;
       }
     }
   } else {
     return null;
   }
 }