You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/12/20 12:13:04 UTC
svn commit: r357961 - in /incubator/jackrabbit/trunk/jackrabbit: ./
applications/test/ applications/test/repository/
applications/test/workspaces/default/ applications/test/workspaces/test/
src/main/config/ src/main/java/org/apache/jackrabbit/core/ src...
Author: mreutegg
Date: Tue Dec 20 03:12:39 2005
New Revision: 357961
URL: http://svn.apache.org/viewcvs?rev=357961&view=rev
Log:
JCR-257: Use separate index for jcr:system tree
Added:
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java (with props)
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java (with props)
Modified:
incubator/jackrabbit/trunk/jackrabbit/ (props changed)
incubator/jackrabbit/trunk/jackrabbit/applications/test/ (props changed)
incubator/jackrabbit/trunk/jackrabbit/applications/test/repository/ (props changed)
incubator/jackrabbit/trunk/jackrabbit/applications/test/repository.xml
incubator/jackrabbit/trunk/jackrabbit/applications/test/workspaces/default/ (props changed)
incubator/jackrabbit/trunk/jackrabbit/applications/test/workspaces/test/ (props changed)
incubator/jackrabbit/trunk/jackrabbit/src/main/config/repository.xml
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandler.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
Propchange: incubator/jackrabbit/trunk/jackrabbit/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Dec 20 03:12:39 2005
@@ -0,0 +1,5 @@
+target
+*.log
+*.iws
+*.ipr
+*.iml
Propchange: incubator/jackrabbit/trunk/jackrabbit/applications/test/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Dec 20 03:12:39 2005
@@ -2,3 +2,4 @@
tx
version
*.log
+.lock
Propchange: incubator/jackrabbit/trunk/jackrabbit/applications/test/repository/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Dec 20 03:12:39 2005
@@ -1,2 +1,3 @@
meta
namespaces
+index
Modified: incubator/jackrabbit/trunk/jackrabbit/applications/test/repository.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/applications/test/repository.xml?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/applications/test/repository.xml (original)
+++ incubator/jackrabbit/trunk/jackrabbit/applications/test/repository.xml Tue Dec 20 03:12:39 2005
@@ -24,13 +24,13 @@
no workspace yet and for creating additional workspaces through
the api
- a SearchIndex element that is used for configuring per workspace
- Indexing-related settings
-
a Versioning element that is used for configuring
versioning-related settings
+
+ a SearchIndex element that is used for configuring Indexing-related
+ settings on the /jcr:system tree.
-->
- <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning)>
+ <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning,SearchIndex?)>
<!--
a virtual file system
@@ -207,6 +207,13 @@
<param name="url" value="jdbc:derby:${rep.home}/version/db;create=true"/>
<param name="schemaObjectPrefix" value="version_"/>
</PersistenceManager>
-
</Versioning>
+
+ <!--
+ Search index for content that is shared repository wide
+ (/jcr:system tree, contains mainly versions)
+ -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/repository/index"/>
+ </SearchIndex>
</Repository>
Propchange: incubator/jackrabbit/trunk/jackrabbit/applications/test/workspaces/default/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Dec 20 03:12:39 2005
@@ -1,4 +1,4 @@
blobs
-data
+db
index
locks
Propchange: incubator/jackrabbit/trunk/jackrabbit/applications/test/workspaces/test/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Dec 20 03:12:39 2005
@@ -1,4 +1,4 @@
blobs
-data
+db
index
locks
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/config/repository.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/config/repository.xml?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/config/repository.xml (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/config/repository.xml Tue Dec 20 03:12:39 2005
@@ -26,13 +26,13 @@
no workspace yet and for creating additional workspaces through
the api
- a SearchIndex element that is used for configuring per workspace
- Indexing-related settings
-
a Versioning element that is used for configuring
versioning-related settings
+
+ a SearchIndex element that is used for configuring Indexing-related
+ settings on the /jcr:system tree.
-->
- <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning)>
+ <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning,SearchIndex?)>
<!--
a virtual file system
@@ -258,4 +258,19 @@
</PersistenceManager>
</Versioning>
+
+ <!--
+ Search index for content that is shared repository wide
+ (/jcr:system tree, contains mainly versions)
+
+ The same parameters are supported as in the search index configuration
+ inside the workspace definition element.
+
+ This element is optional. If omitted, the /jcr:system tree will not be
+ indexed and no results will be returned for that tree!
+ -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/repository/index"/>
+ </SearchIndex>
+
</Repository>
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Tue Dec 20 03:12:39 2005
@@ -41,6 +41,7 @@
import org.apache.jackrabbit.core.version.VersionManager;
import org.apache.jackrabbit.core.version.VersionManagerImpl;
import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
import org.apache.jackrabbit.uuid.UUID;
import org.apache.log4j.Logger;
@@ -55,6 +56,7 @@
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
import javax.security.auth.Subject;
import java.io.File;
import java.io.IOException;
@@ -116,6 +118,12 @@
private final VersionManager vMgr;
private final VirtualNodeTypeStateManager virtNTMgr;
+ /**
+ * Search manager for the jcr:system tree. May be <code>null</code> if
+ * none is configured.
+ */
+ private SearchManager systemSearchMgr;
+
// configuration of the repository
protected final RepositoryConfig repConfig;
@@ -493,6 +501,33 @@
delegatingDispatcher.addDispatcher(getObservationManagerFactory(wspName));
}
+ /**
+ * Returns the system search manager or <code>null</code> if none is
+ * configured.
+ */
+ private SearchManager getSystemSearchManager(String wspName) throws RepositoryException {
+ if (systemSearchMgr == null) {
+ try {
+ if (repConfig.getSearchConfig() != null) {
+ SystemSession defSysSession = getSystemSession(wspName);
+ systemSearchMgr = new SystemSearchManager(repConfig.getSearchConfig(),
+ nsReg, ntReg, defSysSession.getItemStateManager(), SYSTEM_ROOT_NODE_UUID);
+ ObservationManager obsMgr = defSysSession.getWorkspace().getObservationManager();
+ obsMgr.addEventListener(systemSearchMgr, Event.NODE_ADDED |
+ Event.NODE_REMOVED | Event.PROPERTY_ADDED |
+ Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED,
+ "/" + QName.JCR_SYSTEM.toJCRName(defSysSession.getNamespaceResolver()),
+ true, null, null, false);
+ } else {
+ systemSearchMgr = null;
+ }
+ } catch (NoPrefixDeclaredException e) {
+ throw new RepositoryException(e);
+ }
+ }
+ return systemSearchMgr;
+ }
+
NamespaceRegistryImpl getNamespaceRegistry() {
// check sanity of this instance
sanityCheck();
@@ -724,6 +759,11 @@
wspInfo.dispose();
}
+ // shutdown system search manager if there is one
+ if (systemSearchMgr != null) {
+ systemSearchMgr.close();
+ }
+
try {
vMgr.close();
} catch (Exception e) {
@@ -1256,10 +1296,13 @@
// no search index configured
return null;
}
- searchMgr = new SearchManager(getSystemSession(),
- config.getSearchConfig(),
+ searchMgr = new SearchManager(config.getSearchConfig(),
+ nsReg,
ntReg,
- getItemStateProvider());
+ getItemStateProvider(),
+ rootNodeUUID,
+ getSystemSearchManager(getName()),
+ SYSTEM_ROOT_NODE_UUID);
}
return searchMgr;
}
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java Tue Dec 20 03:12:39 2005
@@ -30,7 +30,10 @@
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.ItemStateManager;
import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
import org.apache.log4j.Logger;
import javax.jcr.NamespaceException;
@@ -97,6 +100,16 @@
private final QueryHandler handler;
/**
+ * Namespace resolver that is based on the namespace registry itself.
+ */
+ private final NamespaceResolver nsResolver;
+
+ /**
+ * Path that will be excluded from indexing.
+ */
+ private Path excludePath;
+
+ /**
* Fully qualified name of the query implementation class.
* This class must extend {@link org.apache.jackrabbit.core.query.AbstractQueryImpl}!
*/
@@ -104,21 +117,47 @@
/**
* Creates a new <code>SearchManager</code>.
- * @param session the system session.
- * @param config the search configuration.
- * @param ntReg the node type registry.
- * @param itemMgr the shared item state manager.
- * @throws RepositoryException
+ *
+ * @param config the search configuration.
+ * @param nsReg the namespace registry.
+ * @param ntReg the node type registry.
+ * @param itemMgr the shared item state manager.
+ * @param rootNodeUUID the uuid of the root node.
+ * @param parentMgr the parent search manager or <code>null</code> if
+ * there is no parent search manager.
+ * @param excludedNodeUUID uuid of the node that should be excluded from
+ * indexing. Any descendant of that node will also
+ * be excluded from indexing.
+ * @throws RepositoryException if the search manager cannot be initialized
*/
- public SearchManager(SessionImpl session,
- SearchConfig config,
+ public SearchManager(SearchConfig config,
+ final NamespaceRegistry nsReg,
NodeTypeRegistry ntReg,
- ItemStateManager itemMgr) throws RepositoryException {
+ ItemStateManager itemMgr,
+ String rootNodeUUID,
+ SearchManager parentMgr,
+ String excludedNodeUUID) throws RepositoryException {
this.fs = config.getFileSystem();
this.itemMgr = itemMgr;
+ this.nsResolver = new AbstractNamespaceResolver() {
+ public String getURI(String prefix) throws NamespaceException {
+ try {
+ return nsReg.getURI(prefix);
+ } catch (RepositoryException e) {
+ throw new NamespaceException(e.getMessage());
+ }
+ }
+
+ public String getPrefix(String uri) throws NamespaceException {
+ try {
+ return nsReg.getPrefix(uri);
+ } catch (RepositoryException e) {
+ throw new NamespaceException(e.getMessage());
+ }
+ }
+ };
// register namespaces
- NamespaceRegistry nsReg = session.getWorkspace().getNamespaceRegistry();
try {
nsReg.getPrefix(NS_XS_URI);
} catch (NamespaceException e) {
@@ -134,12 +173,22 @@
queryImplClassName = config.getParameters().getProperty(PARAM_QUERY_IMPL, DEFAULT_QUERY_IMPL_CLASS);
+ QueryHandler parentHandler = null;
+ if (parentMgr != null) {
+ parentHandler = parentMgr.handler;
+ }
+
+ if (excludedNodeUUID != null) {
+ HierarchyManagerImpl hmgr = new HierarchyManagerImpl(rootNodeUUID, itemMgr, nsResolver);
+ excludePath = hmgr.getPath(new NodeId(excludedNodeUUID));
+ }
+
// initialize query handler
try {
handler = (QueryHandler) config.newInstance();
- NodeId rootId = (NodeId) session.getHierarchyManager().resolvePath(Path.ROOT);
QueryHandlerContext context
- = new QueryHandlerContext(fs, itemMgr, rootId.getUUID(), ntReg);
+ = new QueryHandlerContext(fs, itemMgr, rootNodeUUID, ntReg,
+ parentHandler, excludedNodeUUID);
handler.init(context);
} catch (Exception e) {
throw new RepositoryException(e.getMessage(), e);
@@ -213,6 +262,15 @@
log.debug("onEvent: indexing started");
long time = System.currentTimeMillis();
+ String exclude = "";
+ if (excludePath != null) {
+ try {
+ exclude = excludePath.toJCRPath(nsResolver);
+ } catch (NoPrefixDeclaredException e) {
+ log.error("Error filtering events.", e);
+ }
+ }
+
// nodes that need to be removed from the index.
Set removedNodes = new HashSet();
// nodes that need to be added to the index.
@@ -222,6 +280,13 @@
while (events.hasNext()) {
EventImpl e = (EventImpl) events.nextEvent();
+ try {
+ if (excludePath != null && e.getPath().startsWith(exclude)) {
+ continue;
+ }
+ } catch (RepositoryException ex) {
+ log.error("Error filtering events.", ex);
+ }
long type = e.getType();
if (type == Event.NODE_ADDED) {
addedNodes.add(e.getChildUUID());
Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java?rev=357961&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java Tue Dec 20 03:12:39 2005
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core;
+
+import org.apache.jackrabbit.core.config.SearchConfig;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.state.ItemStateManager;
+import org.apache.jackrabbit.core.observation.EventImpl;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.NamespaceException;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.Event;
+import java.util.NoSuchElementException;
+
+/**
+ * <code>SystemSearchManager</code> implements a search manager for the jcr:system
+ * tree of a workspace.
+ */
+public class SystemSearchManager extends SearchManager {
+
+ /**
+ * The namespace registry of the repository.
+ */
+ private final NamespaceRegistry nsReg;
+
+ /**
+ * A system search manager will only index content that is located under
+ * /jcr:system
+ * @inheritDoc
+ */
+ public SystemSearchManager(SearchConfig config,
+ NamespaceRegistry nsReg,
+ NodeTypeRegistry ntReg,
+ ItemStateManager itemMgr,
+ String rootNodeUUID) throws RepositoryException {
+ super(config, nsReg, ntReg, itemMgr, rootNodeUUID, null, null);
+ this.nsReg = nsReg;
+ }
+
+ /**
+ * Overwrites the implementation of the base class and filters out events
+ * that are not under /jcr:system.
+ *
+ * @param events the original events.
+ */
+ public void onEvent(final EventIterator events) {
+
+ // todo FIXME use namespace resolver of session that registered this
+ // SearchManager as listener?
+ String jcrSystem = "";
+ try {
+ jcrSystem = QName.JCR_SYSTEM.toJCRName(new AbstractNamespaceResolver() {
+ public String getURI(String prefix) throws NamespaceException {
+ try {
+ return nsReg.getURI(prefix);
+ } catch (RepositoryException e) {
+ throw new NamespaceException(e.getMessage());
+ }
+ }
+
+ public String getPrefix(String uri) throws NamespaceException {
+ try {
+ return nsReg.getPrefix(uri);
+ } catch (RepositoryException e) {
+ throw new NamespaceException(e.getMessage());
+ }
+ }
+ });
+ } catch (NoPrefixDeclaredException e) {
+ // will never happen
+ }
+ final String jcrSystemPath = "/" + jcrSystem;
+
+ super.onEvent(new EventIterator() {
+
+ /**
+ * The next pre-fetched event. <code>null</code> if no more
+ * events are available.
+ */
+ private Event nextEvent;
+
+ /**
+ * Current position of this event iterator.
+ */
+ private long position = 0;
+
+ {
+ fetchNext();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public Event nextEvent() {
+ if (nextEvent != null) {
+ Event tmp = nextEvent;
+ fetchNext();
+ return tmp;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void skip(long skipNum) {
+ while (skipNum-- > 0) {
+ nextEvent();
+ }
+ }
+
+ /**
+ * @return always -1
+ */
+ public long getSize() {
+ return -1;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public long getPosition() {
+ return position;
+ }
+
+ /**
+ * @exception UnsupportedOperationException always.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("remove");
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public boolean hasNext() {
+ return nextEvent != null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public Object next() {
+ return nextEvent();
+ }
+
+ /**
+ * Sets the next event.
+ */
+ private void fetchNext() {
+ nextEvent = null;
+ while (nextEvent == null && events.hasNext()) {
+ EventImpl tmp = (EventImpl) events.nextEvent();
+ try {
+ if (tmp.getPath().startsWith(jcrSystemPath)) {
+ nextEvent = tmp;
+ }
+ } catch (RepositoryException e) {
+ // ignore and try next
+ }
+ }
+ }
+ });
+ }
+}
Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SystemSearchManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java Tue Dec 20 03:12:39 2005
@@ -234,9 +234,12 @@
// Versioning configuration
VersioningConfig vc = parseVersioningConfig(root);
+ // Optional search configuration
+ SearchConfig sc = parseSearchConfig(root);
+
return new RepositoryConfig(home, appName, amc, lmc, fsc,
workspaceDirectory, workspaceConfigDirectory, defaultWorkspace,
- template, vc, this);
+ template, vc, sc, this);
}
/**
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java Tue Dec 20 03:12:39 2005
@@ -51,10 +51,11 @@
* create configured repository objects.
* <p>
* The contained configuration information are: the home directory and name
- * of the repository, the access manager, file system, and versioning
- * configurations, the workspace directory, the default workspace name, and
- * the workspace configuration template. In addition the workspace
- * configuration object keeps track of all configured workspaces.
+ * of the repository, the access manager, file system, versioning
+ * configuration, repository index configuration, the workspace directory,
+ * the default workspace name, and the workspace configuration template. In
+ * addition the workspace configuration object keeps track of all configured
+ * workspaces.
*/
public class RepositoryConfig {
@@ -206,6 +207,11 @@
private final VersioningConfig vc;
/**
+ * Optional search configuration for system search manager.
+ */
+ private final SearchConfig sc;
+
+ /**
* Creates a repository configuration object.
*
* @param template workspace configuration template
@@ -218,13 +224,14 @@
* @param workspaceConfigDirectory optional workspace configuration directory
* @param defaultWorkspace name of the default workspace
* @param vc versioning configuration
+ * @param sc search configuration for system search manager.
* @param parser the ConfigurationParser that servers as config factory
*/
RepositoryConfig(String home, String name,
AccessManagerConfig amc, LoginModuleConfig lmc, FileSystemConfig fsc,
String workspaceDirectory, String workspaceConfigDirectory,
String defaultWorkspace, Element template, VersioningConfig vc,
- ConfigurationParser parser) {
+ SearchConfig sc, ConfigurationParser parser) {
this.workspaces = new HashMap();
this.home = home;
this.name = name;
@@ -236,6 +243,7 @@
this.defaultWorkspace = defaultWorkspace;
this.template = template;
this.vc = vc;
+ this.sc = sc;
this.parser = parser;
}
@@ -249,6 +257,9 @@
protected void init() throws ConfigurationException {
fsc.init();
vc.init();
+ if (sc != null) {
+ sc.init();
+ }
// Get the physical workspace root directory (create it if not found)
File directory = new File(workspaceDirectory);
@@ -617,4 +628,13 @@
return vc;
}
+ /**
+ * Returns the system search index configuration. Returns
+ * <code>null</code> if no search index has been configured.
+ *
+ * @return search index configuration, or <code>null</code>
+ */
+ public SearchConfig getSearchConfig() {
+ return sc;
+ }
}
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandler.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandler.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandler.java Tue Dec 20 03:12:39 2005
@@ -43,6 +43,14 @@
void init(QueryHandlerContext context) throws IOException;
/**
+ * Returns the query handler context that passed in {@link
+ * #init(QueryHandlerContext)}.
+ *
+ * @return the query handler context.
+ */
+ QueryHandlerContext getContext();
+
+ /**
* Adds a <code>Node</code> to the search index.
* @param node the NodeState to add.
* @throws RepositoryException if an error occurs while indexing the node.
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java Tue Dec 20 03:12:39 2005
@@ -53,25 +53,44 @@
private final PropertyTypeRegistry propRegistry;
/**
+ * The query handler for the jcr:system tree
+ */
+ private final QueryHandler parentHandler;
+
+ /**
+ * UUID of the node that should be excluded from indexing.
+ */
+ private final String excludedNodeUUID;
+
+ /**
* Creates a new context instance.
*
- * @param fs a {@link FileSystem} this <code>QueryHandler</code> may
- * use to store its index. If no <code>FileSystem</code>
- * has been configured <code>fs</code> is
- * <code>null</code>.
- * @param stateMgr provides persistent item states.
- * @param rootUUID the uuid of the root node.
- * @param ntRegistry the node type registry.
+ * @param fs a {@link FileSystem} this <code>QueryHandler</code>
+ * may use to store its index. If no
+ * <code>FileSystem</code> has been configured
+ * <code>fs</code> is <code>null</code>.
+ * @param stateMgr provides persistent item states.
+ * @param rootUUID the uuid of the root node.
+ * @param ntRegistry the node type registry.
+ * @param parentHandler the parent query handler or <code>null</code> it
+ * there is no parent handler.
+ * @param excludedNodeUUID uuid of the node that should be excluded from
+ * indexing. Any descendant of that node is also
+ * excluded from indexing.
*/
public QueryHandlerContext(FileSystem fs,
ItemStateManager stateMgr,
String rootUUID,
- NodeTypeRegistry ntRegistry) {
+ NodeTypeRegistry ntRegistry,
+ QueryHandler parentHandler,
+ String excludedNodeUUID) {
this.fs = fs;
this.stateMgr = stateMgr;
this.rootUUID = rootUUID;
this.ntRegistry = ntRegistry;
propRegistry = new PropertyTypeRegistry(ntRegistry);
+ this.parentHandler = parentHandler;
+ this.excludedNodeUUID = excludedNodeUUID;
ntRegistry.addListener(propRegistry);
}
@@ -120,6 +139,24 @@
*/
public NodeTypeRegistry getNodeTypeRegistry() {
return ntRegistry;
+ }
+
+ /**
+ * Returns the parent query handler.
+ * @return the parent query handler.
+ */
+ public QueryHandler getParentHandler() {
+ return parentHandler;
+ }
+
+ /**
+ * Returns the uuid of the node that should be excluded from indexing. Any
+ * descendant of this node is also excluded from indexing.
+ *
+ * @return the uuid of the exluded node.
+ */
+ public String getExcludedNodeUUID() {
+ return excludedNodeUUID;
}
/**
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java Tue Dec 20 03:12:39 2005
@@ -83,7 +83,7 @@
*/
public Query createQuery(String statement, String language)
throws InvalidQueryException, RepositoryException {
-
+ sanityCheck();
return searchMgr.createQuery(session, itemMgr, statement, language);
}
@@ -92,7 +92,7 @@
*/
public Query getQuery(Node node)
throws InvalidQueryException, RepositoryException {
-
+ sanityCheck();
return searchMgr.createQuery(session, itemMgr, node);
}
@@ -101,5 +101,18 @@
*/
public String[] getSupportedQueryLanguages() throws RepositoryException {
return (String[]) SUPPORTED_QUERIES_LIST.toArray(new String[SUPPORTED_QUERIES.length]);
+ }
+
+ /**
+ * Checks if this <code>QueryManagerImpl</code> instance is still usable,
+ * otherwise throws a {@link javax.jcr.RepositoryException}.
+ *
+ * @throws RepositoryException if this query manager is not usable anymore,
+ * e.g. the corresponding session is closed.
+ */
+ private void sanityCheck() throws RepositoryException {
+ if (!session.isLive()) {
+ throw new RepositoryException("corresponding session has been closed");
+ }
}
}
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java Tue Dec 20 03:12:39 2005
@@ -28,7 +28,7 @@
* Extends a <code>MultiReader</code> with support for cached <code>TermDocs</code>
* on {@link FieldNames#UUID} field.
*/
-final class CachingMultiReader extends MultiReader {
+public final class CachingMultiReader extends MultiReader implements HierarchyResolver {
/**
* The sub readers.
@@ -90,10 +90,23 @@
* @throws IOException if an error occurs while reading from the index.
*/
final public int getParent(int n) throws IOException {
+ DocId id = getParentDocId(n);
+ return id.getDocumentNumber(this);
+ }
+
+ /**
+ * Returns the DocId of the parent of <code>n</code> or {@link DocId#NULL}
+ * if <code>n</code> does not have a parent (<code>n</code> is the root
+ * node).
+ *
+ * @param n the document number.
+ * @return the DocId of <code>n</code>'s parent.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ final public DocId getParentDocId(int n) throws IOException {
int i = readerIndex(n);
DocId id = subReaders[i].getParent(n - starts[i]);
- id = id.applyOffset(starts[i]);
- return id.getDocumentNumber(this);
+ return id.applyOffset(starts[i]);
}
/**
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java Tue Dec 20 03:12:39 2005
@@ -170,8 +170,8 @@
public Scorer scorer(IndexReader reader) throws IOException {
contextScorer = contextQuery.weight(searcher).scorer(reader);
subScorer = subQuery.weight(searcher).scorer(reader);
- CachingMultiReader index = (CachingMultiReader) reader;
- return new DescendantSelfAxisScorer(searcher.getSimilarity(), index);
+ HierarchyResolver resolver = (HierarchyResolver) reader;
+ return new DescendantSelfAxisScorer(searcher.getSimilarity(), reader, resolver);
}
/**
@@ -190,9 +190,9 @@
private class DescendantSelfAxisScorer extends Scorer {
/**
- * An <code>IndexReader</code> to access the index.
+ * The <code>HierarchyResolver</code> of the index.
*/
- private final CachingMultiReader reader;
+ private final HierarchyResolver hResolver;
/**
* BitSet storing the id's of selected documents
@@ -219,10 +219,13 @@
*
* @param similarity the <code>Similarity</code> instance to use.
* @param reader for index access.
+ * @param hResolver the hierarchy resolver of <code>reader</code>.
*/
- protected DescendantSelfAxisScorer(Similarity similarity, CachingMultiReader reader) {
+ protected DescendantSelfAxisScorer(Similarity similarity,
+ IndexReader reader,
+ HierarchyResolver hResolver) {
super(similarity);
- this.reader = reader;
+ this.hResolver = hResolver;
// todo reuse BitSets?
this.contextHits = new BitSet(reader.maxDoc());
this.subHits = new BitSet(reader.maxDoc());
@@ -245,10 +248,10 @@
}
// check if nextDoc is a descendant of one of the context nodes
- int parentDoc = reader.getParent(nextDoc);
+ int parentDoc = hResolver.getParent(nextDoc);
while (parentDoc != -1 && !contextHits.get(parentDoc)) {
// traverse
- parentDoc = reader.getParent(parentDoc);
+ parentDoc = hResolver.getParent(parentDoc);
}
if (parentDoc != -1) {
Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java?rev=357961&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java Tue Dec 20 03:12:39 2005
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.query.lucene;
+
+import java.io.IOException;
+
+/**
+ * <code>HierarchyResolver</code> extends an {@link org.apache.lucene.index.IndexReader}
+ * with the ability to resolve a JCR hierarchy.
+ */
+public interface HierarchyResolver {
+
+ /**
+ * Returns the document number of the parent of <code>n</code> or
+ * <code>-1</code> if <code>n</code> does not have a parent (<code>n</code>
+ * is the root node).
+ *
+ * @param n the document number.
+ * @return the document number of <code>n</code>'s parent.
+ * @throws java.io.IOException if an error occurs while reading from the index.
+ */
+ public int getParent(int n) throws IOException;
+}
Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/HierarchyResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java Tue Dec 20 03:12:39 2005
@@ -172,6 +172,11 @@
private final RedoLog redoLog;
/**
+ * Set<String> of uuids that should not be indexed.
+ */
+ private final Set excludedUUIDs;
+
+ /**
* The next transaction id.
*/
private long nextTransactionId = 0;
@@ -184,21 +189,25 @@
/**
* Creates a new MultiIndex.
*
- * @param indexDir the base file system
- * @param handler the search handler
- * @param stateMgr shared item state manager
- * @param rootUUID uuid of the root node
+ * @param indexDir the base file system
+ * @param handler the search handler
+ * @param stateMgr shared item state manager
+ * @param rootUUID uuid of the root node
+ * @param excludedUUIDs Set<String> that contains uuids that should not
+ * be indexed nor further traversed.
* @throws IOException if an error occurs
*/
MultiIndex(File indexDir,
SearchIndex handler,
ItemStateManager stateMgr,
- String rootUUID) throws IOException {
+ String rootUUID,
+ Set excludedUUIDs) throws IOException {
this.indexDir = indexDir;
this.handler = handler;
this.cache = new DocNumberCache(handler.getCacheSize());
- this.redoLog = new RedoLog(new File(indexDir, REDO_LOG));
+ this.redoLog = new RedoLog(new File(indexDir, REDO_LOG));
+ this.excludedUUIDs = new HashSet(excludedUUIDs);
if (indexNames.exists(indexDir)) {
indexNames.read(indexDir);
@@ -817,6 +826,9 @@
private void createIndex(NodeState node, ItemStateManager stateMgr)
throws IOException, ItemStateException, RepositoryException {
String uuid = node.getId().toString();
+ if (excludedUUIDs.contains(uuid)) {
+ return;
+ }
executeAndLog(new AddNode(getTransactionId(), uuid));
checkVolatileCommit();
List children = node.getChildNodeEntries();
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=357961&r1=357960&r2=357961&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Tue Dec 20 03:12:39 2005
@@ -22,6 +22,7 @@
import org.apache.jackrabbit.core.query.ExecutableQuery;
import org.apache.jackrabbit.core.query.QueryHandlerContext;
import org.apache.jackrabbit.core.query.TextFilter;
+import org.apache.jackrabbit.core.query.QueryHandler;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.name.NoPrefixDeclaredException;
import org.apache.jackrabbit.name.QName;
@@ -31,6 +32,7 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.MultiReader;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
@@ -47,6 +49,8 @@
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
/**
* Implements a {@link org.apache.jackrabbit.core.query.QueryHandler} using
@@ -178,8 +182,14 @@
if (path == null) {
throw new IOException("SearchIndex requires 'path' parameter in configuration!");
}
+
+ Set excludedUUIDs = new HashSet();
+ if (context.getExcludedNodeUUID() != null) {
+ excludedUUIDs.add(context.getExcludedNodeUUID());
+ }
+
index = new MultiIndex(new File(path), this,
- context.getItemStateManager(), context.getRootUUID());
+ context.getItemStateManager(), context.getRootUUID(), excludedUUIDs);
if (index.getRedoLogApplied() || forceConsistencyCheck) {
log.info("Running consistency check...");
try {
@@ -311,9 +321,22 @@
Query query,
QName[] orderProps,
boolean[] orderSpecs) throws IOException {
+ QueryHandler parentHandler = getContext().getParentHandler();
+ IndexReader parentReader = null;
+ if (parentHandler instanceof SearchIndex) {
+ parentReader = ((SearchIndex) parentHandler).index.getIndexReader();
+ }
+
SortField[] sortFields = createSortFields(orderProps, orderSpecs);
IndexReader reader = index.getIndexReader();
+ if (parentReader != null) {
+ // todo FIXME not type safe
+ CachingMultiReader[] readers = {(CachingMultiReader) reader,
+ (CachingMultiReader) parentReader};
+ reader = new CombinedIndexReader(readers);
+ }
+
IndexSearcher searcher = new IndexSearcher(reader);
Hits hits;
if (sortFields.length > 0) {
@@ -403,6 +426,77 @@
*/
protected MultiIndex getIndex() {
return index;
+ }
+
+ //----------------------------< internal >----------------------------------
+
+ /**
+ * Combines multiple {@link CachingMultiReader} into a <code>MultiReader</code>
+ * with {@link HierarchyResolver} support.
+ */
+ protected static final class CombinedIndexReader extends MultiReader implements HierarchyResolver {
+
+ /**
+ * The sub readers.
+ */
+ private CachingMultiReader[] subReaders;
+
+ /**
+ * Doc number starts for each sub reader
+ */
+ private int[] starts;
+
+ public CombinedIndexReader(CachingMultiReader[] indexReaders) throws IOException {
+ super(indexReaders);
+ this.subReaders = indexReaders;
+ this.starts = new int[subReaders.length + 1];
+
+ int maxDoc = 0;
+ for (int i = 0; i < subReaders.length; i++) {
+ starts[i] = maxDoc;
+ maxDoc += subReaders[i].maxDoc();
+ }
+ starts[subReaders.length] = maxDoc;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public int getParent(int n) throws IOException {
+ int i = readerIndex(n);
+ DocId id = subReaders[i].getParentDocId(n - starts[i]);
+ id = id.applyOffset(starts[i]);
+ return id.getDocumentNumber(this);
+ }
+
+ /**
+ * Returns the reader index for document <code>n</code>.
+ * Implementation copied from lucene MultiReader class.
+ *
+ * @param n document number.
+ * @return the reader index.
+ */
+ final private int readerIndex(int n) {
+ int lo = 0; // search starts array
+ int hi = subReaders.length - 1; // for first element less
+
+ while (hi >= lo) {
+ int mid = (lo + hi) >> 1;
+ int midValue = starts[mid];
+ if (n < midValue) {
+ hi = mid - 1;
+ } else if (n > midValue) {
+ lo = mid + 1;
+ } else { // found a match
+ while (mid + 1 < subReaders.length && starts[mid + 1] == midValue) {
+ mid++; // scan to last match
+ }
+ return mid;
+ }
+ }
+ return hi;
+ }
+
}
//--------------------------< properties >----------------------------------