You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2013/02/21 09:51:32 UTC
svn commit: r1448550 [1/6] - in /jackrabbit/oak/trunk: ./ oak-parent/
oak-solr-core/ oak-solr-core/src/ oak-solr-core/src/main/
oak-solr-core/src/main/java/ oak-solr-core/src/main/java/org/
oak-solr-core/src/main/java/org/apache/ oak-solr-core/src/main...
Author: tommaso
Date: Thu Feb 21 08:51:30 2013
New Revision: 1448550
URL: http://svn.apache.org/r1448550
Log:
OAK-646 - oak solr index modules moved from git fork to trunk
Added:
jackrabbit/oak/trunk/oak-solr-core/
jackrabbit/oak/trunk/oak-solr-core/pom.xml (with props)
jackrabbit/oak/trunk/oak-solr-core/src/
jackrabbit/oak/trunk/oak-solr-core/src/main/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/resources/
jackrabbit/oak/trunk/oak-solr-core/src/test/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/solrconfig.xml (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/stopwords.txt (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/synonyms.txt (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/solr.xml (with props)
jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/zoo.cfg
jackrabbit/oak/trunk/oak-solr-embedded/
jackrabbit/oak/trunk/oak-solr-embedded/pom.xml (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/embedded/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/embedded/EmbeddedSolrConfiguration.java (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/embedded/EmbeddedSolrConfigurationProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/embedded/EmbeddedSolrServerProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/currency.xml (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/protwords.txt (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/schema.xml (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/solrconfig.xml (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/stopwords.txt (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/oak/conf/synonyms.txt (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/solr.xml (with props)
jackrabbit/oak/trunk/oak-solr-embedded/src/main/resources/solr/zoo.cfg
jackrabbit/oak/trunk/oak-solr-embedded/src/test/
jackrabbit/oak/trunk/oak-solr-embedded/src/test/java/
jackrabbit/oak/trunk/oak-solr-embedded/src/test/resources/
jackrabbit/oak/trunk/oak-solr-remote/
jackrabbit/oak/trunk/oak-solr-remote/pom.xml (with props)
jackrabbit/oak/trunk/oak-solr-remote/src/
jackrabbit/oak/trunk/oak-solr-remote/src/main/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/index/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/http/
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/http/RemoteSolrConfigurationProvider.java (with props)
jackrabbit/oak/trunk/oak-solr-remote/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/http/RemoteSolrServerProvider.java (with props)
Modified:
jackrabbit/oak/trunk/oak-parent/pom.xml
jackrabbit/oak/trunk/pom.xml
Modified: jackrabbit/oak/trunk/oak-parent/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-parent/pom.xml?rev=1448550&r1=1448549&r2=1448550&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-parent/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-parent/pom.xml Thu Feb 21 08:51:30 2013
@@ -45,6 +45,7 @@
<mongo.port>27017</mongo.port>
<mongo.db>MongoMKDB</mongo.db>
<mongo.db2>MongoMKDB2</mongo.db2>
+ <solr.version>4.0.0</solr.version>
</properties>
<issueManagement>
Added: jackrabbit/oak/trunk/oak-solr-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/pom.xml?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/pom.xml (added)
+++ jackrabbit/oak/trunk/oak-solr-core/pom.xml Thu Feb 21 08:51:30 2013
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-parent</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <relativePath>../oak-parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>oak-solr-core</artifactId>
+ <name>Oak Solr core</name>
+ <description>Oak support for Apache Solr indexing and search</description>
+ <packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.jackrabbit.oak.plugins.index.solr,
+ org.apache.solr.*
+ </Export-Package>
+ <Private-Package>
+ org.apache.jackrabbit.oak.plugins.index.solr.*
+ </Private-Package>
+ <Embed-Dependency>solr-solrj</Embed-Dependency>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>2.12</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*IT.java</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- Optional OSGi dependencies, used only when running within OSGi -->
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-solrj</artifactId>
+ <version>${solr.version}</version>
+ </dependency>
+
+ <!-- sorlj dependencies needed for OSGi deployments -->
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jmx</groupId>
+ <artifactId>jmxri</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jdmk</groupId>
+ <artifactId>jmxtools</artifactId>
+ </exclusion>
+ </exclusions>
+ <version>3.3.6</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>jline</groupId>
+ <artifactId>jline</artifactId>
+ <version>0.9.1</version>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.15</version>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.jdmk</groupId>
+ <artifactId>jmxtools</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jmx</groupId>
+ <artifactId>jmxri</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.1.3</version>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpmime</artifactId>
+ <version>4.1.3</version>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-core</artifactId>
+ <version>${solr.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-core</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <version>1.6.4</version>
+ <optional>true</optional>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.6.4</version>
+ <optional>true</optional>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Propchange: jackrabbit/oak/trunk/oak-solr-core/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr;
+
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+
+/**
+ * A Solr configuration holding all the possible customizable parameters that
+ * can be leveraged for an Oak search index.
+ */
+public interface OakSolrConfiguration {
+
+ /**
+ * Provide a field name to be used for indexing / searching a certain {@link Type}
+ *
+ * @param propertyType the {@link Type} to be indexed / searched
+ * @return a <code>String</code> representing the Solr field to be used for the given {@link Type}.
+ */
+ public String getFieldNameFor(Type<?> propertyType);
+
+ /**
+ * Provide the field name for indexing / searching paths
+ *
+ * @return a <code>String</code> representing the Solr field to be used for paths.
+ */
+ public String getPathField();
+
+ /**
+ * Provide a field name to search over for the given {@link Filter.PathRestriction}
+ *
+ * @param pathRestriction the {@link Filter.PathRestriction} used for filtering search results
+ * @return the field name as a <code>String</code> to be used by Solr for the given restriction
+ */
+ public String getFieldForPathRestriction(Filter.PathRestriction pathRestriction);
+
+
+ /**
+ * Provide a field name to search over for the given {@link Filter.PropertyRestriction}
+ *
+ * @param propertyRestriction the {@link Filter.PropertyRestriction} used for filtering search results
+ * @return the field name as a <code>String</code> to be used by Solr for the given restriction
+ */
+ public String getFieldForPropertyRestriction(Filter.PropertyRestriction propertyRestriction);
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr;
+
+/**
+ * A provider for {@link OakSolrConfiguration}s
+ */
+public interface OakSolrConfigurationProvider {
+
+ /**
+ * Provides a Solr configuration for Oak
+ *
+ * @return a {@link OakSolrConfiguration}
+ */
+ public OakSolrConfiguration getConfiguration();
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrConfigurationProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr;
+
+import java.io.IOException;
+import javax.annotation.Nonnull;
+
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+
+/**
+ * Utilities for Oak Solr integration.
+ */
+public class OakSolrUtils {
+
+ /**
+ * Check if a given Solr instance is alive
+ *
+ * @param solrServer the {@link SolrServer} used to communicate with the Solr instance
+ * @return <code>true</code> if the given Solr instance is alive and responding
+ * @throws IOException if any error occurs while trying to communicate with the Solr instance
+ * @throws SolrServerException
+ */
+ public static boolean checkServerAlive(@Nonnull SolrServer solrServer) throws IOException, SolrServerException {
+ return solrServer.ping().getStatus() == 0;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr;
+
+import org.apache.solr.client.solrj.SolrServer;
+
+/**
+ * Provider of {@link SolrServer}s instances
+ */
+public interface SolrServerProvider {
+
+ /**
+ * provides an already initialized {@link SolrServer} to be used from within Oak
+ *
+ * @return a {@link SolrServer} instance
+ * @throws Exception if anything goes wrong while providing the {@link SolrServer}
+ */
+ public SolrServer getSolrServer() throws Exception;
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrServerProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfigurationProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrServerProvider;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+
+/**
+ * Default implementation of {@link SolrHookFactory}
+ */
+@Component
+@Service(value = SolrHookFactory.class)
+public class DefaultSolrHookFactory implements SolrHookFactory {
+
+ @Reference
+ private SolrServerProvider solrServerProvider;
+
+ @Reference
+ private OakSolrConfigurationProvider oakSolrConfigurationProvider;
+
+ @Override
+ public IndexHook createIndexHook(String path, NodeBuilder builder) throws Exception {
+ return new SolrIndexDiff(builder, solrServerProvider.getSolrServer(), oakSolrConfigurationProvider.getConfiguration());
+ }
+
+ @Override
+ public CommitHook createCommitHook() throws Exception {
+ return new SolrCommitHook(solrServerProvider.getSolrServer());
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/DefaultSolrHookFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.IOException;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+
+/**
+ * A {@link CommitHook} which sends changes to Apache Solr
+ */
+public class SolrCommitHook implements CommitHook {
+
+ private final SolrServer solrServer;
+
+ public SolrCommitHook(SolrServer solrServer) {
+ this.solrServer = solrServer;
+ }
+
+ @Nonnull
+ @Override
+ public NodeState processCommit(NodeState before, NodeState after) throws CommitFailedException {
+ try {
+ SolrNodeStateDiff diff = new SolrNodeStateDiff(solrServer);
+ after.compareAgainstBaseState(before, diff);
+ diff.postProcess(after);
+ return after;
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Failed to update the Solr index", e);
+ }
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+
+/**
+ * Provider interface for {@link SolrCommitHook}s and {@link SolrIndexHook}s
+ */
+public interface SolrHookFactory {
+
+ /**
+ * create a {@link SolrIndexHook} to index data on a Solr server
+ *
+ * @param path the path the created {@link SolrIndexHook} should work on
+ * @param builder the {@link NodeBuilder} to get {@link org.apache.jackrabbit.oak.spi.state.NodeState}s
+ * @return the created {@link IndexHook}
+ * @throws Exception if any failres happen during the hook creation
+ */
+ public IndexHook createIndexHook(String path, NodeBuilder builder) throws Exception;
+
+ /**
+ * create a {@link SolrCommitHook} to index data on a Solr server
+ *
+ * @return the created {@link SolrCommitHook}
+ * @throws Exception if any failres happen during the hook creation
+ */
+ public CommitHook createCommitHook() throws Exception;
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrHookFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
+import org.apache.solr.client.solrj.SolrServer;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
+/**
+ * {@link IndexHook} implementation that is responsible for keeping the
+ * {@link org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex} up to date
+ * <p/>
+ * This handles index updates by keeping a {@link Map} of <code>String</code>
+ * and {@link SolrIndexUpdate} for each path.
+ *
+ * @see org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex
+ * @see SolrIndexHook
+ */
+public class SolrIndexDiff implements IndexHook {
+
+ private final SolrIndexDiff parent;
+
+ private final NodeBuilder node;
+
+ private final String name;
+
+ private String path;
+
+ private final Map<String, SolrIndexUpdate> updates;
+
+ private SolrServer solrServer;
+
+ private OakSolrConfiguration configuration;
+
+ private SolrIndexDiff(SolrIndexDiff parent, NodeBuilder node, SolrServer solrServer,
+ String name, String path, Map<String, SolrIndexUpdate> updates, OakSolrConfiguration configuration) {
+ this.parent = parent;
+ this.node = node;
+ this.name = name;
+ this.path = path;
+ this.updates = updates;
+ this.solrServer = solrServer;
+ this.configuration = configuration;
+
+ // TODO : test properly on PDFs
+
+ if (node != null && node.hasChildNode("oak:index")) {
+ NodeBuilder index = node.child("oak:index");
+ for (String indexName : index.getChildNodeNames()) {
+ NodeBuilder child = index.child(indexName);
+ if (isIndexNode(child) && !this.updates.containsKey(getPath())) {
+ this.updates.put(getPath(), new SolrIndexUpdate(
+ getPath(), child, configuration));
+ }
+ }
+ }
+ if (node != null && name != null && !NodeStateUtils.isHidden(name)) {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.insert(getPath(), node);
+ }
+ }
+ }
+
+ private SolrIndexDiff(SolrIndexDiff parent, SolrServer solrServer, String name) {
+ this(parent, getChildNode(parent.node, name), solrServer, name, null,
+ parent.updates, parent.configuration);
+ }
+
+ public SolrIndexDiff(NodeBuilder root, SolrServer solrServer, OakSolrConfiguration configuration) {
+ this(null, root, solrServer, null, "/", new HashMap<String, SolrIndexUpdate>(), configuration);
+ }
+
+ private static NodeBuilder getChildNode(NodeBuilder node, String name) {
+ if (node != null && node.hasChildNode(name)) {
+ return node.child(name);
+ } else {
+ return null;
+ }
+ }
+
+ public String getPath() {
+ if (path == null) {
+ path = concat(parent.getPath(), name);
+ }
+ return path;
+ }
+
+ private static boolean isIndexNode(NodeBuilder node) {
+ PropertyState ps = node.getProperty(JCR_PRIMARYTYPE);
+ boolean isNodeType = ps != null && !ps.isArray()
+ && ps.getValue(Type.STRING).equals("oak:queryIndexDefinition");
+ if (!isNodeType) {
+ return false;
+ }
+ PropertyState type = node.getProperty("type");
+ boolean isIndexType = type != null && !type.isArray()
+ && type.getValue(Type.STRING).equals(SolrQueryIndex.TYPE);
+ return isIndexType;
+ }
+
+ // -----------------------------------------------------< NodeStateDiff >--
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.insert(getPath(), node);
+ }
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.insert(getPath(), node);
+ }
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.insert(getPath(), node);
+ }
+ }
+
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ for (SolrIndexUpdate update : updates.values()) {
+ update.insert(concat(getPath(), name), new ReadOnlyBuilder(after));
+ }
+ after.compareAgainstBaseState(MemoryNodeState.EMPTY_NODE, child(name));
+ }
+
+ @Override
+ public void childNodeChanged(String name, NodeState before, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ after.compareAgainstBaseState(before, child(name));
+ }
+
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ for (SolrIndexUpdate update : updates.values()) {
+ update.remove(concat(getPath(), name));
+ }
+ }
+
+ // -----------------------------------------------------< IndexHook >--
+
+ @Override
+ public void apply() throws CommitFailedException {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.apply(solrServer);
+ }
+ }
+
+ @Override
+ public void reindex(NodeBuilder state) throws CommitFailedException {
+ boolean reindex = false;
+ for (SolrIndexUpdate update : updates.values()) {
+ if (update.getAndResetReindexFlag()) {
+ reindex = true;
+ }
+ }
+ if (reindex) {
+ state.getNodeState().compareAgainstBaseState(
+ MemoryNodeState.EMPTY_NODE,
+ new SolrIndexDiff(null, state, solrServer, null, "/", updates, configuration));
+ }
+ }
+
+ @Override
+ public IndexHook child(String name) {
+ return new SolrIndexDiff(this, solrServer, name);
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (SolrIndexUpdate update : updates.values()) {
+ update.close();
+ }
+ updates.clear();
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.SolrInputDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link IndexHook} implementation that is responsible for keeping the
+ * {@link org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex} up to date
+ * <p/>
+ * This handles the status of the index update inside a flat list of {@link SolrInputDocument}s
+ * for additions and a {@link StringBuilder} of ids for deletions of documents.
+ * <p/>
+ * Note also that at the moment this is not configurable but assumes Solr has been
+ * configured ot have some specific fields and analyzers..
+ *
+ * @see org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex
+ * @see SolrIndexDiff
+ */
+public class SolrIndexHook implements IndexHook {
+
+ private static final Logger log = LoggerFactory.getLogger(SolrNodeStateDiff.class);
+
+ private final Collection<SolrInputDocument> solrInputDocuments;
+
+ private final StringBuilder deleteByIdQueryBuilder;
+ private final String path;
+ private final String uniqueKey;
+
+ private IOException exception;
+ private final SolrServer solrServer;
+ private final NodeBuilder nodebuilder;
+
+ public SolrIndexHook(String path, NodeBuilder nodeBuilder, SolrServer solrServer) {
+ this.nodebuilder = nodeBuilder;
+ this.path = path;
+ this.solrServer = solrServer;
+ this.uniqueKey = "path_exact";
+ this.solrInputDocuments = new LinkedList<SolrInputDocument>();
+ this.deleteByIdQueryBuilder = initializeDeleteQueryBuilder();
+ }
+
+
+ private Collection<SolrInputDocument> docsFromState(String path, @Nonnull NodeState state) {
+ List<SolrInputDocument> solrInputDocuments = new LinkedList<SolrInputDocument>();
+ SolrInputDocument inputDocument = docFromState(path, state);
+ solrInputDocuments.add(inputDocument);
+ for (ChildNodeEntry childNodeEntry : state.getChildNodeEntries()) {
+ solrInputDocuments.addAll(docsFromState(new StringBuilder(path).append('/').
+ append(childNodeEntry.getName()).toString(), childNodeEntry.getNodeState()));
+ }
+
+ return solrInputDocuments;
+ }
+
+ private SolrInputDocument docFromState(String path, NodeState state) {
+ SolrInputDocument inputDocument = new SolrInputDocument();
+ // TODO : make id field configurable
+ inputDocument.addField(uniqueKey, path);
+ for (PropertyState propertyState : state.getProperties()) {
+ // TODO : enable selecting field from property type
+ if (propertyState.isArray()) {
+ for (String s : propertyState.getValue(Type.STRINGS)) {
+ inputDocument.addField(propertyState.getName(), s);
+ }
+ } else {
+ inputDocument.addField(propertyState.getName(), propertyState.getValue(Type.STRING));
+ }
+ }
+ return inputDocument;
+ }
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ solrInputDocuments.add(docFromState(getPath(), nodebuilder.getNodeState()));
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ solrInputDocuments.add(docFromState(getPath(), nodebuilder.getNodeState()));
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ solrInputDocuments.add(docFromState(getPath(), nodebuilder.getNodeState()));
+ }
+
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ addSubtree(name, after);
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ private void addSubtree(String name, NodeState nodeState) throws IOException {
+ solrInputDocuments.addAll(docsFromState(name, nodeState));
+ }
+
+ @Override
+ public void childNodeChanged(String name, NodeState before, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ SolrIndexHook diff = new SolrIndexHook(name, nodebuilder, solrServer);
+ after.compareAgainstBaseState(before, diff);
+ diff.apply();
+ } catch (CommitFailedException e) {
+ exception = new IOException(e);
+ }
+
+ }
+ }
+
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ deleteSubtree(name, before);
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ private void deleteSubtree(String name, NodeState before) throws IOException {
+ // TODO : handle cases where default operator is AND
+ for (SolrInputDocument doc : docsFromState(name, before)) {
+ deleteByIdQueryBuilder.append(doc.getFieldValue(uniqueKey)).append(" ");
+ }
+ }
+
+ private StringBuilder initializeDeleteQueryBuilder() {
+ return new StringBuilder(uniqueKey).append(":(");
+ }
+
+ @Override
+ public void apply() throws CommitFailedException {
+ try {
+ if (exception != null) {
+ throw exception;
+ }
+ boolean somethingToSend = false;
+ try {
+ // handle adds
+ if (solrInputDocuments.size() > 0) {
+ solrServer.add(solrInputDocuments);
+ somethingToSend = true;
+ }
+ // handle deletions
+ if (deleteByIdQueryBuilder.length() > 12) {
+ solrServer.deleteByQuery(deleteByIdQueryBuilder.append(")").toString());
+ if (!somethingToSend) {
+ somethingToSend = true;
+ }
+ }
+
+ } catch (SolrServerException e) {
+ throw new IOException(e);
+ }
+
+ if (somethingToSend) {
+ solrServer.commit(false, false, true); // default to softCommit
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(new StringBuilder("added ").append(solrInputDocuments.size()).append(" documents").toString());
+ }
+
+ } catch (Exception e) {
+ try {
+ if (solrServer != null) {
+ solrServer.rollback();
+ }
+ } catch (Exception e1) {
+ log.warn("An error occurred while rollback-ing too {}", e);
+ }
+ throw new CommitFailedException(e);
+ }
+ }
+
+ @Override
+ public void reindex(NodeBuilder state) throws CommitFailedException {
+ try {
+ close();
+ deleteByIdQueryBuilder.append(getPath()).append("*");
+ solrInputDocuments.addAll(docsFromState(getPath(), state.getNodeState()));
+ apply();
+ } catch (IOException e) {
+ throw new CommitFailedException(e);
+ }
+
+ }
+
+ @Override
+ public void close() throws IOException {
+ solrInputDocuments.clear();
+ deleteByIdQueryBuilder.delete(4, deleteByIdQueryBuilder.length());
+ }
+
+ @Override
+ public IndexHook child(String name) {
+ return new SolrIndexHook(name, nodebuilder, solrServer);
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.index.IndexHookProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Service that provides {@link SolrIndexHookProvider} based {@link IndexHook}s.
+ *
+ * @see org.apache.jackrabbit.oak.plugins.index.IndexHookProvider
+ */
+@Component
+@Service(IndexHookProvider.class)
+public class SolrIndexHookProvider implements IndexHookProvider {
+
+ @Reference
+ private SolrHookFactory hookFactory;
+
+ private final Logger log = LoggerFactory.getLogger(SolrIndexHookProvider.class);
+
+ @Override
+ @Nonnull
+ public List<? extends IndexHook> getIndexHooks(String type, NodeBuilder builder) {
+ if (SolrQueryIndex.TYPE.equals(type)) {
+ if (log.isInfoEnabled()) {
+ log.info("Creating a Solr index hook");
+ }
+ try {
+ IndexHook indexHook = hookFactory.createIndexHook("/", builder);
+ return ImmutableList.of(indexHook);
+ } catch (Exception e) {
+ log.error("unable to create Solr IndexHook ", e);
+ }
+ }
+ return ImmutableList.of();
+ }
+
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.SolrInputDocument;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * A Solr index update
+ */
+public class SolrIndexUpdate implements Closeable {
+
+ private final String path;
+
+ private final NodeBuilder index;
+ private OakSolrConfiguration configuration;
+
+ private final Map<String, NodeState> insert = new TreeMap<String, NodeState>();
+
+ private final Set<String> remove = new TreeSet<String>();
+
+ public SolrIndexUpdate(String path, NodeBuilder index, OakSolrConfiguration configuration) {
+ this.path = path;
+ this.index = index;
+ this.configuration = configuration;
+ }
+
+ public void insert(String path, NodeBuilder value) {
+ Preconditions.checkArgument(path.startsWith(this.path));
+ if (!insert.containsKey(path)) {
+ String key = path.substring(this.path.length());
+ if ("".equals(key)) {
+ key = "/";
+ }
+ if (value != null) {
+ insert.put(key, value.getNodeState());
+ }
+ }
+ }
+
+ public void remove(String path) {
+ Preconditions.checkArgument(path.startsWith(this.path));
+ remove.add(path.substring(this.path.length()));
+ }
+
+ boolean getAndResetReindexFlag() {
+ boolean reindex = index.getProperty("reindex") != null
+ && index.getProperty("reindex").getValue(
+ Type.BOOLEAN);
+ index.setProperty("reindex", false);
+ return reindex;
+ }
+
+ public void apply(SolrServer solrServer) throws CommitFailedException {
+ if (remove.isEmpty() && insert.isEmpty()) {
+ return;
+ }
+ try {
+ for (String p : remove) {
+ deleteSubtreeWriter(solrServer, p);
+ }
+ for (String p : insert.keySet()) {
+ NodeState ns = insert.get(p);
+ addSubtreeWriter(solrServer, p, ns);
+ }
+ solrServer.commit(false, false, true);
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Failed to update the full text search index", e);
+ } catch (SolrServerException e) {
+ throw new CommitFailedException(
+ "Failed to update the full text search index", e);
+ } finally {
+ remove.clear();
+ insert.clear();
+ }
+ }
+
+ private Collection<SolrInputDocument> docsFromState(String path, @Nonnull NodeState state) {
+ List<SolrInputDocument> solrInputDocuments = new LinkedList<SolrInputDocument>();
+ SolrInputDocument inputDocument = docFromState(path, state);
+ solrInputDocuments.add(inputDocument);
+ for (ChildNodeEntry childNodeEntry : state.getChildNodeEntries()) {
+ solrInputDocuments.addAll(docsFromState(new StringBuilder(path).append('/').
+ append(childNodeEntry.getName()).toString(), childNodeEntry.getNodeState()));
+ }
+
+ return solrInputDocuments;
+ }
+
+ private SolrInputDocument docFromState(String path, NodeState state) {
+ SolrInputDocument inputDocument = new SolrInputDocument();
+ inputDocument.addField(configuration.getPathField(), path);
+ for (PropertyState propertyState : state.getProperties()) {
+ // try to get the field to use for this property from configuration
+ String fieldName = configuration.getFieldNameFor(propertyState.getType());
+ if (fieldName != null) {
+ inputDocument.addField(fieldName, propertyState.getValue(propertyState.getType()));
+ } else {
+ // or fallback to adding propertyName:stringValue(s)
+ if (propertyState.isArray()) {
+ for (String s : propertyState.getValue(Type.STRINGS)) {
+ inputDocument.addField(propertyState.getName(), s);
+ }
+ } else {
+ inputDocument.addField(propertyState.getName(), propertyState.getValue(Type.STRING));
+ }
+ }
+ }
+ return inputDocument;
+ }
+
+ private void deleteSubtreeWriter(SolrServer solrServer, String path)
+ throws IOException, SolrServerException {
+ // TODO verify the removal of the entire sub-hierarchy
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ solrServer.deleteByQuery(new StringBuilder(configuration.getPathField())
+ .append(':').append(path).append("*").toString());
+ }
+
+ private void addSubtreeWriter(SolrServer solrServer, String path,
+ NodeState state) throws IOException, SolrServerException {
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ solrServer.add(docFromState(path, state));
+ }
+
+ @Override
+ public void close() throws IOException {
+ remove.clear();
+ insert.clear();
+ }
+
+ @Override
+ public String toString() {
+ return "SolrIndexUpdate [path=" + path + ", insert=" + insert
+ + ", remove=" + remove + "]";
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.SolrInputDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Solr based {@link IndexHook}
+ */
+class SolrNodeStateDiff implements NodeStateDiff {
+
+ private static final Logger log = LoggerFactory.getLogger(SolrNodeStateDiff.class);
+
+ private final Collection<SolrInputDocument> solrInputDocuments;
+
+ private final StringBuilder deleteByIdQueryBuilder;
+
+ private final SolrServer solrServer;
+
+ private IOException exception;
+
+ public SolrNodeStateDiff(SolrServer solrServer) {
+ this.solrServer = solrServer;
+ solrInputDocuments = new LinkedList<SolrInputDocument>();
+ deleteByIdQueryBuilder = initializeDeleteQueryBuilder();
+ }
+
+ public void postProcess(NodeState state) throws IOException {
+ if (exception != null) {
+ throw exception;
+ }
+ try {
+ // handle adds
+ if (solrInputDocuments.size() > 0) {
+ solrServer.add(solrInputDocuments);
+ }
+ // handle deletions
+ if (deleteByIdQueryBuilder.length() > 12) {
+ solrServer.deleteByQuery(deleteByIdQueryBuilder.append(")").toString());
+ }
+
+ // default to softCommit
+ solrServer.commit(false, false, true);
+
+ if (log.isDebugEnabled()) {
+ log.debug(new StringBuilder("added ").append(solrInputDocuments.size()).append(" documents").toString());
+ }
+
+ // free structures
+ solrInputDocuments.clear();
+ deleteByIdQueryBuilder.delete(4, deleteByIdQueryBuilder.length());
+ } catch (SolrServerException e) {
+ try {
+ if (solrServer != null) {
+ solrServer.rollback();
+ }
+ } catch (SolrServerException e1) {
+ // do nothing
+ }
+ throw new IOException(e);
+ }
+ }
+
+ private Collection<SolrInputDocument> docsFromState(String path, @Nonnull NodeState state) {
+ List<SolrInputDocument> solrInputDocuments = new LinkedList<SolrInputDocument>();
+ SolrInputDocument inputDocument = new SolrInputDocument();
+ // TODO : make id field configurable
+ inputDocument.addField("path_exact", path);
+ for (PropertyState propertyState : state.getProperties()) {
+ // TODO : enable selecting field from property type
+ if (propertyState.isArray()) {
+ for (String s : propertyState.getValue(Type.STRINGS)) {
+ inputDocument.addField(propertyState.getName(), s);
+ }
+ } else {
+ inputDocument.addField(propertyState.getName(), propertyState.getValue(Type.STRING));
+ }
+ }
+ solrInputDocuments.add(inputDocument);
+ for (ChildNodeEntry childNodeEntry : state.getChildNodeEntries()) {
+ solrInputDocuments.addAll(docsFromState(new StringBuilder(path).append('/').
+ append(childNodeEntry.getName()).toString(), childNodeEntry.getNodeState()));
+ }
+
+ return solrInputDocuments;
+ }
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ // TODO implement this
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ // TODO implement this
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ // TODO implement this
+ }
+
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ addSubtree(name, after);
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ private void addSubtree(String name, NodeState after) throws IOException {
+ solrInputDocuments.addAll(docsFromState(name, after));
+ }
+
+ @Override
+ public void childNodeChanged(String name, NodeState before, NodeState after) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ SolrNodeStateDiff diff = new SolrNodeStateDiff(solrServer);
+ after.compareAgainstBaseState(before, diff);
+ diff.postProcess(after);
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ if (NodeStateUtils.isHidden(name)) {
+ return;
+ }
+ if (exception == null) {
+ try {
+ deleteSubtree(name, before);
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ private void deleteSubtree(String name, NodeState before) throws IOException {
+ // TODO : handle cases where default operator is AND
+ for (SolrInputDocument doc : docsFromState(name, before)) {
+ deleteByIdQueryBuilder.append(doc.getFieldValue("path_exact")).append(" ");
+ }
+ }
+
+ private StringBuilder initializeDeleteQueryBuilder() {
+ return new StringBuilder("path_exact:(");
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.index;
+
+import java.io.IOException;
+
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+
+/**
+ * a Solr based {@link Observer}
+ */
+public class SolrObserver implements Observer {
+
+ private final SolrServer solrServer;
+
+ public SolrObserver(SolrServer solrServer) {
+ this.solrServer = solrServer;
+ }
+
+ @Override
+ public void contentChanged(NodeState before, NodeState after) {
+ SolrNodeStateDiff diff = new SolrNodeStateDiff(solrServer);
+ after.compareAgainstBaseState(before, diff);
+ try {
+ diff.postProcess(after);
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.solr.query;
+
+
+import java.util.Collection;
+
+import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.IndexRow;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Solr based {@link QueryIndex}
+ */
+public class SolrQueryIndex implements QueryIndex {
+
+ private static final Logger log = LoggerFactory.getLogger(SolrQueryIndex.class);
+ public static final String TYPE = "solr";
+
+ private final IndexDefinition index;
+ private final SolrServer solrServer;
+ private final OakSolrConfiguration configuration;
+
+ public SolrQueryIndex(IndexDefinition indexDefinition, SolrServer solrServer, OakSolrConfiguration configuration) {
+ this.index = indexDefinition;
+ this.solrServer = solrServer;
+ this.configuration = configuration;
+ }
+
+ @Override
+ public String getIndexName() {
+ return index.getName();
+ }
+
+ @Override
+ public double getCost(Filter filter, NodeState root) {
+ // TODO : estimate no of returned values and 0 is not good for no restrictions
+ return (filter.getPropertyRestrictions() != null ? filter.getPropertyRestrictions().size() * 0.1 : 0)
+ + (filter.getFulltextConditions() != null ? filter.getFulltextConditions().size() * 0.01 : 0)
+ + (filter.getPathRestriction() != null ? 0.2 : 0);
+ }
+
+ @Override
+ public String getPlan(Filter filter, NodeState nodeState) {
+ return getQuery(filter).toString();
+ }
+
+ private SolrQuery getQuery(Filter filter) {
+
+ SolrQuery solrQuery = new SolrQuery();
+ solrQuery.setParam("q.op", "AND");
+ solrQuery.setParam("df", "catch_all");
+ // TODO : can we handle this better?
+ solrQuery.setParam("rows", String.valueOf(Integer.MAX_VALUE));
+
+ StringBuilder queryBuilder = new StringBuilder();
+
+ // TODO : handle node type restriction
+
+ Filter.PathRestriction pathRestriction = filter.getPathRestriction();
+ if (pathRestriction != null) {
+ String path = purgePath(filter);
+ String fieldName = configuration.getFieldForPathRestriction(pathRestriction);
+ if (fieldName != null) {
+ queryBuilder.append(fieldName);
+ queryBuilder.append(':');
+ // TODO : remove this hack for all descendants of root node
+ if (path.equals("\\/") && pathRestriction.equals(Filter.PathRestriction.ALL_CHILDREN)) {
+ queryBuilder.append("*");
+ } else {
+// queryBuilder.append("\"");
+ queryBuilder.append(path);
+// queryBuilder.append("\"");
+ }
+ queryBuilder.append(" ");
+ }
+ }
+ Collection<Filter.PropertyRestriction> propertyRestrictions = filter.getPropertyRestrictions();
+ if (propertyRestrictions != null && !propertyRestrictions.isEmpty()) {
+ for (Filter.PropertyRestriction pr : propertyRestrictions) {
+
+ String first = null;
+ if (pr.first != null) {
+ first = partialEscape(String.valueOf(pr.first.getValue(pr.first.getType()))).toString();
+ }
+ String last = null;
+ if (pr.last != null) {
+ last = partialEscape(String.valueOf(pr.last.getValue(pr.last.getType()))).toString();
+ }
+
+ String prField = configuration.getFieldForPropertyRestriction(pr);
+ CharSequence fieldName = partialEscape(prField != null ?
+ prField : pr.propertyName);
+ if ("jcr\\:path".equals(fieldName.toString())) {
+ queryBuilder.append(configuration.getPathField());
+ queryBuilder.append(':');
+ queryBuilder.append(first);
+ } else {
+ queryBuilder.append(fieldName).append(':');
+ if (pr.first != null && pr.last != null && pr.first.equals(pr.last)) {
+ queryBuilder.append(first);
+ } else if (pr.first == null && pr.last == null) {
+ queryBuilder.append('*');
+ } else if ((pr.first != null && pr.last == null) || (pr.last != null && pr.first == null) || (!pr.first.equals(pr.last))) {
+ // TODO : need to check if this works for all field types (most likely not!)
+ queryBuilder.append(createRangeQuery(first, last, pr.firstIncluding, pr.lastIncluding));
+ } else if (pr.isLike) {
+ // TODO : the current parameter substitution is not expected to work well
+ queryBuilder.append(partialEscape(String.valueOf(pr.first.getValue(pr.first.getType())).replace('%', '*').replace('_', '?')));
+ } else {
+ throw new RuntimeException("[unexpected!] not handled case");
+ }
+ }
+ queryBuilder.append(" ");
+ }
+ }
+
+ Collection<String> fulltextConditions = filter.getFulltextConditions();
+ for (String fulltextCondition : fulltextConditions) {
+ queryBuilder.append(fulltextCondition).append(" ");
+ }
+
+ String escapedQuery = queryBuilder.toString();
+ solrQuery.setQuery(escapedQuery);
+
+ if (log.isInfoEnabled()) {
+ log.info(new StringBuilder("JCR query: \n" + filter.getQueryStatement() + " \nhas been converted to Solr query: \n").
+ append(solrQuery.toString()).toString());
+ }
+
+ return solrQuery;
+ }
+
+ private String createRangeQuery(String first, String last, boolean firstIncluding, boolean lastIncluding) {
+ // TODO : handle inclusion / exclusion of bounds
+ StringBuilder rangeQueryBuilder = new StringBuilder("[");
+ rangeQueryBuilder.append(first != null ? first : "*");
+ rangeQueryBuilder.append(" TO ");
+ rangeQueryBuilder.append(last != null ? last : "*");
+ rangeQueryBuilder.append("]");
+ return rangeQueryBuilder.toString();
+ }
+
+ private String purgePath(Filter filter) {
+ return partialEscape(filter.getPath()).toString();
+ }
+
+
+ // partially borrowed from SolrPluginUtils#partialEscape
+ private CharSequence partialEscape(CharSequence s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' || c == '!' || c == '(' || c == ')' ||
+ c == ':' || c == '^' || c == '[' || c == ']' || c == '/' ||
+ c == '{' || c == '}' || c == '~' || c == '*' || c == '?' ||
+ c == '-'
+ ) {
+ sb.append('\\');
+ }
+ sb.append(c);
+ }
+ return sb;
+ }
+
+ @Override
+ public Cursor query(Filter filter, NodeState root) {
+ Cursor cursor;
+ try {
+ SolrQuery query = getQuery(filter);
+ QueryResponse queryResponse = solrServer.query(query);
+ cursor = new SolrCursor(queryResponse);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return cursor;
+ }
+
+
+ private class SolrCursor implements Cursor {
+
+ private final SolrDocumentList results;
+
+ private int i;
+
+ public SolrCursor(QueryResponse queryResponse) {
+ this.results = queryResponse.getResults();
+ i = 0;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return results != null && i < results.size();
+ }
+
+ @Override
+ public void remove() {
+ results.remove(i);
+ }
+
+ public IndexRow next() {
+ if (i < results.size()) {
+ final SolrDocument doc = results.get(i);
+ i++;
+ return new IndexRow() {
+ @Override
+ public String getPath() {
+ return String.valueOf(doc.getFieldValue(configuration.getPathField()));
+ }
+
+ @Override
+ public PropertyValue getValue(String columnName) {
+ String s = doc.getFieldValue(columnName).toString();
+ return PropertyValues.newString(s);
+ }
+
+ };
+ } else {
+ return null;
+ }
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
------------------------------------------------------------------------------
svn:eol-style = native