From 8aa69caee3bc5eb698b28fc7dc05983055dfede2 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Wed, 27 Jun 2007 18:24:05 +0000 Subject: [PATCH] Performance tweaks for AVM Indexing. Removed calls to getXXXPaths(). Changed mappings of properties and aspects on AVM Nodes to favor get all calls. Added getAspects() and getNodeProperties() which take AVMNodeDescriptors. Used these in AVM Indexing to reduce the number of redundant full lookups. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6121 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/avm-services-context.xml | 2 +- .../messages/patch-service.properties | 4 + .../alfresco/patch/patch-services-context.xml | 11 + config/alfresco/version.properties | 2 +- .../admin/patch/impl/AVMPropertiesPatch.java | 65 ++++ .../repo/avm/AVMLockingAwareService.java | 24 ++ .../java/org/alfresco/repo/avm/AVMNode.java | 6 + .../org/alfresco/repo/avm/AVMNodeImpl.java | 63 ++-- .../alfresco/repo/avm/AVMNodePropertyDAO.java | 7 + .../org/alfresco/repo/avm/AVMRepository.java | 37 +- .../org/alfresco/repo/avm/AVMServiceImpl.java | 36 ++ .../org/alfresco/repo/avm/AVMServiceTest.java | 61 ++-- .../org/alfresco/repo/avm/AVMStoreImpl.java | 2 +- .../org/alfresco/repo/avm/PlainFileNode.java | 8 + .../alfresco/repo/avm/PlainFileNodeImpl.java | 10 +- .../alfresco/repo/avm/hibernate/AVM.hbm.xml | 16 + .../AVMNodePropertyDAOHibernate.java | 12 + .../impl/lucene/AVMLuceneIndexerImpl.java | 323 ++++++++---------- .../alfresco/service/cmr/avm/AVMService.java | 23 ++ 19 files changed, 446 insertions(+), 266 deletions(-) create mode 100644 source/java/org/alfresco/repo/admin/patch/impl/AVMPropertiesPatch.java diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml index a383498990..665fe54040 100644 --- a/config/alfresco/avm-services-context.xml +++ b/config/alfresco/avm-services-context.xml @@ -216,7 +216,7 @@ - + diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 994a81636e..5e1046dcc6 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -166,3 +166,7 @@ patch.AVMAspects.result=Aspects were moved. patch.ReadmeTemplate.description=Deployed ReadMe Template patch.webScriptsReadme.description=Applied ReadMe template to Web Scripts folders + +patch.AVMProperties.description=Changes storage of properties on AVM Nodes. +patch.AVMProperties.result=Properties were moved. + diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 7abea2ce3d..49a55049b2 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -873,4 +873,15 @@ + + + patch.AVMProperties + patch.AVMProperties.description + 0 + 61 + 62 + + + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 675d274391..6c17393627 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=61 +version.schema=62 diff --git a/source/java/org/alfresco/repo/admin/patch/impl/AVMPropertiesPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/AVMPropertiesPatch.java new file mode 100644 index 0000000000..2cc51df15e --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/AVMPropertiesPatch.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.admin.patch.impl; + +import java.util.Iterator; + +import org.alfresco.i18n.I18NUtil; +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.avm.AVMNodeProperty; +import org.alfresco.repo.avm.AVMNodePropertyDAO; + +/** + * Patch more remapping AVM properties. + * @author britt + */ +public class AVMPropertiesPatch extends AbstractPatch +{ + private static final String MSG_SUCCESS = "patch.AVMProperties.result"; + + private AVMNodePropertyDAO fAVMNodePropertyDAO; + + public void setAvmNodePropertyDAO(AVMNodePropertyDAO dao) + { + fAVMNodePropertyDAO = dao; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal() + */ + @Override + protected String applyInternal() throws Exception + { + Iterator iter = fAVMNodePropertyDAO.iterate(); + while (iter.hasNext()) + { + AVMNodeProperty prop = iter.next(); + prop.getNode().getProperties().put(prop.getName(), prop.getValue()); + fAVMNodePropertyDAO.delete(prop.getNode(), prop.getName()); + } + return I18NUtil.getMessage(MSG_SUCCESS); + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java index 6aa70e5c0e..8810b01571 100644 --- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java +++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java @@ -232,6 +232,14 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa return fService.getAspects(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getAspects(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Set getAspects(AVMNodeDescriptor desc) + { + return fService.getAspects(desc); + } + /* (non-Javadoc) * @see org.alfresco.service.cmr.avm.AVMService#getCommonAncestor(org.alfresco.service.cmr.avm.AVMNodeDescriptor, org.alfresco.service.cmr.avm.AVMNodeDescriptor) */ @@ -249,6 +257,14 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa return fService.getContentDataForRead(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public ContentData getContentDataForRead(AVMNodeDescriptor desc) + { + return fService.getContentDataForRead(desc); + } + /* (non-Javadoc) * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForWrite(java.lang.String) */ @@ -445,6 +461,14 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa return fService.getNodeProperties(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Map getNodeProperties(AVMNodeDescriptor desc) + { + return fService.getNodeProperties(desc); + } + /* (non-Javadoc) * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperty(int, java.lang.String, org.alfresco.service.namespace.QName) */ diff --git a/source/java/org/alfresco/repo/avm/AVMNode.java b/source/java/org/alfresco/repo/avm/AVMNode.java index 5251f7743a..e456aeb87d 100644 --- a/source/java/org/alfresco/repo/avm/AVMNode.java +++ b/source/java/org/alfresco/repo/avm/AVMNode.java @@ -235,4 +235,10 @@ public interface AVMNode * @return A Set of Aspects names. */ public Set getAspects(); + + /** + * Add properties to those that already exist. + * @param properties The properties to add. + */ + public void addProperties(Map properties); } diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java index b07abfb443..0a5d3660d5 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java @@ -90,12 +90,15 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ private Set fAspects; + private Map fProperties; + /** * Default constructor. */ protected AVMNodeImpl() { fAspects = new HashSet(); + fProperties = new HashMap(); } /** @@ -107,6 +110,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable AVMStore store) { fAspects = new HashSet(); + fProperties = new HashMap(); fID = id; fVersionID = -1; fIsRoot = false; @@ -343,14 +347,10 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ protected void copyProperties(AVMNode other) { - Map properties = other.getProperties(); - for (QName name : properties.keySet()) + fProperties = new HashMap(); + for (Map.Entry entry : other.getProperties().entrySet()) { - AVMNodeProperty newProp = new AVMNodePropertyImpl(); - newProp.setNode(this); - newProp.setName(name); - newProp.setValue(properties.get(name)); - AVMDAOs.Instance().fAVMNodePropertyDAO.save(newProp); + fProperties.put(entry.getKey(), entry.getValue()); } } @@ -394,18 +394,15 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable { checkReadOnly(); } - AVMNodeProperty prop = AVMDAOs.Instance().fAVMNodePropertyDAO.get(this, name); - if (prop != null) + fProperties.put(name, value); + } + + public void addProperties(Map properties) + { + for (Map.Entry entry : properties.entrySet()) { - prop.setValue(value); - AVMDAOs.Instance().fAVMNodePropertyDAO.update(prop); - return; + fProperties.put(entry.getKey(), entry.getValue()); } - prop = new AVMNodePropertyImpl(); - prop.setNode(this); - prop.setName(name); - prop.setValue(value); - AVMDAOs.Instance().fAVMNodePropertyDAO.save(prop); } /** @@ -414,14 +411,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ public void setProperties(Map properties) { - if (DEBUG) - { - checkReadOnly(); - } - for (QName name : properties.keySet()) - { - setProperty(name, properties.get(name)); - } + fProperties = properties; } /** @@ -431,12 +421,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ public PropertyValue getProperty(QName name) { - AVMNodeProperty prop = AVMDAOs.Instance().fAVMNodePropertyDAO.get(this, name); - if (prop == null) - { - return null; - } - return prop.getValue(); + return fProperties.get(name); } /** @@ -445,13 +430,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ public Map getProperties() { - Map retVal = new HashMap(); - List props = AVMDAOs.Instance().fAVMNodePropertyDAO.get(this); - for (AVMNodeProperty prop : props) - { - retVal.put(prop.getName(), prop.getValue()); - } - return retVal; + return fProperties; } /** @@ -464,7 +443,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable { checkReadOnly(); } - AVMDAOs.Instance().fAVMNodePropertyDAO.delete(this, name); + fProperties.remove(name); } /** @@ -472,11 +451,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable */ public void deleteProperties() { - if (DEBUG) - { - checkReadOnly(); - } - AVMDAOs.Instance().fAVMNodePropertyDAO.deleteAll(this); + fProperties.clear(); } /** diff --git a/source/java/org/alfresco/repo/avm/AVMNodePropertyDAO.java b/source/java/org/alfresco/repo/avm/AVMNodePropertyDAO.java index 1657ba89b6..3ef9580bf0 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodePropertyDAO.java +++ b/source/java/org/alfresco/repo/avm/AVMNodePropertyDAO.java @@ -23,6 +23,7 @@ package org.alfresco.repo.avm; +import java.util.Iterator; import java.util.List; import org.alfresco.service.namespace.QName; @@ -72,4 +73,10 @@ public interface AVMNodePropertyDAO * @param name The name of the property to delete. */ public void delete(AVMNode node, QName name); + + /** + * Get an iterator over all properties. + * @return + */ + public Iterator iterate(); } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index 9918a4e2c8..7be35373f7 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -106,7 +106,7 @@ public class AVMRepository private AVMStorePropertyDAO fAVMStorePropertyDAO; private ChildEntryDAO fChildEntryDAO; - + // A bunch of TransactionListeners that do work for this. /** @@ -2677,4 +2677,39 @@ public class AVMRepository components.remove(components.size() - 1); } } + + public Map getNodeProperties(AVMNodeDescriptor desc) + { + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); + if (node == null) + { + throw new AVMNotFoundException("Node not found: " + desc); + } + return node.getProperties(); + } + + public ContentData getContentDataForRead(AVMNodeDescriptor desc) + { + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); + if (node == null) + { + throw new AVMNotFoundException("Node not found: " + desc); + } + if (node.getType() == AVMNodeType.PLAIN_FILE) + { + PlainFileNode file = (PlainFileNode)node; + return file.getContentData(); + } + throw new AVMWrongTypeException("Not a Plain File: " + desc); + } + + public Set getAspects(AVMNodeDescriptor desc) + { + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); + if (node == null) + { + throw new AVMNotFoundException("Node not found: " + desc); + } + return node.getAspects(); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index 15c71736f0..d2d6046457 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -1068,6 +1068,18 @@ public class AVMServiceImpl implements AVMService return fAVMRepository.getNodeProperties(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Map getNodeProperties(AVMNodeDescriptor desc) + { + if (desc == null) + { + throw new AVMBadArgumentException("Null descriptor."); + } + return fAVMRepository.getNodeProperties(desc); + } + /** * Delete a property. * @param path The path to the node. @@ -1215,6 +1227,18 @@ public class AVMServiceImpl implements AVMService return fAVMRepository.getContentDataForRead(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public ContentData getContentDataForRead(AVMNodeDescriptor desc) + { + if (desc == null) + { + throw new AVMBadArgumentException("Null descriptor."); + } + return fAVMRepository.getContentDataForRead(desc); + } + /** * Get the Content data for writing. * @param path The path to the node. @@ -1295,6 +1319,18 @@ public class AVMServiceImpl implements AVMService return fAVMRepository.getAspects(version, path); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getAspects(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Set getAspects(AVMNodeDescriptor desc) + { + if (desc == null) + { + throw new AVMBadArgumentException("Null descriptor: " + desc); + } + return fAVMRepository.getAspects(desc); + } + /** * Remove an aspect and its properties from a node. * @param path The path to the node. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index ac55503e6f..2d56dbce27 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -101,6 +101,37 @@ import org.alfresco.util.Pair; */ public class AVMServiceTest extends AVMServiceTestBase { + /** + * Test version by date lookup. + */ + public void testVersionByDate() + { + try + { + ArrayList times = new ArrayList(); + BulkLoader loader = new BulkLoader(); + loader.setAvmService(fService); + loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); + loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(2, fService.createSnapshot("main", null, null).get("main").intValue()); + loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(3, fService.createSnapshot("main", null, null).get("main").intValue()); + assertEquals(1, fService.getStoreVersions("main", null, new Date(times.get(0))).size()); + assertEquals(3, fService.getStoreVersions("main", new Date(times.get(0)), null).size()); + assertEquals(2, fService.getStoreVersions("main", new Date(times.get(1)), + new Date(System.currentTimeMillis())).size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } + /** * Test properties. */ @@ -4992,36 +5023,6 @@ public class AVMServiceTest extends AVMServiceTestBase } } - /** - * Test version by date lookup. - */ - public void testVersionByDate() - { - try - { - ArrayList times = new ArrayList(); - BulkLoader loader = new BulkLoader(); - loader.setAvmService(fService); - loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); - loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(2, fService.createSnapshot("main", null, null).get("main").intValue()); - loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(3, fService.createSnapshot("main", null, null).get("main").intValue()); - assertEquals(1, fService.getStoreVersions("main", null, new Date(times.get(0))).size()); - assertEquals(3, fService.getStoreVersions("main", new Date(times.get(0)), null).size()); - assertEquals(2, fService.getStoreVersions("main", new Date(times.get(1)), - new Date(System.currentTimeMillis())).size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - fail(); - } - } /** * Test AVMStore functions. diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index f35bc74538..603e837e53 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -1058,7 +1058,7 @@ public class AVMStoreImpl implements AVMStore, Serializable throw new AVMNotFoundException("Path " + path + " not found."); } AVMNode node = lPath.getCurrentNode(); - node.setProperties(properties); + node.addProperties(properties); node.setGuid(GUID.generate()); } diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java index 49f63390a6..5c9ad1847b 100644 --- a/source/java/org/alfresco/repo/avm/PlainFileNode.java +++ b/source/java/org/alfresco/repo/avm/PlainFileNode.java @@ -1,5 +1,7 @@ package org.alfresco.repo.avm; +import org.alfresco.service.cmr.repository.ContentData; + /** * Interface for Plain file nodes. * @author britt @@ -17,4 +19,10 @@ interface PlainFileNode extends FileNode * @param mimeType */ public void setMimeType(String mimeType); + + /** + * Special case. + * @return + */ + public ContentData getContentData(); } diff --git a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java index bed9506c2c..ca505f6535 100644 --- a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java @@ -129,7 +129,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode setVersionID(versionID + 1); AVMDAOs.Instance().fAVMNodeDAO.save(this); AVMDAOs.Instance().fAVMNodeDAO.flush(); - setProperties(props); + addProperties(props); setAspects(new HashSet(aspects)); if (acl != null) { @@ -376,6 +376,14 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode * @return The ContentData object for this file. */ public ContentData getContentData(Lookup lPath) + { + return getContentData(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.PlainFileNode#getContentData() + */ + public ContentData getContentData() { return new ContentData(fContentURL, fMimeType, fLength, fEncoding); } diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml index b65b8aaf7b..9211b87e6c 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml +++ b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml @@ -51,6 +51,22 @@ + + + + + + + + + + + + + + + + iterate() + { + Query query = + getSession().createQuery("from AVMNodePropertyImpl anp"); + return (Iterator)query.iterate(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java index 59ddeb1696..4833226d4e 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java @@ -34,11 +34,9 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.i18n.I18NUtil; @@ -115,8 +113,6 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl private ContentService contentService; - private Set indexedPaths = new HashSet(); - private FTSIndexerAware callBack; private FullTextSearchIndexer fullTextSearchIndexer; @@ -378,197 +374,142 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl return docs; } - String[] splitPathForDoc = splitPath(stringNodeRef); - String docStore = splitPathForDoc[0]; - - List> allPaths = avmService.getPathsInStoreHead(desc, docStore); - List> paths = new ArrayList>(); - for (Pair pair : allPaths) - { - if (pair.getFirst().intValue() == endVersion) - { - paths.add(pair); - } - } - if (paths.size() == 0) - { - for (Pair pair : allPaths) - { - if (pair.getFirst().intValue() == -1) - { - paths.add(pair); - } - } - } - - if (paths.size() == 0) - { - return docs; - } - for (Pair path : paths) - { - if (indexedPaths.contains(path.getSecond())) - { - return docs; - } - } - for (Pair path : paths) - { - indexedPaths.add(path.getSecond()); - } - + // Naughty, Britt should come up with a fix that doesn't require this. AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); - if (paths.size() > 0) + if (desc != null) { - if (desc != null) + + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(endVersion, stringNodeRef); + + Document xdoc = new Document(); + xdoc.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("TX", AlfrescoTransactionSupport.getTransactionId(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + boolean isAtomic = true; + + Map properties = getIndexableProperties(desc, nodeRef, endVersion, stringNodeRef); + for (QName propertyName : properties.keySet()) { - - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(endVersion, stringNodeRef); - - Document xdoc = new Document(); - xdoc.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - for (Pair path : paths) + Serializable value = properties.get(propertyName); + if (indexAllProperties) { - - String[] splitPath = splitPath(path.getSecond()); - @SuppressWarnings("unused") - String pathInStore = splitPath[1]; - xdoc.add(new Field("ID", path.getSecond(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - } - - xdoc.add(new Field("TX", AlfrescoTransactionSupport.getTransactionId(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - boolean isAtomic = true; - - Map properties = getIndexableProperties(desc, nodeRef, endVersion, stringNodeRef); - for (QName propertyName : properties.keySet()) - { - Serializable value = properties.get(propertyName); - if (indexAllProperties) - { - indexProperty(nodeRef, propertyName, value, xdoc, false, properties); - } - else - { - isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true, properties); - } - } - - StringBuilder qNameBuffer = new StringBuilder(64); - - for (Pair path : paths) - { - - if (node.getIsRoot()) - { - - } - // pseudo roots? - else - { - String[] splitPath = splitPath(path.getSecond()); - String store = splitPath[0]; - String pathInStore = splitPath[1]; - SimplePath simplePath = new SimplePath(pathInStore); - - StringBuilder xpathBuilder = new StringBuilder(); - for (int i = 0; i < simplePath.size(); i++) - { - xpathBuilder.append("/{}").append(simplePath.get(i)); - } - String xpath = xpathBuilder.toString(); - - if (qNameBuffer.length() > 0) - { - qNameBuffer.append(";/"); - } - // Get the parent - - ArrayList ancestors = new ArrayList(); - - StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(store).append(":/"); - ancestors.add(pathBuilder.toString()); - boolean requiresSep = false; - for (int i = 0; i < simplePath.size() - 1; i++) - { - if (requiresSep) - { - pathBuilder.append("/"); - } - else - { - requiresSep = true; - } - pathBuilder.append(simplePath.get(i)); - ancestors.add(pathBuilder.toString()); - } - - qNameBuffer.append(ISO9075.getXPathName(QName.createQName("", simplePath.get(simplePath.size() - 1)))); - xdoc.add(new Field("PARENT", ancestors.get(ancestors.size() - 1), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - // TODO: Categories and LINKASPECT - - if (includeDirectoryDocuments) - { - if (desc.isDirectory()) - { - // TODO: Exclude category paths - - Document directoryEntry = new Document(); - directoryEntry.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - directoryEntry.add(new Field("ID", path.getSecond(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - directoryEntry.add(new Field("PATH", xpath, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - - // Find all parent nodes. - - for (String toAdd : ancestors) - { - directoryEntry.add(new Field("ANCESTOR", toAdd, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - } - directoryEntry.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - docs.add(directoryEntry); - - } - } - } - - } - - if (node.getIsRoot()) - { - // TODO: Does the root element have a QName? - xdoc.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("PATH", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("QNAME", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISROOT", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - docs.add(xdoc); - + indexProperty(nodeRef, propertyName, value, xdoc, false, properties); } else - // not a root node { - xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - - QName typeQName = getType(desc); - - xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - for (QName classRef : avmService.getAspects(endVersion, stringNodeRef)) - { - xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - } - - xdoc.add(new Field("ISROOT", "F", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - docs.add(xdoc); + isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true, properties); } } + + StringBuilder qNameBuffer = new StringBuilder(64); + if (node.getIsRoot()) + { + + } + // pseudo roots? + else + { + String[] splitPath = splitPath(stringNodeRef); + String store = splitPath[0]; + String pathInStore = splitPath[1]; + SimplePath simplePath = new SimplePath(pathInStore); + + StringBuilder xpathBuilder = new StringBuilder(); + for (int i = 0; i < simplePath.size(); i++) + { + xpathBuilder.append("/{}").append(simplePath.get(i)); + } + String xpath = xpathBuilder.toString(); + + if (qNameBuffer.length() > 0) + { + qNameBuffer.append(";/"); + } + // Get the parent + + ArrayList ancestors = new ArrayList(); + + StringBuilder pathBuilder = new StringBuilder(); + pathBuilder.append(store).append(":/"); + ancestors.add(pathBuilder.toString()); + boolean requiresSep = false; + for (int i = 0; i < simplePath.size() - 1; i++) + { + if (requiresSep) + { + pathBuilder.append("/"); + } + else + { + requiresSep = true; + } + pathBuilder.append(simplePath.get(i)); + ancestors.add(pathBuilder.toString()); + } + + qNameBuffer.append(ISO9075.getXPathName(QName.createQName("", simplePath.get(simplePath.size() - 1)))); + xdoc.add(new Field("PARENT", ancestors.get(ancestors.size() - 1), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + // TODO: Categories and LINKASPECT + + if (includeDirectoryDocuments) + { + if (desc.isDirectory()) + { + // TODO: Exclude category paths + + Document directoryEntry = new Document(); + directoryEntry.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + directoryEntry.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + directoryEntry.add(new Field("PATH", xpath, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + + // Find all parent nodes. + + for (String toAdd : ancestors) + { + directoryEntry.add(new Field("ANCESTOR", toAdd, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + } + directoryEntry.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + docs.add(directoryEntry); + + } + } + } + + if (node.getIsRoot()) + { + // TODO: Does the root element have a QName? + xdoc.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PATH", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("QNAME", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ISROOT", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + docs.add(xdoc); + + } + else + // not a root node + { + xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + + QName typeQName = getType(desc); + + xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + for (QName classRef : avmService.getAspects(desc)) + { + xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + } + + xdoc.add(new Field("ISROOT", "F", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + + docs.add(xdoc); + } } else { @@ -612,7 +553,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl private Map getIndexableProperties(AVMNodeDescriptor desc, NodeRef nodeRef, Integer version, String path) { - Map properties = avmService.getNodeProperties(version, path); + Map properties = avmService.getNodeProperties(desc); Map result = new HashMap(); for (QName qName : properties.keySet()) @@ -644,7 +585,15 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl { try { - ContentData contentData = avmService.getContentDataForRead(version, path); + ContentData contentData = null; + if (desc.isPlainFile()) + { + contentData = avmService.getContentDataForRead(desc); + } + else + { + contentData = avmService.getContentDataForRead(endVersion, path); + } result.put(ContentModel.PROP_CONTENT, contentData); } catch (AVMException e) diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java index 8cf0f512b9..de50482156 100644 --- a/source/java/org/alfresco/service/cmr/avm/AVMService.java +++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java @@ -987,6 +987,14 @@ public interface AVMService */ public Map getNodeProperties(int version, String path); + /** + * Get all the properties associated with a node identified by a descriptor. + * @param desc The node descriptor + * @return A Map of the properties. + * @throws AVMNotFoundException + */ + public Map getNodeProperties(AVMNodeDescriptor desc); + /** * Delete a property. * @@ -1083,6 +1091,14 @@ public interface AVMService */ public ContentData getContentDataForRead(int version, String path); + /** + * Get ContentData using only a node descriptor. + * @param desc The node descriptor. + * @return The ContentData + * @throws AVMNotFoundException + */ + public ContentData getContentDataForRead(AVMNodeDescriptor desc); + /** * Low-level internal function:   Get the ContentData for @@ -1137,6 +1153,13 @@ public interface AVMService */ public Set getAspects(int version, String path); + /** + * Get all the aspects from a node descriptor. + * @param desc The node descriptor. + * @return The Set of Aspects. + */ + public Set getAspects(AVMNodeDescriptor desc); + /** * Remove an aspect and its properties from a node. *