Author: rhauch
Date: 2009-11-16 18:24:06 -0500 (Mon, 16 Nov 2009)
New Revision: 1319
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/AbstractAccessComponent.java
trunk/dna-search/src/main/java/org/jboss/dna/search/DualIndexStrategy.java
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexRules.java
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexStrategy.java
trunk/dna-search/src/main/java/org/jboss/dna/search/KitchenSinkIndexStrategy.java
trunk/dna-search/src/main/java/org/jboss/dna/search/SearchContext.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ValueCache.java
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingRules.java
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingStrategy.java
trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryComponent.java
trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java
trunk/dna-search/src/main/java/org/jboss/dna/search/StoreLittleIndexingStrategy.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryContext.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/Queryable.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/AddAccessNodesTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ChooseJoinAlgorithmTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/PushSelectCriteriaTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RightOuterToLeftOuterJoinsTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/DistinctComponentTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortLocationsComponentTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexContext.java
trunk/dna-search/src/main/java/org/jboss/dna/search/SearchEngine.java
trunk/dna-search/src/main/java/org/jboss/dna/search/WorkspaceSearchEngine.java
trunk/dna-search/src/test/java/org/jboss/dna/search/IndexingRulesTest.java
trunk/dna-search/src/test/java/org/jboss/dna/search/SearchEngineTest.java
trunk/dna-search/src/test/java/org/jboss/dna/search/WorkspaceSearchEngineTest.java
Log:
DNA-467 Additional refactoring to move toward a working search engine.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryContext.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryContext.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryContext.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import net.jcip.annotations.Immutable;
import org.jboss.dna.common.collection.Problems;
import org.jboss.dna.common.collection.SimpleProblems;
import org.jboss.dna.common.util.CheckArg;
@@ -35,64 +36,120 @@
import org.jboss.dna.graph.query.validate.Schemata;
/**
- *
+ * An immutable context in which queries are to be executed. Each query context defines
the information that is available during
+ * query execution.
*/
-public final class QueryContext {
+@Immutable
+public class QueryContext {
private final ExecutionContext context;
private final PlanHints hints;
private final Schemata schemata;
private final Problems problems;
private final Map<String, Object> variables;
+ /**
+ * Create a new context for query execution.
+ *
+ * @param context the execution context
+ * @param schemata the schemata
+ * @param hints the hints, or null if there are no hints
+ * @param problems the problems container, or null if a new problems container should
be created
+ * @param variables the mapping of variables and values, or null if there are no such
variables
+ * @throws IllegalArgumentException if the context or schmata are null
+ */
public QueryContext( ExecutionContext context,
+ Schemata schemata,
PlanHints hints,
- Schemata schemata,
Problems problems,
Map<String, Object> variables ) {
CheckArg.isNotNull(context, "context");
+ CheckArg.isNotNull(schemata, "schemata");
this.context = context;
this.hints = hints != null ? hints : new PlanHints();
this.schemata = schemata;
this.problems = problems != null ? problems : new SimpleProblems();
this.variables = variables != null ? Collections.<String,
Object>unmodifiableMap(new HashMap<String, Object>(variables)) :
Collections.<String, Object>emptyMap();
+ assert this.context != null;
+ assert this.hints != null;
+ assert this.schemata != null;
+ assert this.problems != null;
+ assert this.variables != null;
}
+ /**
+ * Create a new context for query execution.
+ *
+ * @param context the execution context
+ * @param schemata the schemata
+ * @param hints the hints, or null if there are no hints
+ * @param problems the problems container, or null if a new problems container should
be created
+ * @throws IllegalArgumentException if the context or schmata are null
+ */
public QueryContext( ExecutionContext context,
+ Schemata schemata,
PlanHints hints,
- Schemata schemata,
Problems problems ) {
- this(context, hints, schemata, problems, null);
+ this(context, schemata, hints, problems, null);
}
+ /**
+ * Create a new context for query execution.
+ *
+ * @param context the execution context
+ * @param schemata the schemata
+ * @param hints the hints, or null if there are no hints
+ * @throws IllegalArgumentException if the context or schmata are null
+ */
public QueryContext( ExecutionContext context,
- PlanHints hints,
+ Schemata schemata,
+ PlanHints hints ) {
+ this(context, schemata, hints, null, null);
+ }
+
+ /**
+ * Create a new context for query execution.
+ *
+ * @param context the execution context
+ * @param schemata the schemata
+ * @throws IllegalArgumentException if the context or schmata are null
+ */
+ public QueryContext( ExecutionContext context,
Schemata schemata ) {
- this(context, hints, schemata, null, null);
+ this(context, schemata, null, null, null);
}
/**
- * @return context
+ * Get the execution context available to this query context.
+ *
+ * @return the execution context; never null
*/
public final ExecutionContext getExecutionContext() {
return context;
}
/**
- * @return hints
+ * Get the plan hints.
+ *
+ * @return the plan hints; never null
*/
public final PlanHints getHints() {
return hints;
}
/**
- * @return problems
+ * Get the problem container used by this query context. Any problems that have been
encountered will be accumlated in this
+ * container.
+ *
+ * @return the problem container; never null
*/
public final Problems getProblems() {
return problems;
}
/**
- * @return schemata
+ * Get the definition of the tables available within this query context.
+ *
+ * @return the schemata; never null
*/
public Schemata getSchemata() {
return schemata;
@@ -101,10 +158,66 @@
/**
* Get the variables that are to be substituted into the {@link BindVariableName}
used in the query.
*
- * @return immutable map of variable values keyed by their name; never null
+ * @return immutable map of variable values keyed by their name; never null but
possibly empty
*/
public Map<String, Object> getVariables() {
return variables;
}
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied execution
context.
+ *
+ * @param context the execution context that should be used in the new query context
+ * @return the new context; never null
+ * @throws IllegalArgumentException if the execution context reference is null
+ */
+ public QueryContext with( ExecutionContext context ) {
+ CheckArg.isNotNull(context, "context");
+ return new QueryContext(context, schemata, hints, problems, variables);
+ }
+
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied schemata.
+ *
+ * @param schemata the schemata that should be used in the new context
+ * @return the new context; never null
+ * @throws IllegalArgumentException if the schemata reference is null
+ */
+ public QueryContext with( Schemata schemata ) {
+ CheckArg.isNotNull(schemata, "schemata");
+ return new QueryContext(context, schemata, hints, problems, variables);
+ }
+
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied hints.
+ *
+ * @param hints the hints that should be used in the new context
+ * @return the new context; never null
+ * @throws IllegalArgumentException if the hints reference is null
+ */
+ public QueryContext with( PlanHints hints ) {
+ CheckArg.isNotNull(hints, "hints");
+ return new QueryContext(context, schemata, hints, problems, variables);
+ }
+
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied problem
container.
+ *
+ * @param problems the problems that should be used in the new context; may be null
if a new problem container should be used
+ * @return the new context; never null
+ */
+ public QueryContext with( Problems problems ) {
+ return new QueryContext(context, schemata, hints, problems, variables);
+ }
+
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied variables.
+ *
+ * @param variables the variables that should be used in the new context; may be null
if there are no such variables
+ * @return the new context; never null
+ */
+ public QueryContext with( Map<String, Object> variables ) {
+ return new QueryContext(context, schemata, hints, problems, variables);
+ }
+
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -27,18 +27,15 @@
import java.util.concurrent.atomic.AtomicBoolean;
import net.jcip.annotations.ThreadSafe;
import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.QueryResults.Statistics;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Constraint;
import org.jboss.dna.graph.query.model.FullTextSearch;
import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.model.SelectorName;
import org.jboss.dna.graph.query.model.Visitors;
import org.jboss.dna.graph.query.optimize.Optimizer;
import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.Planner;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
@@ -54,17 +51,6 @@
@ThreadSafe
public class QueryEngine implements Queryable {
- /**
- * A {@link Schemata} implementation that always returns null, meaning the table does
not exist.
- */
- private static final Schemata DEFAULT_SCHEMATA = new Schemata() {
- public Table getTable( SelectorName name ) {
- // This won't allow the query engine to do anything (or much of
anything),
- // but it is legal and will result in meaningful problems
- return null;
- }
- };
-
private final Planner planner;
private final Optimizer optimizer;
private final Processor processor;
@@ -92,42 +78,25 @@
/**
* {@inheritDoc}
*
- * @see
org.jboss.dna.graph.query.Queryable#execute(org.jboss.dna.graph.ExecutionContext,
- * org.jboss.dna.graph.query.model.QueryCommand,
org.jboss.dna.graph.query.validate.Schemata)
+ * @see
org.jboss.dna.graph.query.Queryable#execute(org.jboss.dna.graph.query.QueryContext,
+ * org.jboss.dna.graph.query.model.QueryCommand)
*/
- public QueryResults execute( ExecutionContext context,
- QueryCommand query,
- Schemata schemata ) {
- return execute(context, query, schemata, new PlanHints());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.query.Queryable#execute(org.jboss.dna.graph.ExecutionContext,
- * org.jboss.dna.graph.query.model.QueryCommand,
org.jboss.dna.graph.query.validate.Schemata,
- * org.jboss.dna.graph.query.plan.PlanHints)
- */
- public QueryResults execute( ExecutionContext context,
- QueryCommand query,
- Schemata schemata,
- PlanHints hints ) {
+ public QueryResults execute( QueryContext context,
+ QueryCommand query ) {
CheckArg.isNotNull(context, "context");
CheckArg.isNotNull(query, "query");
- if (schemata == null) schemata = DEFAULT_SCHEMATA;
- QueryContext queryContext = new QueryContext(context, hints, schemata);
// Create the canonical plan ...
long start = System.nanoTime();
- PlanNode plan = planner.createPlan(queryContext, query);
+ PlanNode plan = planner.createPlan(context, query);
long duration = System.nanoTime() - start;
Statistics stats = new Statistics(duration);
QueryResultColumns resultColumns = QueryResultColumns.empty();
- if (!queryContext.getProblems().hasErrors()) {
+ if (!context.getProblems().hasErrors()) {
// Optimize the plan ...
start = System.nanoTime();
- PlanNode optimizedPlan = optimizer.optimize(queryContext, plan);
+ PlanNode optimizedPlan = optimizer.optimize(context, plan);
duration = System.nanoTime() - start;
stats = stats.withOptimizationTime(duration);
@@ -137,11 +106,11 @@
duration = System.nanoTime() - start;
stats = stats.withOptimizationTime(duration);
- if (!queryContext.getProblems().hasErrors()) {
+ if (!context.getProblems().hasErrors()) {
// Execute the plan ...
try {
start = System.nanoTime();
- return processor.execute(queryContext, query, stats, optimizedPlan);
+ return processor.execute(context, query, stats, optimizedPlan);
} finally {
duration = System.nanoTime() - start;
stats = stats.withOptimizationTime(duration);
@@ -149,7 +118,7 @@
}
}
// There were problems somewhere ...
- return new org.jboss.dna.graph.query.process.QueryResults(queryContext, query,
resultColumns, stats);
+ return new org.jboss.dna.graph.query.process.QueryResults(context, query,
resultColumns, stats);
}
protected QueryResultColumns determineQueryResultColumns( PlanNode optimizedPlan ) {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/Queryable.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/Queryable.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/Queryable.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -23,10 +23,7 @@
*/
package org.jboss.dna.graph.query;
-import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.validate.Schemata;
/**
* An interface defining the ability to submit a query and obtain results.
@@ -38,26 +35,9 @@
*
* @param context the context in which the query should be executed
* @param query the query that is to be executed
- * @param schemata the schemata that should be used to validate the query
* @return the query results; never null
* @throws IllegalArgumentException if the context or query references are null
*/
- QueryResults execute( ExecutionContext context,
- QueryCommand query,
- Schemata schemata );
-
- /**
- * Execute the supplied query by planning, optimizing, and then processing it.
- *
- * @param context the context in which the query should be executed
- * @param query the query that is to be executed
- * @param schemata the schemata that should be used to validate the query
- * @param hints the hints for the execution; may be null if there are no hints
- * @return the query results; never null
- * @throws IllegalArgumentException if the context or query references are null
- */
- QueryResults execute( ExecutionContext context,
- QueryCommand query,
- Schemata schemata,
- PlanHints hints );
+ QueryResults execute( QueryContext context,
+ QueryCommand query );
}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/AbstractAccessComponent.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/AbstractAccessComponent.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/AbstractAccessComponent.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,120 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.process;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.QueryResults.Columns;
+import org.jboss.dna.graph.query.model.AllNodes;
+import org.jboss.dna.graph.query.model.And;
+import org.jboss.dna.graph.query.model.Column;
+import org.jboss.dna.graph.query.model.Constraint;
+import org.jboss.dna.graph.query.model.Limit;
+import org.jboss.dna.graph.query.model.SelectorName;
+import org.jboss.dna.graph.query.plan.PlanNode;
+import org.jboss.dna.graph.query.plan.PlanNode.Property;
+import org.jboss.dna.graph.query.plan.PlanNode.Type;
+import org.jboss.dna.graph.query.validate.Schemata;
+
+/**
+ * A reusable base class for {@link ProcessingComponent} implementations that does
everything except obtain the correct
+ * {@link Location} objects for the query results.
+ */
+public abstract class AbstractAccessComponent extends ProcessingComponent {
+
+ protected final PlanNode accessNode;
+ protected final SelectorName sourceName;
+ protected final List<Column> projectedColumns;
+ protected final Constraint constraint;
+ protected final Limit limit;
+
+ protected AbstractAccessComponent( QueryContext context,
+ Columns columns,
+ PlanNode accessNode ) {
+ super(context, columns);
+ this.accessNode = accessNode;
+
+ // Find the table name; should be
+ PlanNode source = accessNode.findAtOrBelow(Type.SOURCE);
+ if (source != null) {
+ this.sourceName = source.getProperty(Property.SOURCE_NAME,
SelectorName.class);
+ if (!AllNodes.ALL_NODES_NAME.equals(this.sourceName)) {
+ throw new IllegalArgumentException();
+ }
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ // Find the project ...
+ PlanNode project = accessNode.findAtOrBelow(Type.PROJECT);
+ if (project != null) {
+ List<Column> projectedColumns =
project.getPropertyAsList(Property.PROJECT_COLUMNS, Column.class);
+ if (projectedColumns != null) {
+ this.projectedColumns = projectedColumns;
+ } else {
+ // Get the columns from the source columns ...
+ List<Schemata.Column> schemataColumns =
source.getPropertyAsList(Property.SOURCE_COLUMNS, Schemata.Column.class);
+ this.projectedColumns = new
ArrayList<Column>(schemataColumns.size());
+ NameFactory nameFactory =
context.getExecutionContext().getValueFactories().getNameFactory();
+ for (Schemata.Column schemataColumn : schemataColumns) {
+ String columnName = schemataColumn.getName();
+ // PropertyType type = schemataColumn.getPropertyType();
+ Name propertyName = nameFactory.create(columnName);
+ Column column = new Column(sourceName, propertyName, columnName);
+ this.projectedColumns.add(column);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ // Add the criteria ...
+ Constraint constraint = null;
+ for (PlanNode select : accessNode.findAllAtOrBelow(Type.SELECT)) {
+ Constraint selectConstraint = select.getProperty(Property.SELECT_CRITERIA,
Constraint.class);
+ if (constraint != null) {
+ constraint = new And(constraint, selectConstraint);
+ } else {
+ constraint = selectConstraint;
+ }
+ }
+ this.constraint = constraint;
+
+ // Find the limit ...
+ Limit limit = Limit.NONE;
+ PlanNode limitNode = accessNode.findAtOrBelow(Type.LIMIT);
+ if (limitNode != null) {
+ Integer count = limitNode.getProperty(Property.LIMIT_COUNT, Integer.class);
+ if (count != null) limit = limit.withRowLimit(count.intValue());
+ Integer offset = limitNode.getProperty(Property.LIMIT_OFFSET,
Integer.class);
+ if (offset != null) limit = limit.withOffset(offset.intValue());
+ }
+ this.limit = limit;
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/AbstractAccessComponent.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ValueCache.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ValueCache.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ValueCache.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,44 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.graph.query.process;
-
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.query.QueryResults;
-
-/**
- * Interface representing a cache of property values used in a {@link QueryResults}.
- */
-public interface ValueCache {
-
- /**
- * Get the value of the named property on the node at the supplied location.
- *
- * @param location the location of the node; may not be null
- * @param name the property name
- * @return the value of the property, or null if there is no such value
- */
- Object getProperty( Location location,
- Name name );
-}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -45,7 +45,6 @@
import org.jboss.dna.graph.query.parse.InvalidQueryException;
import org.jboss.dna.graph.query.parse.SqlQueryParser;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
@@ -394,7 +393,7 @@
for (SelectorName name : viewNames) {
QueryCommand command = definitions.get(name);
// Create the canonical plan for the definition ...
- QueryContext queryContext = new QueryContext(context, new
PlanHints(), schemata);
+ QueryContext queryContext = new QueryContext(context, schemata);
CanonicalPlanner planner = new CanonicalPlanner();
PlanNode plan = planner.createPlan(queryContext, command);
if (queryContext.getProblems().hasErrors()) continue;
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/AddAccessNodesTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/AddAccessNodesTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/AddAccessNodesTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -31,9 +31,6 @@
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.AbstractQueryTest;
import org.jboss.dna.graph.query.QueryContext;
-import org.jboss.dna.graph.query.optimize.AddAccessNodes;
-import org.jboss.dna.graph.query.optimize.OptimizerRule;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
import org.jboss.dna.graph.query.validate.Schemata;
@@ -50,7 +47,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
rule = AddAccessNodes.INSTANCE;
}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ChooseJoinAlgorithmTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ChooseJoinAlgorithmTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ChooseJoinAlgorithmTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -35,10 +35,7 @@
import org.jboss.dna.graph.query.model.DescendantNodeJoinCondition;
import org.jboss.dna.graph.query.model.JoinCondition;
import org.jboss.dna.graph.query.model.JoinType;
-import org.jboss.dna.graph.query.optimize.ChooseJoinAlgorithm;
-import org.jboss.dna.graph.query.optimize.OptimizerRule;
import org.jboss.dna.graph.query.plan.JoinAlgorithm;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
@@ -57,7 +54,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
bestRule = ChooseJoinAlgorithm.USE_BEST_JOIN_ALGORITHM;
nestedRule = ChooseJoinAlgorithm.USE_ONLY_NESTED_JOIN_ALGORITHM;
}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/PushSelectCriteriaTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/PushSelectCriteriaTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/PushSelectCriteriaTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -32,9 +32,6 @@
import org.jboss.dna.graph.query.AbstractQueryTest;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.model.JoinType;
-import org.jboss.dna.graph.query.optimize.OptimizerRule;
-import org.jboss.dna.graph.query.optimize.PushSelectCriteria;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
@@ -52,7 +49,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
rule = PushSelectCriteria.INSTANCE;
}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -38,7 +38,6 @@
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.PropertyValue;
import org.jboss.dna.graph.query.model.SelectorName;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
@@ -67,7 +66,7 @@
builder.addView("v1", "SELECT c11, c12 FROM t1 WHERE c13 <
CAST('3' AS LONG)");
builder.addView("v2", "SELECT t1.c11, t1.c12, t2.c23 FROM t1 JOIN
t2 ON t1.c11 = t2.c21");
schemata = builder.build();
- context = new QueryContext(execContext, new PlanHints(), schemata);
+ context = new QueryContext(execContext, schemata);
}
/**
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RightOuterToLeftOuterJoinsTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RightOuterToLeftOuterJoinsTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RightOuterToLeftOuterJoinsTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -32,9 +32,6 @@
import org.jboss.dna.graph.query.AbstractQueryTest;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.model.JoinType;
-import org.jboss.dna.graph.query.optimize.OptimizerRule;
-import org.jboss.dna.graph.query.optimize.RightOuterToLeftOuterJoins;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
@@ -52,7 +49,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
rule = RightOuterToLeftOuterJoins.INSTANCE;
}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -86,7 +86,7 @@
builder.addView("type2",
"SELECT all.a3, all.a4 FROM all WHERE all.primaryType IN
('t2','t0') AND all.mixins IN ('t4','t5')");
Schemata schemata = builder.build();
- context = new QueryContext(execContext, new PlanHints(), schemata);
+ context = new QueryContext(execContext, schemata);
node = new PlanNode(Type.ACCESS);
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -112,7 +112,7 @@
public void shouldProducePlanForSelectStarFromTable() {
schemata = schemataBuilder.addTable("__ALLNODES__",
"column1", "column2", "column3").build();
query = builder.selectStar().fromAllNodes().query();
- queryContext = new QueryContext(context, hints, schemata, problems);
+ queryContext = new QueryContext(context, schemata, hints, problems);
plan = planner.createPlan(queryContext, query);
assertThat(problems.isEmpty(), is(true));
assertProjectNode(plan, "column1", "column2",
"column3");
@@ -128,7 +128,7 @@
public void shouldProduceErrorWhenSelectingNonExistantTable() {
schemata = schemataBuilder.addTable("someTable", "column1",
"column2", "column3").build();
query = builder.selectStar().fromAllNodes().query();
- queryContext = new QueryContext(context, hints, schemata, problems);
+ queryContext = new QueryContext(context, schemata, hints, problems);
plan = planner.createPlan(queryContext, query);
assertThat(problems.hasErrors(), is(true));
}
@@ -137,7 +137,7 @@
public void shouldProduceErrorWhenSelectingNonExistantColumnOnExistingTable() {
schemata = schemataBuilder.addTable("someTable", "column1",
"column2", "column3").build();
query = builder.select("column1",
"column4").from("someTable").query();
- queryContext = new QueryContext(context, hints, schemata, problems);
+ queryContext = new QueryContext(context, schemata, hints, problems);
plan = planner.createPlan(queryContext, query);
assertThat(problems.hasErrors(), is(true));
}
@@ -146,7 +146,7 @@
public void shouldProducePlanWhenSelectingAllColumnsOnExistingTable() {
schemata = schemataBuilder.addTable("someTable", "column1",
"column2", "column3").build();
query = builder.selectStar().from("someTable").query();
- queryContext = new QueryContext(context, hints, schemata, problems);
+ queryContext = new QueryContext(context, schemata, hints, problems);
plan = planner.createPlan(queryContext, query);
System.out.println(plan);
assertThat(problems.hasErrors(), is(false));
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/DistinctComponentTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/DistinctComponentTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/DistinctComponentTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -31,9 +31,6 @@
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryResults.Columns;
-import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.process.DistinctComponent;
-import org.jboss.dna.graph.query.process.ProcessingComponent;
import org.jboss.dna.graph.query.validate.Schemata;
import org.junit.Before;
import org.junit.Test;
@@ -50,7 +47,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
inputTuples = new ArrayList<Object[]>();
// Define the columns for the results ...
columns = resultColumns("Selector1", "ColA",
"ColB", "ColC");
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -37,9 +37,6 @@
import org.jboss.dna.graph.query.QueryResults.Statistics;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.process.QueryResultColumns;
-import org.jboss.dna.graph.query.process.QueryResults;
import org.jboss.dna.graph.query.validate.Schemata;
import org.junit.Before;
import org.junit.Test;
@@ -66,7 +63,7 @@
@Before
public void beforeEach() {
MockitoAnnotations.initMocks(this);
- context = new QueryContext(executionContext, new PlanHints(), schemata);
+ context = new QueryContext(executionContext, schemata);
columnList = new ArrayList<Column>();
columnList.add(new Column(selector("table1"), name("colA"),
"colA"));
columnList.add(new Column(selector("table1"), name("colB"),
"colB"));
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortLocationsComponentTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortLocationsComponentTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortLocationsComponentTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -31,9 +31,6 @@
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryResults.Columns;
-import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.process.ProcessingComponent;
-import org.jboss.dna.graph.query.process.SortLocationsComponent;
import org.jboss.dna.graph.query.validate.Schemata;
import org.junit.Before;
import org.junit.Test;
@@ -50,7 +47,7 @@
@Before
public void beforeEach() {
- context = new QueryContext(new ExecutionContext(), new PlanHints(),
mock(Schemata.class));
+ context = new QueryContext(new ExecutionContext(), mock(Schemata.class));
inputTuples = new ArrayList<Object[]>();
// Define the columns for the results ...
columns = resultColumns("Selector1", "ColA",
"ColB", "ColC");
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -32,7 +32,6 @@
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryResults.Columns;
import org.jboss.dna.graph.query.model.Ordering;
-import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.validate.Schemata;
import org.junit.Before;
import org.junit.Test;
@@ -56,7 +55,7 @@
columns = resultColumns("Selector1", "ColA",
"ColB", "ColC");
schemata = schemataFor(columns, PropertyType.STRING, PropertyType.LONG,
PropertyType.STRING);
// Define the context ...
- context = new QueryContext(new ExecutionContext(), new PlanHints(), schemata);
+ context = new QueryContext(new ExecutionContext(), schemata);
inputTuples = new ArrayList<Object[]>();
// And define the delegating component ...
delegate = new ProcessingComponent(context, columns) {
Copied: trunk/dna-search/src/main/java/org/jboss/dna/search/DualIndexStrategy.java (from
rev 1318,
trunk/dna-search/src/main/java/org/jboss/dna/search/StoreLittleIndexingStrategy.java)
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/DualIndexStrategy.java
(rev 0)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/DualIndexStrategy.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,399 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.search;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+import net.jcip.annotations.ThreadSafe;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldSelector;
+import org.apache.lucene.document.FieldSelectorResult;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.util.Version;
+import org.jboss.dna.common.text.NoOpEncoder;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.DateTime;
+import org.jboss.dna.graph.property.DateTimeFactory;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.QueryEngine;
+import org.jboss.dna.graph.query.QueryResults;
+import org.jboss.dna.graph.query.QueryResults.Columns;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.optimize.Optimizer;
+import org.jboss.dna.graph.query.optimize.OptimizerRule;
+import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
+import org.jboss.dna.graph.query.plan.CanonicalPlanner;
+import org.jboss.dna.graph.query.plan.PlanHints;
+import org.jboss.dna.graph.query.plan.PlanNode;
+import org.jboss.dna.graph.query.plan.Planner;
+import org.jboss.dna.graph.query.process.ProcessingComponent;
+import org.jboss.dna.graph.query.process.QueryProcessor;
+import org.jboss.dna.search.IndexRules.Rule;
+
+/**
+ * A simple {@link IndexStrategy} implementation that relies upon two separate indexes:
one for the node content and a second
+ * one for paths and UUIDs.
+ */
+@ThreadSafe
+abstract class DualIndexStrategy implements IndexStrategy {
+
+ static class PathIndex {
+ public static final String PATH = "path";
+ public static final String UUID = "uuid";
+ }
+
+ static class ContentIndex {
+ public static final String UUID = PathIndex.UUID;
+ public static final String FULL_TEXT = "fts";
+ }
+
+ /**
+ * The number of results that should be returned when performing queries while
deleting entire branches of content. The
+ * current value is {@value} .
+ */
+ protected static final int SIZE_OF_DELETE_BATCHES = 1000;
+
+ private ThreadLocal<DateFormat> dateFormatter = new
ThreadLocal<DateFormat>() {
+ @Override
+ protected DateFormat initialValue() {
+ return new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+ }
+ };
+
+ /**
+ * Obtain an immutable {@link FieldSelector} instance that accesses the UUID field.
+ */
+ protected static final FieldSelector UUID_FIELD_SELECTOR = new FieldSelector() {
+ private static final long serialVersionUID = 1L;
+
+ public FieldSelectorResult accept( String fieldName ) {
+ return PathIndex.UUID.equals(fieldName) ? FieldSelectorResult.LOAD_AND_BREAK
: FieldSelectorResult.NO_LOAD;
+ }
+ };
+
+ private final IndexRules rules;
+ private final Logger logger;
+ private final QueryEngine queryEngine;
+
+ /**
+ * Create a new indexing strategy instance.
+ *
+ * @param rules the indexing rules that govern how properties are to be index; may
not be null
+ */
+ protected DualIndexStrategy( IndexRules rules ) {
+ assert rules != null;
+ this.rules = rules;
+ this.logger = Logger.getLogger(getClass());
+ // Create the query engine ...
+ Planner planner = new CanonicalPlanner();
+ Optimizer optimizer = new RuleBasedOptimizer() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.optimize.RuleBasedOptimizer#populateRuleStack(java.util.LinkedList,
+ * org.jboss.dna.graph.query.plan.PlanHints)
+ */
+ @Override
+ protected void populateRuleStack( LinkedList<OptimizerRule> ruleStack,
+ PlanHints hints ) {
+ super.populateRuleStack(ruleStack, hints);
+ // Add any custom rules here, either at the front of the stack or at the
end
+ }
+ };
+ QueryProcessor processor = new QueryProcessor() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.process.QueryProcessor#createAccessComponent(org.jboss.dna.graph.query.QueryContext,
+ * org.jboss.dna.graph.query.plan.PlanNode,
org.jboss.dna.graph.query.QueryResults.Columns,
+ * org.jboss.dna.graph.query.process.SelectComponent.Analyzer)
+ */
+ @Override
+ protected ProcessingComponent createAccessComponent( QueryContext context,
+ PlanNode accessNode,
+ Columns resultColumns,
+
org.jboss.dna.graph.query.process.SelectComponent.Analyzer analyzer ) {
+ return
DualIndexStrategy.this.createAccessComponent((SearchContext)context, accessNode,
resultColumns, analyzer);
+ }
+ };
+
+ this.queryEngine = new QueryEngine(planner, optimizer, processor);
+ }
+
+ protected abstract ProcessingComponent createAccessComponent( SearchContext context,
+ PlanNode accessNode,
+ Columns resultColumns,
+
org.jboss.dna.graph.query.process.SelectComponent.Analyzer analyzer );
+
+ /**
+ * Utility method to obtain a {@link DateFormat} instance that can be used safely
within a single thread.
+ *
+ * @return the date formatter; never null
+ */
+ protected final DateFormat dateFormatter() {
+ return dateFormatter.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#getNamespaceEncoder()
+ */
+ public TextEncoder getNamespaceEncoder() {
+ return new NoOpEncoder();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#getChangeCountForAutomaticOptimization()
+ */
+ public int getChangeCountForAutomaticOptimization() {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#createAnalyzer()
+ */
+ public Analyzer createAnalyzer() {
+ return new StandardAnalyzer(Version.LUCENE_CURRENT);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Because this strategy uses multiple indexes, and since there's no correlation
between the documents in those indexes, we
+ * need to perform the delete in multiple steps. First, we need to perform a query to
find out which nodes exist below a
+ * certain path. Then, we need to delete those nodes from the paths index. Finally,
we need to delete the corresponding
+ * documents in the content index that represent those same nodes.
+ * </p>
+ * <p>
+ * Since we don't know how many documents there will be, we perform these steps
in batches, where each batch limits the number
+ * of results to a maximum number. We repeat batches as long as we find more results.
This approach has the advantage that
+ * we'll never bring in a large number of results, and it allows us to delete the
documents from the content node using a
+ * query.
+ * </p>
+ *
+ * @see org.jboss.dna.search.IndexStrategy#deleteBelow(Path, IndexContext)
+ */
+ public int deleteBelow( Path path,
+ IndexContext indexes ) throws IOException {
+ // Perform a query using the reader to find those nodes at/below the path ...
+ try {
+ IndexReader pathReader = indexes.getPathsReader();
+ IndexSearcher pathSearcher = new IndexSearcher(pathReader);
+ String pathStr = indexes.stringFactory().create(path) + "/";
+ PrefixQuery query = new PrefixQuery(new Term(PathIndex.PATH, pathStr));
+ int numberDeleted = 0;
+ while (true) {
+ // Execute the query and get the results ...
+ TopDocs results = pathSearcher.search(query, SIZE_OF_DELETE_BATCHES);
+ int numResultsInBatch = results.scoreDocs.length;
+ // Walk the results, delete the doc, and add to the query that we'll
use against the content index ...
+ IndexReader contentReader = indexes.getContentReader();
+ for (ScoreDoc result : results.scoreDocs) {
+ int docId = result.doc;
+ // Find the UUID of the node ...
+ Document doc = pathReader.document(docId, UUID_FIELD_SELECTOR);
+ String uuid = doc.get(PathIndex.UUID);
+ // Delete the document from the paths index ...
+ pathReader.deleteDocument(docId);
+ // Delete the corresponding document from the content index ...
+ contentReader.deleteDocuments(new Term(ContentIndex.UUID, uuid));
+ }
+ numberDeleted += numResultsInBatch;
+ if (numResultsInBatch < SIZE_OF_DELETE_BATCHES) break;
+ }
+ indexes.commit();
+ return numberDeleted;
+ } catch (FileNotFoundException e) {
+ // There are no index files yet, so nothing to delete ...
+ return 0;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#index(Node, IndexContext)
+ */
+ public void index( Node node,
+ IndexContext indexes ) throws IOException {
+ ValueFactory<String> strings = indexes.stringFactory();
+ Location location = node.getLocation();
+ UUID uuid = location.getUuid();
+ if (uuid == null) uuid = UUID.randomUUID();
+ Path path = location.getPath();
+ String pathStr = path.isRoot() ? "/" :
strings.create(location.getPath()) + "/";
+ String uuidStr = uuid.toString();
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("indexing {0}", pathStr);
+ }
+
+ // Create a separate document for the path, which makes it easier to handle moves
since the path can
+ // be changed without changing any other content fields ...
+ Document doc = new Document();
+ doc.add(new Field(PathIndex.PATH, pathStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
+ doc.add(new Field(PathIndex.UUID, uuidStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
+ indexes.getPathsWriter().addDocument(doc);
+
+ // Create the document for the content (properties) ...
+ doc = new Document();
+ doc.add(new Field(ContentIndex.UUID, uuidStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
+ String stringValue = null;
+ StringBuilder fullTextSearchValue = null;
+ for (Property property : node.getProperties()) {
+ Name name = property.getName();
+ Rule rule = rules.getRule(name);
+ if (rule.isSkipped()) continue;
+ String nameString = strings.create(name);
+ if (rule.isDate()) {
+ DateTimeFactory dateFactory = indexes.dateFactory();
+ for (Object value : property) {
+ if (value == null) continue;
+ DateTime dateValue = dateFactory.create(value);
+ stringValue = dateFormatter().format(dateValue.toDate());
+ // Add a separate field for each property value ...
+ doc.add(new Field(nameString, stringValue, rule.getStoreOption(),
rule.getIndexOption()));
+ // Dates are not added to the full-text search field (since this
wouldn't make sense)
+ }
+ continue;
+ }
+ for (Object value : property) {
+ if (value == null) continue;
+ if (value instanceof Binary) {
+ // don't include binary values as individual fields but do
include them in the full-text search ...
+ // TODO : add to full-text search ...
+ continue;
+ }
+ stringValue = strings.create(value);
+ // Add a separate field for each property value ...
+ doc.add(new Field(nameString, stringValue, rule.getStoreOption(),
rule.getIndexOption()));
+ // And add to the full-text field ...
+ if (rule.isFullText()) {
+ if (fullTextSearchValue == null) {
+ fullTextSearchValue = new StringBuilder();
+ } else {
+ fullTextSearchValue.append(' ');
+ }
+ fullTextSearchValue.append(stringValue);
+ }
+ }
+ }
+ // Add the full-text-search field ...
+ if (fullTextSearchValue != null) {
+ doc.add(new Field(ContentIndex.FULL_TEXT, fullTextSearchValue.toString(),
Field.Store.NO, Field.Index.ANALYZED));
+ }
+ indexes.getContentWriter().addDocument(doc);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#search(String, int, int, IndexContext,
List)
+ */
+ public void search( String fullTextString,
+ int maxResults,
+ int offset,
+ IndexContext indexes,
+ List<Location> results ) throws IOException, ParseException
{
+ assert fullTextString != null;
+ assert fullTextString.length() > 0;
+ assert offset >= 0;
+ assert maxResults > 0;
+ assert indexes != null;
+ assert results != null;
+
+ // Parse the full-text search and search against the 'fts' field ...
+ QueryParser parser = new QueryParser(ContentIndex.FULL_TEXT, createAnalyzer());
+ Query query = parser.parse(fullTextString);
+ TopDocs docs = indexes.getContentSearcher().search(query, maxResults + offset);
+
+ // Collect the results ...
+ IndexReader contentReader = indexes.getContentReader();
+ IndexReader pathReader = indexes.getPathsReader();
+ IndexSearcher pathSearcher = indexes.getPathsSearcher();
+ ScoreDoc[] scoreDocs = docs.scoreDocs;
+ int numberOfResults = scoreDocs.length;
+ if (numberOfResults > offset) {
+ // There are enough results to satisfy the offset ...
+ for (int i = offset, num = scoreDocs.length; i != num; ++i) {
+ ScoreDoc result = scoreDocs[i];
+ int docId = result.doc;
+ // Find the UUID of the node (this UUID might be artificial, so we have
to find the path) ...
+ Document doc = contentReader.document(docId, UUID_FIELD_SELECTOR);
+ String uuid = doc.get(ContentIndex.UUID);
+ // Find the path for this node (is there a better way to do this than one
search per UUID?) ...
+ TopDocs pathDocs = pathSearcher.search(new TermQuery(new
Term(PathIndex.UUID, uuid)), 1);
+ if (pathDocs.scoreDocs.length < 1) {
+ // No path record found ...
+ continue;
+ }
+ Document pathDoc = pathReader.document(pathDocs.scoreDocs[0].doc);
+ Path path = indexes.pathFactory().create(pathDoc.get(PathIndex.PATH));
+ // Now add the location ...
+ results.add(Location.create(path, UUID.fromString(uuid)));
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#query(org.jboss.dna.search.SearchContext,
+ * org.jboss.dna.graph.query.model.QueryCommand)
+ */
+ public QueryResults query( SearchContext context,
+ QueryCommand query ) {
+ return this.queryEngine.execute(context, query);
+ }
+}
Property changes on:
trunk/dna-search/src/main/java/org/jboss/dna/search/DualIndexStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexContext.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/IndexContext.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/IndexContext.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -31,16 +31,17 @@
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
+import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.property.DateTimeFactory;
import org.jboss.dna.graph.property.PathFactory;
import org.jboss.dna.graph.property.ValueFactory;
/**
- * A set of index readers and writers.
+ * A context for working with the index readers and writers.
*/
@NotThreadSafe
-public final class IndexContext {
+final class IndexContext {
private final ExecutionContext context;
private final Directory pathsIndexDirectory;
@@ -278,4 +279,16 @@
if (runtimeError != null) throw runtimeError;
}
+ /**
+ * Create a copy of this index context, except that it uses the supplied execution
context.
+ *
+ * @param context the new execution context that should be used in the copy
+ * @return the new context; never null
+ * @throws IllegalArgumentException if the context is null
+ */
+ public IndexContext with( ExecutionContext context ) {
+ CheckArg.isNotNull(context, "context");
+ return new IndexContext(context, pathsIndexDirectory, contentIndexDirectory,
analyzer, overwrite, readOnly);
+ }
+
}
Copied: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexRules.java (from rev
1318, trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingRules.java)
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/IndexRules.java
(rev 0)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/IndexRules.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,628 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.search;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import net.jcip.annotations.Immutable;
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.property.Name;
+
+/**
+ * The set of rules that dictate how properties should be indexed.
+ */
+@Immutable
+class IndexRules {
+
+ public static final int INDEX = 2 << 0;
+ public static final int ANALYZE = 2 << 1;
+ public static final int STORE = 2 << 2;
+ public static final int STORE_COMPRESSED = 2 << 3;
+ public static final int ANALYZED_WITHOUT_NORMS = 2 << 4;
+ public static final int FULL_TEXT = 2 << 5;
+ public static final int TREAT_AS_DATE = 2 << 6;
+
+ /**
+ * A single rule that dictates how a single property should be indexed.
+ *
+ * @see IndexRules#getRule(Name)
+ */
+ @Immutable
+ public static interface Rule {
+ boolean isIncluded();
+
+ boolean isSkipped();
+
+ boolean isAnalyzed();
+
+ boolean isAnalyzedWithoutNorms();
+
+ boolean isStored();
+
+ boolean isStoredCompressed();
+
+ boolean isFullText();
+
+ boolean isDate();
+
+ int getMask();
+
+ Field.Store getStoreOption();
+
+ Field.Index getIndexOption();
+ }
+
+ public static final Rule SKIP = new SkipRule();
+
+ @Immutable
+ protected static class SkipRule implements Rule {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getMask()
+ */
+ public int getMask() {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isAnalyzed()
+ */
+ public boolean isAnalyzed() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isAnalyzedWithoutNorms()
+ */
+ public boolean isAnalyzedWithoutNorms() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isFullText()
+ */
+ public boolean isFullText() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isIncluded()
+ */
+ public boolean isIncluded() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isSkipped()
+ */
+ public boolean isSkipped() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isStored()
+ */
+ public boolean isStored() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isStoredCompressed()
+ */
+ public boolean isStoredCompressed() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isDate()
+ */
+ public boolean isDate() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getIndexOption()
+ */
+ public Index getIndexOption() {
+ return Field.Index.NO;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getStoreOption()
+ */
+ public Store getStoreOption() {
+ return Field.Store.NO;
+ }
+ }
+
+ @Immutable
+ public static final class GeneralRule implements Rule {
+ private final int value;
+ private final Field.Store store;
+ private final Field.Index index;
+
+ protected GeneralRule( int value ) {
+ this.value = value;
+ this.index = isAnalyzed() ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED;
+ this.store = isStored() ? Field.Store.YES : Field.Store.NO;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getMask()
+ */
+ public int getMask() {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isAnalyzed()
+ */
+ public boolean isAnalyzed() {
+ return (value & ANALYZE) == ANALYZE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isAnalyzedWithoutNorms()
+ */
+ public boolean isAnalyzedWithoutNorms() {
+ return (value & ANALYZED_WITHOUT_NORMS) == ANALYZED_WITHOUT_NORMS;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isFullText()
+ */
+ public boolean isFullText() {
+ return (value & FULL_TEXT) == FULL_TEXT;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isIncluded()
+ */
+ public boolean isIncluded() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isSkipped()
+ */
+ public boolean isSkipped() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isStored()
+ */
+ public boolean isStored() {
+ return (value & STORE) == STORE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isStoredCompressed()
+ */
+ public boolean isStoredCompressed() {
+ return (value & STORE_COMPRESSED) == STORE_COMPRESSED;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#isDate()
+ */
+ public boolean isDate() {
+ return (value & TREAT_AS_DATE) == TREAT_AS_DATE;
+ }
+
+ protected Rule with( int options ) {
+ return createRule(value | options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getIndexOption()
+ */
+ public Index getIndexOption() {
+ return index;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexRules.Rule#getStoreOption()
+ */
+ public Store getStoreOption() {
+ return store;
+ }
+ }
+
+ private static final ConcurrentHashMap<Integer, Rule> CACHE = new
ConcurrentHashMap<Integer, Rule>();
+
+ protected static Rule createRule( int value ) {
+ if (value <= 0) {
+ return SKIP;
+ }
+ Integer key = new Integer(value);
+ Rule rule = CACHE.get(key);
+ if (rule == null) {
+ Rule newRule = new GeneralRule(value);
+ rule = CACHE.putIfAbsent(value, newRule);
+ if (rule == null) rule = newRule;
+ }
+ return rule;
+ }
+
+ private final Map<Name, Rule> rulesByName;
+ private final Rule defaultRule;
+
+ protected IndexRules( Map<Name, Rule> rulesByName,
+ Rule defaultRule ) {
+ this.rulesByName = rulesByName;
+ this.defaultRule = defaultRule != null ? defaultRule : SKIP;
+ assert this.defaultRule != null;
+ }
+
+ /**
+ * Get the rule associated with the given property name.
+ *
+ * @param name the property name, or null if the default rule is to be returned
+ * @return the rule; never null
+ */
+ public Rule getRule( Name name ) {
+ Rule result = rulesByName.get(name);
+ return result != null ? result : this.defaultRule;
+ }
+
+ /**
+ * Return a new builder that can be used to create {@link IndexRules} objects.
+ *
+ * @return a builder; never null
+ */
+ public static Builder createBuilder() {
+ return new Builder(new HashMap<Name, Rule>());
+ }
+
+ /**
+ * Return a new builder that can be used to create {@link IndexRules} objects.
+ *
+ * @param initialRules the rules that the builder should start with
+ * @return a builder; never null
+ * @throws IllegalArgumentException if the initial rules reference is null
+ */
+ public static Builder createBuilder( IndexRules initialRules ) {
+ CheckArg.isNotNull(initialRules, "initialRules");
+ return new
Builder(initialRules.rulesByName).defaultTo(initialRules.defaultRule);
+ }
+
+ /**
+ * A builder of immutable {@link IndexRules} objects.
+ */
+ @NotThreadSafe
+ public static class Builder {
+ private final Map<Name, Rule> rulesByName;
+ private Rule defaultRule;
+
+ Builder( Map<Name, Rule> rulesByName ) {
+ assert rulesByName != null;
+ this.rulesByName = rulesByName;
+ }
+
+ /**
+ * Set the default rules.
+ *
+ * @param rule the default rule to use
+ * @return this builder for convenience and method chaining; never null
+ * @throws IllegalArgumentException if the rule mask is negative
+ */
+ public Builder defaultTo( Rule rule ) {
+ CheckArg.isNotNull(rule, "rule");
+ defaultRule = rule;
+ return this;
+ }
+
+ /**
+ * Set the default rules.
+ *
+ * @param ruleMask the bitmask of rule to use
+ * @return this builder for convenience and method chaining; never null
+ * @throws IllegalArgumentException if the rule mask is negative
+ */
+ public Builder defaultTo( int ruleMask ) {
+ CheckArg.isNonNegative(ruleMask, "options");
+ if (ruleMask == 0) {
+ defaultRule = SKIP;
+ } else {
+ // Make sure the index flag is set ...
+ ruleMask |= INDEX;
+ defaultRule = createRule(ruleMask);
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be skipped from indexing.
+ *
+ * @param namesToIndex the names of the properties that are to be skipped
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder skip( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ rulesByName.put(name, SKIP);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Set the properties with the supplied names to use the supplied rules.
+ *
+ * @param ruleMask the bitmask of rules to use
+ * @param namesToIndex the names of the properties that are to be skipped
+ * @return this builder for convenience and method chaining; never null
+ * @throws IllegalArgumentException if the rule mask is negative
+ */
+ public Builder set( int ruleMask,
+ Name... namesToIndex ) {
+ CheckArg.isNonNegative(ruleMask, "options");
+ if (namesToIndex != null) {
+ if (ruleMask > 0) {
+ skip(namesToIndex);
+ } else {
+ // Make sure the index flag is set ...
+ ruleMask |= INDEX;
+ Rule rule = createRule(ruleMask);
+ for (Name name : namesToIndex) {
+ rulesByName.put(name, rule);
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to use the supplied rule mask.
This does not remove any other rules for
+ * these properties.
+ *
+ * @param ruleMask the bitmask of rules to add
+ * @param namesToIndex the names of the properties that are to be skipped
+ * @return this builder for convenience and method chaining; never null
+ * @throws IllegalArgumentException if the rule mask is negative
+ */
+ public Builder add( int ruleMask,
+ Name... namesToIndex ) {
+ CheckArg.isNonNegative(ruleMask, "options");
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, ruleMask);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be indexed. This does not
remove any other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be indexed
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder index( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, INDEX);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be analyzed (and obviously
indexed). This does not remove any other
+ * rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be analyzed
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder analyze( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, ANALYZE | INDEX);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be stored (and obviously
indexed). This does not remove any other rules
+ * for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be stored
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder store( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, STORE | INDEX);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be included in full-text
searches (and obviously indexed). This does not
+ * remove any other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be included in
full-text searches
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder fullText( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, FULL_TEXT | INDEX);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be treated as dates (and
obviously indexed). This does not remove any
+ * other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be included in
full-text searches
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder treatAsDates( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, TREAT_AS_DATE | INDEX);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be indexed, analyzed and
stored. This does not remove any other rules
+ * for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be indexed,
analyzed and stored
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder analyzeAndStore( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, INDEX | ANALYZE | STORE);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be indexed, analyzed, stored
and included in full-text searches. This
+ * does not remove any other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be indexed,
analyzed, stored and included in full-text
+ * searches
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder analyzeAndStoreAndFullText( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, INDEX | ANALYZE | STORE | FULL_TEXT);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be indexed, analyzed and
included in full-text searches. This does not
+ * remove any other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be indexed,
analyzed and included in full-text searches
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder analyzeAndFullText( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, INDEX | ANALYZE | FULL_TEXT);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Mark the properties with the supplied names to be indexed, stored and included
in full-text searches. This does not
+ * remove any other rules for these properties.
+ *
+ * @param namesToIndex the names of the properties that are to be indexed, stored
and included in full-text searches
+ * @return this builder for convenience and method chaining; never null
+ */
+ public Builder storeAndFullText( Name... namesToIndex ) {
+ if (namesToIndex != null) {
+ for (Name name : namesToIndex) {
+ add(name, INDEX | STORE | FULL_TEXT);
+ }
+ }
+ return this;
+ }
+
+ protected void add( Name name,
+ int option ) {
+ Rule rule = rulesByName.get(name);
+ if (rule != null) {
+ option |= rule.getMask();
+ }
+ rulesByName.put(name, createRule(option));
+ }
+
+ /**
+ * Build the indexing rules.
+ *
+ * @return the immutable indexing rules.
+ */
+ public IndexRules build() {
+ return new IndexRules(Collections.unmodifiableMap(new HashMap<Name,
Rule>(rulesByName)), defaultRule);
+ }
+ }
+}
Property changes on: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexRules.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexStrategy.java (from rev
1318, trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingStrategy.java)
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/IndexStrategy.java
(rev 0)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/IndexStrategy.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,133 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.search;
+
+import java.io.IOException;
+import java.util.List;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.queryParser.ParseException;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.query.QueryResults;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.validate.Schemata;
+import org.jboss.dna.graph.request.ChangeRequest;
+
+/**
+ * Interface defining the behaviors associated with indexing graph content.
+ */
+interface IndexStrategy {
+
+ /**
+ * Get the number of changes that are allowed before optimization is automatically
run.
+ *
+ * @return a positive number denoting the minimum number of changes between automatic
optimization operations, or a
+ * non-positive number if automatic optimization should never be run
+ */
+ int getChangeCountForAutomaticOptimization();
+
+ /**
+ * Get the {@link TextEncoder} that should be used to encode the namespace URIs.
+ *
+ * @return the encoder; may not be null
+ */
+ TextEncoder getNamespaceEncoder();
+
+ /**
+ * Index the node given the index writers. Note that implementors should simply just
use the writers to add documents to the
+ * index(es), and should never call any of the writer lifecycle methods (e.g., {@link
IndexWriter#commit()},
+ * {@link IndexWriter#rollback()}, etc.).
+ *
+ * @param node the node to be indexed; never null
+ * @param indexes the set of index readers and writers; never null
+ * @throws IOException if there is a problem indexing or using the writers
+ */
+ void index( Node node,
+ IndexContext indexes ) throws IOException;
+
+ /**
+ * Update the indexes to reflect the supplied changes to the graph content. Note that
implementors should simply just use the
+ * writers to add documents to the index(es), and should never call any of the writer
lifecycle methods (e.g.,
+ * {@link IndexWriter#commit()}, {@link IndexWriter#rollback()}, etc.).
+ *
+ * @param changes the set of changes to the content
+ * @param indexes the set of index readers and writers; never null
+ * @return the (approximate) number of nodes that were affected by the changes
+ * @throws IOException if there is a problem indexing or using the writers
+ */
+ int apply( Iterable<ChangeRequest> changes,
+ IndexContext indexes ) throws IOException;
+
+ /**
+ * Remove from the index(es) all of the information pertaining to the nodes at or
below the supplied path. Note that
+ * implementors should simply just use the writers to add documents to the index(es),
and should never call any of the writer
+ * lifecycle methods (e.g., {@link IndexWriter#commit()}, {@link
IndexWriter#rollback()}, etc.).
+ *
+ * @param path the path identifying the graph content that is to be removed; never
null
+ * @param indexes the set of index readers and writers; never null
+ * @return the (approximate) number of nodes that were affected by the changes
+ * @throws IOException if there is a problem indexing or using the writers
+ */
+ int deleteBelow( Path path,
+ IndexContext indexes ) throws IOException;
+
+ /**
+ * Create the analyzer that is used for reading and updating the indexes.
+ *
+ * @return the analyzer; may not be null
+ */
+ Analyzer createAnalyzer();
+
+ /**
+ * Perform a full-text search given the supplied query.
+ *
+ * @param fullTextString the full-text query; never null or blank
+ * @param maxResults the maximum number of results that are to be returned; always
positive
+ * @param offset the number of initial results to skip, or 0 if the first results are
to be returned
+ * @param indexes the set of index readers and writers; never null
+ * @param results the list where the results should be accumulated; never null
+ * @throws IOException if there is a problem indexing or using the writers
+ * @throws ParseException if there is a problem parsing the query
+ */
+ void search( String fullTextString,
+ int maxResults,
+ int offset,
+ IndexContext indexes,
+ List<Location> results ) throws IOException, ParseException;
+
+ /**
+ * Perform a query of the content. The {@link QueryCommand query} is supplied in the
form of the Abstract Query Model, with
+ * the {@link Schemata} that defines the tables and views that are available to the
query, and the set of index readers (and
+ * writers) that should be used.
+ *
+ * @param context the context in which the query should be executed; never null
+ * @param query the query; never null
+ * @return the results of the query
+ */
+ QueryResults query( SearchContext context,
+ QueryCommand query );
+}
Property changes on:
trunk/dna-search/src/main/java/org/jboss/dna/search/IndexStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingRules.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingRules.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingRules.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,628 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.search;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import net.jcip.annotations.Immutable;
-import net.jcip.annotations.NotThreadSafe;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Field.Index;
-import org.apache.lucene.document.Field.Store;
-import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.graph.property.Name;
-
-/**
- * The set of rules that dictate how properties should be indexed.
- */
-@Immutable
-public class IndexingRules {
-
- public static final int INDEX = 2 << 0;
- public static final int ANALYZE = 2 << 1;
- public static final int STORE = 2 << 2;
- public static final int STORE_COMPRESSED = 2 << 3;
- public static final int ANALYZED_WITHOUT_NORMS = 2 << 4;
- public static final int FULL_TEXT = 2 << 5;
- public static final int TREAT_AS_DATE = 2 << 6;
-
- /**
- * A single rule that dictates how a single property should be indexed.
- *
- * @see IndexingRules#getRule(Name)
- */
- @Immutable
- public static interface Rule {
- boolean isIncluded();
-
- boolean isSkipped();
-
- boolean isAnalyzed();
-
- boolean isAnalyzedWithoutNorms();
-
- boolean isStored();
-
- boolean isStoredCompressed();
-
- boolean isFullText();
-
- boolean isDate();
-
- int getMask();
-
- Field.Store getStoreOption();
-
- Field.Index getIndexOption();
- }
-
- public static final Rule SKIP = new SkipRule();
-
- @Immutable
- protected static class SkipRule implements Rule {
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getMask()
- */
- public int getMask() {
- return 0;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isAnalyzed()
- */
- public boolean isAnalyzed() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isAnalyzedWithoutNorms()
- */
- public boolean isAnalyzedWithoutNorms() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isFullText()
- */
- public boolean isFullText() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isIncluded()
- */
- public boolean isIncluded() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isSkipped()
- */
- public boolean isSkipped() {
- return true;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isStored()
- */
- public boolean isStored() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isStoredCompressed()
- */
- public boolean isStoredCompressed() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isDate()
- */
- public boolean isDate() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getIndexOption()
- */
- public Index getIndexOption() {
- return Field.Index.NO;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getStoreOption()
- */
- public Store getStoreOption() {
- return Field.Store.NO;
- }
- }
-
- @Immutable
- public static final class GeneralRule implements Rule {
- private final int value;
- private final Field.Store store;
- private final Field.Index index;
-
- protected GeneralRule( int value ) {
- this.value = value;
- this.index = isAnalyzed() ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED;
- this.store = isStored() ? Field.Store.YES : Field.Store.NO;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getMask()
- */
- public int getMask() {
- return value;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isAnalyzed()
- */
- public boolean isAnalyzed() {
- return (value & ANALYZE) == ANALYZE;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isAnalyzedWithoutNorms()
- */
- public boolean isAnalyzedWithoutNorms() {
- return (value & ANALYZED_WITHOUT_NORMS) == ANALYZED_WITHOUT_NORMS;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isFullText()
- */
- public boolean isFullText() {
- return (value & FULL_TEXT) == FULL_TEXT;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isIncluded()
- */
- public boolean isIncluded() {
- return true;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isSkipped()
- */
- public boolean isSkipped() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isStored()
- */
- public boolean isStored() {
- return (value & STORE) == STORE;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isStoredCompressed()
- */
- public boolean isStoredCompressed() {
- return (value & STORE_COMPRESSED) == STORE_COMPRESSED;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#isDate()
- */
- public boolean isDate() {
- return (value & TREAT_AS_DATE) == TREAT_AS_DATE;
- }
-
- protected Rule with( int options ) {
- return createRule(value | options);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getIndexOption()
- */
- public Index getIndexOption() {
- return index;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingRules.Rule#getStoreOption()
- */
- public Store getStoreOption() {
- return store;
- }
- }
-
- private static final ConcurrentHashMap<Integer, Rule> CACHE = new
ConcurrentHashMap<Integer, Rule>();
-
- protected static Rule createRule( int value ) {
- if (value <= 0) {
- return SKIP;
- }
- Integer key = new Integer(value);
- Rule rule = CACHE.get(key);
- if (rule == null) {
- Rule newRule = new GeneralRule(value);
- rule = CACHE.putIfAbsent(value, newRule);
- if (rule == null) rule = newRule;
- }
- return rule;
- }
-
- private final Map<Name, Rule> rulesByName;
- private final Rule defaultRule;
-
- protected IndexingRules( Map<Name, Rule> rulesByName,
- Rule defaultRule ) {
- this.rulesByName = rulesByName;
- this.defaultRule = defaultRule != null ? defaultRule : SKIP;
- assert this.defaultRule != null;
- }
-
- /**
- * Get the rule associated with the given property name.
- *
- * @param name the property name, or null if the default rule is to be returned
- * @return the rule; never null
- */
- public Rule getRule( Name name ) {
- Rule result = rulesByName.get(name);
- return result != null ? result : this.defaultRule;
- }
-
- /**
- * Return a new builder that can be used to create {@link IndexingRules} objects.
- *
- * @return a builder; never null
- */
- public static Builder createBuilder() {
- return new Builder(new HashMap<Name, Rule>());
- }
-
- /**
- * Return a new builder that can be used to create {@link IndexingRules} objects.
- *
- * @param initialRules the rules that the builder should start with
- * @return a builder; never null
- * @throws IllegalArgumentException if the initial rules reference is null
- */
- public static Builder createBuilder( IndexingRules initialRules ) {
- CheckArg.isNotNull(initialRules, "initialRules");
- return new
Builder(initialRules.rulesByName).defaultTo(initialRules.defaultRule);
- }
-
- /**
- * A builder of immutable {@link IndexingRules} objects.
- */
- @NotThreadSafe
- public static class Builder {
- private final Map<Name, Rule> rulesByName;
- private Rule defaultRule;
-
- Builder( Map<Name, Rule> rulesByName ) {
- assert rulesByName != null;
- this.rulesByName = rulesByName;
- }
-
- /**
- * Set the default rules.
- *
- * @param rule the default rule to use
- * @return this builder for convenience and method chaining; never null
- * @throws IllegalArgumentException if the rule mask is negative
- */
- public Builder defaultTo( Rule rule ) {
- CheckArg.isNotNull(rule, "rule");
- defaultRule = rule;
- return this;
- }
-
- /**
- * Set the default rules.
- *
- * @param ruleMask the bitmask of rule to use
- * @return this builder for convenience and method chaining; never null
- * @throws IllegalArgumentException if the rule mask is negative
- */
- public Builder defaultTo( int ruleMask ) {
- CheckArg.isNonNegative(ruleMask, "options");
- if (ruleMask == 0) {
- defaultRule = SKIP;
- } else {
- // Make sure the index flag is set ...
- ruleMask |= INDEX;
- defaultRule = createRule(ruleMask);
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be skipped from indexing.
- *
- * @param namesToIndex the names of the properties that are to be skipped
- * @return this builder for convenience and method chaining; never null
- */
- public Builder skip( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- rulesByName.put(name, SKIP);
- }
- }
- return this;
- }
-
- /**
- * Set the properties with the supplied names to use the supplied rules.
- *
- * @param ruleMask the bitmask of rules to use
- * @param namesToIndex the names of the properties that are to be skipped
- * @return this builder for convenience and method chaining; never null
- * @throws IllegalArgumentException if the rule mask is negative
- */
- public Builder set( int ruleMask,
- Name... namesToIndex ) {
- CheckArg.isNonNegative(ruleMask, "options");
- if (namesToIndex != null) {
- if (ruleMask > 0) {
- skip(namesToIndex);
- } else {
- // Make sure the index flag is set ...
- ruleMask |= INDEX;
- Rule rule = createRule(ruleMask);
- for (Name name : namesToIndex) {
- rulesByName.put(name, rule);
- }
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to use the supplied rule mask.
This does not remove any other rules for
- * these properties.
- *
- * @param ruleMask the bitmask of rules to add
- * @param namesToIndex the names of the properties that are to be skipped
- * @return this builder for convenience and method chaining; never null
- * @throws IllegalArgumentException if the rule mask is negative
- */
- public Builder add( int ruleMask,
- Name... namesToIndex ) {
- CheckArg.isNonNegative(ruleMask, "options");
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, ruleMask);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be indexed. This does not
remove any other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be indexed
- * @return this builder for convenience and method chaining; never null
- */
- public Builder index( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, INDEX);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be analyzed (and obviously
indexed). This does not remove any other
- * rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be analyzed
- * @return this builder for convenience and method chaining; never null
- */
- public Builder analyze( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, ANALYZE | INDEX);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be stored (and obviously
indexed). This does not remove any other rules
- * for these properties.
- *
- * @param namesToIndex the names of the properties that are to be stored
- * @return this builder for convenience and method chaining; never null
- */
- public Builder store( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, STORE | INDEX);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be included in full-text
searches (and obviously indexed). This does not
- * remove any other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be included in
full-text searches
- * @return this builder for convenience and method chaining; never null
- */
- public Builder fullText( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, FULL_TEXT | INDEX);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be treated as dates (and
obviously indexed). This does not remove any
- * other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be included in
full-text searches
- * @return this builder for convenience and method chaining; never null
- */
- public Builder treatAsDates( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, TREAT_AS_DATE | INDEX);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be indexed, analyzed and
stored. This does not remove any other rules
- * for these properties.
- *
- * @param namesToIndex the names of the properties that are to be indexed,
analyzed and stored
- * @return this builder for convenience and method chaining; never null
- */
- public Builder analyzeAndStore( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, INDEX | ANALYZE | STORE);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be indexed, analyzed, stored
and included in full-text searches. This
- * does not remove any other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be indexed,
analyzed, stored and included in full-text
- * searches
- * @return this builder for convenience and method chaining; never null
- */
- public Builder analyzeAndStoreAndFullText( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, INDEX | ANALYZE | STORE | FULL_TEXT);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be indexed, analyzed and
included in full-text searches. This does not
- * remove any other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be indexed,
analyzed and included in full-text searches
- * @return this builder for convenience and method chaining; never null
- */
- public Builder analyzeAndFullText( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, INDEX | ANALYZE | FULL_TEXT);
- }
- }
- return this;
- }
-
- /**
- * Mark the properties with the supplied names to be indexed, stored and included
in full-text searches. This does not
- * remove any other rules for these properties.
- *
- * @param namesToIndex the names of the properties that are to be indexed, stored
and included in full-text searches
- * @return this builder for convenience and method chaining; never null
- */
- public Builder storeAndFullText( Name... namesToIndex ) {
- if (namesToIndex != null) {
- for (Name name : namesToIndex) {
- add(name, INDEX | STORE | FULL_TEXT);
- }
- }
- return this;
- }
-
- protected void add( Name name,
- int option ) {
- Rule rule = rulesByName.get(name);
- if (rule != null) {
- option |= rule.getMask();
- }
- rulesByName.put(name, createRule(option));
- }
-
- /**
- * Build the indexing rules.
- *
- * @return the immutable indexing rules.
- */
- public IndexingRules build() {
- return new IndexingRules(Collections.unmodifiableMap(new HashMap<Name,
Rule>(rulesByName)), defaultRule);
- }
- }
-}
Deleted: trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingStrategy.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingStrategy.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/IndexingStrategy.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,126 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.search;
-
-import java.io.IOException;
-import java.util.List;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.queryParser.ParseException;
-import org.jboss.dna.common.text.TextEncoder;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.Node;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.query.QueryResults;
-import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.validate.Schemata;
-import org.jboss.dna.graph.request.ChangeRequest;
-
-/**
- * Interface defining the behaviors associated with indexing graph content.
- */
-public interface IndexingStrategy {
-
- int getChangeCountForAutomaticOptimization();
-
- TextEncoder getNamespaceEncoder();
-
- /**
- * Index the node given the index writers. Note that implementors should simply just
use the writers to add documents to the
- * index(es), and should never call any of the writer lifecycle methods (e.g., {@link
IndexWriter#commit()},
- * {@link IndexWriter#rollback()}, etc.).
- *
- * @param node the node to be indexed; never null
- * @param indexes the set of index readers and writers; never null
- * @throws IOException if there is a problem indexing or using the writers
- */
- void index( Node node,
- IndexContext indexes ) throws IOException;
-
- /**
- * Update the indexes to reflect the supplied changes to the graph content. Note that
implementors should simply just use the
- * writers to add documents to the index(es), and should never call any of the writer
lifecycle methods (e.g.,
- * {@link IndexWriter#commit()}, {@link IndexWriter#rollback()}, etc.).
- *
- * @param changes the set of changes to the content
- * @param indexes the set of index readers and writers; never null
- * @return the (approximate) number of nodes that were affected by the changes
- * @throws IOException if there is a problem indexing or using the writers
- */
- int apply( Iterable<ChangeRequest> changes,
- IndexContext indexes ) throws IOException;
-
- /**
- * Remove from the index(es) all of the information pertaining to the nodes at or
below the supplied path. Note that
- * implementors should simply just use the writers to add documents to the index(es),
and should never call any of the writer
- * lifecycle methods (e.g., {@link IndexWriter#commit()}, {@link
IndexWriter#rollback()}, etc.).
- *
- * @param path the path identifying the graph content that is to be removed; never
null
- * @param indexes the set of index readers and writers; never null
- * @return the (approximate) number of nodes that were affected by the changes
- * @throws IOException if there is a problem indexing or using the writers
- */
- int deleteBelow( Path path,
- IndexContext indexes ) throws IOException;
-
- /**
- * Create the analyzer that is used for reading and updating the indexes.
- *
- * @return the analyzer; may not be null
- */
- Analyzer createAnalyzer();
-
- /**
- * Perform a full-text search given the supplied query.
- *
- * @param fullTextString the full-text query; never null or blank
- * @param maxResults the maximum number of results that are to be returned; always
positive
- * @param offset the number of initial results to skip, or 0 if the first results are
to be returned
- * @param indexes the set of index readers and writers; never null
- * @param results the list where the results should be accumulated; never null
- * @throws IOException if there is a problem indexing or using the writers
- * @throws ParseException if there is a problem parsing the query
- */
- void performQuery( String fullTextString,
- int maxResults,
- int offset,
- IndexContext indexes,
- List<Location> results ) throws IOException,
ParseException;
-
- /**
- * Perform a query of the content. The {@link QueryCommand query} is supplied in the
form of the Abstract Query Model, with
- * the {@link Schemata} that defines the tables and views that are available to the
query, and the set of index readers (and
- * writers) that should be used.
- *
- * @param query the query; never null
- * @param schemata the definition of the tables used in the query; never null
- * @param indexes the set of index readers and writers; never null
- * @return the results of the query
- * @throws IOException if there is a problem indexing or using the writers
- * @throws ParseException if there is a problem parsing the query
- */
- QueryResults performQuery( QueryCommand query,
- Schemata schemata,
- IndexContext indexes ) throws IOException,
ParseException;
-}
Added: trunk/dna-search/src/main/java/org/jboss/dna/search/KitchenSinkIndexStrategy.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/KitchenSinkIndexStrategy.java
(rev 0)
+++
trunk/dna-search/src/main/java/org/jboss/dna/search/KitchenSinkIndexStrategy.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,115 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.search;
+
+import java.util.List;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.graph.DnaLexicon;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.query.QueryResults.Columns;
+import org.jboss.dna.graph.query.plan.PlanNode;
+import org.jboss.dna.graph.query.process.AbstractAccessComponent;
+import org.jboss.dna.graph.query.process.ProcessingComponent;
+import org.jboss.dna.graph.query.process.SelectComponent.Analyzer;
+import org.jboss.dna.graph.request.ChangeRequest;
+
+/**
+ * An {@link IndexStrategy} implementation that stores all content within a set of two
indexes: one for the node content and a
+ * second one for paths and UUIDs.
+ */
+@ThreadSafe
+class KitchenSinkIndexStrategy extends DualIndexStrategy {
+
+ /**
+ * The default set of {@link IndexRules} used by {@link KitchenSinkIndexStrategy}
instances when no rules are provided.
+ */
+ public static final IndexRules DEFAULT_RULES;
+
+ static {
+ IndexRules.Builder builder = IndexRules.createBuilder();
+ // Configure the default behavior ...
+ builder.defaultTo(IndexRules.INDEX | IndexRules.ANALYZE);
+ // Configure the UUID properties to be just indexed (not stored, not analyzed,
not included in full-text) ...
+ builder.index(JcrLexicon.UUID, DnaLexicon.UUID);
+ // Configure the properties that we'll treat as dates ...
+ builder.treatAsDates(JcrLexicon.CREATED, JcrLexicon.LAST_MODIFIED);
+ DEFAULT_RULES = builder.build();
+ }
+
+ /**
+ * Create a new indexing strategy instance uses the {@link #DEFAULT_RULES default
indexing rules}.
+ */
+ public KitchenSinkIndexStrategy() {
+ this(null);
+ }
+
+ /**
+ * Create a new indexing strategy instance.
+ *
+ * @param rules the indexing rules that govern how properties are to be index, or
null if the {@link #DEFAULT_RULES default
+ * rules} are to be used
+ */
+ public KitchenSinkIndexStrategy( IndexRules rules ) {
+ super(rules != null ? rules : DEFAULT_RULES);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.search.DualIndexStrategy#createAccessComponent(org.jboss.dna.search.SearchContext,
+ * org.jboss.dna.graph.query.plan.PlanNode,
org.jboss.dna.graph.query.QueryResults.Columns,
+ * org.jboss.dna.graph.query.process.SelectComponent.Analyzer)
+ */
+ @Override
+ protected ProcessingComponent createAccessComponent( final SearchContext context,
+ PlanNode accessNode,
+ Columns resultColumns,
+ Analyzer analyzer ) {
+ // Create a processing component for this access query ...
+ return new AbstractAccessComponent(context, resultColumns, accessNode) {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.process.ProcessingComponent#execute()
+ */
+ @Override
+ public List<Object[]> execute() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.search.IndexStrategy#apply(Iterable, IndexContext)
+ */
+ public int apply( Iterable<ChangeRequest> changes,
+ IndexContext indexes ) /*throws IOException*/{
+ for (ChangeRequest change : changes) {
+ if (change != null) continue;
+ }
+ return 0;
+ }
+}
Property changes on:
trunk/dna-search/src/main/java/org/jboss/dna/search/KitchenSinkIndexStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryComponent.java
===================================================================
---
trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryComponent.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryComponent.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,57 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.search;
-
-import java.util.List;
-import org.jboss.dna.graph.query.QueryContext;
-import org.jboss.dna.graph.query.QueryResults.Columns;
-import org.jboss.dna.graph.query.plan.PlanNode;
-import org.jboss.dna.graph.query.process.ProcessingComponent;
-
-/**
- * A {@link ProcessingComponent} implementation that is used by the {@link
LuceneQueryEngine.LuceneProcessor} to perform atomic
- * queries against the Lucene indexes.
- */
-class LuceneQueryComponent extends ProcessingComponent {
-
- private final PlanNode accessNode;
-
- LuceneQueryComponent( QueryContext context,
- Columns columns,
- PlanNode accessNode ) {
- super(context, columns);
- this.accessNode = accessNode;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.query.process.ProcessingComponent#execute()
- */
- @Override
- public List<Object[]> execute() {
- if (accessNode != null) return null;
- return null;
- }
-}
Deleted: trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,114 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.search;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import org.apache.lucene.queryParser.ParseException;
-import org.jboss.dna.graph.query.QueryContext;
-import org.jboss.dna.graph.query.QueryEngine;
-import org.jboss.dna.graph.query.QueryResults;
-import org.jboss.dna.graph.query.QueryResults.Columns;
-import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.optimize.Optimizer;
-import org.jboss.dna.graph.query.optimize.OptimizerRule;
-import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
-import org.jboss.dna.graph.query.plan.CanonicalPlanner;
-import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.plan.PlanNode;
-import org.jboss.dna.graph.query.process.ProcessingComponent;
-import org.jboss.dna.graph.query.process.QueryProcessor;
-import org.jboss.dna.graph.query.process.SelectComponent.Analyzer;
-import org.jboss.dna.graph.query.validate.Schemata;
-
-/**
- *
- */
-class LuceneQueryEngine {
-
- private QueryEngine engine;
-
- public LuceneQueryEngine() {
- engine = new QueryEngine(new CanonicalPlanner(), new LuceneOptimizer(), new
LuceneProcessor());
- }
-
- /**
- * Execute the supplied query by planning, optimizing, and then processing it.
- *
- * @param query the query that is to be executed
- * @param schemata the schemata that defines the tables used in the query
- * @param indexes the indexes that should be used to execute the query; never null
- * @return the query results; never null
- * @throws IllegalArgumentException if the context or query references are null
- * @throws IOException if there is a problem indexing or using the writers
- * @throws ParseException if there is a problem parsing the query
- */
- public QueryResults execute( QueryCommand query,
- Schemata schemata,
- IndexContext indexes ) throws IOException,
ParseException {
- return engine.execute(indexes.context(), query, schemata, new PlanHints());
- }
-
- /**
- * An {@link Optimizer} implementation that specializes the {@link
RuleBasedOptimizer} by using custom rules.
- */
- protected static class LuceneOptimizer extends RuleBasedOptimizer {
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.query.optimize.RuleBasedOptimizer#populateRuleStack(java.util.LinkedList,
- * org.jboss.dna.graph.query.plan.PlanHints)
- */
- @Override
- protected void populateRuleStack( LinkedList<OptimizerRule> ruleStack,
- PlanHints hints ) {
- super.populateRuleStack(ruleStack, hints);
- // Add any custom rules here, either at the front of the stack or at the end
- }
- }
-
- /**
- * A query processor that operates against Lucene indexes. All functionality is
inherited from the {@link QueryProcessor},
- * except for the creation of the {@link ProcessingComponent} that does the low-level
atomic queries (against the Lucene
- * indexes).
- */
- protected static class LuceneProcessor extends QueryProcessor {
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.query.process.QueryProcessor#createAccessComponent(org.jboss.dna.graph.query.QueryContext,
- * org.jboss.dna.graph.query.plan.PlanNode,
org.jboss.dna.graph.query.QueryResults.Columns,
- * org.jboss.dna.graph.query.process.SelectComponent.Analyzer)
- */
- @Override
- protected ProcessingComponent createAccessComponent( QueryContext context,
- PlanNode accessNode,
- Columns resultColumns,
- Analyzer analyzer ) {
- return new LuceneQueryComponent(context, resultColumns, accessNode);
- }
- }
-}
Added: trunk/dna-search/src/main/java/org/jboss/dna/search/SearchContext.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/SearchContext.java
(rev 0)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/SearchContext.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -0,0 +1,161 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.search;
+
+import java.util.Map;
+import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.plan.PlanHints;
+import org.jboss.dna.graph.query.validate.Schemata;
+
+/**
+ *
+ */
+class SearchContext extends QueryContext {
+
+ private final IndexContext indexes;
+
+ /**
+ * Create a new context for searching and querying.
+ *
+ * @param indexes the indexes that should be used
+ * @param schemata the definition of the tables available to this query
+ */
+ public SearchContext( IndexContext indexes,
+ Schemata schemata ) {
+ super(indexes.context(), schemata);
+ this.indexes = indexes;
+ assert this.indexes != null;
+ }
+
+ /**
+ * Create a new context for searching and querying.
+ *
+ * @param queryContext
+ * @param indexes
+ */
+ public SearchContext( QueryContext queryContext,
+ IndexContext indexes ) {
+ super(queryContext.getExecutionContext(), queryContext.getSchemata(),
queryContext.getHints(),
+ queryContext.getProblems(), queryContext.getVariables());
+ this.indexes = indexes;
+ assert this.indexes != null;
+ }
+
+ /**
+ * Create a new context for searching and querying.
+ *
+ * @param context the execution context
+ * @param schemata the schemata
+ * @param hints the hints, or null if there are no hints
+ * @param problems the problems container, or null if a new problems container should
be created
+ * @param variables the mapping of variables and values, or null if there are no such
variables
+ * @throws IllegalArgumentException if the context or schmata are null
+ */
+ public SearchContext( IndexContext context,
+ Schemata schemata,
+ PlanHints hints,
+ Problems problems,
+ Map<String, Object> variables ) {
+ super(context.context(), schemata, hints, problems, variables);
+ this.indexes = context;
+ assert this.indexes != null;
+ }
+
+ /**
+ * Get the {@link IndexContext} for this query context.
+ *
+ * @return the index context; never null
+ */
+ public IndexContext getIndexes() {
+ return indexes;
+ }
+
+ /**
+ * Obtain a copy of this context, except that the copy uses the supplied index
context.
+ *
+ * @param context the index context that should be used in the new query context
+ * @return the new context; never null
+ * @throws IllegalArgumentException if the index context reference is null
+ */
+ public SearchContext with( IndexContext context ) {
+ CheckArg.isNotNull(context, "context");
+ return new SearchContext(context, getSchemata(), getHints(), getProblems(),
getVariables());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.QueryContext#with(org.jboss.dna.graph.ExecutionContext)
+ */
+ @Override
+ public SearchContext with( ExecutionContext context ) {
+ CheckArg.isNotNull(context, "context");
+ return new SearchContext(indexes.with(context), getSchemata(), getHints(),
getProblems(), getVariables());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.QueryContext#with(org.jboss.dna.graph.query.validate.Schemata)
+ */
+ @Override
+ public SearchContext with( Schemata schemata ) {
+ CheckArg.isNotNull(schemata, "schemata");
+ return new SearchContext(indexes, schemata, getHints(), getProblems(),
getVariables());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.QueryContext#with(org.jboss.dna.graph.query.plan.PlanHints)
+ */
+ @Override
+ public SearchContext with( PlanHints hints ) {
+ CheckArg.isNotNull(hints, "hints");
+ return new SearchContext(indexes, getSchemata(), hints, getProblems(),
getVariables());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.QueryContext#with(org.jboss.dna.common.collection.Problems)
+ */
+ @Override
+ public SearchContext with( Problems problems ) {
+ return new SearchContext(indexes, getSchemata(), getHints(), problems,
getVariables());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryContext#with(java.util.Map)
+ */
+ @Override
+ public SearchContext with( Map<String, Object> variables ) {
+ return new SearchContext(indexes, getSchemata(), getHints(), getProblems(),
variables);
+ }
+}
Property changes on:
trunk/dna-search/src/main/java/org/jboss/dna/search/SearchContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-search/src/main/java/org/jboss/dna/search/SearchEngine.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/SearchEngine.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/SearchEngine.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -61,7 +61,7 @@
private final String sourceName;
private final RepositoryConnectionFactory connectionFactory;
private final DirectoryConfiguration directoryFactory;
- private final IndexingStrategy indexingStrategy;
+ private final IndexStrategy indexStrategy;
private final PathFactory pathFactory;
@GuardedBy( "workspaceEngineLock" )
private final Map<String, WorkspaceSearchEngine> workspaceEnginesByName;
@@ -76,15 +76,12 @@
* @param sourceName the name of the {@link RepositorySource}
* @param connectionFactory the connection factory
* @param directoryFactory the factory for Lucene {@link Directory directories}
- * @param indexingStrategy the indexing strategy that governs how properties are to
be indexed; or null if the default
- * strategy should be used
* @throws IllegalArgumentException if any of the parameters (other than indexing
strategy) are null
*/
public SearchEngine( ExecutionContext context,
String sourceName,
RepositoryConnectionFactory connectionFactory,
- DirectoryConfiguration directoryFactory,
- IndexingStrategy indexingStrategy ) {
+ DirectoryConfiguration directoryFactory ) {
CheckArg.isNotNull(context, "context");
CheckArg.isNotNull(sourceName, "sourceName");
CheckArg.isNotNull(connectionFactory, "connectionFactory");
@@ -95,7 +92,7 @@
this.context = context;
this.pathFactory = context.getValueFactories().getPathFactory();
this.workspaceEnginesByName = new HashMap<String,
WorkspaceSearchEngine>();
- this.indexingStrategy = indexingStrategy != null ? indexingStrategy : new
StoreLittleIndexingStrategy();
+ this.indexStrategy = new KitchenSinkIndexStrategy();
}
/**
@@ -153,7 +150,7 @@
engine = workspaceEnginesByName.get(workspaceName);
if (engine == null) {
// Create the engine and register it ...
- engine = new WorkspaceSearchEngine(context, directoryFactory,
indexingStrategy, sourceName, workspaceName,
+ engine = new WorkspaceSearchEngine(context, directoryFactory,
indexStrategy, sourceName, workspaceName,
connectionFactory);
workspaceEnginesByName.put(workspaceName, engine);
}
Deleted:
trunk/dna-search/src/main/java/org/jboss/dna/search/StoreLittleIndexingStrategy.java
===================================================================
---
trunk/dna-search/src/main/java/org/jboss/dna/search/StoreLittleIndexingStrategy.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-search/src/main/java/org/jboss/dna/search/StoreLittleIndexingStrategy.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -1,372 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.search;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import java.util.UUID;
-import net.jcip.annotations.ThreadSafe;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldSelector;
-import org.apache.lucene.document.FieldSelectorResult;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queryParser.ParseException;
-import org.apache.lucene.queryParser.QueryParser;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.PrefixQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.util.Version;
-import org.jboss.dna.common.text.NoOpEncoder;
-import org.jboss.dna.common.text.TextEncoder;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.graph.DnaLexicon;
-import org.jboss.dna.graph.JcrLexicon;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.Node;
-import org.jboss.dna.graph.property.Binary;
-import org.jboss.dna.graph.property.DateTime;
-import org.jboss.dna.graph.property.DateTimeFactory;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.ValueFactory;
-import org.jboss.dna.graph.query.QueryResults;
-import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.validate.Schemata;
-import org.jboss.dna.graph.request.ChangeRequest;
-import org.jboss.dna.search.IndexingRules.Rule;
-
-/**
- * A simple {@link IndexingStrategy} implementation that relies upon very few fields to
be stored in the indexes.
- */
-@ThreadSafe
-class StoreLittleIndexingStrategy implements IndexingStrategy {
-
- static class PathIndex {
- public static final String PATH = "path";
- public static final String UUID = "uuid";
- }
-
- static class ContentIndex {
- public static final String UUID = PathIndex.UUID;
- public static final String FULL_TEXT = "fts";
- }
-
- public static final int SIZE_OF_DELETE_BATCHES = 100;
-
- private ThreadLocal<DateFormat> dateFormatter = new
ThreadLocal<DateFormat>() {
- @Override
- protected DateFormat initialValue() {
- return new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
- }
- };
-
- private static final FieldSelector UUID_FIELD_SELECTOR = new FieldSelector() {
- private static final long serialVersionUID = 1L;
-
- public FieldSelectorResult accept( String fieldName ) {
- return PathIndex.UUID.equals(fieldName) ? FieldSelectorResult.LOAD_AND_BREAK
: FieldSelectorResult.NO_LOAD;
- }
- };
-
- /**
- * The default set of {@link IndexingRules} used by {@link
StoreLittleIndexingStrategy} instances when no rules are provided.
- */
- public static final IndexingRules DEFAULT_RULES;
-
- static {
- IndexingRules.Builder builder = IndexingRules.createBuilder();
- // Configure the default behavior ...
- builder.defaultTo(IndexingRules.INDEX | IndexingRules.ANALYZE);
- // Configure the UUID properties to be just indexed (not stored, not analyzed,
not included in full-text) ...
- builder.index(JcrLexicon.UUID, DnaLexicon.UUID);
- // Configure the properties that we'll treat as dates ...
- builder.treatAsDates(JcrLexicon.CREATED, JcrLexicon.LAST_MODIFIED);
- DEFAULT_RULES = builder.build();
- }
-
- private final IndexingRules rules;
- private final Logger logger;
- private final LuceneQueryEngine queryEngine;
-
- /**
- * Create a new indexing strategy instance that does not support queries.
- */
- public StoreLittleIndexingStrategy() {
- this(null);
- }
-
- /**
- * Create a new indexing strategy instance.
- *
- * @param rules the indexing rules that govern how properties are to be index, or
null if the {@link #DEFAULT_RULES default
- * rules} are to be used
- */
- public StoreLittleIndexingStrategy( IndexingRules rules ) {
- this.rules = rules != null ? rules : DEFAULT_RULES;
- this.logger = Logger.getLogger(getClass());
- this.queryEngine = new LuceneQueryEngine();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingStrategy#getNamespaceEncoder()
- */
- public TextEncoder getNamespaceEncoder() {
- return new NoOpEncoder();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.search.IndexingStrategy#getChangeCountForAutomaticOptimization()
- */
- public int getChangeCountForAutomaticOptimization() {
- return 0;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingStrategy#createAnalyzer()
- */
- public Analyzer createAnalyzer() {
- return new StandardAnalyzer(Version.LUCENE_CURRENT);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Because this strategy uses multiple indexes, and since there's no correlation
between the documents in those indexes, we
- * need to perform the delete in multiple steps. First, we need to perform a query to
find out which nodes exist below a
- * certain path. Then, we need to delete those nodes from the paths index. Finally,
we need to delete the corresponding
- * documents in the content index that represent those same nodes.
- * </p>
- * <p>
- * Since we don't know how many documents there will be, we perform these steps
in batches, where each batch limits the number
- * of results to a maximum number. We repeat batches as long as we find more results.
This approach has the advantage that
- * we'll never bring in a large number of results, and it allows us to delete the
documents from the content node using a
- * query.
- * </p>
- *
- * @see org.jboss.dna.search.IndexingStrategy#deleteBelow(Path, IndexContext)
- */
- public int deleteBelow( Path path,
- IndexContext indexes ) throws IOException {
- // Perform a query using the reader to find those nodes at/below the path ...
- try {
- IndexReader pathReader = indexes.getPathsReader();
- IndexSearcher pathSearcher = new IndexSearcher(pathReader);
- String pathStr = indexes.stringFactory().create(path) + "/";
- PrefixQuery query = new PrefixQuery(new Term(PathIndex.PATH, pathStr));
- int numberDeleted = 0;
- while (true) {
- // Execute the query and get the results ...
- TopDocs results = pathSearcher.search(query, SIZE_OF_DELETE_BATCHES);
- int numResultsInBatch = results.scoreDocs.length;
- // Walk the results, delete the doc, and add to the query that we'll
use against the content index ...
- IndexReader contentReader = indexes.getContentReader();
- for (ScoreDoc result : results.scoreDocs) {
- int docId = result.doc;
- // Find the UUID of the node ...
- Document doc = pathReader.document(docId, UUID_FIELD_SELECTOR);
- String uuid = doc.get(PathIndex.UUID);
- // Delete the document from the paths index ...
- pathReader.deleteDocument(docId);
- // Delete the corresponding document from the content index ...
- contentReader.deleteDocuments(new Term(ContentIndex.UUID, uuid));
- }
- numberDeleted += numResultsInBatch;
- if (numResultsInBatch < SIZE_OF_DELETE_BATCHES) break;
- }
- indexes.commit();
- return numberDeleted;
- } catch (FileNotFoundException e) {
- // There are no index files yet, so nothing to delete ...
- return 0;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingStrategy#index(Node, IndexContext)
- */
- public void index( Node node,
- IndexContext indexes ) throws IOException {
- ValueFactory<String> strings = indexes.stringFactory();
- Location location = node.getLocation();
- UUID uuid = location.getUuid();
- if (uuid == null) uuid = UUID.randomUUID();
- Path path = location.getPath();
- String pathStr = path.isRoot() ? "/" :
strings.create(location.getPath()) + "/";
- String uuidStr = uuid.toString();
-
- if (logger.isTraceEnabled()) {
- logger.trace("indexing {0}", pathStr);
- }
-
- // Create a separate document for the path, which makes it easier to handle moves
since the path can
- // be changed without changing any other content fields ...
- Document doc = new Document();
- doc.add(new Field(PathIndex.PATH, pathStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
- doc.add(new Field(PathIndex.UUID, uuidStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
- indexes.getPathsWriter().addDocument(doc);
-
- // Create the document for the content (properties) ...
- doc = new Document();
- doc.add(new Field(ContentIndex.UUID, uuidStr, Field.Store.YES,
Field.Index.NOT_ANALYZED));
- String stringValue = null;
- StringBuilder fullTextSearchValue = null;
- for (Property property : node.getProperties()) {
- Name name = property.getName();
- Rule rule = rules.getRule(name);
- if (rule.isSkipped()) continue;
- String nameString = strings.create(name);
- if (rule.isDate()) {
- DateTimeFactory dateFactory = indexes.dateFactory();
- for (Object value : property) {
- if (value == null) continue;
- DateTime dateValue = dateFactory.create(value);
- stringValue = dateFormatter.get().format(dateValue.toDate());
- // Add a separate field for each property value ...
- doc.add(new Field(nameString, stringValue, rule.getStoreOption(),
rule.getIndexOption()));
- // Dates are not added to the full-text search field (since this
wouldn't make sense)
- }
- continue;
- }
- for (Object value : property) {
- if (value == null) continue;
- if (value instanceof Binary) {
- // don't include binary values as individual fields but do
include them in the full-text search ...
- // TODO : add to full-text search ...
- continue;
- }
- stringValue = strings.create(value);
- // Add a separate field for each property value ...
- doc.add(new Field(nameString, stringValue, rule.getStoreOption(),
rule.getIndexOption()));
- // And add to the full-text field ...
- if (rule.isFullText()) {
- if (fullTextSearchValue == null) {
- fullTextSearchValue = new StringBuilder();
- } else {
- fullTextSearchValue.append(' ');
- }
- fullTextSearchValue.append(stringValue);
- }
- }
- }
- // Add the full-text-search field ...
- if (fullTextSearchValue != null) {
- doc.add(new Field(ContentIndex.FULL_TEXT, fullTextSearchValue.toString(),
Field.Store.NO, Field.Index.ANALYZED));
- }
- indexes.getContentWriter().addDocument(doc);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingStrategy#performQuery(String, int, int,
IndexContext, List)
- */
- public void performQuery( String fullTextString,
- int maxResults,
- int offset,
- IndexContext indexes,
- List<Location> results ) throws IOException,
ParseException {
- assert fullTextString != null;
- assert fullTextString.length() > 0;
- assert offset >= 0;
- assert maxResults > 0;
- assert indexes != null;
- assert results != null;
-
- // Parse the full-text search and search against the 'fts' field ...
- QueryParser parser = new QueryParser(ContentIndex.FULL_TEXT, createAnalyzer());
- Query query = parser.parse(fullTextString);
- TopDocs docs = indexes.getContentSearcher().search(query, maxResults + offset);
-
- // Collect the results ...
- IndexReader contentReader = indexes.getContentReader();
- IndexReader pathReader = indexes.getPathsReader();
- IndexSearcher pathSearcher = indexes.getPathsSearcher();
- ScoreDoc[] scoreDocs = docs.scoreDocs;
- int numberOfResults = scoreDocs.length;
- if (numberOfResults > offset) {
- // There are enough results to satisfy the offset ...
- for (int i = offset, num = scoreDocs.length; i != num; ++i) {
- ScoreDoc result = scoreDocs[i];
- int docId = result.doc;
- // Find the UUID of the node (this UUID might be artificial, so we have
to find the path) ...
- Document doc = contentReader.document(docId, UUID_FIELD_SELECTOR);
- String uuid = doc.get(ContentIndex.UUID);
- // Find the path for this node (is there a better way to do this than one
search per UUID?) ...
- TopDocs pathDocs = pathSearcher.search(new TermQuery(new
Term(PathIndex.UUID, uuid)), 1);
- if (pathDocs.scoreDocs.length < 1) {
- // No path record found ...
- continue;
- }
- Document pathDoc = pathReader.document(pathDocs.scoreDocs[0].doc);
- Path path = indexes.pathFactory().create(pathDoc.get(PathIndex.PATH));
- // Now add the location ...
- results.add(Location.create(path, UUID.fromString(uuid)));
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.search.IndexingStrategy#performQuery(org.jboss.dna.graph.query.model.QueryCommand,
- * org.jboss.dna.graph.query.validate.Schemata,
org.jboss.dna.search.IndexContext)
- */
- public QueryResults performQuery( QueryCommand query,
- Schemata schemata,
- IndexContext indexes ) throws IOException,
ParseException {
- return this.queryEngine.execute(query, schemata, indexes);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.search.IndexingStrategy#apply(Iterable, IndexContext)
- */
- public int apply( Iterable<ChangeRequest> changes,
- IndexContext indexes ) /*throws IOException*/{
- for (ChangeRequest change : changes) {
- if (change != null) continue;
- }
- return 0;
- }
-}
Modified: trunk/dna-search/src/main/java/org/jboss/dna/search/WorkspaceSearchEngine.java
===================================================================
---
trunk/dna-search/src/main/java/org/jboss/dna/search/WorkspaceSearchEngine.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-search/src/main/java/org/jboss/dna/search/WorkspaceSearchEngine.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -55,7 +55,7 @@
* A search engine dedicated to a single workspace.
*/
@ThreadSafe
-public class WorkspaceSearchEngine {
+class WorkspaceSearchEngine {
protected static final String PATHS_INDEX_NAME = "paths";
protected static final String CONTENT_INDEX_NAME = "content";
@@ -67,7 +67,7 @@
private final String sourceName;
private final String workspaceName;
private final RepositoryConnectionFactory connectionFactory;
- private final IndexingStrategy indexingStrategy;
+ private final IndexStrategy indexingStrategy;
protected final AtomicInteger modifiedNodesSinceLastOptimize = new AtomicInteger(0);
/**
@@ -86,7 +86,7 @@
*/
protected WorkspaceSearchEngine( ExecutionContext context,
DirectoryConfiguration directoryFactory,
- IndexingStrategy indexingStrategy,
+ IndexStrategy indexingStrategy,
String sourceName,
String workspaceName,
RepositoryConnectionFactory connectionFactory )
throws SearchEngineException {
@@ -168,7 +168,7 @@
return context.getValueFactories().getStringFactory().create(path);
}
- final IndexingStrategy strategy() {
+ final IndexStrategy strategy() {
return indexingStrategy;
}
@@ -523,7 +523,7 @@
final List<Location> results = new ArrayList<Location>(maxResults);
return new Search() {
public void execute( IndexContext indexes ) throws IOException,
ParseException {
- strategy().performQuery(fullTextSearch, maxResults, offset, indexes,
results);
+ strategy().search(fullTextSearch, maxResults, offset, indexes, results);
}
public String messageFor( Throwable error ) {
@@ -550,9 +550,11 @@
final Schemata schemata ) {
return new Query() {
private QueryResults results = null;
+ private SearchContext context = null;
- public void execute( IndexContext indexes ) throws IOException,
ParseException {
- results = strategy().performQuery(query, schemata, indexes);
+ public void execute( IndexContext indexes ) {
+ context = new SearchContext(indexes, schemata);
+ results = strategy().query(context, query);
}
public String messageFor( Throwable error ) {
Modified: trunk/dna-search/src/test/java/org/jboss/dna/search/IndexingRulesTest.java
===================================================================
--- trunk/dna-search/src/test/java/org/jboss/dna/search/IndexingRulesTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/test/java/org/jboss/dna/search/IndexingRulesTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -25,7 +25,7 @@
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
-import org.jboss.dna.search.IndexingRules.Builder;
+import org.jboss.dna.search.IndexRules.Builder;
import org.junit.Before;
import org.junit.Test;
@@ -35,23 +35,23 @@
public class IndexingRulesTest {
private Builder builder;
- private IndexingRules rules;
+ private IndexRules rules;
@Before
public void beforeEach() {
- builder = IndexingRules.createBuilder();
+ builder = IndexRules.createBuilder();
rules = builder.build();
}
@Test
public void shouldBuildValidRulesFromBuilderThatIsNotInvoked() {
- builder = IndexingRules.createBuilder();
+ builder = IndexRules.createBuilder();
rules = builder.build();
}
@Test
public void shouldBuildValidRulesFromBuilderAfterJustSettingDefaultRules() {
- builder.defaultTo(IndexingRules.FULL_TEXT);
+ builder.defaultTo(IndexRules.FULL_TEXT);
rules = builder.build();
assertThat(rules.getRule(null).isFullText(), is(true));
}
Modified: trunk/dna-search/src/test/java/org/jboss/dna/search/SearchEngineTest.java
===================================================================
--- trunk/dna-search/src/test/java/org/jboss/dna/search/SearchEngineTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++ trunk/dna-search/src/test/java/org/jboss/dna/search/SearchEngineTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -48,7 +48,6 @@
private InMemoryRepositorySource source;
private RepositoryConnectionFactory connectionFactory;
private DirectoryConfiguration directoryFactory;
- private IndexingStrategy indexingStrategy;
private Graph content;
@Before
@@ -81,15 +80,9 @@
}
};
- // Set up the indexing strategy ...
- IndexingRules rules =
IndexingRules.createBuilder(StoreLittleIndexingStrategy.DEFAULT_RULES)
- .defaultTo(IndexingRules.INDEX |
IndexingRules.ANALYZE | IndexingRules.FULL_TEXT)
- .build();
- indexingStrategy = new StoreLittleIndexingStrategy(rules);
-
// Now set up the search engine ...
directoryFactory = DirectoryConfigurations.inMemory();
- engine = new SearchEngine(context, sourceName, connectionFactory,
directoryFactory, indexingStrategy);
+ engine = new SearchEngine(context, sourceName, connectionFactory,
directoryFactory);
}
protected Path path( String string ) {
Modified:
trunk/dna-search/src/test/java/org/jboss/dna/search/WorkspaceSearchEngineTest.java
===================================================================
---
trunk/dna-search/src/test/java/org/jboss/dna/search/WorkspaceSearchEngineTest.java 2009-11-16
23:23:02 UTC (rev 1318)
+++
trunk/dna-search/src/test/java/org/jboss/dna/search/WorkspaceSearchEngineTest.java 2009-11-16
23:24:06 UTC (rev 1319)
@@ -47,7 +47,7 @@
private InMemoryRepositorySource source;
private RepositoryConnectionFactory connectionFactory;
private DirectoryConfiguration directoryFactory;
- private IndexingStrategy indexingStrategy;
+ private IndexStrategy indexingStrategy;
private Graph content;
@Before
@@ -74,10 +74,10 @@
};
// Set up the indexing strategy ...
- IndexingRules rules =
IndexingRules.createBuilder(StoreLittleIndexingStrategy.DEFAULT_RULES)
- .defaultTo(IndexingRules.INDEX |
IndexingRules.ANALYZE | IndexingRules.FULL_TEXT)
+ IndexRules rules =
IndexRules.createBuilder(KitchenSinkIndexStrategy.DEFAULT_RULES)
+ .defaultTo(IndexRules.INDEX |
IndexRules.ANALYZE | IndexRules.FULL_TEXT)
.build();
- indexingStrategy = new StoreLittleIndexingStrategy(rules);
+ indexingStrategy = new KitchenSinkIndexStrategy(rules);
// Now set up the search engine ...
directoryFactory = DirectoryConfigurations.inMemory();