First rough implementation
authorBertrand Delacretaz <bdelacretaz@apache.org>
Thu, 18 Oct 2018 16:00:35 +0000 (18:00 +0200)
committerBertrand Delacretaz <bdelacretaz@apache.org>
Thu, 18 Oct 2018 16:00:35 +0000 (18:00 +0200)
pom.xml
src/main/java/org/apache/sling/capabilities/jcr/SearchSource.java

diff --git a/pom.xml b/pom.xml
index fd83750..5d1061f 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>javax.jcr</groupId>
+      <artifactId>jcr</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.capabilities</artifactId>
       <version>0.0.1-SNAPSHOT</version>
index 1deec51..250ed5a 100644 (file)
@@ -20,20 +20,69 @@ package org.apache.sling.capabilities.jcr;
 
 import java.util.HashMap;
 import java.util.Map;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
 import org.apache.sling.capabilities.CapabilitiesSource;
+import org.apache.sling.jcr.api.SlingRepository;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /** CapabilitiesSource that provides information on the JCR Repository's search features */
 @Component(service = CapabilitiesSource.class)
 public class SearchSource implements CapabilitiesSource {
 
     public static final String NAMESPACE = "org.apache.sling.jcr.search";
+
+    public static final String SSA_PROP_NAME = "similarity.search.active";
+
+    public static final int SIMILARITY_SEARCH_CACHE_LIFETIME_SECONDS = 60;
+
+    private final Logger log = LoggerFactory.getLogger(getClass().getName());
+    private boolean similaritySearchActive;
+    private long similaritySearchCacheExpires;
+
+    @Reference
+    private SlingRepository repository;
     
     @Override
     public Map<String, Object> getCapabilities() throws Exception {
+        refreshCachedValues();
         final Map<String, Object> result = new HashMap<>();
+        result.put("similarity.search.active", String.valueOf(similaritySearchActive));
         return result;
     }
+
+    /** Find out whether the Oak similarity search is active, by
+     *  searching for any index definition that has useInSimilarity=true.
+     *  Cache the result to avoid making too many searches.
+     */
+    private void refreshCachedValues() throws RepositoryException {
+        if(System.currentTimeMillis() < similaritySearchCacheExpires) {
+            log.debug("Using cached similaritySearchActive value");
+            return;
+        }
+
+        similaritySearchCacheExpires = System.currentTimeMillis() + (SIMILARITY_SEARCH_CACHE_LIFETIME_SECONDS * 1000L);
+
+        synchronized(this) {
+            // TODO use a service user
+            final Session session = repository.loginAdministrative(null);
+            try {
+                    String query = "/jcr:root/oak:index//properties//* [@useInSimilarity = \"true\"]";
+                    final QueryManager qm = session.getWorkspace().getQueryManager();
+                    final QueryResult qr = qm.createQuery(query, Query.XPATH).execute();
+                    similaritySearchActive = qr.getNodes().hasNext();
+                    log.debug("Recomputed {}={} using query {}", SSA_PROP_NAME, similaritySearchActive, query);
+            } finally {
+                session.logout();
+            }
+        }
+    }
     
     @Override
     public String getNamespace() {