exo-jcr SVN: r3914 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr: impl/core/query and 3 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-02 11:15:14 -0500 (Wed, 02 Feb 2011)
New Revision: 3914
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NodeDataIndexing.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
Log:
EXOJCR-1104: re-indexing mechanism for RDBMS
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NodeDataIndexing.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NodeDataIndexing.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NodeDataIndexing.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ * This software 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.exoplatform.services.jcr.datamodel;
+
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.dataflow.ItemDataVisitor;
+
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 1 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: NodeDataIndexing.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class NodeDataIndexing implements NodeData
+{
+ private final NodeData nodeData;
+
+ private final List<PropertyData> properties;
+
+ /**
+ * Constructor NodeDataIndexing.
+ */
+ public NodeDataIndexing(NodeData nodeData)
+ {
+ this(nodeData, null);
+ }
+
+ /**
+ * Constructor NodeDataIndexing.
+ */
+ public NodeDataIndexing(NodeData nodeData, List<PropertyData> properties)
+ {
+ this.nodeData = nodeData;
+ this.properties = properties;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public List<PropertyData> getChildPropertiesData()
+ {
+ return properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public QPath getQPath()
+ {
+ return nodeData.getQPath();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getIdentifier()
+ {
+ return nodeData.getIdentifier();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getPersistedVersion()
+ {
+ return nodeData.getPersistedVersion();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getParentIdentifier()
+ {
+ return nodeData.getParentIdentifier();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isNode()
+ {
+ return nodeData.isNode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void accept(ItemDataVisitor visitor) throws RepositoryException
+ {
+ nodeData.accept(visitor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getOrderNumber()
+ {
+ return nodeData.getOrderNumber();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public InternalQName getPrimaryTypeName()
+ {
+ return nodeData.getPrimaryTypeName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public InternalQName[] getMixinTypeNames()
+ {
+ return nodeData.getMixinTypeNames();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AccessControlList getACL()
+ {
+ throw new UnsupportedOperationException("getACL() method is not supported");
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ * This software 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.exoplatform.services.jcr.impl.core.query;
+
+import java.io.IOException;
+
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 1 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: Indexing.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public interface Indexable
+{
+ NodeDataIndexingIterator getNodeDataIndexingIterator() throws IOException;
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ * This software 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.exoplatform.services.jcr.impl.core.query;
+
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 1 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: IndexingDataIterator.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public interface NodeDataIndexingIterator
+{
+
+ /**
+ * Returns <tt>true</tt> if the iteration has more elements. (In other
+ * words, returns <tt>true</tt> if <tt>next</tt> would return an element
+ * rather than throwing an exception.)
+ *
+ * @return <tt>true</tt> if the iterator has more elements.
+ */
+ boolean hasNext();
+
+ /**
+ * Returns the next element in the iteration.
+ *
+ * @return the next element in the iteration.
+ * @exception NoSuchElementException iteration has no more elements.
+ */
+ NodeDataIndexing next() throws IOException;
+
+ /**
+ * Closes the iterator and releases all resources.
+ */
+ void close() throws IOException;
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -17,6 +17,7 @@
package org.exoplatform.services.jcr.impl.core.query;
import org.exoplatform.services.document.DocumentReaderService;
+import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
@@ -73,6 +74,11 @@
private final LuceneVirtualTableResolver virtualTableResolver;
/**
+ * Workspace container.
+ */
+ private final WorkspaceContainerFacade container;
+
+ /**
* Creates a new context instance.
*
* @param fs
@@ -95,11 +101,12 @@
* id of the node that should be excluded from indexing. Any
* descendant of that node is also excluded from indexing.
*/
- public QueryHandlerContext(ItemDataConsumer stateMgr, IndexingTree indexingTree,
+ public QueryHandlerContext(WorkspaceContainerFacade container, ItemDataConsumer stateMgr, IndexingTree indexingTree,
NodeTypeDataManager nodeTypeDataManager, NamespaceRegistryImpl nsRegistry, QueryHandler parentHandler,
String indexDirectory, DocumentReaderService extractor, boolean createInitialIndex,
LuceneVirtualTableResolver virtualTableResolver)
{
+ this.container = container;
this.stateMgr = stateMgr;
this.indexingTree = indexingTree;
this.nodeTypeDataManager = nodeTypeDataManager;
@@ -114,6 +121,14 @@
}
/**
+ * @return the workspace container
+ */
+ public WorkspaceContainerFacade getContainer()
+ {
+ return container;
+ }
+
+ /**
* @return the virtualTableResolver
*/
public LuceneVirtualTableResolver getVirtualTableResolver()
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -24,10 +24,13 @@
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
+import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.dataflow.ItemState;
@@ -154,6 +157,18 @@
protected IndexerChangesFilter changesFilter;
/**
+ * The Repository name.
+ */
+ protected final String repositoryName;
+
+ /**
+ * The Repository name.
+ */
+ protected final String workspaceName;
+
+ protected final RepositoryService rService;
+
+ /**
* The unique name of the related workspace
*/
protected final String wsId;
@@ -191,6 +206,10 @@
/**
* Creates a new <code>SearchManager</code>.
*
+ * @param rEntry
+ * repository configuration
+ * @param rService
+ * repository service
* @param config
* the search configuration.
* @param nsReg
@@ -212,17 +231,23 @@
* @throws RepositoryConfigurationException
*/
- public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
- NodeTypeDataManager ntReg, WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
+ public SearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+ QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
+ WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm, final RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException
{
- this(wsConfig, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm, indexSearcherHolder, null);
+ this(wsConfig, rEntry, rService, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
+ indexSearcherHolder, null);
}
/**
* Creates a new <code>SearchManager</code>.
*
+ * @param rEntry
+ * repository configuration
+ * @param rService
+ * repository service
* @param config
* the search configuration.
* @param nsReg
@@ -246,12 +271,16 @@
* @throws RepositoryConfigurationException
*/
- public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
- NodeTypeDataManager ntReg, WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
+ public SearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+ QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
+ WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm,
final RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
RepositoryConfigurationException
{
+ this.repositoryName = rEntry.getName();
+ this.workspaceName = wsConfig.getName();
+ this.rService = rService;
this.rpcService = rpcService;
this.wsId = wsConfig.getUniqueName();
this.extractor = extractor;
@@ -660,10 +689,19 @@
protected QueryHandlerContext createQueryHandlerContext(QueryHandler parentHandler)
throws RepositoryConfigurationException
{
+ WorkspaceContainerFacade container;
+ try
+ {
+ container = rService.getRepository(repositoryName).getWorkspaceContainer(workspaceName);
+ }
+ catch (RepositoryException e)
+ {
+ throw new RepositoryConfigurationException(e);
+ }
QueryHandlerContext context =
- new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDirectory(),
- extractor, true, virtualTableResolver);
+ new QueryHandlerContext(container, itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler,
+ getIndexDirectory(), extractor, true, virtualTableResolver);
return context;
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -18,8 +18,10 @@
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
+import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -58,11 +60,12 @@
public static final String INDEX_DIR_SUFFIX = "system";
- public SystemSearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
+ public SystemSearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+ QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException, RepositoryConfigurationException
{
- super(wsConfig, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder);
+ super(wsConfig, rEntry, rService, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder);
}
@Override
@@ -103,16 +106,6 @@
}
}
- @Override
- protected QueryHandlerContext createQueryHandlerContext(QueryHandler parentHandler)
- throws RepositoryConfigurationException
- {
- QueryHandlerContext context =
- new QueryHandlerContext(itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler, getIndexDirectory(),
- extractor, true, virtualTableResolver);
- return context;
- }
-
/**
* {@inheritDoc}
*/
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -24,11 +24,14 @@
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.query.Indexable;
import org.exoplatform.services.jcr.impl.core.query.IndexerIoMode;
import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeListener;
import org.exoplatform.services.jcr.impl.core.query.IndexingTree;
+import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -400,8 +403,19 @@
long count = 0;
// traverse and index workspace
executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
+
// NodeData rootState = (NodeData) stateMgr.getItemData(rootId);
- count = createIndex(indexingTree.getIndexingRoot(), stateMgr, count);
+
+ // check if we have deal with JDBC indexing mechanism
+ Indexable indexableComponent = (Indexable)handler.getContext().getContainer().getComponent(Indexable.class);
+ if (indexableComponent == null)
+ {
+ count = createIndex(indexingTree.getIndexingRoot(), stateMgr, count);
+ }
+ else
+ {
+ count = createIndex(indexableComponent, indexingTree.getIndexingRoot(), stateMgr, count);
+ }
executeAndLog(new Commit(getTransactionId()));
log.info("Created initial index for {} nodes", new Long(count));
releaseMultiReader();
@@ -1035,6 +1049,20 @@
*/
Document createDocument(NodeData node) throws RepositoryException
{
+ return createDocument(new NodeDataIndexing(node));
+ }
+
+ /**
+ * Returns a lucene Document for the <code>node</code>.
+ *
+ * @param node
+ * the node to index wrapped into NodeDataIndexing
+ * @return the index document.
+ * @throws RepositoryException
+ * if an error occurs while reading from the workspace.
+ */
+ Document createDocument(NodeDataIndexing node) throws RepositoryException
+ {
return handler.createDocument(node, nsMappings, version);
}
@@ -1395,6 +1423,7 @@
return count;
}
executeAndLog(new AddNode(getTransactionId(), node.getIdentifier()));
+
if (++count % 100 == 0)
{
@@ -1426,6 +1455,69 @@
}
/**
+ * Recursively creates an index starting with the NodeState
+ * <code>node</code>.
+ *
+ * @param indexableComponent
+ * the component which responsible for quick indexing
+ * @param rootNode
+ * the current NodeState.
+ * @param path
+ * the path of the current node.
+ * @param stateMgr
+ * the shared item state manager.
+ * @param count
+ * the number of nodes already indexed.
+ * @return the number of nodes indexed so far.
+ * @throws IOException
+ * if an error occurs while writing to the index.
+ * @throws ItemStateException
+ * if an node state cannot be found.
+ * @throws RepositoryException
+ * if any other error occurs
+ */
+ private long createIndex(Indexable indexableComponent, NodeData rootNode, ItemDataConsumer stateMgr, long count)
+ throws IOException, RepositoryException
+ {
+ NodeDataIndexingIterator iterator = indexableComponent.getNodeDataIndexingIterator();
+ try
+ {
+ while (iterator.hasNext())
+ {
+ NodeDataIndexing node = iterator.next();
+
+ if (indexingTree.isExcluded(node))
+ {
+ continue;
+ }
+
+ if (!node.getQPath().isDescendantOf(rootNode.getQPath()) && !node.getQPath().equals(rootNode.getQPath()))
+ {
+ continue;
+ }
+
+ executeAndLog(new AddNode(getTransactionId(), node));
+
+ if (++count % 100 == 0)
+ {
+ log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count));
+ }
+ if (count % 10 == 0)
+ {
+ checkIndexingQueue(true);
+ }
+ checkVolatileCommit();
+ }
+ }
+ finally
+ {
+ iterator.close();
+ }
+
+ return count;
+ }
+
+ /**
* Attempts to delete all files recorded in {@link #deletable}.
*/
private void attemptDelete()
@@ -1946,6 +2038,11 @@
private Document doc;
/**
+ * The node to add.
+ */
+ private NodeDataIndexing node;
+
+ /**
* Creates a new AddNode action.
*
* @param transactionId
@@ -1964,6 +2061,20 @@
*
* @param transactionId
* the id of the transaction that executes this action.
+ * @param uuid
+ * the uuid of the node to add.
+ */
+ AddNode(long transactionId, NodeDataIndexing node)
+ {
+ this(transactionId, node.getIdentifier());
+ this.node = node;
+ }
+
+ /**
+ * Creates a new AddNode action.
+ *
+ * @param transactionId
+ * the id of the transaction that executes this action.
* @param doc
* the document to add.
*/
@@ -2006,7 +2117,14 @@
{
try
{
- doc = index.createDocument(uuid);
+ if (node != null)
+ {
+ doc = index.createDocument(node);
+ }
+ else
+ {
+ doc = index.createDocument(uuid);
+ }
}
catch (RepositoryException e)
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -29,7 +29,7 @@
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.ItemType;
-import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
@@ -75,7 +75,7 @@
/**
* The <code>NodeState</code> of the node to index
*/
- protected final NodeData node;
+ protected final NodeDataIndexing node;
/**
* The persistent item state provider
@@ -130,7 +130,7 @@
* @param mappings internal namespace mappings.
* @param extractor content extractor
*/
- public NodeIndexer(NodeData node, ItemDataConsumer stateProvider, NamespaceMappings mappings,
+ public NodeIndexer(NodeDataIndexing node, ItemDataConsumer stateProvider, NamespaceMappings mappings,
DocumentReaderService extractor)
{
this.node = node;
@@ -219,9 +219,15 @@
// unknown uri<->prefix mappings
}
- for (final PropertyData prop : stateProvider.listChildPropertiesData(node))
+ List<PropertyData> props = node.getChildPropertiesData();
+ if (props == null)
{
+ props = stateProvider.listChildPropertiesData(node);
+ }
+ for (final PropertyData prop : props)
+ {
+
// add each property to the _PROPERTIES_SET for searching
// beginning with V2
if (indexFormatVersion.getVersion() >= IndexFormatVersion.V2.getVersion())
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -45,6 +45,7 @@
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.Constants;
@@ -1221,6 +1222,28 @@
protected Document createDocument(NodeData node, NamespaceMappings nsMappings, IndexFormatVersion indexFormatVersion)
throws RepositoryException
{
+ return createDocument(new NodeDataIndexing(node), nsMappings, indexFormatVersion);
+ }
+
+ /**
+ * Creates a lucene <code>Document</code> for a node state using the
+ * namespace mappings <code>nsMappings</code>.
+ *
+ * @param node
+ * the node state to index.
+ * @param nsMappings
+ * the namespace mappings of the search index.
+ * @param indexFormatVersion
+ * the index format version that should be used to index the
+ * passed node state.
+ * @return a lucene <code>Document</code> that contains all properties of
+ * <code>node</code>.
+ * @throws RepositoryException
+ * if an error occurs while indexing the <code>node</code>.
+ */
+ protected Document createDocument(NodeDataIndexing node, NamespaceMappings nsMappings,
+ IndexFormatVersion indexFormatVersion) throws RepositoryException
+ {
NodeIndexer indexer = new NodeIndexer(node, getContext().getItemStateManager(), nsMappings, extractor);
indexer.setSupportHighlighting(supportHighlighting);
indexer.setIndexingConfiguration(indexingConfig);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-02 13:49:51 UTC (rev 3913)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -37,6 +37,8 @@
import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestor;
import org.exoplatform.services.jcr.impl.backup.rdbms.RestoreTableRule;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.core.query.Indexable;
+import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectWriterImpl;
import org.exoplatform.services.jcr.impl.storage.WorkspaceDataContainerBase;
@@ -45,6 +47,7 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.db.MySQLConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.OracleConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.WorkspaceStorageConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.indexing.JdbcNodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.storage.jdbc.init.IngresSQLDBInitializer;
import org.exoplatform.services.jcr.impl.storage.jdbc.init.OracleDBInitializer;
import org.exoplatform.services.jcr.impl.storage.jdbc.init.PgSQLDBInitializer;
@@ -92,7 +95,8 @@
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
* @version $Id:GenericWorkspaceDataContainer.java 13433 2007-03-15 16:07:23Z peterit $
*/
-public class JDBCWorkspaceDataContainer extends WorkspaceDataContainerBase implements Startable, JdbcBackupable
+public class JDBCWorkspaceDataContainer extends WorkspaceDataContainerBase implements Startable, JdbcBackupable,
+ Indexable
{
protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JDBCWorkspaceDataContainer");
@@ -1417,4 +1421,37 @@
throw new BackupException(e);
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public NodeDataIndexingIterator getNodeDataIndexingIterator() throws IOException
+ {
+ try
+ {
+ final DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+
+ if (ds != null)
+ {
+ Connection jdbcConn =
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+ }
+ });
+ return new JdbcNodeDataIndexingIterator(jdbcConn, multiDb, containerName, swapCleaner, maxBufferSize,
+ swapDirectory, valueStorageProvider);
+ }
+ else
+ {
+ throw new NameNotFoundException("Data source " + dbSourceName + " not found");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new IOException(e);
+ }
+ }
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java 2011-02-02 16:15:14 UTC (rev 3914)
@@ -0,0 +1,770 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ * This software 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.exoplatform.services.jcr.impl.storage.jdbc.indexing;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
+import org.exoplatform.services.jcr.datamodel.IllegalNameException;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.PrimaryTypeNotFoundException;
+import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
+import org.exoplatform.services.jcr.impl.storage.value.fs.operations.ValueFileIOHelper;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SwapFile;
+import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.jcr.InvalidItemStateException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 1 02 2011
+ *
+ * Iterator for fetching NodeData from database with all properties and its values.
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: JdbcIndexingDataIterator.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class JdbcNodeDataIndexingIterator extends DBConstants implements NodeDataIndexingIterator
+{
+
+ /**
+ * Logger.
+ */
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JdbcIndexingDataIterator");
+
+ /**
+ * Connection to the database. Should be released on close.
+ */
+ private final Connection jdbcConn;
+
+ /**
+ * Temporary used prepared statement for query execution. Should be released on close.
+ */
+ private PreparedStatement st = null;
+
+ /**
+ * Temporary used prepared statement. Should be released on close.
+ */
+ private PreparedStatement findItemQPathByIdentifierCQ;
+
+ /**
+ * Temporary used result set during fetching data. Should be released on close.
+ */
+ private ResultSet resultSet = null;
+
+ /**
+ * Connection to the database. Should be released on close.
+ */
+ private TempNodeData data = null;
+
+ /**
+ * Indicates if mulit db is used or not.
+ */
+ private final boolean multiDb;
+
+ /**
+ * Container name.
+ */
+ private final String containerName;
+
+ /**
+ * The File Cleaner.
+ */
+ private final FileCleaner swapCleaner;
+
+ /**
+ * Maximum buffer size.
+ */
+ private final int maxBufferSize;
+
+ /**
+ * Swap directory.
+ */
+ private final File swapDirectory;
+
+ /**
+ * Value storage provider.
+ */
+ private final ValueStoragePluginProvider valueStorageProvider;
+
+ /**
+ * The next node data to return in next() method.
+ */
+ private NodeDataIndexing nextNode = null;
+
+ /**
+ * Search query for single db.
+ */
+ private static final String FIND_NODES_SINGLE_DB =
+ "select I.ID AS N_ID, I.PARENT_ID AS N_PARENT_ID, I.NAME AS N_NAME, I.VERSION AS N_VERSION, I.I_INDEX AS N_I_INDEX, I.N_ORDER_NUM, "
+ + "P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED, "
+ + "V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V where I.I_CLASS=1 and I.CONTAINER_NAME=? and"
+ + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID" + " and V.PROPERTY_ID=P.ID order by N_ID";
+
+ /**
+ * Search query for multi db.
+ */
+ private static final String FIND_NODES_MULTI_DB =
+ "select I.ID AS N_ID, I.PARENT_ID AS N_PARENT_ID, I.NAME AS N_NAME, I.VERSION AS N_VERSION, I.I_INDEX AS N_I_INDEX, I.N_ORDER_NUM, "
+ + "P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED, "
+ + "V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V where I.I_CLASS=1 and"
+ + " P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by N_ID";
+
+ /**
+ * Constructor JdbcIndexingDataIterator.
+ *
+ */
+ public JdbcNodeDataIndexingIterator(Connection jdbcConn, boolean multiDb, String containerName, FileCleaner swapCleaner,
+ int maxBufferSize, File swapDirectory, ValueStoragePluginProvider valueStorageProvider) throws SQLException,
+ PrimaryTypeNotFoundException, InvalidItemStateException, ValueStorageNotFoundException, IllegalNameException,
+ IOException
+ {
+ this.jdbcConn = jdbcConn;
+ this.multiDb = multiDb;
+ this.containerName = containerName;
+ this.swapCleaner = swapCleaner;
+ this.maxBufferSize = maxBufferSize;
+ this.swapDirectory = swapDirectory;
+ this.valueStorageProvider = valueStorageProvider;
+
+ String sql = multiDb ? FIND_NODES_MULTI_DB : FIND_NODES_SINGLE_DB;
+ st = jdbcConn.prepareStatement(sql);
+
+ if (!multiDb)
+ {
+ st.setString(1, containerName);
+ st.setString(2, containerName);
+ }
+ resultSet = st.executeQuery();
+
+ this.nextNode = readNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext()
+ {
+ return this.nextNode != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NodeDataIndexing next() throws IOException
+ {
+ NodeDataIndexing current = this.nextNode;
+
+ try
+ {
+ this.nextNode = readNext();
+ }
+ catch (PrimaryTypeNotFoundException e)
+ {
+ throw new IOException(e);
+ }
+ catch (InvalidItemStateException e)
+ {
+ throw new IOException(e);
+ }
+ catch (ValueStorageNotFoundException e)
+ {
+ throw new IOException(e);
+ }
+ catch (SQLException e)
+ {
+ throw new IOException(e);
+ }
+ catch (IllegalNameException e)
+ {
+ throw new IOException(e);
+ }
+
+ return current;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws IOException
+ {
+ try
+ {
+ if (resultSet != null)
+ {
+ resultSet.close();
+ }
+
+ if (st != null)
+ {
+ st.close();
+ }
+
+ if (findItemQPathByIdentifierCQ != null)
+ {
+ findItemQPathByIdentifierCQ.close();
+ }
+
+ jdbcConn.close();
+ }
+ catch (SQLException e)
+ {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Read next node from database.
+ *
+ * @return NodeDataIndexing
+ */
+ private NodeDataIndexing readNext() throws PrimaryTypeNotFoundException, InvalidItemStateException,
+ ValueStorageNotFoundException, SQLException, IllegalNameException, IOException
+ {
+ while (resultSet.next())
+ {
+ if (data == null)
+ {
+ data = new TempNodeData(resultSet);
+ readTempPropertyData();
+ }
+ else if (!resultSet.getString("N_ID").equals(data.cid))
+ {
+ NodeDataIndexing node = createNodeData(data);
+
+ data = new TempNodeData(resultSet);
+ readTempPropertyData();
+
+ return node;
+ }
+ else
+ {
+ readTempPropertyData();
+ }
+ }
+
+ if (data != null)
+ {
+ NodeDataIndexing node = createNodeData(data);
+ data = null;
+
+ return node;
+ }
+
+ return null;
+ }
+
+ /**
+ * Read temporary property data.
+ *
+ * @throws SQLException
+ */
+ private void readTempPropertyData() throws SQLException
+ {
+ String key = resultSet.getString("P_NAME");
+
+ SortedSet<TempPropertyData> values = data.properties.get(key);
+ if (values == null)
+ {
+ values = new TreeSet<TempPropertyData>();
+ data.properties.put(key, values);
+ }
+
+ values.add(new TempPropertyData(resultSet));
+ }
+
+ /**
+ * Build node data and its properties data from temporary stored info.
+ *
+ * @return NodeDataIndexing
+ */
+ private NodeDataIndexing createNodeData(TempNodeData tempNode) throws IllegalNameException,
+ InvalidItemStateException, SQLException, PrimaryTypeNotFoundException, IOException, ValueStorageNotFoundException
+ {
+ QPath parentPath;
+ String parentCid;
+
+ if (tempNode.cpid.equals(Constants.ROOT_PARENT_UUID))
+ {
+ // root node
+ parentPath = Constants.ROOT_PATH;
+ parentCid = null;
+ }
+ else
+ {
+ parentPath =
+ QPath.makeChildPath(traverseQPath(tempNode.cpid), InternalQName.parse(tempNode.cname), tempNode.cindex);
+ parentCid = tempNode.cpid;
+ }
+
+ // primary type
+ SortedSet<TempPropertyData> primaryTypeTempProp = tempNode.properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
+ if (primaryTypeTempProp == null)
+ {
+ throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not found. Node "
+ + parentPath.getAsString() + ", id " + tempNode.cid + ", container " + this.containerName, null);
+ }
+
+ ByteArrayInputStream ba = ((ByteArrayInputStream)primaryTypeTempProp.first().cdata);
+ byte[] data = new byte[ba.available()];
+ ba.read(data);
+
+ primaryTypeTempProp.first().cdata = new ByteArrayInputStream(data);
+
+ InternalQName ptName =
+ InternalQName.parse(new String((data != null ? data : new byte[]{}), Constants.DEFAULT_ENCODING));
+
+ // mixins
+ List<InternalQName> mixins = new ArrayList<InternalQName>();
+ Set<TempPropertyData> mixinsTempProps = tempNode.properties.get(Constants.JCR_MIXINTYPES.getAsString());
+ if (mixinsTempProps != null)
+ {
+
+ for (TempPropertyData mxnb : mixinsTempProps)
+ {
+ ba = ((ByteArrayInputStream)mxnb.cdata);
+ data = new byte[ba.available()];
+ ba.read(data);
+
+ mxnb.cdata = new ByteArrayInputStream(data);
+
+ mixins.add(InternalQName.parse(new String(data, Constants.DEFAULT_ENCODING)));
+ }
+ }
+
+ // build node data
+ NodeData nodeData =
+ new PersistedNodeData(getIdentifier(tempNode.cid), parentPath, getIdentifier(parentCid), tempNode.cversion,
+ tempNode.cnordernumb, ptName, mixins.toArray(new InternalQName[mixins.size()]), null);
+
+ List<PropertyData> childProps = new ArrayList<PropertyData>();
+
+ for (String propName : tempNode.properties.keySet())
+ {
+ TempPropertyData prop = tempNode.properties.get(propName).first();
+ String identifier = getIdentifier(prop.cid);
+
+ // read values
+ List<ValueData> valueData = new ArrayList<ValueData>();
+ for (TempPropertyData tempProp : tempNode.properties.get(propName))
+ {
+ ValueData vdata =
+ tempProp.cstorage_desc == null ? readValueData(tempProp.cid, tempProp.corderNum, tempProp.cversion,
+ tempProp.cdata) : readValueData(identifier, tempProp.corderNum, tempProp.cstorage_desc);
+
+ valueData.add(vdata);
+ }
+ Collections.sort(valueData, COMPARATOR_VALUE_DATA);
+
+ QPath qpath = QPath.makeChildPath(parentPath, InternalQName.parse(prop.cname));
+
+ // build property data
+ PropertyData pdata =
+ new PersistedPropertyData(identifier, qpath, tempNode.cid, prop.cversion, prop.ctype, prop.cmulti,
+ valueData);
+
+ childProps.add(pdata);
+ }
+
+ return new NodeDataIndexing(nodeData, childProps);
+ }
+
+ /**
+ * Build Item path by id.
+ *
+ * @param cpid
+ * - Item id (container id)
+ * @return Item QPath
+ * @throws SQLException
+ * - if database error occurs
+ * @throws InvalidItemStateException
+ * - if parent not found
+ * @throws IllegalNameException
+ * - if name on the path is wrong
+ */
+ private QPath traverseQPath(String cpid) throws SQLException, InvalidItemStateException, IllegalNameException
+ {
+ String id = getIdentifier(cpid);
+ if (id.equals(Constants.ROOT_UUID))
+ {
+ return Constants.ROOT_PATH;
+ }
+
+ // get item by Identifier usecase
+ List<QPathEntry> qrpath = new ArrayList<QPathEntry>(); // reverted path
+ String caid = cpid; // container ancestor id
+ boolean isRoot = false;
+ do
+ {
+ ResultSet result = null;
+ try
+ {
+ result = findItemQPathByIdentifier(caid);
+ if (!result.next())
+ throw new InvalidItemStateException("Parent not found, uuid: " + getIdentifier(caid));
+
+ QPathEntry qpe1 =
+ new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+ boolean isChild = caid.equals(result.getString(COLUMN_ID));
+ caid = result.getString(COLUMN_PARENTID);
+ if (result.next())
+ {
+ QPathEntry qpe2 =
+ new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+ if (isChild)
+ {
+ // The child is the first result then we have the parent
+ qrpath.add(qpe1);
+ qrpath.add(qpe2);
+ // We need to take the value of the parent node
+ caid = result.getString(COLUMN_PARENTID);
+ }
+ else
+ {
+ // The parent is the first result then we have the child
+ qrpath.add(qpe2);
+ qrpath.add(qpe1);
+ }
+ }
+ else
+ {
+ qrpath.add(qpe1);
+ }
+ }
+ finally
+ {
+ if (result != null)
+ {
+ try
+ {
+ result.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+
+ if (caid.equals(Constants.ROOT_PARENT_UUID) || (id = getIdentifier(caid)).equals(Constants.ROOT_UUID))
+ {
+ if (id.equals(Constants.ROOT_UUID))
+ {
+ qrpath.add(Constants.ROOT_PATH.getEntries()[0]);
+ }
+ isRoot = true;
+ }
+ }
+ while (!isRoot);
+
+ QPathEntry[] qentries = new QPathEntry[qrpath.size()];
+ int qi = 0;
+ for (int i = qrpath.size() - 1; i >= 0; i--)
+ {
+ qentries[qi++] = qrpath.get(i);
+ }
+ return new QPath(qentries);
+ }
+
+ /**
+ * Invoke item identifier from internalId. In case of single db need to
+ * remove prefix from internalId.
+ *
+ * @param internalId
+ * the internal identifier
+ */
+ private String getIdentifier(final String internalId)
+ {
+ if (internalId == null)
+ return null;
+
+ return multiDb ? internalId : internalId.substring(containerName.length());
+ }
+
+ /**
+ *
+ * @param identifier
+ * @return
+ * @throws SQLException
+ */
+ private ResultSet findItemQPathByIdentifier(String identifier) throws SQLException
+ {
+ String findItemQPathByIdentifier;
+ if (multiDb)
+ {
+ findItemQPathByIdentifier =
+ "select I.ID, I.PARENT_ID, I.NAME, I.I_INDEX"
+ + " from JCR_MITEM I, (SELECT ID, PARENT_ID from JCR_MITEM where ID=?) J"
+ + " where I.ID = J.ID or I.ID = J.PARENT_ID";
+ }
+ else
+ {
+ findItemQPathByIdentifier =
+ "select I.ID, I.PARENT_ID, I.NAME, I.I_INDEX"
+ + " from JCR_SITEM I, (SELECT ID, PARENT_ID from JCR_SITEM where ID=?) J"
+ + " where I.ID = J.ID or I.ID = J.PARENT_ID";
+ }
+
+ if (findItemQPathByIdentifierCQ == null)
+ {
+ findItemQPathByIdentifierCQ = jdbcConn.prepareStatement(findItemQPathByIdentifier);
+ }
+ else
+ {
+ findItemQPathByIdentifierCQ.clearParameters();
+ }
+
+ findItemQPathByIdentifierCQ.setString(1, identifier);
+ return findItemQPathByIdentifierCQ.executeQuery();
+ }
+
+ /**
+ * Read ValueData from database.
+ *
+ * @param cid
+ * property id
+ * @param orderNumber
+ * value order number
+ * @param version
+ * persistent version (used for BLOB swapping)
+ * @param content
+ * input stream
+ * @return ValueData
+ * @throws SQLException
+ * database error
+ * @throws IOException
+ * I/O error (swap)
+ */
+ private ValueData readValueData(String cid, int orderNumber, int version, final InputStream content)
+ throws SQLException, IOException
+ {
+
+ byte[] buffer = new byte[0];
+ byte[] spoolBuffer = new byte[ValueFileIOHelper.IOBUFFER_SIZE];
+ int read;
+ int len = 0;
+ OutputStream out = null;
+
+ SwapFile swapFile = null;
+ try
+ {
+ // stream from database
+ if (content != null)
+ while ((read = content.read(spoolBuffer)) >= 0)
+ {
+ if (out != null)
+ {
+ // spool to temp file
+ out.write(spoolBuffer, 0, read);
+ len += read;
+ }
+ else if (len + read > maxBufferSize)
+ {
+ // threshold for keeping data in memory exceeded;
+ // create temp file and spool buffer contents
+ swapFile = SwapFile.get(swapDirectory, cid + orderNumber + "." + version);
+ if (swapFile.isSpooled())
+ {
+ // break, value already spooled
+ buffer = null;
+ break;
+ }
+ out = PrivilegedFileHelper.fileOutputStream(swapFile);
+ out.write(buffer, 0, len);
+ out.write(spoolBuffer, 0, read);
+ buffer = null;
+ len += read;
+ }
+ else
+ {
+ // reallocate new buffer and spool old buffer contents
+ byte[] newBuffer = new byte[len + read];
+ System.arraycopy(buffer, 0, newBuffer, 0, len);
+ System.arraycopy(spoolBuffer, 0, newBuffer, len, read);
+ buffer = newBuffer;
+ len += read;
+ }
+ }
+ }
+ finally
+ {
+ if (out != null)
+ {
+ out.close();
+ swapFile.spoolDone();
+ }
+ }
+
+ if (buffer == null)
+ {
+ return new CleanableFilePersistedValueData(orderNumber, swapFile, swapCleaner);
+ }
+
+ return new ByteArrayPersistedValueData(orderNumber, buffer);
+ }
+
+ /**
+ * Read ValueData from external storage.
+ *
+ * @param identifier
+ * property identifier
+ * @param orderNumber
+ * value order number
+ * @param storageId
+ * external Value storage id
+ * @return ValueData
+ * @throws SQLException
+ * database error
+ * @throws IOException
+ * I/O error
+ * @throws ValueStorageNotFoundException
+ * if no such storage found with Value storageId
+ */
+ private ValueData readValueData(String identifier, int orderNumber, String storageId) throws SQLException,
+ IOException, ValueStorageNotFoundException
+ {
+ ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+ try
+ {
+ return channel.read(identifier, orderNumber, maxBufferSize);
+ }
+ finally
+ {
+ channel.close();
+ }
+ }
+
+ /**
+ * The comparator used to sort the value data
+ */
+ private static Comparator<ValueData> COMPARATOR_VALUE_DATA = new Comparator<ValueData>()
+ {
+ public int compare(ValueData vd1, ValueData vd2)
+ {
+ return vd1.getOrderNumber() - vd2.getOrderNumber();
+ }
+ };
+
+ /**
+ * Class needed to store temporary node data.
+ */
+ private class TempNodeData
+ {
+ String cid;
+
+ String cname;
+
+ int cversion;
+
+ String cpid;
+
+ int cindex;
+
+ int cnordernumb;
+
+ Map<String, SortedSet<TempPropertyData>> properties = new HashMap<String, SortedSet<TempPropertyData>>();
+
+ public TempNodeData(ResultSet item) throws SQLException
+ {
+ cid = item.getString("N_ID");
+ cname = item.getString("N_NAME");
+ cversion = item.getInt("N_VERSION");
+ cpid = item.getString("N_PARENT_ID");
+ cindex = item.getInt("N_I_INDEX");
+ cnordernumb = item.getInt("N_ORDER_NUM");
+ }
+ }
+
+ /**
+ * Class needs to store temporary property data.
+ */
+ private class TempPropertyData implements Comparable<TempPropertyData>
+ {
+ String cid;
+
+ String cname;
+
+ int cversion;
+
+ int ctype;
+
+ boolean cmulti;
+
+ int corderNum;
+
+ InputStream cdata;
+
+ String cstorage_desc;
+
+ public TempPropertyData(ResultSet item) throws SQLException
+ {
+ cid = item.getString("P_ID");
+ cname = item.getString("P_NAME");
+ cversion = item.getInt("P_VERSION");
+ ctype = item.getInt("P_TYPE");
+ cmulti = item.getBoolean("P_MULTIVALUED");
+ cdata = item.getBinaryStream(COLUMN_VDATA);
+ cstorage_desc = item.getString(COLUMN_VSTORAGE_DESC);
+ corderNum = item.getInt(COLUMN_VORDERNUM);
+ }
+
+ public int compareTo(TempPropertyData o)
+ {
+ return corderNum - o.corderNum;
+ }
+ }
+}
+
13 years, 3 months
exo-jcr SVN: r3913 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene: hits and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-02-02 08:49:51 -0500 (Wed, 02 Feb 2011)
New Revision: 3913
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/hits/AbstractHitCollector.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllScorer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java
Log:
EXOJCR-1157 : Getting rid of HitCollector in favor of Collector class.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java 2011-02-02 12:57:34 UTC (rev 3912)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -33,6 +33,7 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.query.LocationStepQueryNode;
+import org.exoplatform.services.jcr.impl.core.query.lucene.hits.AbstractHitCollector;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.AdaptingHits;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.Hits;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.ScorerHits;
@@ -489,7 +490,7 @@
{
// always use simple in that case
calc[0] = new SimpleChildrenCalculator(reader, hResolver);
- contextScorer.score(new HitCollector()
+ contextScorer.score(new AbstractHitCollector()
{
@Override
public void collect(int doc, float score)
@@ -502,7 +503,7 @@
{
// start simple but switch once threshold is reached
calc[0] = new SimpleChildrenCalculator(reader, hResolver);
- contextScorer.score(new HitCollector()
+ contextScorer.score(new AbstractHitCollector()
{
private List docIds = new ArrayList();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java 2011-02-02 12:57:34 UTC (rev 3912)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -27,6 +27,7 @@
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.core.query.lucene.hits.AbstractHitCollector;
import java.io.IOException;
import java.util.ArrayList;
@@ -338,7 +339,7 @@
if (uuids == null)
{
uuids = new ArrayList();
- contextScorer.score(new HitCollector()
+ contextScorer.score(new AbstractHitCollector()
{
@Override
public void collect(int doc, float score)
@@ -351,7 +352,7 @@
final BitSet nameTestHits = new BitSet();
if (nameTestScorer != null)
{
- nameTestScorer.score(new HitCollector()
+ nameTestScorer.score(new AbstractHitCollector()
{
@Override
public void collect(int doc, float score)
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java 2011-02-02 12:57:34 UTC (rev 3912)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -18,7 +18,6 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.HitCollector;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Searcher;
@@ -27,6 +26,7 @@
import org.apache.lucene.search.Weight;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.query.lucene.hits.AbstractHitCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -588,7 +588,7 @@
if (!contextHitsCalculated)
{
long time = System.currentTimeMillis();
- contextScorer.score(new HitCollector()
+ contextScorer.score(new AbstractHitCollector()
{
@Override
public void collect(int doc, float score)
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllScorer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllScorer.java 2011-02-02 12:57:34 UTC (rev 3912)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllScorer.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -16,20 +16,20 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.HitCollector;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Similarity;
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* The MatchAllScorer implements a Scorer that scores / collects all
* documents in the index that match a field.
@@ -84,9 +84,9 @@
/**
* {@inheritDoc}
*/
- public void score(HitCollector hc) throws IOException {
+ public void score(Collector hc) throws IOException {
while (next()) {
- hc.collect(doc(), score());
+ hc.collect(doc());
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java 2011-02-02 12:57:34 UTC (rev 3912)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -18,13 +18,13 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.HitCollector;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.core.query.lucene.hits.AbstractHitCollector;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.Hits;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.ScorerHits;
@@ -350,7 +350,7 @@
hits = new BitSet(reader.maxDoc());
final IOException[] ex = new IOException[1];
- contextScorer.score(new HitCollector()
+ contextScorer.score(new AbstractHitCollector()
{
private int[] docs = new int[1];
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/hits/AbstractHitCollector.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/hits/AbstractHitCollector.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/hits/AbstractHitCollector.java 2011-02-02 13:49:51 UTC (rev 3913)
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene.hits;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.Scorer;
+
+/**
+ * Collector implementation which simply provides the collection
+ * of re-based doc base with scorer.
+ */
+public abstract class AbstractHitCollector extends Collector {
+ protected int base = 0;
+ protected Scorer scorer = null;
+
+ @Override
+ public void setNextReader(IndexReader reader, int docBase) throws IOException {
+ base = docBase;
+ }
+
+ @Override
+ public void setScorer(Scorer scorer) throws IOException {
+ this.scorer = scorer;
+ }
+
+ @Override
+ public void collect(int doc) throws IOException {
+ collect(base + doc, scorer.score());
+ }
+
+ /**
+ * Called once for every document matching a query, with the re-based document
+ * number and its computed score.
+ * @param doc the re-based document number.
+ * @param doc the document's score.
+ */
+ protected abstract void collect(int doc, float score);
+
+ @Override
+ public boolean acceptsDocsOutOfOrder() {
+ return false;
+ }
+}
\ No newline at end of file
13 years, 3 months
exo-jcr SVN: r3912 - core/trunk/packaging/module/src/main/javascript.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-02-02 07:57:34 -0500 (Wed, 02 Feb 2011)
New Revision: 3912
Modified:
core/trunk/packaging/module/src/main/javascript/core.packaging.module.js
Log:
EXOJCR-1175: removed iText dependency
Modified: core/trunk/packaging/module/src/main/javascript/core.packaging.module.js
===================================================================
--- core/trunk/packaging/module/src/main/javascript/core.packaging.module.js 2011-02-02 07:42:58 UTC (rev 3911)
+++ core/trunk/packaging/module/src/main/javascript/core.packaging.module.js 2011-02-02 12:57:34 UTC (rev 3912)
@@ -39,15 +39,14 @@
module.component.documents =
new Project("org.exoplatform.core", "exo.core.component.document", "jar", module.version).
addDependency(new Project("org.apache.pdfbox", "pdfbox", "jar", "1.1.0")).
- addDependency(new Project("com.lowagie", "itext", "jar", "2.1.0")).
addDependency(new Project("bouncycastle", "bcmail-jdk14", "jar", "136")).
addDependency(new Project("bouncycastle", "bcprov-jdk14", "jar", "136")).
addDependency(new Project("html-parser", "html-parser", "jar", "1.6")).
addDependency(new Project("org.apache.poi", "poi", "jar", "3.6")).
- addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.6")).
- addDependency(new Project("org.apache.poi", "poi-ooxml", "jar", "3.6")).
+ addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.6")).
+ addDependency(new Project("org.apache.poi", "poi-ooxml", "jar", "3.6")).
addDependency(new Project("org.apache.poi", "poi-ooxml-schemas", "jar", "3.6")).
- addDependency(new Project("org.apache.xmlbeans", "xmlbeans", "jar", "2.3.0"));
+ addDependency(new Project("org.apache.xmlbeans", "xmlbeans", "jar", "2.3.0"));
module.component.organization =
new Project("org.exoplatform.core", "exo.core.component.organization.api", "jar", module.version).
13 years, 3 months
exo-jcr SVN: r3911 - in jcr/trunk: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene and 2 other directories.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-02-02 02:42:58 -0500 (Wed, 02 Feb 2011)
New Revision: 3911
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractWeight.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingIndexReader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingMultiIndexReader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexReader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexSearcher.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrTermQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryHits.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllWeight.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NotQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryHitsQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RangeQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RefCountingIndexReader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/TermDocsCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/WildcardQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/directory/FSDirectoryManager.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/directory/DirectoryManagerTest.java
jcr/trunk/pom.xml
Log:
EXOJCR-1157 : merging changes done in EXOJCR-744 into the trunt.
1. Query class: changed definition (visibility modifier) of createWeight(..) method.
2. Interface Weight replaced with it's abstract type.
3. Weight.score(IndexReader) replaced with Weight.score(IndexReader, boolean, boolean) [should be reviewed if upgrading to 2.9 on trunk].
4. IndexReader.getSequenceReaders() introduced and used in LucenInternals for per-segment search and caching. In our custom IndexReader should be overridden and return null (This is safe solution confirmed within lucene's mailing list by Simon Willnauer).
5. FSdirectory.getDirectory(...) replaced with FSdirectory.open(...). But open(...) doesn't create a directory structure anymore.
6. Term can be null, when reader.termDocs(Term) invoked. Adding safe check to avoid NPE.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractIndex.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractIndex.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -287,8 +287,7 @@
if (indexReader == null || !indexReader.isCurrent())
{
- IndexReader reader = IndexReader.open(getDirectory());
- reader.setTermInfosIndexDivisor(termInfosIndexDivisor);
+ IndexReader reader = IndexReader.open(getDirectory(), null, false, termInfosIndexDivisor);
indexReader = new CommittableIndexReader(reader);
}
return indexReader;
@@ -357,8 +356,7 @@
if (sharedReader == null)
{
// create new shared reader
- IndexReader reader = IndexReader.open(getDirectory(), true);
- reader.setTermInfosIndexDivisor(termInfosIndexDivisor);
+ IndexReader reader = IndexReader.open(getDirectory(), null, true, termInfosIndexDivisor);
CachingIndexReader cr = new CachingIndexReader(reader, cache, initCache);
sharedReader = new SharedIndexReader(cr);
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractWeight.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractWeight.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractWeight.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,72 +16,81 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Weight;
+import java.io.IOException;
+
/**
* <code>AbstractWeight</code> implements base functionality for custom lucene
* weights in jackrabbit.
*/
-abstract class AbstractWeight implements Weight {
+abstract class AbstractWeight extends Weight
+{
- /**
- * The searcher for this weight.
- */
- protected final Searcher searcher;
+ /**
+ * The searcher for this weight.
+ */
+ protected final Searcher searcher;
- /**
- * Creates a new <code>AbstractWeight</code> for the given
- * <code>searcher</code>.
- *
- * @param searcher the searcher instance for this weight.
- */
- public AbstractWeight(Searcher searcher) {
- this.searcher = searcher;
- }
+ /**
+ * Creates a new <code>AbstractWeight</code> for the given
+ * <code>searcher</code>.
+ *
+ * @param searcher the searcher instance for this weight.
+ */
+ public AbstractWeight(Searcher searcher)
+ {
+ this.searcher = searcher;
+ }
- /**
- * Abstract factory method for crating a scorer instance for the
- * specified reader.
- *
- * @param reader the index reader the created scorer instance should use
- * @return the scorer instance
- * @throws IOException if an error occurs while reading from the index
- */
- protected abstract Scorer createScorer(IndexReader reader)
- throws IOException;
+ /**
+ * Abstract factory method for crating a scorer instance for the
+ * specified reader.
+ *
+ * @param reader the index reader the created scorer instance should use
+ * @return the scorer instance
+ * @throws IOException if an error occurs while reading from the index
+ */
+ protected abstract Scorer createScorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer)
+ throws IOException;
- /**
- * {@inheritDoc}
- * <p/>
- * Returns a {@link MultiScorer} if the passed <code>reader</code> is of
- * type {@link MultiIndexReader}.
- */
- public Scorer scorer(IndexReader reader) throws IOException {
- if (reader instanceof MultiIndexReader) {
- MultiIndexReader mir = (MultiIndexReader) reader;
- IndexReader[] readers = mir.getIndexReaders();
- int[] starts = new int[readers.length + 1];
- int maxDoc = 0;
- for (int i = 0; i < readers.length; i++) {
- starts[i] = maxDoc;
- maxDoc += readers[i].maxDoc();
- }
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Returns a {@link MultiScorer} if the passed <code>reader</code> is of
+ * type {@link MultiIndexReader}.
+ */
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
+ {
+ if (reader instanceof MultiIndexReader)
+ {
+ MultiIndexReader mir = (MultiIndexReader)reader;
+ IndexReader[] readers = mir.getIndexReaders();
+ int[] starts = new int[readers.length + 1];
+ int maxDoc = 0;
+ for (int i = 0; i < readers.length; i++)
+ {
+ starts[i] = maxDoc;
+ maxDoc += readers[i].maxDoc();
+ }
- starts[readers.length] = maxDoc;
- Scorer[] scorers = new Scorer[readers.length];
- for (int i = 0; i < readers.length; i++) {
- scorers[i] = scorer(readers[i]);
- }
+ starts[readers.length] = maxDoc;
+ Scorer[] scorers = new Scorer[readers.length];
+ for (int i = 0; i < readers.length; i++)
+ {
+ scorers[i] = scorer(readers[i], scoreDocsInOrder, topScorer);
+ }
- return new MultiScorer(searcher.getSimilarity(), scorers, starts);
- } else {
- return createScorer(reader);
- }
- }
+ return new MultiScorer(searcher.getSimilarity(), scorers, starts);
+ }
+ else
+ {
+ return createScorer(reader, scoreDocsInOrder, topScorer);
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingIndexReader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingIndexReader.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingIndexReader.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -278,7 +278,7 @@
*/
public TermDocs termDocs(Term term) throws IOException
{
- if (term.field() == FieldNames.UUID)
+ if (term!=null && term.field() == FieldNames.UUID)
{
// check cache if we have one
if (cache != null)
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingMultiIndexReader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingMultiIndexReader.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/CachingMultiIndexReader.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -113,7 +113,7 @@
* {@inheritDoc}
*/
public TermDocs termDocs(Term term) throws IOException {
- if (term.field() == FieldNames.UUID) {
+ if (term!=null && term.field() == FieldNames.UUID) {
// check cache
DocNumberCache.Entry e = cache.get(term.text());
if (e != null) {
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -192,7 +192,8 @@
* @param searcher the <code>Searcher</code> instance to use.
* @return a <code>ChildAxisWeight</code>.
*/
- protected Weight createWeight(Searcher searcher)
+ @Override
+ public Weight createWeight(Searcher searcher)
{
return new ChildAxisWeight(searcher);
}
@@ -200,6 +201,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void extractTerms(Set terms)
{
contextQuery.extractTerms(terms);
@@ -208,6 +210,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Query rewrite(IndexReader reader) throws IOException
{
Query cQuery = contextQuery.rewrite(reader);
@@ -247,6 +250,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String toString(String field)
{
StringBuffer sb = new StringBuffer();
@@ -286,7 +290,7 @@
/**
* The <code>Weight</code> implementation for this <code>ChildAxisQuery</code>.
*/
- private class ChildAxisWeight implements Weight
+ private class ChildAxisWeight extends Weight
{
/**
@@ -310,6 +314,7 @@
*
* @return this <code>ChildAxisQuery</code>.
*/
+ @Override
public Query getQuery()
{
return ChildAxisQuery.this;
@@ -318,6 +323,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float getValue()
{
return 1.0f;
@@ -326,6 +332,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float sumOfSquaredWeights() throws IOException
{
return 1.0f;
@@ -334,6 +341,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void normalize(float norm)
{
}
@@ -345,12 +353,15 @@
* @return a <code>ChildAxisScorer</code>.
* @throws IOException if an error occurs while reading from the index.
*/
- public Scorer scorer(IndexReader reader) throws IOException
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
{
- contextScorer = contextQuery.weight(searcher).scorer(reader);
+ contextScorer = contextQuery.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
if (nameTest != null)
{
- nameTestScorer = new NameQuery(nameTest, version, nsMappings).weight(searcher).scorer(reader);
+ nameTestScorer =
+ new NameQuery(nameTest, version, nsMappings).weight(searcher)
+ .scorer(reader, scoreDocsInOrder, topScorer);
}
return new ChildAxisScorer(searcher.getSimilarity(), reader, (HierarchyResolver)reader);
}
@@ -358,6 +369,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Explanation explain(IndexReader reader, int doc) throws IOException
{
return new Explanation();
@@ -409,6 +421,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean next() throws IOException
{
calculateChildren();
@@ -424,6 +437,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public int doc()
{
return nextDoc;
@@ -432,6 +446,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float score() throws IOException
{
return 1.0f;
@@ -440,6 +455,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean skipTo(int target) throws IOException
{
calculateChildren();
@@ -457,6 +473,7 @@
* @throws UnsupportedOperationException this implementation always
* throws an <code>UnsupportedOperationException</code>.
*/
+ @Override
public Explanation explain(int doc) throws IOException
{
throw new UnsupportedOperationException();
@@ -474,6 +491,7 @@
calc[0] = new SimpleChildrenCalculator(reader, hResolver);
contextScorer.score(new HitCollector()
{
+ @Override
public void collect(int doc, float score)
{
calc[0].collectContextHit(doc);
@@ -489,6 +507,7 @@
private List docIds = new ArrayList();
+ @Override
public void collect(int doc, float score)
{
calc[0].collectContextHit(doc);
@@ -583,7 +602,9 @@
else
{
if (nodeData.getQPath().getIndex() != position)
+ {
return false;
+ }
}
}
}
@@ -667,6 +688,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected void collectContextHit(int doc)
{
contextHits.set(doc);
@@ -675,6 +697,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Hits getHits() throws IOException
{
// read the uuids of the context nodes
@@ -709,7 +732,9 @@
for (NodeData nodeData : childs)
{
if (nameTest.equals(nodeData.getQPath().getName()))
+ {
datas.add(nodeData);
+ }
}
}
@@ -775,6 +800,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected void collectContextHit(int doc)
{
docIds.add(new Integer(doc));
@@ -783,6 +809,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Hits getHits() throws IOException
{
long time = System.currentTimeMillis();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DerefQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,13 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
@@ -35,315 +28,383 @@
import org.apache.lucene.search.Weight;
import org.exoplatform.services.jcr.datamodel.InternalQName;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
/**
* Implements a lucene <code>Query</code> which returns the nodes selected by
* a reference property of the context node.
*/
-class DerefQuery extends Query {
+class DerefQuery extends Query
+{
- /**
- * The context query
- */
- private final Query contextQuery;
+ /**
+ * The context query
+ */
+ private final Query contextQuery;
- /**
- * The name of the reference property.
- */
- private final String refProperty;
+ /**
+ * The name of the reference property.
+ */
+ private final String refProperty;
- /**
- * The nameTest to apply on target node, or <code>null</code> if all
- * target nodes should be selected.
- */
- private final InternalQName nameTest;
+ /**
+ * The nameTest to apply on target node, or <code>null</code> if all
+ * target nodes should be selected.
+ */
+ private final InternalQName nameTest;
- /**
- * The index format version.
- */
- private final IndexFormatVersion version;
+ /**
+ * The index format version.
+ */
+ private final IndexFormatVersion version;
- /**
- * The internal namespace mappings.
- */
- private final NamespaceMappings nsMappings;
+ /**
+ * The internal namespace mappings.
+ */
+ private final NamespaceMappings nsMappings;
- /**
- * The scorer of the context query
- */
- private Scorer contextScorer;
+ /**
+ * The scorer of the context query
+ */
+ private Scorer contextScorer;
- /**
- * The scorer of the name test query
- */
- private Scorer nameTestScorer;
+ /**
+ * The scorer of the name test query
+ */
+ private Scorer nameTestScorer;
- /**
- * Creates a new <code>DerefQuery</code> based on a <code>context</code>
- * query.
- *
- * @param context the context for this query.
- * @param refProperty the name of the reference property.
- * @param nameTest a name test or <code>null</code> if any node is
- * selected.
- * @param version the index format version.
- * @param nsMappings the namespace mappings.
- */
- DerefQuery(Query context, String refProperty, InternalQName nameTest,
- IndexFormatVersion version, NamespaceMappings nsMappings) {
- this.contextQuery = context;
- this.refProperty = refProperty;
- this.nameTest = nameTest;
- this.version = version;
- this.nsMappings = nsMappings;
- }
+ /**
+ * Creates a new <code>DerefQuery</code> based on a <code>context</code>
+ * query.
+ *
+ * @param context the context for this query.
+ * @param refProperty the name of the reference property.
+ * @param nameTest a name test or <code>null</code> if any node is
+ * selected.
+ * @param version the index format version.
+ * @param nsMappings the namespace mappings.
+ */
+ DerefQuery(Query context, String refProperty, InternalQName nameTest, IndexFormatVersion version,
+ NamespaceMappings nsMappings)
+ {
+ this.contextQuery = context;
+ this.refProperty = refProperty;
+ this.nameTest = nameTest;
+ this.version = version;
+ this.nsMappings = nsMappings;
+ }
- /**
- * Creates a <code>Weight</code> instance for this query.
- *
- * @param searcher the <code>Searcher</code> instance to use.
- * @return a <code>DerefWeight</code>.
- */
- protected Weight createWeight(Searcher searcher) {
- return new DerefWeight(searcher);
- }
+ /**
+ * Creates a <code>Weight</code> instance for this query.
+ *
+ * @param searcher the <code>Searcher</code> instance to use.
+ * @return a <code>DerefWeight</code>.
+ */
+ @Override
+ public Weight createWeight(Searcher searcher)
+ {
+ return new DerefWeight(searcher);
+ }
- /**
- * Always returns 'DerefQuery'.
- *
- * @param field the name of a field.
- * @return 'DerefQuery'.
- */
- public String toString(String field) {
- return "DerefQuery";
- }
+ /**
+ * Always returns 'DerefQuery'.
+ *
+ * @param field the name of a field.
+ * @return 'DerefQuery'.
+ */
+ @Override
+ public String toString(String field)
+ {
+ return "DerefQuery";
+ }
- /**
- * {@inheritDoc}
- */
- public void extractTerms(Set terms) {
- // no terms to extract
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void extractTerms(Set terms)
+ {
+ // no terms to extract
+ }
- /**
- * {@inheritDoc}
- */
- public Query rewrite(IndexReader reader) throws IOException {
- Query cQuery = contextQuery.rewrite(reader);
- if (cQuery == contextQuery) {
- return this;
- } else {
- return new DerefQuery(cQuery, refProperty, nameTest, version, nsMappings);
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException
+ {
+ Query cQuery = contextQuery.rewrite(reader);
+ if (cQuery == contextQuery)
+ {
+ return this;
+ }
+ else
+ {
+ return new DerefQuery(cQuery, refProperty, nameTest, version, nsMappings);
+ }
+ }
- //-------------------< DerefWeight >------------------------------------
+ //-------------------< DerefWeight >------------------------------------
- /**
- * The <code>Weight</code> implementation for this <code>DerefQuery</code>.
- */
- private class DerefWeight implements Weight {
+ /**
+ * The <code>Weight</code> implementation for this <code>DerefQuery</code>.
+ */
+ private class DerefWeight extends Weight
+ {
- /**
- * The searcher in use
- */
- private final Searcher searcher;
+ /**
+ * The searcher in use
+ */
+ private final Searcher searcher;
- /**
- * Creates a new <code>DerefWeight</code> instance using
- * <code>searcher</code>.
- *
- * @param searcher a <code>Searcher</code> instance.
- */
- private DerefWeight(Searcher searcher) {
- this.searcher = searcher;
- }
+ /**
+ * Creates a new <code>DerefWeight</code> instance using
+ * <code>searcher</code>.
+ *
+ * @param searcher a <code>Searcher</code> instance.
+ */
+ private DerefWeight(Searcher searcher)
+ {
+ this.searcher = searcher;
+ }
- /**
- * Returns this <code>DerefQuery</code>.
- *
- * @return this <code>DerefQuery</code>.
- */
- public Query getQuery() {
- return DerefQuery.this;
- }
+ /**
+ * Returns this <code>DerefQuery</code>.
+ *
+ * @return this <code>DerefQuery</code>.
+ */
+ @Override
+ public Query getQuery()
+ {
+ return DerefQuery.this;
+ }
- /**
- * {@inheritDoc}
- */
- public float getValue() {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float getValue()
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public float sumOfSquaredWeights() throws IOException {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float sumOfSquaredWeights() throws IOException
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public void normalize(float norm) {
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void normalize(float norm)
+ {
+ }
- /**
- * Creates a scorer for this <code>DerefQuery</code>.
- *
- * @param reader a reader for accessing the index.
- * @return a <code>DerefScorer</code>.
- * @throws IOException if an error occurs while reading from the index.
- */
- public Scorer scorer(IndexReader reader) throws IOException {
- contextScorer = contextQuery.weight(searcher).scorer(reader);
- if (nameTest != null) {
- nameTestScorer = new NameQuery(nameTest, version, nsMappings).weight(searcher).scorer(reader);
- }
- return new DerefScorer(searcher.getSimilarity(), reader);
- }
+ /**
+ * Creates a scorer for this <code>DerefQuery</code>.
+ *
+ * @param reader a reader for accessing the index.
+ * @return a <code>DerefScorer</code>.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
+ {
+ contextScorer = contextQuery.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
+ if (nameTest != null)
+ {
+ nameTestScorer =
+ new NameQuery(nameTest, version, nsMappings).weight(searcher)
+ .scorer(reader, scoreDocsInOrder, topScorer);
+ }
+ return new DerefScorer(searcher.getSimilarity(), reader);
+ }
- /**
- * {@inheritDoc}
- */
- public Explanation explain(IndexReader reader, int doc) throws IOException {
- return new Explanation();
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException
+ {
+ return new Explanation();
+ }
+ }
- //----------------------< DerefScorer >---------------------------------
+ //----------------------< DerefScorer >---------------------------------
- /**
- * Implements a <code>Scorer</code> for this <code>DerefQuery</code>.
- */
- private class DerefScorer extends Scorer {
+ /**
+ * Implements a <code>Scorer</code> for this <code>DerefQuery</code>.
+ */
+ private class DerefScorer extends Scorer
+ {
- /**
- * An <code>IndexReader</code> to access the index.
- */
- private final IndexReader reader;
+ /**
+ * An <code>IndexReader</code> to access the index.
+ */
+ private final IndexReader reader;
- /**
- * BitSet storing the id's of selected documents
- */
- private final BitSet hits;
+ /**
+ * BitSet storing the id's of selected documents
+ */
+ private final BitSet hits;
- /**
- * List of UUIDs of selected nodes
- */
- private List uuids = null;
+ /**
+ * List of UUIDs of selected nodes
+ */
+ private List uuids = null;
- /**
- * The next document id to return
- */
- private int nextDoc = -1;
+ /**
+ * The next document id to return
+ */
+ private int nextDoc = -1;
- /**
- * Creates a new <code>DerefScorer</code>.
- *
- * @param similarity the <code>Similarity</code> instance to use.
- * @param reader for index access.
- */
- protected DerefScorer(Similarity similarity, IndexReader reader) {
- super(similarity);
- this.reader = reader;
- this.hits = new BitSet(reader.maxDoc());
- }
+ /**
+ * Creates a new <code>DerefScorer</code>.
+ *
+ * @param similarity the <code>Similarity</code> instance to use.
+ * @param reader for index access.
+ */
+ protected DerefScorer(Similarity similarity, IndexReader reader)
+ {
+ super(similarity);
+ this.reader = reader;
+ this.hits = new BitSet(reader.maxDoc());
+ }
- /**
- * {@inheritDoc}
- */
- public boolean next() throws IOException {
- calculateChildren();
- nextDoc = hits.nextSetBit(nextDoc + 1);
- return nextDoc > -1;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean next() throws IOException
+ {
+ calculateChildren();
+ nextDoc = hits.nextSetBit(nextDoc + 1);
+ return nextDoc > -1;
+ }
- /**
- * {@inheritDoc}
- */
- public int doc() {
- return nextDoc;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int doc()
+ {
+ return nextDoc;
+ }
- /**
- * {@inheritDoc}
- */
- public float score() throws IOException {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float score() throws IOException
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public boolean skipTo(int target) throws IOException {
- calculateChildren();
- nextDoc = hits.nextSetBit(target);
- return nextDoc > -1;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean skipTo(int target) throws IOException
+ {
+ calculateChildren();
+ nextDoc = hits.nextSetBit(target);
+ return nextDoc > -1;
+ }
- /**
- * {@inheritDoc}
- *
- * @throws UnsupportedOperationException this implementation always
- * throws an <code>UnsupportedOperationException</code>.
- */
- public Explanation explain(int doc) throws IOException {
- throw new UnsupportedOperationException();
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @throws UnsupportedOperationException this implementation always
+ * throws an <code>UnsupportedOperationException</code>.
+ */
+ @Override
+ public Explanation explain(int doc) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
- private void calculateChildren() throws IOException {
- if (uuids == null) {
- uuids = new ArrayList();
- contextScorer.score(new HitCollector() {
- public void collect(int doc, float score) {
- hits.set(doc);
- }
- });
+ private void calculateChildren() throws IOException
+ {
+ if (uuids == null)
+ {
+ uuids = new ArrayList();
+ contextScorer.score(new HitCollector()
+ {
+ @Override
+ public void collect(int doc, float score)
+ {
+ hits.set(doc);
+ }
+ });
- // collect nameTest hits
- final BitSet nameTestHits = new BitSet();
- if (nameTestScorer != null) {
- nameTestScorer.score(new HitCollector() {
- public void collect(int doc, float score) {
- nameTestHits.set(doc);
- }
- });
- }
+ // collect nameTest hits
+ final BitSet nameTestHits = new BitSet();
+ if (nameTestScorer != null)
+ {
+ nameTestScorer.score(new HitCollector()
+ {
+ @Override
+ public void collect(int doc, float score)
+ {
+ nameTestHits.set(doc);
+ }
+ });
+ }
- // retrieve uuids of target nodes
- String prefix = FieldNames.createNamedValue(refProperty, "");
- for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
- String[] values = reader.document(i).getValues(FieldNames.PROPERTIES);
- if (values == null) {
- // no reference properties at all on this node
- continue;
- }
- for (int v = 0; v < values.length; v++) {
- if (values[v].startsWith(prefix)) {
- uuids.add(values[v].substring(prefix.length()));
- }
- }
- }
+ // retrieve uuids of target nodes
+ String prefix = FieldNames.createNamedValue(refProperty, "");
+ for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1))
+ {
+ String[] values = reader.document(i).getValues(FieldNames.PROPERTIES);
+ if (values == null)
+ {
+ // no reference properties at all on this node
+ continue;
+ }
+ for (int v = 0; v < values.length; v++)
+ {
+ if (values[v].startsWith(prefix))
+ {
+ uuids.add(values[v].substring(prefix.length()));
+ }
+ }
+ }
- // collect the doc ids of all target nodes. we reuse the existing
- // bitset.
- hits.clear();
- for (Iterator it = uuids.iterator(); it.hasNext();) {
- TermDocs node = reader.termDocs(new Term(FieldNames.UUID, (String) it.next()));
- try {
- while (node.next()) {
- hits.set(node.doc());
- }
- } finally {
- node.close();
- }
- }
- // filter out the target nodes that do not match the name test
- // if there is any name test at all.
- if (nameTestScorer != null) {
- hits.and(nameTestHits);
- }
+ // collect the doc ids of all target nodes. we reuse the existing
+ // bitset.
+ hits.clear();
+ for (Iterator it = uuids.iterator(); it.hasNext();)
+ {
+ TermDocs node = reader.termDocs(new Term(FieldNames.UUID, (String)it.next()));
+ try
+ {
+ while (node.next())
+ {
+ hits.set(node.doc());
+ }
+ }
+ finally
+ {
+ node.close();
+ }
}
- }
- }
+ // filter out the target nodes that do not match the name test
+ // if there is any name test at all.
+ if (nameTestScorer != null)
+ {
+ hits.and(nameTestHits);
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DescendantSelfAxisQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -181,7 +181,8 @@
* @param searcher the <code>Searcher</code> instance to use.
* @return a <code>DescendantSelfAxisWeight</code>.
*/
- protected Weight createWeight(Searcher searcher)
+ @Override
+ public Weight createWeight(Searcher searcher)
{
return new DescendantSelfAxisWeight(searcher);
}
@@ -189,6 +190,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String toString(String field)
{
StringBuffer sb = new StringBuffer();
@@ -205,6 +207,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void extractTerms(Set terms)
{
contextQuery.extractTerms(terms);
@@ -214,6 +217,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Query rewrite(IndexReader reader) throws IOException
{
Query cQuery = contextQuery.rewrite(reader);
@@ -314,6 +318,7 @@
fetchNextTraversal();
}
+ @Override
public void close() throws IOException
{
if (currentTraversal != null)
@@ -379,7 +384,7 @@
* The <code>Weight</code> implementation for this
* <code>DescendantSelfAxisWeight</code>.
*/
- private class DescendantSelfAxisWeight implements Weight
+ private class DescendantSelfAxisWeight extends Weight
{
/**
@@ -405,6 +410,7 @@
*
* @return this <code>DescendantSelfAxisQuery</code>.
*/
+ @Override
public Query getQuery()
{
return DescendantSelfAxisQuery.this;
@@ -413,6 +419,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float getValue()
{
return 1.0f;
@@ -421,6 +428,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float sumOfSquaredWeights() throws IOException
{
return 1.0f;
@@ -429,6 +437,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void normalize(float norm)
{
}
@@ -440,10 +449,11 @@
* @return a <code>DescendantSelfAxisScorer</code>.
* @throws IOException if an error occurs while reading from the index.
*/
- public Scorer scorer(IndexReader reader) throws IOException
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
{
- contextScorer = contextQuery.weight(searcher).scorer(reader);
- subScorer = subQuery.weight(searcher).scorer(reader);
+ contextScorer = contextQuery.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
+ subScorer = subQuery.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
HierarchyResolver resolver = (HierarchyResolver)reader;
return new DescendantSelfAxisScorer(searcher.getSimilarity(), reader, resolver);
}
@@ -451,6 +461,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Explanation explain(IndexReader reader, int doc) throws IOException
{
return new Explanation();
@@ -513,6 +524,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean next() throws IOException
{
collectContextHits();
@@ -538,6 +550,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public int doc()
{
return subScorer.doc();
@@ -546,6 +559,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float score() throws IOException
{
return subScorer.score();
@@ -554,6 +568,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean skipTo(int target) throws IOException
{
boolean match = subScorer.skipTo(target);
@@ -575,6 +590,7 @@
long time = System.currentTimeMillis();
contextScorer.score(new HitCollector()
{
+ @Override
public void collect(int doc, float score)
{
contextHits.set(doc);
@@ -594,6 +610,7 @@
* @throws UnsupportedOperationException this implementation always
* throws an <code>UnsupportedOperationException</code>.
*/
+ @Override
public Explanation explain(int doc) throws IOException
{
throw new UnsupportedOperationException();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexReader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexReader.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexReader.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -115,4 +115,14 @@
public void release() throws IOException {
reader.release();
}
+
+ @Override
+ public IndexReader[] getSequentialSubReaders()
+ {
+ // This method returns null, so Lucene internals doesn't explode this reader on it's subreaders.
+ // This is used to retrieve this index reader as HierarchyResolver in ChildAxisQuery. If this method
+ // is not overridden with null-returning one, then ClassCast exception is thrown.
+ // This solution confirmed via Lucene mailing-list on May 27 2010.
+ return null;
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexSearcher.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexSearcher.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrIndexSearcher.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -107,7 +107,7 @@
{
if (sort == null)
{
- hits = new LuceneQueryHits(reader, JcrIndexSearcher.this, localQuery);
+ hits = new LuceneQueryHits(reader, JcrIndexSearcher.this, query);
}
else
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrTermQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrTermQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/JcrTermQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,8 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Explanation;
@@ -27,80 +25,99 @@
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.Weight;
+import java.io.IOException;
+
/**
* <code>JackrabbitTermQuery</code> implements a {@link TermQuery} where score
* values are retrieved on a per index segment basis using {@link MultiScorer}.
*/
-public class JcrTermQuery extends TermQuery {
+public class JcrTermQuery extends TermQuery
+{
- private static final long serialVersionUID = 4244799812287335957L;
+ private static final long serialVersionUID = 4244799812287335957L;
- public JcrTermQuery(Term t) {
- super(t);
- }
+ public JcrTermQuery(Term t)
+ {
+ super(t);
+ }
- protected Weight createWeight(Searcher searcher) throws IOException {
- return new JackrabbitTermWeight(searcher, super.createWeight(searcher));
- }
+ @Override
+ public Weight createWeight(Searcher searcher) throws IOException
+ {
+ return new JackrabbitTermWeight(searcher, super.createWeight(searcher));
+ }
- /**
- * The weight implementation.
- */
- protected class JackrabbitTermWeight extends AbstractWeight {
+ /**
+ * The weight implementation.
+ */
+ protected class JackrabbitTermWeight extends AbstractWeight
+ {
- private static final long serialVersionUID = -2070964510010945854L;
+ private static final long serialVersionUID = -2070964510010945854L;
- /**
- * The default lucene TermQuery weight.
- */
- private final Weight weight;
+ /**
+ * The default lucene TermQuery weight.
+ */
+ private final Weight weight;
- public JackrabbitTermWeight(Searcher searcher, Weight weight) {
- super(searcher);
- this.weight = weight;
- }
+ public JackrabbitTermWeight(Searcher searcher, Weight weight)
+ {
+ super(searcher);
+ this.weight = weight;
+ }
- /**
- * {@inheritDoc}
- */
- protected Scorer createScorer(IndexReader reader) throws IOException {
- return weight.scorer(reader);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Scorer createScorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
+ {
+ return weight.scorer(reader, scoreDocsInOrder, topScorer);
+ }
- /**
- * {@inheritDoc}
- */
- public Query getQuery() {
- return JcrTermQuery.this;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Query getQuery()
+ {
+ return JcrTermQuery.this;
+ }
- /**
- * {@inheritDoc}
- */
- public float getValue() {
- return weight.getValue();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float getValue()
+ {
+ return weight.getValue();
+ }
- /**
- * {@inheritDoc}
- */
- public float sumOfSquaredWeights() throws IOException {
- return weight.sumOfSquaredWeights();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float sumOfSquaredWeights() throws IOException
+ {
+ return weight.sumOfSquaredWeights();
+ }
- /**
- * {@inheritDoc}
- */
- public void normalize(float norm) {
- weight.normalize(norm);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void normalize(float norm)
+ {
+ weight.normalize(norm);
+ }
- /**
- * {@inheritDoc}
- */
- public Explanation explain(IndexReader reader, int doc) throws
- IOException {
- return weight.explain(reader, doc);
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException
+ {
+ return weight.explain(reader, doc);
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryHits.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryHits.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryHits.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -23,67 +23,72 @@
import java.io.IOException;
-
/**
* Wraps a lucene query result and adds a close method that allows to release
* resources after a query has been executed and the results have been read
* completely.
*/
-public class LuceneQueryHits implements QueryHits {
+public class LuceneQueryHits implements QueryHits
+{
- /**
- * The IndexReader in use by the lucene hits.
- */
- private final IndexReader reader;
+ /**
+ * The IndexReader in use by the lucene hits.
+ */
+ private final IndexReader reader;
- /**
- * The scorer for the query.
- */
- private final Scorer scorer;
+ /**
+ * The scorer for the query.
+ */
+ private final Scorer scorer;
- public LuceneQueryHits(IndexReader reader,
- IndexSearcher searcher,
- Query query)
- throws IOException {
- this.reader = reader;
- this.scorer = query.weight(searcher).scorer(reader);
- }
+ public LuceneQueryHits(IndexReader reader, IndexSearcher searcher, Query query) throws IOException
+ {
+ this.reader = reader;
+ this.scorer = query.weight(searcher).scorer(reader, true, false);
+ }
- /**
- * {@inheritDoc}
- */
- public ScoreNode nextScoreNode() throws IOException {
- if (!scorer.next()) {
- return null;
- }
- int doc = scorer.doc();
- String uuid = reader.document(doc).get(FieldNames.UUID);
- return new ScoreNode(uuid, scorer.score(), doc);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public ScoreNode nextScoreNode() throws IOException
+ {
+ if (!scorer.next())
+ {
+ return null;
+ }
+ int doc = scorer.doc();
+ String uuid = reader.document(doc).get(FieldNames.UUID);
+ return new ScoreNode(uuid, scorer.score(), doc);
+ }
- /**
- * {@inheritDoc}
- */
- public void close() throws IOException {
- // make sure scorer frees resources
- scorer.skipTo(Integer.MAX_VALUE);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws IOException
+ {
+ // make sure scorer frees resources
+ scorer.skipTo(Integer.MAX_VALUE);
+ }
- /**
- * @return always -1.
- */
- public int getSize() {
- return -1;
- }
+ /**
+ * @return always -1.
+ */
+ public int getSize()
+ {
+ return -1;
+ }
- /**
- * {@inheritDoc}
- */
- public void skip(int n) throws IOException {
- while (n-- > 0) {
- if (nextScoreNode() == null) {
- return;
- }
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void skip(int n) throws IOException
+ {
+ while (n-- > 0)
+ {
+ if (nextScoreNode() == null)
+ {
+ return;
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,12 +16,12 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.util.Set;
-
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Weight;
+import java.util.Set;
+
/**
* Specialized query that returns / scores all pages in the search index.
* <p>Use this Query to perform a match '*'.
@@ -50,7 +50,8 @@
* @param searcher the current searcher.
* @return the <code>Weight</code> for this Query.
*/
- protected Weight createWeight(Searcher searcher) {
+ @Override
+ public Weight createWeight(Searcher searcher) {
return new MatchAllWeight(this, searcher, field);
}
@@ -60,13 +61,15 @@
* @param field default field for the query.
* @return the String "%".
*/
- public String toString(String field) {
+ @Override
+ public String toString(String field) {
return "%";
}
/**
* Does nothing but simply returns. There are no terms to extract.
*/
- public void extractTerms(Set terms) {
+ @Override
+ public void extractTerms(Set terms) {
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllWeight.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllWeight.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MatchAllWeight.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,8 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Query;
@@ -25,6 +23,8 @@
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;
+import java.io.IOException;
+
/**
* This class implements the Weight calculation for the MatchAllQuery.
*/
@@ -72,28 +72,32 @@
* @param reader index reader
* @return a {@link MatchAllScorer} instance
*/
- protected Scorer createScorer(IndexReader reader) throws IOException {
+ @Override
+ protected Scorer createScorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
return new MatchAllScorer(reader, field);
}
/**
* {@inheritDoc}
*/
- public Query getQuery() {
+ @Override
+ public Query getQuery() {
return query;
}
/**
* {@inheritDoc}
*/
- public float getValue() {
+ @Override
+ public float getValue() {
return value;
}
/**
* {@inheritDoc}
*/
- public float sumOfSquaredWeights() throws IOException {
+ @Override
+ public float sumOfSquaredWeights() throws IOException {
idf = searcher.getSimilarity().idf(searcher.maxDoc(), searcher.maxDoc()); // compute idf
queryWeight = idf * 1.0f; // boost // compute query weight
return queryWeight * queryWeight; // square it
@@ -102,7 +106,8 @@
/**
* {@inheritDoc}
*/
- public void normalize(float queryNorm) {
+ @Override
+ public void normalize(float queryNorm) {
queryWeight *= queryNorm; // normalize query weight
value = queryWeight * idf; // idf for document
}
@@ -110,7 +115,8 @@
/**
* {@inheritDoc}
*/
- public Explanation explain(IndexReader reader, int doc) throws IOException {
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException {
return new Explanation(Similarity.getDefault().idf(reader.maxDoc(), reader.maxDoc()),
"matchAll");
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NotQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NotQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NotQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,9 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.Set;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Query;
@@ -27,217 +24,271 @@
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
+import java.io.IOException;
+import java.util.Set;
+
/**
* Implements a query that negates documents of a context query. Documents
* that matched the context query will not match the <code>NotQuery</code> and
* Documents that did not match the context query will be selected by this
* <code>NotQuery</code>.
*/
-class NotQuery extends Query {
+class NotQuery extends Query
+{
- /**
- * The context query to invert.
- */
- private final Query context;
+ /**
+ * The context query to invert.
+ */
+ private final Query context;
- /**
- * The context scorer to invert.
- */
- private Scorer contextScorer;
+ /**
+ * The context scorer to invert.
+ */
+ private Scorer contextScorer;
- /**
- * Creates a new <code>NotQuery</code>.
- * @param context the context query.
- */
- NotQuery(Query context) {
- this.context = context;
- }
+ /**
+ * Creates a new <code>NotQuery</code>.
+ * @param context the context query.
+ */
+ NotQuery(Query context)
+ {
+ this.context = context;
+ }
- /**
- * {@inheritDoc}
- */
- protected Weight createWeight(Searcher searcher) {
- return new NotQueryWeight(searcher);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Weight createWeight(Searcher searcher)
+ {
+ return new NotQueryWeight(searcher);
+ }
- /**
- * {@inheritDoc}
- */
- public String toString(String field) {
- return "NotQuery";
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString(String field)
+ {
+ return "NotQuery";
+ }
- /**
- * {@inheritDoc}
- */
- public void extractTerms(Set terms) {
- context.extractTerms(terms);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void extractTerms(Set terms)
+ {
+ context.extractTerms(terms);
+ }
- /**
- * {@inheritDoc}
- */
- public Query rewrite(IndexReader reader) throws IOException {
- Query cQuery = context.rewrite(reader);
- if (cQuery == context) {
- return this;
- } else {
- return new NotQuery(cQuery);
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException
+ {
+ Query cQuery = context.rewrite(reader);
+ if (cQuery == context)
+ {
+ return this;
+ }
+ else
+ {
+ return new NotQuery(cQuery);
+ }
+ }
- /**
- * Implements a weight for this <code>NotQuery</code>.
- */
- private class NotQueryWeight implements Weight {
+ /**
+ * Implements a weight for this <code>NotQuery</code>.
+ */
+ private class NotQueryWeight extends Weight
+ {
- /**
- * The searcher to access the index.
- */
- private final Searcher searcher;
+ /**
+ * The searcher to access the index.
+ */
+ private final Searcher searcher;
- /**
- * Creates a new NotQueryWeight with a searcher.
- * @param searcher the searcher.
- */
- NotQueryWeight(Searcher searcher) {
- this.searcher = searcher;
- }
+ /**
+ * Creates a new NotQueryWeight with a searcher.
+ * @param searcher the searcher.
+ */
+ NotQueryWeight(Searcher searcher)
+ {
+ this.searcher = searcher;
+ }
- /**
- * @inheritDoc
- */
- public Query getQuery() {
- return NotQuery.this;
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public Query getQuery()
+ {
+ return NotQuery.this;
+ }
- /**
- * @inheritDoc
- */
- public float getValue() {
- return 1.0f;
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public float getValue()
+ {
+ return 1.0f;
+ }
- /**
- * @inheritDoc
- */
- public float sumOfSquaredWeights() throws IOException {
- return 1.0f;
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public float sumOfSquaredWeights() throws IOException
+ {
+ return 1.0f;
+ }
- /**
- * @inheritDoc
- */
- public void normalize(float norm) {
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public void normalize(float norm)
+ {
+ }
- /**
- * @inheritDoc
- */
- public Scorer scorer(IndexReader reader) throws IOException {
- contextScorer = context.weight(searcher).scorer(reader);
- return new NotQueryScorer(reader);
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
+ {
+ contextScorer = context.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
+ return new NotQueryScorer(reader);
+ }
- /**
- * @throws UnsupportedOperationException always
- */
- public Explanation explain(IndexReader reader, int doc) throws IOException {
- throw new UnsupportedOperationException();
- }
- }
+ /**
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
- /**
- * Implements a scorer that inverts the document matches of the context
- * scorer.
- */
- private class NotQueryScorer extends Scorer {
+ /**
+ * Implements a scorer that inverts the document matches of the context
+ * scorer.
+ */
+ private class NotQueryScorer extends Scorer
+ {
- /**
- * The index reader.
- */
- private final IndexReader reader;
+ /**
+ * The index reader.
+ */
+ private final IndexReader reader;
- /**
- * Current document number.
- */
- private int docNo = -1;
+ /**
+ * Current document number.
+ */
+ private int docNo = -1;
- /**
- * Current document number of the context scorer;
- */
- private int contextNo = -1;
+ /**
+ * Current document number of the context scorer;
+ */
+ private int contextNo = -1;
- /**
- * Creates a new scorer
- * @param reader
- */
- NotQueryScorer(IndexReader reader) {
- super(Similarity.getDefault());
- this.reader = reader;
- }
+ /**
+ * Creates a new scorer
+ * @param reader
+ */
+ NotQueryScorer(IndexReader reader)
+ {
+ super(Similarity.getDefault());
+ this.reader = reader;
+ }
- /**
- * {@inheritDoc}
- */
- public boolean next() throws IOException {
- if (docNo == -1) {
- // get first doc of context scorer
- if (contextScorer.next()) {
- contextNo = contextScorer.doc();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean next() throws IOException
+ {
+ if (docNo == -1)
+ {
+ // get first doc of context scorer
+ if (contextScorer.next())
+ {
+ contextNo = contextScorer.doc();
}
- // move to next candidate
- do {
- docNo++;
- } while (reader.isDeleted(docNo) && docNo < reader.maxDoc());
+ }
+ // move to next candidate
+ do
+ {
+ docNo++;
+ }
+ while (reader.isDeleted(docNo) && docNo < reader.maxDoc());
- // check with contextScorer
- while (contextNo != -1 && contextNo == docNo) {
- docNo++;
- if (contextScorer.next()) {
- contextNo = contextScorer.doc();
- } else {
- contextNo = -1;
- }
+ // check with contextScorer
+ while (contextNo != -1 && contextNo == docNo)
+ {
+ docNo++;
+ if (contextScorer.next())
+ {
+ contextNo = contextScorer.doc();
}
- return docNo < reader.maxDoc();
- }
+ else
+ {
+ contextNo = -1;
+ }
+ }
+ return docNo < reader.maxDoc();
+ }
- /**
- * {@inheritDoc}
- */
- public int doc() {
- return docNo;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int doc()
+ {
+ return docNo;
+ }
- /**
- * {@inheritDoc}
- */
- public float score() throws IOException {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float score() throws IOException
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public boolean skipTo(int target) throws IOException {
- if (contextNo != -1 && contextNo < target) {
- if (contextScorer.skipTo(target)) {
- contextNo = contextScorer.doc();
- } else {
- contextNo = -1;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean skipTo(int target) throws IOException
+ {
+ if (contextNo != -1 && contextNo < target)
+ {
+ if (contextScorer.skipTo(target))
+ {
+ contextNo = contextScorer.doc();
}
- docNo = target - 1;
- return next();
- }
+ else
+ {
+ contextNo = -1;
+ }
+ }
+ docNo = target - 1;
+ return next();
+ }
- /**
- * @throws UnsupportedOperationException always
- */
- public Explanation explain(int doc) throws IOException {
- throw new UnsupportedOperationException();
- }
- }
+ /**
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Explanation explain(int doc) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ParentAxisQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,12 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.HitCollector;
@@ -30,339 +24,402 @@
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
-
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.Hits;
import org.exoplatform.services.jcr.impl.core.query.lucene.hits.ScorerHits;
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
/**
* <code>ParentAxisQuery</code> selects the parent nodes of a context query.
*/
-class ParentAxisQuery extends Query {
+class ParentAxisQuery extends Query
+{
- /**
- * Default score is 1.0f.
- */
- private static final Float DEFAULT_SCORE = new Float(1.0f);
+ /**
+ * Default score is 1.0f.
+ */
+ private static final Float DEFAULT_SCORE = new Float(1.0f);
- /**
- * The context query
- */
- private final Query contextQuery;
+ /**
+ * The context query
+ */
+ private final Query contextQuery;
- /**
- * The nameTest to apply on the parent axis, or <code>null</code> if any
- * parent node should be selected.
- */
- private final InternalQName nameTest;
+ /**
+ * The nameTest to apply on the parent axis, or <code>null</code> if any
+ * parent node should be selected.
+ */
+ private final InternalQName nameTest;
- /**
- * The index format version.
- */
- private final IndexFormatVersion version;
+ /**
+ * The index format version.
+ */
+ private final IndexFormatVersion version;
- /**
- * The internal namespace mappings.
- */
- private final NamespaceMappings nsMappings;
+ /**
+ * The internal namespace mappings.
+ */
+ private final NamespaceMappings nsMappings;
- /**
- * The scorer of the context query
- */
- private Scorer contextScorer;
+ /**
+ * The scorer of the context query
+ */
+ private Scorer contextScorer;
- /**
- * Creates a new <code>ParentAxisQuery</code> based on a
- * <code>context</code> query.
- *
- * @param context the context for this query.
- * @param nameTest a name test or <code>null</code> if any parent node is
- * selected.
- * @param version the index format version.
- * @param nsMappings the internal namespace mappings.
- */
- ParentAxisQuery(Query context, InternalQName nameTest,
- IndexFormatVersion version, NamespaceMappings nsMappings) {
- this.contextQuery = context;
- this.nameTest = nameTest;
- this.version = version;
- this.nsMappings = nsMappings;
- }
+ /**
+ * Creates a new <code>ParentAxisQuery</code> based on a
+ * <code>context</code> query.
+ *
+ * @param context the context for this query.
+ * @param nameTest a name test or <code>null</code> if any parent node is
+ * selected.
+ * @param version the index format version.
+ * @param nsMappings the internal namespace mappings.
+ */
+ ParentAxisQuery(Query context, InternalQName nameTest, IndexFormatVersion version, NamespaceMappings nsMappings)
+ {
+ this.contextQuery = context;
+ this.nameTest = nameTest;
+ this.version = version;
+ this.nsMappings = nsMappings;
+ }
- /**
- * Creates a <code>Weight</code> instance for this query.
- *
- * @param searcher the <code>Searcher</code> instance to use.
- * @return a <code>ParentAxisWeight</code>.
- */
- protected Weight createWeight(Searcher searcher) {
- return new ParentAxisWeight(searcher);
- }
+ /**
+ * Creates a <code>Weight</code> instance for this query.
+ *
+ * @param searcher the <code>Searcher</code> instance to use.
+ * @return a <code>ParentAxisWeight</code>.
+ */
+ @Override
+ public Weight createWeight(Searcher searcher)
+ {
+ return new ParentAxisWeight(searcher);
+ }
- /**
- * {@inheritDoc}
- */
- public void extractTerms(Set terms) {
- contextQuery.extractTerms(terms);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void extractTerms(Set terms)
+ {
+ contextQuery.extractTerms(terms);
+ }
- /**
- * {@inheritDoc}
- */
- public Query rewrite(IndexReader reader) throws IOException {
- Query cQuery = contextQuery.rewrite(reader);
- if (cQuery == contextQuery) {
- return this;
- } else {
- return new ParentAxisQuery(cQuery, nameTest, version, nsMappings);
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException
+ {
+ Query cQuery = contextQuery.rewrite(reader);
+ if (cQuery == contextQuery)
+ {
+ return this;
+ }
+ else
+ {
+ return new ParentAxisQuery(cQuery, nameTest, version, nsMappings);
+ }
+ }
- /**
- * Always returns 'ParentAxisQuery'.
- *
- * @param field the name of a field.
- * @return 'ParentAxisQuery'.
- */
- public String toString(String field) {
- return "ParentAxisQuery "+"nameTest="+(nameTest!=null?nameTest.toString():"null")+" contextQuery="+contextQuery.toString();
- }
+ /**
+ * Always returns 'ParentAxisQuery'.
+ *
+ * @param field the name of a field.
+ * @return 'ParentAxisQuery'.
+ */
+ @Override
+ public String toString(String field)
+ {
+ return "ParentAxisQuery " + "nameTest=" + (nameTest != null ? nameTest.toString() : "null") + " contextQuery="
+ + contextQuery.toString();
+ }
- //-----------------------< ParentAxisWeight >-------------------------------
+ //-----------------------< ParentAxisWeight >-------------------------------
- /**
- * The <code>Weight</code> implementation for this <code>ParentAxisQuery</code>.
- */
- private class ParentAxisWeight implements Weight {
+ /**
+ * The <code>Weight</code> implementation for this <code>ParentAxisQuery</code>.
+ */
+ private class ParentAxisWeight extends Weight
+ {
- /**
- * The searcher in use
- */
- private final Searcher searcher;
+ /**
+ * The searcher in use
+ */
+ private final Searcher searcher;
- /**
- * Creates a new <code>ParentAxisWeight</code> instance using
- * <code>searcher</code>.
- *
- * @param searcher a <code>Searcher</code> instance.
- */
- private ParentAxisWeight(Searcher searcher) {
- this.searcher = searcher;
- }
+ /**
+ * Creates a new <code>ParentAxisWeight</code> instance using
+ * <code>searcher</code>.
+ *
+ * @param searcher a <code>Searcher</code> instance.
+ */
+ private ParentAxisWeight(Searcher searcher)
+ {
+ this.searcher = searcher;
+ }
- /**
- * Returns this <code>ParentAxisQuery</code>.
- *
- * @return this <code>ParentAxisQuery</code>.
- */
- public Query getQuery() {
- return ParentAxisQuery.this;
- }
+ /**
+ * Returns this <code>ParentAxisQuery</code>.
+ *
+ * @return this <code>ParentAxisQuery</code>.
+ */
+ @Override
+ public Query getQuery()
+ {
+ return ParentAxisQuery.this;
+ }
- /**
- * {@inheritDoc}
- */
- public float getValue() {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float getValue()
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public float sumOfSquaredWeights() throws IOException {
- return 1.0f;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float sumOfSquaredWeights() throws IOException
+ {
+ return 1.0f;
+ }
- /**
- * {@inheritDoc}
- */
- public void normalize(float norm) {
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void normalize(float norm)
+ {
+ }
- /**
- * Creates a scorer for this <code>ParentAxisQuery</code>.
- *
- * @param reader a reader for accessing the index.
- * @return a <code>ParentAxisScorer</code>.
- * @throws IOException if an error occurs while reading from the index.
- */
- public Scorer scorer(IndexReader reader) throws IOException {
- contextScorer = contextQuery.weight(searcher).scorer(reader);
- HierarchyResolver resolver = (HierarchyResolver) reader;
- return new ParentAxisScorer(searcher.getSimilarity(),
- reader, searcher, resolver);
- }
+ /**
+ * Creates a scorer for this <code>ParentAxisQuery</code>.
+ *
+ * @param reader a reader for accessing the index.
+ * @return a <code>ParentAxisScorer</code>.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException
+ {
+ contextScorer = contextQuery.weight(searcher).scorer(reader, scoreDocsInOrder, topScorer);
+ HierarchyResolver resolver = (HierarchyResolver)reader;
+ return new ParentAxisScorer(searcher.getSimilarity(), reader, searcher, resolver);
+ }
- /**
- * {@inheritDoc}
- */
- public Explanation explain(IndexReader reader, int doc) throws IOException {
- return new Explanation();
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException
+ {
+ return new Explanation();
+ }
+ }
- //--------------------------< ParentAxisScorer >----------------------------
+ //--------------------------< ParentAxisScorer >----------------------------
- /**
- * Implements a <code>Scorer</code> for this <code>ParentAxisQuery</code>.
- */
- private class ParentAxisScorer extends Scorer {
+ /**
+ * Implements a <code>Scorer</code> for this <code>ParentAxisQuery</code>.
+ */
+ private class ParentAxisScorer extends Scorer
+ {
- /**
- * An <code>IndexReader</code> to access the index.
- */
- private final IndexReader reader;
+ /**
+ * An <code>IndexReader</code> to access the index.
+ */
+ private final IndexReader reader;
- /**
- * The <code>HierarchyResolver</code> of the index.
- */
- private final HierarchyResolver hResolver;
+ /**
+ * The <code>HierarchyResolver</code> of the index.
+ */
+ private final HierarchyResolver hResolver;
- /**
- * The searcher instance.
- */
- private final Searcher searcher;
+ /**
+ * The searcher instance.
+ */
+ private final Searcher searcher;
- /**
- * BitSet storing the id's of selected documents
- */
- private BitSet hits;
+ /**
+ * BitSet storing the id's of selected documents
+ */
+ private BitSet hits;
- /**
- * Map that contains the scores from matching documents from the context
- * query. To save memory only scores that are not equal to 1.0f are put
- * to this map.
- * <p/>
- * key=[Integer] id of selected document from context query<br>
- * value=[Float] score for that document
- */
- private final Map scores = new HashMap();
+ /**
+ * Map that contains the scores from matching documents from the context
+ * query. To save memory only scores that are not equal to 1.0f are put
+ * to this map.
+ * <p/>
+ * key=[Integer] id of selected document from context query<br>
+ * value=[Float] score for that document
+ */
+ private final Map scores = new HashMap();
- /**
- * The next document id to return
- */
- private int nextDoc = -1;
+ /**
+ * The next document id to return
+ */
+ private int nextDoc = -1;
- /**
- * Creates a new <code>ParentAxisScorer</code>.
- *
- * @param similarity the <code>Similarity</code> instance to use.
- * @param reader for index access.
- * @param searcher the index searcher.
- * @param resolver the hierarchy resolver.
- */
- protected ParentAxisScorer(Similarity similarity,
- IndexReader reader,
- Searcher searcher,
- HierarchyResolver resolver) {
- super(similarity);
- this.reader = reader;
- this.searcher = searcher;
- this.hResolver = resolver;
- }
+ /**
+ * Creates a new <code>ParentAxisScorer</code>.
+ *
+ * @param similarity the <code>Similarity</code> instance to use.
+ * @param reader for index access.
+ * @param searcher the index searcher.
+ * @param resolver the hierarchy resolver.
+ */
+ protected ParentAxisScorer(Similarity similarity, IndexReader reader, Searcher searcher,
+ HierarchyResolver resolver)
+ {
+ super(similarity);
+ this.reader = reader;
+ this.searcher = searcher;
+ this.hResolver = resolver;
+ }
- /**
- * {@inheritDoc}
- */
- public boolean next() throws IOException {
- calculateParent();
- nextDoc = hits.nextSetBit(nextDoc + 1);
- return nextDoc > -1;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean next() throws IOException
+ {
+ calculateParent();
+ nextDoc = hits.nextSetBit(nextDoc + 1);
+ return nextDoc > -1;
+ }
- /**
- * {@inheritDoc}
- */
- public int doc() {
- return nextDoc;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int doc()
+ {
+ return nextDoc;
+ }
- /**
- * {@inheritDoc}
- */
- public float score() throws IOException {
- Float score = (Float) scores.get(new Integer(nextDoc));
- if (score == null) {
- score = DEFAULT_SCORE;
- }
- return score.floatValue();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float score() throws IOException
+ {
+ Float score = (Float)scores.get(new Integer(nextDoc));
+ if (score == null)
+ {
+ score = DEFAULT_SCORE;
+ }
+ return score.floatValue();
+ }
- /**
- * {@inheritDoc}
- */
- public boolean skipTo(int target) throws IOException {
- calculateParent();
- nextDoc = hits.nextSetBit(target);
- return nextDoc > -1;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean skipTo(int target) throws IOException
+ {
+ calculateParent();
+ nextDoc = hits.nextSetBit(target);
+ return nextDoc > -1;
+ }
- /**
- * {@inheritDoc}
- *
- * @throws UnsupportedOperationException this implementation always
- * throws an <code>UnsupportedOperationException</code>.
- */
- public Explanation explain(int doc) throws IOException {
- throw new UnsupportedOperationException();
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @throws UnsupportedOperationException this implementation always
+ * throws an <code>UnsupportedOperationException</code>.
+ */
+ @Override
+ public Explanation explain(int doc) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
- private void calculateParent() throws IOException {
- if (hits == null) {
- hits = new BitSet(reader.maxDoc());
+ private void calculateParent() throws IOException
+ {
+ if (hits == null)
+ {
+ hits = new BitSet(reader.maxDoc());
- final IOException[] ex = new IOException[1];
- contextScorer.score(new HitCollector() {
+ final IOException[] ex = new IOException[1];
+ contextScorer.score(new HitCollector()
+ {
- private int[] docs = new int[1];
+ private int[] docs = new int[1];
- public void collect(int doc, float score) {
- try {
- docs = hResolver.getParents(doc, docs);
- if (docs.length == 1) {
- // optimize single value
- hits.set(docs[0]);
- if (score != DEFAULT_SCORE.floatValue()) {
- scores.put(new Integer(docs[0]), new Float(score));
- }
- } else {
- for (int i = 0; i < docs.length; i++) {
- hits.set(docs[i]);
- if (score != DEFAULT_SCORE.floatValue()) {
- scores.put(new Integer(docs[i]), new Float(score));
- }
- }
- }
- } catch (IOException e) {
- ex[0] = e;
+ @Override
+ public void collect(int doc, float score)
+ {
+ try
+ {
+ docs = hResolver.getParents(doc, docs);
+ if (docs.length == 1)
+ {
+ // optimize single value
+ hits.set(docs[0]);
+ if (score != DEFAULT_SCORE.floatValue())
+ {
+ scores.put(new Integer(docs[0]), new Float(score));
}
- }
- });
+ }
+ else
+ {
+ for (int i = 0; i < docs.length; i++)
+ {
+ hits.set(docs[i]);
+ if (score != DEFAULT_SCORE.floatValue())
+ {
+ scores.put(new Integer(docs[i]), new Float(score));
+ }
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ ex[0] = e;
+ }
+ }
+ });
- if (ex[0] != null) {
- throw ex[0];
- }
+ if (ex[0] != null)
+ {
+ throw ex[0];
+ }
- // filter out documents that do not match the name test
- if (nameTest != null) {
- Query nameQuery = new NameQuery(nameTest, version, nsMappings);
- Hits nameHits = new ScorerHits(nameQuery.weight(searcher).scorer(reader));
- for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
- int doc = nameHits.skipTo(i);
- if (doc == -1) {
- // no more name tests, clear remaining
- hits.clear(i, hits.length());
- } else {
- // assert doc >= i
- if (doc > i) {
- // clear hits
- hits.clear(i, doc);
- i = doc;
- }
- }
- }
- }
+ // filter out documents that do not match the name test
+ if (nameTest != null)
+ {
+ Query nameQuery = new NameQuery(nameTest, version, nsMappings);
+ Hits nameHits = new ScorerHits(nameQuery.weight(searcher).scorer(reader, true, false));
+ for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1))
+ {
+ int doc = nameHits.skipTo(i);
+ if (doc == -1)
+ {
+ // no more name tests, clear remaining
+ hits.clear(i, hits.length());
+ }
+ else
+ {
+ // assert doc >= i
+ if (doc > i)
+ {
+ // clear hits
+ hits.clear(i, doc);
+ i = doc;
+ }
+ }
+ }
}
- }
- }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryHitsQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryHitsQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryHitsQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,13 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
@@ -35,6 +28,13 @@
import org.apache.lucene.search.Weight;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
/**
* <code>QueryHitsQuery</code> exposes a {@link QueryHits} implementation again
* as a Lucene Query.
@@ -58,21 +58,24 @@
/**
* {@inheritDoc}
*/
- protected Weight createWeight(Searcher searcher) throws IOException {
+ @Override
+ public Weight createWeight(Searcher searcher) throws IOException {
return new QueryHitsQueryWeight(searcher.getSimilarity());
}
/**
* {@inheritDoc}
*/
- public String toString(String field) {
+ @Override
+ public String toString(String field) {
return "QueryHitsQuery";
}
/**
* {@inheritDoc}
*/
- public void extractTerms(Set terms) {
+ @Override
+ public void extractTerms(Set terms) {
// no terms
}
@@ -96,7 +99,7 @@
/**
* The Weight implementation for this query.
*/
- public class QueryHitsQueryWeight implements Weight {
+ public class QueryHitsQueryWeight extends Weight {
/**
* The similarity.
@@ -115,41 +118,48 @@
/**
* {@inheritDoc}
*/
- public Query getQuery() {
+ @Override
+ public Query getQuery() {
return QueryHitsQuery.this;
}
/**
* {@inheritDoc}
*/
- public float getValue() {
+ @Override
+ public float getValue() {
return 1.0f;
}
/**
* {@inheritDoc}
*/
- public float sumOfSquaredWeights() throws IOException {
+ @Override
+ public float sumOfSquaredWeights() throws IOException {
return 1.0f;
}
/**
* {@inheritDoc}
*/
- public void normalize(float norm) {
+ @Override
+ public void normalize(float norm) {
}
/**
* {@inheritDoc}
*/
- public Scorer scorer(IndexReader reader) throws IOException {
+ @Override
+ public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
+ // TODO: use arguments!
return new QueryHitsQueryScorer(reader, similarity);
}
/**
* {@inheritDoc}
*/
- public Explanation explain(IndexReader reader, int doc) throws IOException {
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException {
return new Explanation();
}
}
@@ -215,7 +225,8 @@
/**
* {@inheritDoc}
*/
- public boolean next() throws IOException {
+ @Override
+ public boolean next() throws IOException {
if (docs.hasNext()) {
currentDoc = (Integer) docs.next();
return true;
@@ -226,21 +237,24 @@
/**
* {@inheritDoc}
*/
- public int doc() {
+ @Override
+ public int doc() {
return currentDoc.intValue();
}
/**
* {@inheritDoc}
*/
- public float score() throws IOException {
+ @Override
+ public float score() throws IOException {
return ((Float) scores.get(currentDoc)).floatValue();
}
/**
* {@inheritDoc}
*/
- public boolean skipTo(int target) throws IOException {
+ @Override
+ public boolean skipTo(int target) throws IOException {
do {
if (!next()) {
return false;
@@ -252,7 +266,8 @@
/**
* {@inheritDoc}
*/
- public Explanation explain(int doc) throws IOException {
+ @Override
+ public Explanation explain(int doc) throws IOException {
return new Explanation();
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RangeQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RangeQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RangeQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,15 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
@@ -37,6 +28,15 @@
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* Implements a lucene range query.
*/
@@ -121,7 +121,8 @@
* @return the rewritten query or this query if rewriting is not possible.
* @throws IOException if an error occurs.
*/
- public Query rewrite(IndexReader reader) throws IOException {
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
if (transform == TRANSFORM_NONE) {
return new ConstantScoreRangeQuery(lowerTerm.field(),
lowerTerm.text(), upperTerm.text(), inclusive,
@@ -139,7 +140,8 @@
* @param searcher the searcher to use for the <code>Weight</code>.
* @return the <code>Weigth</code> for this query.
*/
- protected Weight createWeight(Searcher searcher) {
+ @Override
+ public Weight createWeight(Searcher searcher) {
return new RangeQueryWeight(searcher);
}
@@ -148,7 +150,8 @@
* @param field the field name for which to create a string representation.
* @return a string representation of this query.
*/
- public String toString(String field) {
+ @Override
+ public String toString(String field) {
StringBuffer buffer = new StringBuffer();
if (!getField().equals(field)) {
buffer.append(getField());
@@ -169,7 +172,8 @@
/**
* {@inheritDoc}
*/
- public void extractTerms(Set terms) {
+ @Override
+ public void extractTerms(Set terms) {
// cannot extract terms
}
@@ -203,7 +207,8 @@
* @param reader index reader
* @return a {@link RangeQueryScorer} instance
*/
- protected Scorer createScorer(IndexReader reader) {
+ @Override
+ protected Scorer createScorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) {
return new RangeQueryScorer(searcher.getSimilarity(), reader);
};
@@ -212,34 +217,39 @@
*
* @return this <code>RangeQuery</code>.
*/
- public Query getQuery() {
+ @Override
+ public Query getQuery() {
return RangeQuery.this;
}
/**
* {@inheritDoc}
*/
- public float getValue() {
+ @Override
+ public float getValue() {
return 1.0f;
}
/**
* {@inheritDoc}
*/
- public float sumOfSquaredWeights() throws IOException {
+ @Override
+ public float sumOfSquaredWeights() throws IOException {
return 1.0f;
}
/**
* {@inheritDoc}
*/
- public void normalize(float norm) {
+ @Override
+ public void normalize(float norm) {
}
/**
* {@inheritDoc}
*/
- public Explanation explain(IndexReader reader, int doc) throws IOException {
+ @Override
+ public Explanation explain(IndexReader reader, int doc) throws IOException {
return new Explanation();
}
}
@@ -321,7 +331,8 @@
/**
* {@inheritDoc}
*/
- public boolean next() throws IOException {
+ @Override
+ public boolean next() throws IOException {
calculateHits();
nextDoc = hits.nextSetBit(nextDoc + 1);
return nextDoc > -1;
@@ -330,21 +341,24 @@
/**
* {@inheritDoc}
*/
- public int doc() {
+ @Override
+ public int doc() {
return nextDoc;
}
/**
* {@inheritDoc}
*/
- public float score() {
+ @Override
+ public float score() {
return 1.0f;
}
/**
* {@inheritDoc}
*/
- public boolean skipTo(int target) throws IOException {
+ @Override
+ public boolean skipTo(int target) throws IOException {
calculateHits();
nextDoc = hits.nextSetBit(target);
return nextDoc > -1;
@@ -354,7 +368,8 @@
* Returns an empty Explanation object.
* @return an empty Explanation object.
*/
- public Explanation explain(int doc) {
+ @Override
+ public Explanation explain(int doc) {
return new Explanation();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RefCountingIndexReader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RefCountingIndexReader.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RefCountingIndexReader.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -16,11 +16,11 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-
import org.apache.lucene.index.FilterIndexReader;
import org.apache.lucene.index.IndexReader;
+import java.io.IOException;
+
/**
* <code>RefCountingIndexReader</code>...
*/
@@ -48,7 +48,8 @@
/**
* @return the current reference count value.
*/
- synchronized int getRefCount() {
+ @Override
+ public synchronized int getRefCount() {
return refCount;
}
@@ -65,7 +66,8 @@
//-----------------------< FilterIndexReader >--------------------------
- protected void doClose() throws IOException {
+ @Override
+ protected void doClose() throws IOException {
Util.closeOrRelease(in);
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/TermDocsCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/TermDocsCache.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/TermDocsCache.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -92,7 +92,7 @@
*/
public TermDocs termDocs(final Term t) throws IOException
{
- if (t.field() != field)
+ if (t==null || t.field() != field)
{
return reader.termDocs(t);
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/WildcardQuery.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/WildcardQuery.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/WildcardQuery.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -129,10 +129,12 @@
* @return the rewritten query.
* @throws IOException if an error occurs while reading from the index.
*/
+ @Override
public Query rewrite(IndexReader reader) throws IOException
{
Query stdWildcardQuery = new MultiTermQuery(new Term(field, pattern))
{
+ @Override
protected FilteredTermEnum getEnum(IndexReader reader) throws IOException
{
return new WildcardTermEnum(reader, field, propName, pattern, transform);
@@ -157,7 +159,8 @@
* @param searcher the searcher to use for the <code>Weight</code>.
* @return the <code>Weigth</code> for this query.
*/
- protected Weight createWeight(Searcher searcher)
+ @Override
+ public Weight createWeight(Searcher searcher)
{
return new WildcardQueryWeight(searcher);
}
@@ -168,6 +171,7 @@
* @param field the field name for which to create a string representation.
* @return a string representation of this query.
*/
+ @Override
public String toString(String field)
{
return propName + ":" + pattern;
@@ -176,6 +180,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void extractTerms(Set terms)
{
if (multiTermQuery != null)
@@ -207,7 +212,8 @@
* @param reader index reader
* @return a {@link WildcardQueryScorer} instance
*/
- protected Scorer createScorer(IndexReader reader)
+ @Override
+ protected Scorer createScorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer)
{
return new WildcardQueryScorer(searcher.getSimilarity(), reader);
}
@@ -217,6 +223,7 @@
*
* @return this <code>WildcardQuery</code>.
*/
+ @Override
public Query getQuery()
{
return WildcardQuery.this;
@@ -225,6 +232,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float getValue()
{
return 1.0f;
@@ -233,6 +241,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float sumOfSquaredWeights() throws IOException
{
return 1.0f;
@@ -241,6 +250,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void normalize(float norm)
{
}
@@ -248,6 +258,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Explanation explain(IndexReader reader, int doc) throws IOException
{
return new Explanation();
@@ -326,6 +337,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean next() throws IOException
{
calculateHits();
@@ -336,6 +348,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public int doc()
{
return nextDoc;
@@ -344,6 +357,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public float score()
{
return 1.0f;
@@ -352,6 +366,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean skipTo(int target) throws IOException
{
calculateHits();
@@ -363,6 +378,7 @@
* Returns an empty Explanation object.
* @return an empty Explanation object.
*/
+ @Override
public Explanation explain(int doc)
{
return new Explanation();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/directory/FSDirectoryManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/directory/FSDirectoryManager.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/directory/FSDirectoryManager.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -89,7 +89,15 @@
{
dir = new File(baseDir, name);
}
- return FSDirectory.getDirectory(dir, new NativeFSLockFactory(dir));
+ // FSDirectory itself doesnt create dirs now
+ if (!dir.exists())
+ {
+ if (!dir.mkdirs())
+ {
+ throw new IOException("Cannot create directory: " + dir);
+ }
+ }
+ return FSDirectory.open(dir, new NativeFSLockFactory(dir));
}
});
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/directory/DirectoryManagerTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/directory/DirectoryManagerTest.java 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/directory/DirectoryManagerTest.java 2011-02-02 07:42:58 UTC (rev 3911)
@@ -33,88 +33,105 @@
* <code>DirectoryManagerTest</code> performs tests on directory manager
* implementations.
*/
-public class DirectoryManagerTest extends TestCase {
+public class DirectoryManagerTest extends TestCase
+{
- private static final Collection IMPLEMENTATIONS = Arrays
- .asList(new Class[] { FSDirectoryManager.class,
- RAMDirectoryManager.class });
+ private static final Collection IMPLEMENTATIONS =
+ Arrays.asList(new Class[]{FSDirectoryManager.class, RAMDirectoryManager.class});
- private static final SearchIndex INDEX = new SearchIndex();
+ private static final SearchIndex INDEX = new SearchIndex();
- private static final String TEST = "test";
+ private static final String TEST = "test";
- private static final String RENAMED = "renamed";
+ private static final String RENAMED = "renamed";
- static {
- INDEX.setPath(new File(new File("target"), "directory-factory-test")
- .getAbsolutePath());
- }
+ static
+ {
+ File dst = new File(new File("target"), "directory-factory-test");
+ dst.mkdirs();
+ INDEX.setPath(dst.getAbsolutePath());
+ }
- protected void tearDown() throws Exception {
- new File(INDEX.getPath(), TEST).delete();
- new File(INDEX.getPath(), RENAMED).delete();
- }
+ @Override
+ protected void tearDown() throws Exception
+ {
+// new File(INDEX.getPath(), TEST).delete();
+// new File(INDEX.getPath(), RENAMED).delete();
+ }
- public void testHasDirectory() throws Exception {
- execute(new Callable() {
- public void call(DirectoryManager directoryManager)
- throws Exception {
- Directory dir = directoryManager.getDirectory(TEST);
- assertTrue(directoryManager.hasDirectory(TEST));
- dir.close();
- }
- });
- }
+ public void testHasDirectory() throws Exception
+ {
+ execute(new Callable()
+ {
+ public void call(DirectoryManager directoryManager) throws Exception
+ {
+ Directory dir = directoryManager.getDirectory(TEST);
+ assertTrue("Impl:" + directoryManager.getClass().getName(), directoryManager.hasDirectory(TEST));
+ dir.close();
+ }
+ });
+ }
- public void testDelete() throws Exception {
- execute(new Callable() {
- public void call(DirectoryManager directoryManager)
- throws Exception {
- directoryManager.getDirectory(TEST).close();
- directoryManager.delete(TEST);
- assertFalse(directoryManager.hasDirectory(TEST));
- }
- });
- }
+ public void testDelete() throws Exception
+ {
+ execute(new Callable()
+ {
+ public void call(DirectoryManager directoryManager) throws Exception
+ {
+ directoryManager.getDirectory(TEST).close();
+ directoryManager.delete(TEST);
+ assertFalse("Impl:" + directoryManager.getClass().getName(), directoryManager.hasDirectory(TEST));
+ }
+ });
+ }
- public void testGetDirectoryNames() throws Exception {
- execute(new Callable() {
- public void call(DirectoryManager directoryManager)
- throws Exception {
- directoryManager.getDirectory(TEST).close();
- assertTrue(Arrays.asList(directoryManager.getDirectoryNames())
- .contains(TEST));
- }
- });
- }
+ public void testGetDirectoryNames() throws Exception
+ {
+ execute(new Callable()
+ {
+ public void call(DirectoryManager directoryManager) throws Exception
+ {
+ directoryManager.getDirectory(TEST).close();
+ assertTrue("Impl:" + directoryManager.getClass().getName(), Arrays.asList(directoryManager.getDirectoryNames()).contains(TEST));
+ }
+ });
+ }
- public void testRename() throws Exception {
- execute(new Callable() {
- public void call(DirectoryManager directoryManager)
- throws Exception {
- directoryManager.getDirectory(TEST).close();
- directoryManager.rename(TEST, RENAMED);
- assertTrue(directoryManager.hasDirectory(RENAMED));
- assertFalse(directoryManager.hasDirectory(TEST));
- }
- });
- }
+ public void testRename() throws Exception
+ {
+ execute(new Callable()
+ {
+ public void call(DirectoryManager directoryManager) throws Exception
+ {
+ directoryManager.getDirectory(TEST).close();
+ directoryManager.rename(TEST, RENAMED);
+ assertTrue("Impl:" + directoryManager.getClass().getName(), directoryManager.hasDirectory(RENAMED));
+ assertFalse("Impl:" + directoryManager.getClass().getName(), directoryManager.hasDirectory(TEST));
+ }
+ });
+ }
- private void execute(Callable callable) throws Exception {
- for (Iterator it = IMPLEMENTATIONS.iterator(); it.hasNext();) {
- Class clazz = (Class) it.next();
- DirectoryManager dirMgr = (DirectoryManager) clazz.newInstance();
- dirMgr.init(INDEX);
- try {
- callable.call(dirMgr);
- } finally {
- dirMgr.dispose();
- }
- }
- }
+ private void execute(Callable callable) throws Exception
+ {
+ for (Iterator it = IMPLEMENTATIONS.iterator(); it.hasNext();)
+ {
+ Class clazz = (Class)it.next();
+ DirectoryManager dirMgr = (DirectoryManager)clazz.newInstance();
+ dirMgr.init(INDEX);
+ try
+ {
+ callable.call(dirMgr);
+ }
+ finally
+ {
+ dirMgr.dispose();
+ }
+ }
+ }
- private interface Callable {
+ private interface Callable
+ {
- public void call(DirectoryManager directoryManager) throws Exception;
- }
+ public void call(DirectoryManager directoryManager) throws Exception;
+ }
}
Modified: jcr/trunk/pom.xml
===================================================================
--- jcr/trunk/pom.xml 2011-02-01 17:50:06 UTC (rev 3910)
+++ jcr/trunk/pom.xml 2011-02-02 07:42:58 UTC (rev 3911)
@@ -274,17 +274,17 @@
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
- <version>2.4.1</version>
+ <version>2.9.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-spellchecker</artifactId>
- <version>2.4.1</version>
+ <version>2.9.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-memory</artifactId>
- <version>2.4.1</version>
+ <version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream</groupId>
13 years, 3 months
exo-jcr SVN: r3910 - kernel/trunk/exo.kernel.component.cache/src/main/java/org/exoplatform/services/cache/impl and 2 other directories.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-02-01 12:50:06 -0500 (Tue, 01 Feb 2011)
New Revision: 3910
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/cache.xml
kernel/trunk/exo.kernel.component.cache/src/main/java/org/exoplatform/services/cache/impl/CacheServiceImpl.java
kernel/trunk/exo.kernel.component.cache/src/test/java/org/exoplatform/services/cache/test/TestCacheService.java
kernel/trunk/exo.kernel.component.cache/src/test/resources/conf/portal/test-configuration.xml
Log:
EXOJCR-1179: Bug fixed
EXOJCR-1180: Improvement implemented to avoid the bug
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/cache.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/cache.xml 2011-02-01 14:14:32 UTC (rev 3909)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/cache.xml 2011-02-01 17:50:06 UTC (rev 3910)
@@ -176,7 +176,14 @@
<type>org.exoplatform.tutorial.MyExoCacheFactoryImpl</type>
...
</component>
-</configuration></programlisting></para>
+</configuration></programlisting><note>
+ <para>Since kernel 2.3.0-CR1, if the configuration is not a sub class
+ of <envar>ExoCacheConfig</envar> and the implementation given in the
+ configuration is the full qualified name of an existing implementation
+ of eXo Cache, we will assume that the user expects to have an instance
+ of this eXo Cache type so we won't use the configured cache
+ factory.</para>
+ </note></para>
</section>
<section>
Modified: kernel/trunk/exo.kernel.component.cache/src/main/java/org/exoplatform/services/cache/impl/CacheServiceImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.cache/src/main/java/org/exoplatform/services/cache/impl/CacheServiceImpl.java 2011-02-01 14:14:32 UTC (rev 3909)
+++ kernel/trunk/exo.kernel.component.cache/src/main/java/org/exoplatform/services/cache/impl/CacheServiceImpl.java 2011-02-01 17:50:06 UTC (rev 3910)
@@ -28,12 +28,19 @@
import org.exoplatform.services.cache.ExoCacheFactory;
import org.exoplatform.services.cache.ExoCacheInitException;
import org.exoplatform.services.cache.SimpleExoCache;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
/**
* Created by The eXo Platform SAS. Author : Tuan Nguyen
@@ -42,11 +49,18 @@
@ManagedBy(CacheServiceManaged.class)
public class CacheServiceImpl implements CacheService
{
+ /**
+ * Logger.
+ */
+ private static final Log LOG = ExoLogger.getLogger("exo.kernel.component.cache.CacheServiceImpl");
+
+ private final ExoCacheFactory DEFAULT_FACTORY = new SimpleExoCacheFactory();
+
private final HashMap<String, ExoCacheConfig> configs_ = new HashMap<String, ExoCacheConfig>();
- private final ConcurrentHashMap<String, ExoCache<? extends Serializable, ?>> cacheMap_ =
- new ConcurrentHashMap<String, ExoCache<? extends Serializable, ?>>();
-
+ private final ConcurrentHashMap<String, FutureExoCacheCreationTask> cacheMap_ =
+ new ConcurrentHashMap<String, FutureExoCacheCreationTask>();
+
private final ExoCacheConfig defaultConfig_;
private final LoggingCacheListener loggingListener_;
@@ -72,7 +86,7 @@
}
defaultConfig_ = configs_.get("default");
loggingListener_ = new LoggingCacheListener();
- factory_ = factory == null ? new SimpleExoCacheFactory() : factory;
+ factory_ = factory == null ? DEFAULT_FACTORY : factory;
}
public void addExoCacheConfig(ComponentPlugin plugin)
@@ -89,7 +103,8 @@
}
}
- public <K extends Serializable, V> ExoCache<K, V> getCacheInstance(String region)
+ @SuppressWarnings("unchecked")
+ public <K extends Serializable, V> ExoCache<K, V> getCacheInstance(final String region)
{
if (region == null)
{
@@ -99,27 +114,47 @@
{
throw new IllegalArgumentException("region cannot be empty");
}
- ExoCache<? extends Serializable, ?> cache = cacheMap_.get(region);
- if (cache == null)
+ FutureExoCacheCreationTask creationTask = cacheMap_.get(region);
+ if (creationTask == null)
{
- try
+ Callable<ExoCache<? extends Serializable,?>> task = new Callable<ExoCache<? extends Serializable,?>>()
{
- cache = createCacheInstance(region);
- ExoCache<? extends Serializable, ?> existing = cacheMap_.putIfAbsent(region, cache);
- if (existing != null)
+ public ExoCache<? extends Serializable, ?> call() throws Exception
{
- cache = existing;
+ return createCacheInstance(region);
}
+ };
+ creationTask = new FutureExoCacheCreationTask(task);
+ FutureExoCacheCreationTask existingTask = cacheMap_.putIfAbsent(region, creationTask);
+ if (existingTask != null)
+ {
+ creationTask = existingTask;
}
- catch (Exception e)
+ else
{
- e.printStackTrace();
+ creationTask.run();
}
}
- return (ExoCache<K, V>)cache;
+ try
+ {
+ return (ExoCache<K, V>)creationTask.get();
+ }
+ catch (CancellationException e)
+ {
+ cacheMap_.remove(region, creationTask);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (ExecutionException e)
+ {
+ LOG.error("Could not create the cache for the region '" + region + "'", e.getCause());
+ }
+ return null;
}
- synchronized private ExoCache<? extends Serializable, ?> createCacheInstance(String region) throws Exception
+ private ExoCache<? extends Serializable, ?> createCacheInstance(String region) throws Exception
{
ExoCacheConfig config = configs_.get(region);
if (config == null)
@@ -129,8 +164,36 @@
final ExoCacheConfig safeConfig = config.clone();
// Set the region as name
safeConfig.setName(region);
- final ExoCache simple = factory_.createCache(safeConfig);
-
+
+ ExoCache simple = null;
+ if (factory_ != DEFAULT_FACTORY && safeConfig.getClass().isAssignableFrom(ExoCacheConfig.class)
+ && safeConfig.getImplementation() != null)
+ {
+ // The implementation exists and the config is not a sub class of ExoCacheConfig
+ // we assume that we expect to use the default cache factory
+ try
+ {
+ final ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ // We check if the given implementation is a known class
+ Class implClass = cl.loadClass(safeConfig.getImplementation());
+ // Implementation is an existing class
+ if (ExoCache.class.isAssignableFrom(implClass))
+ {
+ // The implementation is a sub class of eXo Cache so we use the default factory
+ simple = DEFAULT_FACTORY.createCache(safeConfig);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ // The implementation could not be found
+ }
+ }
+ if (simple == null)
+ {
+ // We use the configured cache factory
+ simple = factory_.createCache(safeConfig);
+ }
+
if (managed != null)
{
managed.registerCache(simple);
@@ -140,7 +203,24 @@
public Collection<ExoCache<? extends Serializable, ?>> getAllCacheInstances()
{
- return cacheMap_.values();
+ Collection<ExoCache<? extends Serializable, ?>> caches = new ArrayList<ExoCache<? extends Serializable,?>>(cacheMap_.size());
+ for (FutureTask<ExoCache<? extends Serializable,?>> task : cacheMap_.values())
+ {
+ ExoCache<? extends Serializable, ?> cache = null;
+ try
+ {
+ cache = task.get();
+ }
+ catch (Exception e)
+ {
+ // ignore me
+ }
+ if (cache != null)
+ {
+ caches.add(cache);
+ }
+ }
+ return caches;
}
/**
@@ -203,4 +283,31 @@
}
}
}
+
+ /**
+ * This class is used to reduce the contention when the cache is already created
+ */
+ private static class FutureExoCacheCreationTask extends FutureTask<ExoCache<? extends Serializable, ?>>
+ {
+
+ private volatile ExoCache<? extends Serializable, ?> cache;
+
+ /**
+ * @param callable
+ */
+ public FutureExoCacheCreationTask(Callable<ExoCache<? extends Serializable, ?>> callable)
+ {
+ super(callable);
+ }
+
+ @Override
+ public ExoCache<? extends Serializable, ?> get() throws InterruptedException, ExecutionException
+ {
+ if (cache != null)
+ {
+ return cache;
+ }
+ return cache = super.get();
+ }
+ }
}
Modified: kernel/trunk/exo.kernel.component.cache/src/test/java/org/exoplatform/services/cache/test/TestCacheService.java
===================================================================
--- kernel/trunk/exo.kernel.component.cache/src/test/java/org/exoplatform/services/cache/test/TestCacheService.java 2011-02-01 14:14:32 UTC (rev 3909)
+++ kernel/trunk/exo.kernel.component.cache/src/test/java/org/exoplatform/services/cache/test/TestCacheService.java 2011-02-01 17:50:06 UTC (rev 3910)
@@ -19,17 +19,31 @@
package org.exoplatform.services.cache.test;
import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ObjectParameter;
+import org.exoplatform.services.cache.CacheListener;
import org.exoplatform.services.cache.CacheService;
+import org.exoplatform.services.cache.CachedObjectSelector;
import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.cache.ExoCacheConfig;
+import org.exoplatform.services.cache.ExoCacheFactory;
+import org.exoplatform.services.cache.ExoCacheInitException;
import org.exoplatform.services.cache.FIFOExoCache;
import org.exoplatform.services.cache.SimpleExoCache;
+import org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache;
+import org.exoplatform.services.cache.impl.CacheServiceImpl;
import org.exoplatform.test.BasicTestCase;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
@@ -194,6 +208,179 @@
}
*/
+ public void testConcurrentCreation() throws Exception
+ {
+ int threads = 20;
+ final CountDownLatch startSignal = new CountDownLatch(1);
+ final CountDownLatch doneSignal = new CountDownLatch(threads);
+ final List<Exception> errors = Collections.synchronizedList(new ArrayList<Exception>());
+ for (int i = 0; i < threads; i++)
+ {
+ Thread thread = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ startSignal.await();
+ assertNotNull(service_.getCacheInstance("TestConcurrentCreation"));
+ }
+ catch (Exception e)
+ {
+ errors.add(e);
+ }
+ finally
+ {
+ doneSignal.countDown();
+ }
+ }
+ };
+ thread.start();
+ }
+ startSignal.countDown();
+ doneSignal.await();
+ if (!errors.isEmpty())
+ {
+ for (Exception e : errors)
+ {
+ e.printStackTrace();
+ }
+ throw errors.get(0);
+ }
+ assertEquals(1, MyExoCache.count.get());
+ }
+
+ public void testGetAllCacheInstances() throws Exception
+ {
+ assertNotNull(service_.getAllCacheInstances());
+ assertEquals(8, service_.getAllCacheInstances().size());
+ }
+
+ public void testPerf() throws Exception
+ {
+ // Pre-create it
+ service_.getCacheInstance("FooCache");
+ int threads = 100;
+ final CountDownLatch startSignal = new CountDownLatch(1);
+ final CountDownLatch doneSignal = new CountDownLatch(threads);
+ final List<Exception> errors = Collections.synchronizedList(new ArrayList<Exception>());
+ for (int i = 0; i < threads; i++)
+ {
+ Thread thread = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ startSignal.await();
+ for (int i = 0; i < 1000000; i++)
+ {
+ assertNotNull(service_.getCacheInstance("FooCache"));
+ }
+ }
+ catch (Exception e)
+ {
+ errors.add(e);
+ }
+ finally
+ {
+ doneSignal.countDown();
+ }
+ }
+ };
+ thread.start();
+ }
+ long start = System.currentTimeMillis();
+ startSignal.countDown();
+ doneSignal.await();
+ System.out.println("Total Time = " + (System.currentTimeMillis() - start));
+ if (!errors.isEmpty())
+ {
+ for (Exception e : errors)
+ {
+ e.printStackTrace();
+ }
+ throw errors.get(0);
+ }
+ }
+
+ public void testCacheFactory() throws Exception
+ {
+ InitParams params = new InitParams();
+ ObjectParameter param = new ObjectParameter();
+ param.setName("NoImpl");
+ ExoCacheConfig config = new ExoCacheConfig();
+ config.setName(param.getName());
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("KnownImpl");
+ config = new ExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache");
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("UnKnownImpl");
+ config = new ExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("fakeImpl");
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("UnKnownImplButCorrectFQN");
+ config = new ExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("java.lang.String");
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("NoImpl-MyExoCacheConfig");
+ config = new MyExoCacheConfig();
+ config.setName(param.getName());
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("KnownImpl-MyExoCacheConfig");
+ config = new MyExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("org.exoplatform.services.cache.FIFOExoCache");
+ param.setObject(config);
+ params.addParameter(param);
+
+ param = new ObjectParameter();
+ param.setName("UnKnownImpl-MyExoCacheConfig");
+ config = new MyExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("fakeImpl");
+ param.setObject(config);
+ params.addParameter(param);
+
+
+ param = new ObjectParameter();
+ param.setName("UnKnownImplButCorrectFQN-MyExoCacheConfig");
+ config = new MyExoCacheConfig();
+ config.setName(param.getName());
+ config.setImplementation("java.lang.String");
+ param.setObject(config);
+ params.addParameter(param);
+
+ CacheService cs = new CacheServiceImpl(params, new MyExoCacheFactory());
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("NoImpl").getClass(), cs.getCacheInstance("NoImpl") instanceof MyExoCache);
+ assertTrue("Expected type ConcurrentFIFOExoCache found " + cs.getCacheInstance("KnownImpl").getClass(), cs.getCacheInstance("KnownImpl") instanceof ConcurrentFIFOExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("UnKnownImpl").getClass(), cs.getCacheInstance("UnKnownImpl") instanceof MyExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("UnKnownImplButCorrectFQN").getClass(), cs.getCacheInstance("UnKnownImplButCorrectFQN") instanceof MyExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("NoImpl-MyExoCacheConfig").getClass(), cs.getCacheInstance("NoImpl-MyExoCacheConfig") instanceof MyExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("KnownImpl-MyExoCacheConfig").getClass(), cs.getCacheInstance("KnownImpl-MyExoCacheConfig") instanceof MyExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("UnKnownImpl-MyExoCacheConfig").getClass(), cs.getCacheInstance("UnKnownImpl-MyExoCacheConfig") instanceof MyExoCache);
+ assertTrue("Expected type MyExoCache found " + cs.getCacheInstance("UnKnownImplButCorrectFQN-MyExoCacheConfig").getClass(), cs.getCacheInstance("UnKnownImplButCorrectFQN-MyExoCacheConfig") instanceof MyExoCache);
+ }
+
private static class ExoCacheComparator implements Comparator
{
@@ -214,4 +401,202 @@
{
return "Test Cache Service";
}
+
+ public static class MyExoCache<V> implements ExoCache<Serializable, V>
+ {
+
+ private static AtomicInteger count = new AtomicInteger();
+
+ public MyExoCache()
+ {
+ count.incrementAndGet();
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getName()
+ */
+ public String getName()
+ {
+ return "TestConcurrentCreation";
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#setName(java.lang.String)
+ */
+ public void setName(String name)
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getLabel()
+ */
+ public String getLabel()
+ {
+ return "TestConcurrentCreation";
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#setLabel(java.lang.String)
+ */
+ public void setLabel(String s)
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#get(java.io.Serializable)
+ */
+ public V get(Serializable key)
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#remove(java.io.Serializable)
+ */
+ public V remove(Serializable key) throws NullPointerException
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#put(java.io.Serializable, java.lang.Object)
+ */
+ public void put(Serializable key, V value) throws NullPointerException
+ {
+
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#putMap(java.util.Map)
+ */
+ public void putMap(Map<? extends Serializable, ? extends V> objs) throws NullPointerException,
+ IllegalArgumentException
+ {
+
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#clearCache()
+ */
+ public void clearCache()
+ {
+
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#select(org.exoplatform.services.cache.CachedObjectSelector)
+ */
+ public void select(CachedObjectSelector<? super Serializable, ? super V> selector) throws Exception
+ {
+
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getCacheSize()
+ */
+ public int getCacheSize()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getMaxSize()
+ */
+ public int getMaxSize()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#setMaxSize(int)
+ */
+ public void setMaxSize(int max)
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getLiveTime()
+ */
+ public long getLiveTime()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#setLiveTime(long)
+ */
+ public void setLiveTime(long period)
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getCacheHit()
+ */
+ public int getCacheHit()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getCacheMiss()
+ */
+ public int getCacheMiss()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#getCachedObjects()
+ */
+ public List<? extends V> getCachedObjects() throws Exception
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#removeCachedObjects()
+ */
+ public List<? extends V> removeCachedObjects()
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#addCacheListener(org.exoplatform.services.cache.CacheListener)
+ */
+ public void addCacheListener(CacheListener<? super Serializable, ? super V> listener) throws NullPointerException
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#isLogEnabled()
+ */
+ public boolean isLogEnabled()
+ {
+ return false;
+ }
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCache#setLogEnabled(boolean)
+ */
+ public void setLogEnabled(boolean b)
+ {
+ }
+
+ }
+
+ public static class MyExoCacheFactory implements ExoCacheFactory
+ {
+
+ /**
+ * @see org.exoplatform.services.cache.ExoCacheFactory#createCache(org.exoplatform.services.cache.ExoCacheConfig)
+ */
+ public ExoCache createCache(ExoCacheConfig config) throws ExoCacheInitException
+ {
+ return new MyExoCache();
+ }
+
+ }
+
+ public static class MyExoCacheConfig extends ExoCacheConfig {}
}
Modified: kernel/trunk/exo.kernel.component.cache/src/test/resources/conf/portal/test-configuration.xml
===================================================================
--- kernel/trunk/exo.kernel.component.cache/src/test/resources/conf/portal/test-configuration.xml 2011-02-01 14:14:32 UTC (rev 3909)
+++ kernel/trunk/exo.kernel.component.cache/src/test/resources/conf/portal/test-configuration.xml 2011-02-01 17:50:06 UTC (rev 3910)
@@ -223,6 +223,31 @@
</object>
</object-param>
+ <object-param>
+ <name>TestConcurrentCreationPlugin</name>
+ <description>cache used to test the concurrent creation</description>
+ <object type="org.exoplatform.services.cache.ExoCacheConfig">
+ <field name="name">
+ <string>TestConcurrentCreation</string>
+ </field>
+ <field name="implementation">
+ <string>org.exoplatform.services.cache.test.TestCacheService$MyExoCache</string>
+ </field>
+ </object>
+ </object-param>
+
+ <object-param>
+ <name>TestErrorCreationPlugin</name>
+ <description>cache used to test the concurrent creation</description>
+ <object type="org.exoplatform.services.cache.ExoCacheConfig">
+ <field name="name">
+ <string>TestErrorCreation</string>
+ </field>
+ <field name="implementation">
+ <string>org.exoplatform.services.cache.test.TestCacheService$MyExoCacheFake</string>
+ </field>
+ </object>
+ </object-param>
</init-params>
</component-plugin>
</external-component-plugins>
13 years, 3 months
exo-jcr SVN: r3909 - in jcr/trunk/exo.jcr.component.webdav/src: main/java/org/exoplatform/services/jcr/webdav/command and 1 other directories.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-02-01 09:14:32 -0500 (Tue, 01 Feb 2011)
New Revision: 3909
Modified:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java
Log:
EXOJCR-1122: yet another tests fix and UriBuilder passing instead of URI to commands
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -73,7 +73,6 @@
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
@@ -397,7 +396,7 @@
this.repositoryService = repositoryService;
this.nullResourceLocks = new NullResourceLocksHolder();
}
-
+
/**
* {@inheritDoc}
*/
@@ -479,8 +478,6 @@
{
String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
- URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
-
destinationHeader = TextUtil.unescape(destinationHeader, '%');
if (!destinationHeader.startsWith(serverURI))
@@ -522,11 +519,13 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand(destinationHeader).copy(session, srcNodePath, destNodePath);
+ return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).copy(session,
+ srcNodePath, destNodePath);
}
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand(destinationHeader).copy(destSession, srcWorkspace, srcNodePath, destNodePath);
+ return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).copy(destSession,
+ srcWorkspace, srcNodePath, destNodePath);
}
else if (depth.getIntValue() == 0)
@@ -537,9 +536,8 @@
Session session = session(repoName, destWorkspace, lockTokens);
- return new MkColCommand(nullResourceLocks, destinationUri).mkCol(session, destNodePath + "/"
- + nodeName,
- defaultFolderNodeType, null, lockTokens);
+ return new MkColCommand(nullResourceLocks, uriInfo.getBaseUriBuilder().path(getClass()).path(repoName))
+ .mkCol(session, destNodePath + "/" + nodeName, defaultFolderNodeType, null, lockTokens);
}
else
@@ -642,8 +640,8 @@
int dash = token.indexOf("-");
if (dash == -1)
{
- return Response.status(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE).entity(
- "Requested Range Not Satisfiable").build();
+ return Response.status(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
+ .entity("Requested Range Not Satisfiable").build();
}
else if (dash == 0)
{
@@ -816,8 +814,6 @@
@HeaderParam(ExtHttpHeaders.CONTENT_MIXINTYPES) String mixinTypesHeader, @Context UriInfo uriInfo)
{
-
-
if (log.isDebugEnabled())
{
log.debug("MKCOL " + repoName + "/" + repoPath);
@@ -835,10 +831,8 @@
nodeType = defaultFolderNodeType;
}
- URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
-
- return new MkColCommand(nullResourceLocks, destinationUri).mkCol(session, path(repoPath), nodeType,
- NodeTypeUtil.getMixinTypes(mixinTypesHeader), tokens);
+ return new MkColCommand(nullResourceLocks, uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).mkCol(
+ session, path(repoPath), nodeType, NodeTypeUtil.getMixinTypes(mixinTypesHeader), tokens);
}
catch (NoSuchWorkspaceException exc)
{
@@ -917,12 +911,14 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, srcWorkspace, lockTokens);
- return new MoveCommand(destinationHeader).move(session, srcNodePath, destNodePath);
+ return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).move(session,
+ srcNodePath, destNodePath);
}
Session srcSession = session(repoName, srcWorkspace, lockTokens);
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new MoveCommand(destinationHeader).move(srcSession, destSession, srcNodePath, destNodePath);
+ return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).move(srcSession,
+ destSession, srcNodePath, destNodePath);
}
else
{
@@ -955,9 +951,9 @@
"<DAV:basicsearch>" + "<exo:sql xmlns:exo=\"http://exoplatform.com/jcr\"/>"
+ "<exo:xpath xmlns:exo=\"http://exoplatform.com/jcr\"/>";
- return Response.ok().header(ExtHttpHeaders.ALLOW, /* allowCommands */ALLOW).header(ExtHttpHeaders.DAV,
- "1, 2, ordered-collections, access-control").header(ExtHttpHeaders.DASL, DASL_VALUE).header(ExtHttpHeaders.MSAUTHORVIA, "DAV")
- .build();
+ return Response.ok().header(ExtHttpHeaders.ALLOW, /* allowCommands */ALLOW)
+ .header(ExtHttpHeaders.DAV, "1, 2, ordered-collections, access-control")
+ .header(ExtHttpHeaders.DASL, DASL_VALUE).header(ExtHttpHeaders.MSAUTHORVIA, "DAV").build();
}
/**
@@ -1093,9 +1089,6 @@
@HeaderParam(ExtHttpHeaders.CONTENT_MIXINTYPES) String mixinTypes,
@HeaderParam(ExtHttpHeaders.CONTENT_TYPE) MediaType mediatype, InputStream inputStream, @Context UriInfo uriInfo)
{
-
- URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
-
if (log.isDebugEnabled())
{
log.debug("PUT " + repoName + "/" + repoPath);
@@ -1134,10 +1127,9 @@
NodeType nodeType = ntm.getNodeType(contentNodeType);
NodeTypeUtil.checkContentResourceType(nodeType);
- return new PutCommand(nullResourceLocks, destinationUri).put(session, path(repoPath), inputStream,
- fileNodeType,
- contentNodeType, NodeTypeUtil.getMixinTypes(mixinTypes), mimeType, encoding, updatePolicyType,
- autoVersionType, tokens);
+ return new PutCommand(nullResourceLocks, uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).put(
+ session, path(repoPath), inputStream, fileNodeType, contentNodeType,
+ NodeTypeUtil.getMixinTypes(mixinTypes), mimeType, encoding, updatePolicyType, autoVersionType, tokens);
}
catch (NoSuchWorkspaceException exc)
@@ -1330,8 +1322,8 @@
return Response.status(HTTPStatus.INTERNAL_ERROR).entity(exc.getMessage()).build();
}
}
-
- /**
+
+ /**
* Gives access to the current session.
*
* @param repoName repository name
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -21,15 +21,16 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.exoplatform.services.rest.ExtHttpHeaders;
import javax.jcr.AccessDeniedException;
import javax.jcr.ItemExistsException;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
/**
* Created by The eXo Platform SAS Author : <a
@@ -47,26 +48,27 @@
private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.CopyCommand");
/**
- * Provides URI information needed for 'location' header in 'CREATED' response
- */
- private final String destination;
+ * Provides URI information needed for 'location' header in 'CREATED'
+ * response
+ */
+ private final UriBuilder uriBuilder;
/**
* Empty constructor
*/
public CopyCommand()
{
- this.destination = null;
+ this.uriBuilder = null;
}
/**
* Constructor
*
- * @param destination - provide data used in 'location' header
+ * @param uriBuilder - provide data used in 'location' header
*/
- public CopyCommand(String destination)
+ public CopyCommand(UriBuilder uriBuilder)
{
- this.destination = destination;
+ this.uriBuilder = uriBuilder;
}
/**
@@ -81,13 +83,14 @@
{
try
{
- destSession.getWorkspace().copy(sourcePath, destPath);
- if (destination != null)
+ Workspace workspace = destSession.getWorkspace();
+ workspace.copy(sourcePath, destPath);
+ if (uriBuilder != null)
{
- return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ return Response.created(uriBuilder.path(workspace.getName()).path(destPath).build()).build();
}
- // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
+ // to save compatibility if uribuilder is not provided
return Response.status(HTTPStatus.CREATED).build();
}
catch (ItemExistsException e)
@@ -126,13 +129,14 @@
{
try
{
- destSession.getWorkspace().copy(sourceWorkspace, sourcePath, destPath);
- if (destination != null)
+ Workspace destWorkspace = destSession.getWorkspace();
+ destWorkspace.copy(sourceWorkspace, sourcePath, destPath);
+ if (uriBuilder != null)
{
- return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ return Response.created(uriBuilder.path(destWorkspace.getName()).path(destPath).build()).build();
}
- // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
+ // to save compatibility if uriBuilder is not provided
return Response.status(HTTPStatus.CREATED).build();
}
catch (ItemExistsException e)
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -24,7 +24,6 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import java.net.URI;
import java.util.List;
import javax.jcr.AccessDeniedException;
@@ -35,6 +34,7 @@
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
/**
* Created by The eXo Platform SAS Author : <a
@@ -59,7 +59,7 @@
/**
* Provides URI information needed for 'location' header in 'CREATED' response
*/
- private final URI destinationUri;
+ private final UriBuilder uriBuilder;
/**
* Constructor.
@@ -69,19 +69,19 @@
public MkColCommand(final NullResourceLocksHolder nullResourceLocks)
{
this.nullResourceLocks = nullResourceLocks;
- this.destinationUri = null;
+ this.uriBuilder = null;
}
/**
* Constructor.
*
* @param nullResourceLocks resource locks.
- * @param uriInfo - provide data used in 'location' header
+ * @param uriBuilder - provide data used in 'location' header
*/
- public MkColCommand(final NullResourceLocksHolder nullResourceLocks, URI serverUri)
+ public MkColCommand(final NullResourceLocksHolder nullResourceLocks, UriBuilder uriBuilder)
{
this.nullResourceLocks = nullResourceLocks;
- this.destinationUri = serverUri;
+ this.uriBuilder = uriBuilder;
}
/**
@@ -138,12 +138,12 @@
return Response.serverError().entity(exc.getMessage()).build();
}
- if (destinationUri != null)
+ if (uriBuilder != null)
{
- return Response.created(destinationUri).build();
+ return Response.created(uriBuilder.path(session.getWorkspace().getName()).path(path).build()).build();
}
- // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
+ // to save compatibility if uriBuilder is not provided
return Response.status(HTTPStatus.CREATED).build();
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -21,7 +21,6 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.exoplatform.services.rest.ExtHttpHeaders;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
@@ -29,6 +28,7 @@
import javax.jcr.lock.LockException;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
/**
* Created by The eXo Platform SAS Author : <a
@@ -52,7 +52,7 @@
/**
* Provides URI information needed for 'location' header in 'CREATED' response
*/
- private final String destination;
+ private final UriBuilder uriBuilder;
// Fix problem with moving under Windows Explorer.
static
@@ -65,16 +65,17 @@
*/
public MoveCommand()
{
- this.destination = null;
+ this.uriBuilder = null;
}
/**
* Constructor to receive URI Info
- * @param destination - provide data used in 'location' header
+ *
+ * @param uriBuilder - provide data used in 'location' header
*/
- public MoveCommand(String destination)
+ public MoveCommand(UriBuilder uriBuilder)
{
- this.destination = destination;
+ this.uriBuilder = uriBuilder;
}
/**
@@ -105,13 +106,13 @@
}
else
{
- if (destination != null)
+ if (uriBuilder != null)
{
- return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination)
+ return Response.created(uriBuilder.path(session.getWorkspace().getName()).path(destPath).build())
.cacheControl(cacheControl).build();
}
- // to save compatibility for deprecated WebDavServiceImpl.move(..), which does not provide uriInfo
+ // to save compatibility if uriBuilder is not provided
return Response.status(HTTPStatus.CREATED).cacheControl(cacheControl).build();
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -23,7 +23,6 @@
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import java.io.InputStream;
-import java.net.URI;
import java.util.Calendar;
import java.util.List;
@@ -34,6 +33,7 @@
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
/**
* Created by The eXo Platform SAS Author : <a
@@ -51,9 +51,10 @@
private final NullResourceLocksHolder nullResourceLocks;
/**
- * Provides URI information needed for 'location' header in 'CREATED' response
+ * Provides URI information needed for 'location' header in 'CREATED'
+ * response
*/
- private final URI destinationUri;
+ private final UriBuilder uriBuilder;
/**
* Constructor.
@@ -63,19 +64,19 @@
public PutCommand(final NullResourceLocksHolder nullResourceLocks)
{
this.nullResourceLocks = nullResourceLocks;
- this.destinationUri = null;
+ this.uriBuilder = null;
}
/**
- * Constructor.
- *
- * @param nullResourceLocks resource locks.
- * @param uriInfo - provide data used in 'location' header
- */
- public PutCommand(final NullResourceLocksHolder nullResourceLocks, URI destinationUri)
+ * Constructor.
+ *
+ * @param nullResourceLocks resource locks.
+ * @param uriBuilder - provide data used in 'location' header
+ */
+ public PutCommand(final NullResourceLocksHolder nullResourceLocks, UriBuilder uriBuilder)
{
this.nullResourceLocks = nullResourceLocks;
- this.destinationUri = destinationUri;
+ this.uriBuilder = uriBuilder;
}
/**
@@ -171,14 +172,12 @@
{
return Response.status(HTTPStatus.CONFLICT).entity(exc.getMessage()).build();
}
- if (destinationUri != null)
+ if (uriBuilder != null)
{
- // String destination = destinationUri + "/" + session.getWorkspace().getName() + path;
- // return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
- return Response.created(destinationUri).build();
+ return Response.created(uriBuilder.path(session.getWorkspace().getName()).path(path).build()).build();
}
- // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
+ // to save compatibility if uriBuilder is not provided
return Response.status(HTTPStatus.CREATED).build();
}
@@ -221,7 +220,7 @@
* Updates jcr:content node.
*
* @param node parent node
- * @param inputStream inputStream input stream that contains the content of
+ * @param inputStream inputStream input stream that contains the content of
* file
* @param mimeType content type
* @param mixins list of mixins
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -127,7 +127,7 @@
// check if response 'CREATED' contains 'LOCATION' header
assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
// check if 'CREATED' response 'LOCATION' header contains correct location path
- assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + destFilename));
+ assertEquals(getPathWS() + destFilename, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
}
@Override
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -77,7 +77,8 @@
// here we check if response 'CREATED' contains 'LOCATION' header
assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
// here we check if 'CREATED' response 'LOCATION' header contains correct location path
- assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + folder));
+ assertEquals(getPathWS() + folder, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
+
}
@Override
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -112,7 +112,7 @@
// check if 'CREATED' response contains 'LOCATION' header
assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
// check if 'CREATED' response 'LOCATION' header contains correct location path
- assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + destFilename));
+ assertEquals(getPathWS() + destFilename, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
}
@Override
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java 2011-02-01 10:54:55 UTC (rev 3908)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java 2011-02-01 14:14:32 UTC (rev 3909)
@@ -164,8 +164,8 @@
// check if response 'CREATED' contains 'LOCATION' header
assertTrue(containerResponse.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
// check if 'CREATED' response 'LOCATION' header contains correct location path
- assertTrue(containerResponse.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString()
- .contains(getPathWS() + filename));
+ assertEquals(getPathWS() + filename, containerResponse.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION)
+ .toString());
}
@Override
13 years, 3 months
exo-jcr SVN: r3908 - jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-02-01 05:54:55 -0500 (Tue, 01 Feb 2011)
New Revision: 3908
Modified:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
Log:
EXOJCR-1122: small fix
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
@@ -49,7 +49,7 @@
/**
* Provides URI information needed for 'location' header in 'CREATED' response
*/
- private static String destination;
+ private final String destination;
/**
* Empty constructor
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-02-01 10:54:55 UTC (rev 3908)
@@ -107,7 +107,8 @@
{
if (destination != null)
{
- return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination)
+ .cacheControl(cacheControl).build();
}
// to save compatibility for deprecated WebDavServiceImpl.move(..), which does not provide uriInfo
13 years, 3 months
exo-jcr SVN: r3907 - in jcr/trunk/exo.jcr.component.webdav/src: main/java/org/exoplatform/services/jcr/webdav/command and 1 other directories.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-02-01 05:23:16 -0500 (Tue, 01 Feb 2011)
New Revision: 3907
Modified:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java
Log:
EXOJCR-1122: location header added to CREATED response
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -73,6 +73,7 @@
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
@@ -478,6 +479,8 @@
{
String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
+ URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
+
destinationHeader = TextUtil.unescape(destinationHeader, '%');
if (!destinationHeader.startsWith(serverURI))
@@ -519,11 +522,11 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand().copy(session, srcNodePath, destNodePath);
+ return new CopyCommand(destinationHeader).copy(session, srcNodePath, destNodePath);
}
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand().copy(destSession, srcWorkspace, srcNodePath, destNodePath);
+ return new CopyCommand(destinationHeader).copy(destSession, srcWorkspace, srcNodePath, destNodePath);
}
else if (depth.getIntValue() == 0)
@@ -534,7 +537,8 @@
Session session = session(repoName, destWorkspace, lockTokens);
- return new MkColCommand(nullResourceLocks).mkCol(session, destNodePath + "/" + nodeName,
+ return new MkColCommand(nullResourceLocks, destinationUri).mkCol(session, destNodePath + "/"
+ + nodeName,
defaultFolderNodeType, null, lockTokens);
}
@@ -794,13 +798,26 @@
/**
* {@inheritDoc}
*/
+ @Deprecated
+ public Response mkcol(String repoName, String repoPath, String lockTokenHeader, String ifHeader,
+ String nodeTypeHeader, String mixinTypesHeader)
+ {
+ return mkcol(repoName, repoPath, lockTokenHeader, ifHeader, nodeTypeHeader, mixinTypesHeader, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@MKCOL
@Path("/{repoName}/{repoPath:.*}/")
public Response mkcol(@PathParam("repoName") String repoName, @PathParam("repoPath") String repoPath,
@HeaderParam(ExtHttpHeaders.LOCKTOKEN) String lockTokenHeader, @HeaderParam(ExtHttpHeaders.IF) String ifHeader,
@HeaderParam(ExtHttpHeaders.CONTENT_NODETYPE) String nodeTypeHeader,
- @HeaderParam(ExtHttpHeaders.CONTENT_MIXINTYPES) String mixinTypesHeader)
+ @HeaderParam(ExtHttpHeaders.CONTENT_MIXINTYPES) String mixinTypesHeader, @Context UriInfo uriInfo)
{
+
+
+
if (log.isDebugEnabled())
{
log.debug("MKCOL " + repoName + "/" + repoPath);
@@ -818,8 +835,10 @@
nodeType = defaultFolderNodeType;
}
- return new MkColCommand(nullResourceLocks).mkCol(session, path(repoPath), nodeType, NodeTypeUtil
- .getMixinTypes(mixinTypesHeader), tokens);
+ URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
+
+ return new MkColCommand(nullResourceLocks, destinationUri).mkCol(session, path(repoPath), nodeType,
+ NodeTypeUtil.getMixinTypes(mixinTypesHeader), tokens);
}
catch (NoSuchWorkspaceException exc)
{
@@ -898,12 +917,12 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, srcWorkspace, lockTokens);
- return new MoveCommand().move(session, srcNodePath, destNodePath);
+ return new MoveCommand(destinationHeader).move(session, srcNodePath, destNodePath);
}
Session srcSession = session(repoName, srcWorkspace, lockTokens);
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new MoveCommand().move(srcSession, destSession, srcNodePath, destNodePath);
+ return new MoveCommand(destinationHeader).move(srcSession, destSession, srcNodePath, destNodePath);
}
else
{
@@ -1053,6 +1072,18 @@
/**
* {@inheritDoc}
*/
+ @Deprecated
+ public Response put(String repoName, String repoPath, String lockTokenHeader, String ifHeader,
+ String fileNodeTypeHeader, String contentNodeTypeHeader, String mixinTypes, MediaType mediatype,
+ InputStream inputStream)
+ {
+ return put(repoName, repoPath, lockTokenHeader, ifHeader, fileNodeTypeHeader, contentNodeTypeHeader, mixinTypes,
+ mediatype, inputStream, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@PUT
@Path("/{repoName}/{repoPath:.*}/")
public Response put(@PathParam("repoName") String repoName, @PathParam("repoPath") String repoPath,
@@ -1060,9 +1091,11 @@
@HeaderParam(ExtHttpHeaders.FILE_NODETYPE) String fileNodeTypeHeader,
@HeaderParam(ExtHttpHeaders.CONTENT_NODETYPE) String contentNodeTypeHeader,
@HeaderParam(ExtHttpHeaders.CONTENT_MIXINTYPES) String mixinTypes,
- @HeaderParam(ExtHttpHeaders.CONTENT_TYPE) MediaType mediatype, InputStream inputStream)
+ @HeaderParam(ExtHttpHeaders.CONTENT_TYPE) MediaType mediatype, InputStream inputStream, @Context UriInfo uriInfo)
{
+ URI destinationUri = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).path(repoPath).build();
+
if (log.isDebugEnabled())
{
log.debug("PUT " + repoName + "/" + repoPath);
@@ -1101,7 +1134,8 @@
NodeType nodeType = ntm.getNodeType(contentNodeType);
NodeTypeUtil.checkContentResourceType(nodeType);
- return new PutCommand(nullResourceLocks).put(session, path(repoPath), inputStream, fileNodeType,
+ return new PutCommand(nullResourceLocks, destinationUri).put(session, path(repoPath), inputStream,
+ fileNodeType,
contentNodeType, NodeTypeUtil.getMixinTypes(mixinTypes), mimeType, encoding, updatePolicyType,
autoVersionType, tokens);
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -21,6 +21,7 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.ExtHttpHeaders;
import javax.jcr.AccessDeniedException;
import javax.jcr.ItemExistsException;
@@ -46,6 +47,29 @@
private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.CopyCommand");
/**
+ * Provides URI information needed for 'location' header in 'CREATED' response
+ */
+ private static String destination;
+
+ /**
+ * Empty constructor
+ */
+ public CopyCommand()
+ {
+ this.destination = null;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param destination - provide data used in 'location' header
+ */
+ public CopyCommand(String destination)
+ {
+ this.destination = destination;
+ }
+
+ /**
* Webdav COPY method implementation for the same workspace.
*
* @param destSession destination session
@@ -58,6 +82,12 @@
try
{
destSession.getWorkspace().copy(sourcePath, destPath);
+ if (destination != null)
+ {
+ return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ }
+
+ // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
return Response.status(HTTPStatus.CREATED).build();
}
catch (ItemExistsException e)
@@ -97,6 +127,12 @@
try
{
destSession.getWorkspace().copy(sourceWorkspace, sourcePath, destPath);
+ if (destination != null)
+ {
+ return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ }
+
+ // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
return Response.status(HTTPStatus.CREATED).build();
}
catch (ItemExistsException e)
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MkColCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -24,6 +24,7 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import java.net.URI;
import java.util.List;
import javax.jcr.AccessDeniedException;
@@ -56,6 +57,11 @@
private final NullResourceLocksHolder nullResourceLocks;
/**
+ * Provides URI information needed for 'location' header in 'CREATED' response
+ */
+ private final URI destinationUri;
+
+ /**
* Constructor.
*
* @param nullResourceLocks resource locks.
@@ -63,9 +69,22 @@
public MkColCommand(final NullResourceLocksHolder nullResourceLocks)
{
this.nullResourceLocks = nullResourceLocks;
+ this.destinationUri = null;
}
/**
+ * Constructor.
+ *
+ * @param nullResourceLocks resource locks.
+ * @param uriInfo - provide data used in 'location' header
+ */
+ public MkColCommand(final NullResourceLocksHolder nullResourceLocks, URI serverUri)
+ {
+ this.nullResourceLocks = nullResourceLocks;
+ this.destinationUri = serverUri;
+ }
+
+ /**
* Webdav Mkcol method implementation.
*
* @param session current session
@@ -77,6 +96,7 @@
*/
public Response mkCol(Session session, String path, String nodeType, List<String> mixinTypes, List<String> tokens)
{
+
Node node;
try
{
@@ -89,6 +109,7 @@
addMixins(node, mixinTypes);
}
session.save();
+
}
catch (ItemExistsException exc)
@@ -117,6 +138,12 @@
return Response.serverError().entity(exc.getMessage()).build();
}
+ if (destinationUri != null)
+ {
+ return Response.created(destinationUri).build();
+ }
+
+ // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
return Response.status(HTTPStatus.CREATED).build();
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -21,6 +21,7 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.ExtHttpHeaders;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
@@ -48,6 +49,11 @@
*/
private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.MoveCommand");
+ /**
+ * Provides URI information needed for 'location' header in 'CREATED' response
+ */
+ private final String destination;
+
// Fix problem with moving under Windows Explorer.
static
{
@@ -55,6 +61,23 @@
}
/**
+ * Empty constructor
+ */
+ public MoveCommand()
+ {
+ this.destination = null;
+ }
+
+ /**
+ * Constructor to receive URI Info
+ * @param destination - provide data used in 'location' header
+ */
+ public MoveCommand(String destination)
+ {
+ this.destination = destination;
+ }
+
+ /**
* Webdav Move method implementation.
*
* @param session current session.
@@ -82,6 +105,12 @@
}
else
{
+ if (destination != null)
+ {
+ return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ }
+
+ // to save compatibility for deprecated WebDavServiceImpl.move(..), which does not provide uriInfo
return Response.status(HTTPStatus.CREATED).cacheControl(cacheControl).build();
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/PutCommand.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -23,6 +23,7 @@
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import java.io.InputStream;
+import java.net.URI;
import java.util.Calendar;
import java.util.List;
@@ -50,6 +51,11 @@
private final NullResourceLocksHolder nullResourceLocks;
/**
+ * Provides URI information needed for 'location' header in 'CREATED' response
+ */
+ private final URI destinationUri;
+
+ /**
* Constructor.
*
* @param nullResourceLocks resource locks.
@@ -57,9 +63,22 @@
public PutCommand(final NullResourceLocksHolder nullResourceLocks)
{
this.nullResourceLocks = nullResourceLocks;
+ this.destinationUri = null;
}
/**
+ * Constructor.
+ *
+ * @param nullResourceLocks resource locks.
+ * @param uriInfo - provide data used in 'location' header
+ */
+ public PutCommand(final NullResourceLocksHolder nullResourceLocks, URI destinationUri)
+ {
+ this.nullResourceLocks = nullResourceLocks;
+ this.destinationUri = destinationUri;
+ }
+
+ /**
* Webdav Put method implementation.
*
* @param session current session
@@ -86,6 +105,7 @@
{
node = (Node)session.getItem(path);
}
+
catch (PathNotFoundException pexc)
{
nullResourceLocks.checkLock(session, path, tokens);
@@ -151,7 +171,14 @@
{
return Response.status(HTTPStatus.CONFLICT).entity(exc.getMessage()).build();
}
+ if (destinationUri != null)
+ {
+ // String destination = destinationUri + "/" + session.getWorkspace().getName() + path;
+ // return Response.status(HTTPStatus.CREATED).header(ExtHttpHeaders.LOCATION, destination).build();
+ return Response.created(destinationUri).build();
+ }
+ // to save compatibility for deprecated WebDavServiceImpl.put(..), which does not provide uriInfo
return Response.status(HTTPStatus.CREATED).build();
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -21,6 +21,7 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods;
+import org.exoplatform.services.jcr.webdav.WebDavServiceImpl;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import org.exoplatform.services.jcr.webdav.utils.TestUtils;
import org.exoplatform.services.rest.ExtHttpHeaders;
@@ -101,6 +102,34 @@
}
+ /**
+ * Testing {@link WebDavServiceImpl} COPY method for correct response
+ * building. According to 'RFC-2616' it is expected to contain 'location' header.
+ * More info is introduced <a href=http://tools.ietf.org/html/rfc2616#section-14.30>here</a>.
+ * @throws Exception
+ */
+ public void testLocationHeaderInCopyResponse() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+
+ // execute query
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+ // check if response 'CREATED' contains 'LOCATION' header
+ assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
+ // check if 'CREATED' response 'LOCATION' header contains correct location path
+ assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + destFilename));
+ }
+
@Override
protected String getRepositoryName()
{
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMkCol.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -21,8 +21,10 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods;
+import org.exoplatform.services.jcr.webdav.WebDavServiceImpl;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import org.exoplatform.services.jcr.webdav.utils.TestUtils;
+import org.exoplatform.services.rest.ExtHttpHeaders;
import org.exoplatform.services.rest.impl.ContainerResponse;
import java.io.ByteArrayInputStream;
@@ -58,6 +60,26 @@
assertTrue(folderNode.hasNode(TextUtil.relativizePath(file)));
}
+ /**
+ * Testing {@link WebDavServiceImpl} MKCOL method for correct response
+ * building. According to 'RFC-2616' it is expected to contain 'location' header.
+ * More info is introduced <a href=http://tools.ietf.org/html/rfc2616#section-14.30>here</a>.
+ * @throws Exception
+ */
+ public void testLocationHeaderInMkColResponse() throws Exception
+ {
+ String folder = TestUtils.getFolderName();
+
+ // execute query
+ ContainerResponse response = service(WebDAVMethods.MKCOL, getPathWS() + folder, "", null, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+ // here we check if response 'CREATED' contains 'LOCATION' header
+ assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
+ // here we check if 'CREATED' response 'LOCATION' header contains correct location path
+ assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + folder));
+ }
+
@Override
protected String getRepositoryName()
{
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -21,6 +21,7 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods;
+import org.exoplatform.services.jcr.webdav.WebDavServiceImpl;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import org.exoplatform.services.jcr.webdav.utils.TestUtils;
import org.exoplatform.services.rest.ExtHttpHeaders;
@@ -85,6 +86,35 @@
assertFalse(session.getRootNode().hasNode(TextUtil.relativizePath(filename)));
}
+ /**
+ * Testing {@link WebDavServiceImpl} MOVE method for correct response
+ * building. According to 'RFC-2616' it is expected to contain 'location' header.
+ * More info is introduced <a href=http://tools.ietf.org/html/rfc2616#section-14.30>here</a>.
+ * @throws Exception
+ */
+ public void testLocationHeaderInMoveResponse() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ // check if 'CREATED' response contains 'LOCATION' header
+ assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
+ // check if 'CREATED' response 'LOCATION' header contains correct location path
+ assertTrue(response.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString().contains(getPathWS() + destFilename));
+ }
+
@Override
protected String getRepositoryName()
{
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java 2011-01-31 17:03:05 UTC (rev 3906)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPut.java 2011-02-01 10:23:16 UTC (rev 3907)
@@ -22,6 +22,7 @@
import org.exoplatform.services.jcr.impl.core.PropertyImpl;
import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods;
+import org.exoplatform.services.jcr.webdav.WebDavServiceImpl;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import org.exoplatform.services.jcr.webdav.utils.TestUtils;
import org.exoplatform.services.rest.ExtHttpHeaders;
@@ -144,6 +145,29 @@
assertEquals(headers.getFirst(HttpHeaders.CONTENT_TYPE), property.getString());
}
+ /**
+ * Testing {@link WebDavServiceImpl} PUT method for correct response
+ * building. According to 'RFC-2616' it is expected to contain 'location' header.
+ * More info is introduced <a href=http://tools.ietf.org/html/rfc2616#section-14.30>here</a>.
+ * @throws Exception
+ */
+ public void testLocationHeaderInPutResponse() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+
+ // now we execute the query
+ ContainerResponse containerResponse =
+ service(WebDAVMethods.PUT, getPathWS() + filename, "", null, content.getBytes());
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, containerResponse.getStatus());
+ // check if response 'CREATED' contains 'LOCATION' header
+ assertTrue(containerResponse.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
+ // check if 'CREATED' response 'LOCATION' header contains correct location path
+ assertTrue(containerResponse.getHttpHeaders().get(ExtHttpHeaders.LOCATION).toString()
+ .contains(getPathWS() + filename));
+ }
+
@Override
protected String getRepositoryName()
{
13 years, 3 months