Change to mapping of AVM aspects.

This seems to make indexing a bit quicker, and at least doesn't make other things
slower. Bulk import now just sucks; it used to be an order of magnitude suckier.
98% of that is due to Andy's recent changes.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6103 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2007-06-26 01:15:39 +00:00
parent 4c232e02b1
commit cf0685b7ef
26 changed files with 306 additions and 194 deletions

View File

@@ -161,5 +161,8 @@ patch.redeploySubmitProcess.description=Re-deploy WCM Submit Process Definition.
patch.AVMLocking.description=Adds existing web projects to locking service. patch.AVMLocking.description=Adds existing web projects to locking service.
patch.AVMLocking.result=Necessary web projects added. patch.AVMLocking.result=Necessary web projects added.
patch.AVMAspects.description=Changes storage of aspects on AVM Nodes.
patch.AVMAspects.result=Aspects were moved.
patch.ReadmeTemplate.description=Deployed ReadMe Template patch.ReadmeTemplate.description=Deployed ReadMe Template
patch.webScriptsReadme.description=Applied ReadMe template to Web Scripts folders patch.webScriptsReadme.description=Applied ReadMe template to Web Scripts folders

View File

@@ -753,23 +753,23 @@
<value>classpath:alfresco/dbscripts/upgrade/2.1/${db.script.dialect}/AlfrescoSchemaUpdate-2.1-VersionColumns.sql</value> <value>classpath:alfresco/dbscripts/upgrade/2.1/${db.script.dialect}/AlfrescoSchemaUpdate-2.1-VersionColumns.sql</value>
</property> </property>
</bean> </bean>
<bean id="patch.webscriptsExtension" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" > <bean id="patch.webscriptsExtension" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<property name="id"><value>patch.webscriptsExtension</value></property> <property name="id"><value>patch.webscriptsExtension</value></property>
<property name="description"><value>patch.webscriptsExtension.description</value></property> <property name="description"><value>patch.webscriptsExtension.description</value></property>
<property name="fixesFromSchema"><value>0</value></property> <property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>54</value></property> <property name="fixesToSchema"><value>54</value></property>
<property name="targetSchema"><value>55</value></property> <property name="targetSchema"><value>55</value></property>
<!-- bootstrap view --> <!-- bootstrap view -->
<property name="importerBootstrap"> <property name="importerBootstrap">
<ref bean="spacesBootstrap" /> <ref bean="spacesBootstrap" />
</property> </property>
<property name="bootstrapView"> <property name="bootstrapView">
<props> <props>
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}</prop> <prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}</prop>
<prop key="location">alfresco/bootstrap/webScriptsExtensions.xml</prop> <prop key="location">alfresco/bootstrap/webScriptsExtensions.xml</prop>
</props> </props>
</property> </property>
</bean> </bean>
<bean id="patch.AVMLayeredSnapshot" class="org.alfresco.repo.admin.patch.impl.AVMLayeredSnapshotPatch" parent="basePatch"> <bean id="patch.AVMLayeredSnapshot" class="org.alfresco.repo.admin.patch.impl.AVMLayeredSnapshotPatch" parent="basePatch">
@@ -814,18 +814,18 @@
</props> </props>
</list> </list>
</property> </property>
</bean> </bean>
<bean id="patch.AVMLocking" class="org.alfresco.repo.admin.patch.impl.AVMLockingPatch" parent="basePatch"> <bean id="patch.AVMLocking" class="org.alfresco.repo.admin.patch.impl.AVMLockingPatch" parent="basePatch">
<property name="id"><value>patch.AVMLocking</value></property> <property name="id"><value>patch.AVMLocking</value></property>
<property name="description"><value>patch.AVMLocking.description</value></property> <property name="description"><value>patch.AVMLocking.description</value></property>
<property name="fixesFromSchema"><value>0</value></property> <property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>58</value></property> <property name="fixesToSchema"><value>58</value></property>
<property name="targetSchema"><value>59</value></property> <property name="targetSchema"><value>59</value></property>
<property name="avmLockingService"> <property name="avmLockingService">
<ref bean="avmLockingService"/> <ref bean="avmLockingService"/>
</property> </property>
</bean> </bean>
<bean id="patch.ReadmeTemplate" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" > <bean id="patch.ReadmeTemplate" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<property name="id"><value>patch.ReadmeTemplate</value></property> <property name="id"><value>patch.ReadmeTemplate</value></property>
@@ -862,5 +862,15 @@
</props> </props>
</property> </property>
</bean> </bean>
<bean id="patch.AVMAspects" class="org.alfresco.repo.admin.patch.impl.AVMAspectsPatch" parent="basePatch">
<property name="id"><value>patch.AVMAspects</value></property>
<property name="description"><value>patch.AVMAspects.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>60</value></property>
<property name="targetSchema"><value>61</value></property>
<property name="avmAspectNameDAO">
<ref bean="avmAspectNameDAO"/>
</property>
</bean>
</beans> </beans>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=60 version.schema=61

View File

@@ -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.AVMAspectName;
import org.alfresco.repo.avm.AVMAspectNameDAO;
/**
* Patches from old style aspect storage for AVM to new style.
* @author britt
*/
public class AVMAspectsPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.AVMAspects.result";
private AVMAspectNameDAO fAVMAspectDAO;
public void setAvmAspectNameDAO(AVMAspectNameDAO dao)
{
fAVMAspectDAO = dao;
}
/* (non-Javadoc)
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
Iterator<AVMAspectName> iter = fAVMAspectDAO.iterator();
while (iter.hasNext())
{
AVMAspectName aspect = iter.next();
aspect.getNode().getAspects().add(aspect.getName());
fAVMAspectDAO.delete(aspect);
}
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -23,6 +23,7 @@
package org.alfresco.repo.avm; package org.alfresco.repo.avm;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -72,4 +73,10 @@ public interface AVMAspectNameDAO
* @return Whether the aspect is there. * @return Whether the aspect is there.
*/ */
public boolean exists(AVMNode node, QName name); public boolean exists(AVMNode node, QName name);
/**
* Get an iterator over all aspect instances.
* @return
*/
public Iterator<AVMAspectName> iterator();
} }

View File

@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -226,7 +227,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.AVMService#getAspects(int, java.lang.String) * @see org.alfresco.service.cmr.avm.AVMService#getAspects(int, java.lang.String)
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
return fService.getAspects(version, path); return fService.getAspects(version, path);
} }

View File

@@ -23,6 +23,7 @@
package org.alfresco.repo.avm; package org.alfresco.repo.avm;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -228,4 +229,10 @@ public interface AVMNode
* @param guid * @param guid
*/ */
public void setGuid(String guid); public void setGuid(String guid);
/**
* Get the Aspects that this node has.
* @return A Set of Aspects names.
*/
public Set<QName> getAspects();
} }

View File

@@ -25,8 +25,10 @@ package org.alfresco.repo.avm;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.alfresco.repo.avm.util.RawServices; import org.alfresco.repo.avm.util.RawServices;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
@@ -83,11 +85,17 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
*/ */
private String fGUID; private String fGUID;
/**
* The Aspects that belong to this node.
*/
private Set<QName> fAspects;
/** /**
* Default constructor. * Default constructor.
*/ */
protected AVMNodeImpl() protected AVMNodeImpl()
{ {
fAspects = new HashSet<QName>();
} }
/** /**
@@ -98,6 +106,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
protected AVMNodeImpl(long id, protected AVMNodeImpl(long id,
AVMStore store) AVMStore store)
{ {
fAspects = new HashSet<QName>();
fID = id; fID = id;
fVersionID = -1; fVersionID = -1;
fIsRoot = false; fIsRoot = false;
@@ -351,16 +360,7 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
*/ */
protected void copyAspects(AVMNode other) protected void copyAspects(AVMNode other)
{ {
List<AVMAspectName> aspects = fAspects = new HashSet<QName>(other.getAspects());
AVMDAOs.Instance().fAVMAspectNameDAO.get(other);
for (AVMAspectName name : aspects)
{
AVMAspectName newName =
new AVMAspectNameImpl();
newName.setName(name.getName());
newName.setNode(this);
AVMDAOs.Instance().fAVMAspectNameDAO.save(newName);
}
} }
protected void copyACLs(AVMNode other) protected void copyACLs(AVMNode other)
@@ -538,4 +538,21 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
{ {
fGUID = guid; fGUID = guid;
} }
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNode#getAspects()
*/
public Set<QName> getAspects()
{
return fAspects;
}
/**
* Set the aspects on this node.
* @param aspects
*/
public void setAspects(Set<QName> aspects)
{
fAspects = aspects;
}
} }

View File

@@ -742,8 +742,7 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
} }
try try
{ {
List<QName> aspects = fAVMService.getAspects(version, path); for (QName name : fAVMService.getAspects(version, path))
for (QName name : aspects)
{ {
result.add(name); result.add(name);
} }

View File

@@ -8,6 +8,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -476,7 +477,7 @@ public class AVMRemoteLocal implements AVMRemote
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.remote.AVMRemote#getAspects(int, java.lang.String) * @see org.alfresco.service.cmr.remote.AVMRemote#getAspects(int, java.lang.String)
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
return fService.getAspects(version, path); return fService.getAspects(version, path);
} }

View File

@@ -11,6 +11,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -1013,7 +1014,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.remote.AVMRemoteTransport#getAspects(java.lang.String, int, java.lang.String) * @see org.alfresco.service.cmr.remote.AVMRemoteTransport#getAspects(java.lang.String, int, java.lang.String)
*/ */
public List<QName> getAspects(String ticket, int version, String path) public Set<QName> getAspects(String ticket, int version, String path)
{ {
fAuthService.validate(ticket); fAuthService.validate(ticket);
return fAVMService.getAspects(version, path); return fAVMService.getAspects(version, path);

View File

@@ -31,6 +31,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.ContentStore;
@@ -2260,7 +2261,7 @@ public class AVMRepository
* @param path The path to the node. * @param path The path to the node.
* @return A List of the QNames of the Aspects. * @return A List of the QNames of the Aspects.
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
fLookupCount.set(1); fLookupCount.set(1);
try try

View File

@@ -31,6 +31,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
@@ -1285,7 +1286,7 @@ public class AVMServiceImpl implements AVMService
* @param path The path to the node. * @param path The path to the node.
* @return A List of the QNames of the aspects. * @return A List of the QNames of the aspects.
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
if (path == null) if (path == null)
{ {
@@ -1424,7 +1425,7 @@ public class AVMServiceImpl implements AVMService
// In either case copy properties, aspects, and acls. // In either case copy properties, aspects, and acls.
Map<QName, PropertyValue> props = getNodeProperties(version, desc.getPath()); Map<QName, PropertyValue> props = getNodeProperties(version, desc.getPath());
setNodeProperties(newPath, props); setNodeProperties(newPath, props);
List<QName> aspects = getAspects(version, desc.getPath()); Set<QName> aspects = getAspects(version, desc.getPath());
for (QName aspect : aspects) for (QName aspect : aspects)
{ {
addAspect(newPath, aspect); addAspect(newPath, aspect);

View File

@@ -101,6 +101,105 @@ import org.alfresco.util.Pair;
*/ */
public class AVMServiceTest extends AVMServiceTestBase public class AVMServiceTest extends AVMServiceTestBase
{ {
/**
* Test properties.
*/
public void testProperties()
{
try
{
setupBasicTree();
StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty")+":\"Silly\"");
assertEquals(0, results.length());
results.close();
QName name = QName.createQName("silly.uri", "SillyProperty");
PropertyValue value = new PropertyValue(name, "Silly Property Value");
fService.setNodeProperty("main:/a/b/c/foo", name, value);
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty")+":\"Silly\"");
assertEquals(1, results.length());
results.close();
PropertyValue returned = fService.getNodeProperty(-1, "main:/a/b/c/foo", name);
assertEquals(value.toString(), returned.toString());
Map<QName, PropertyValue> props = fService.getNodeProperties(-1, "main:/a/b/c/foo");
assertEquals(1, props.size());
assertEquals(value.toString(), props.get(name).toString());
props = new HashMap<QName, PropertyValue>();
QName n1 = QName.createQName("silly.uri", "Prop1");
PropertyValue p1 = new PropertyValue(null, new Date(System.currentTimeMillis()));
props.put(n1, p1);
QName n2 = QName.createQName("silly.uri", "Prop2");
PropertyValue p2 = new PropertyValue(null, "A String Property.");
props.put(n2, p2);
QName n3 = QName.createQName("silly.uri", "Prop3");
PropertyValue p3 = new PropertyValue(null, 42);
props.put(n3, p3);
fService.setNodeProperties("main:/a/b/c/bar", props);
fService.createSnapshot("main", null, null);
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(3, props.size());
assertEquals(p1.toString(), props.get(n1).toString());
assertEquals(p2.toString(), props.get(n2).toString());
assertEquals(p3.toString(), props.get(n3).toString());
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
fService.deleteNodeProperty("main:/a/b/c/bar", n1);
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(2, props.size());
assertEquals(p2.toString(), props.get(n2).toString());
assertEquals(p3.toString(), props.get(n3).toString());
fService.deleteNodeProperties("main:/a/b/c/bar");
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + p1.getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(0, props.size());
fService.removeNode("main:/a/b/c/foo");
fService.setNodeProperty("main:/a/b/c/foo", QName.createQName("silly.uri", "Prop1"), new PropertyValue(
null, 42));
assertEquals(1, fService.getNodeProperties(-1, "main:/a/b/c/foo").size());
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + p1.getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + p2.getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
/** /**
* Test getStoreVersionRootPaths(). * Test getStoreVersionRootPaths().
*/ */
@@ -5029,103 +5128,6 @@ public class AVMServiceTest extends AVMServiceTestBase
} }
} }
/**
* Test properties.
*/
public void testProperties()
{
try
{
setupBasicTree();
StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty")+":\"Silly\"");
assertEquals(0, results.length());
results.close();
QName name = QName.createQName("silly.uri", "SillyProperty");
PropertyValue value = new PropertyValue(name, "Silly Property Value");
fService.setNodeProperty("main:/a/b/c/foo", name, value);
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty")+":\"Silly\"");
assertEquals(1, results.length());
results.close();
PropertyValue returned = fService.getNodeProperty(-1, "main:/a/b/c/foo", name);
assertEquals(value.toString(), returned.toString());
Map<QName, PropertyValue> props = fService.getNodeProperties(-1, "main:/a/b/c/foo");
assertEquals(1, props.size());
assertEquals(value.toString(), props.get(name).toString());
props = new HashMap<QName, PropertyValue>();
QName n1 = QName.createQName("silly.uri", "Prop1");
PropertyValue p1 = new PropertyValue(null, new Date(System.currentTimeMillis()));
props.put(n1, p1);
QName n2 = QName.createQName("silly.uri", "Prop2");
PropertyValue p2 = new PropertyValue(null, "A String Property.");
props.put(n2, p2);
QName n3 = QName.createQName("silly.uri", "Prop3");
PropertyValue p3 = new PropertyValue(null, 42);
props.put(n3, p3);
fService.setNodeProperties("main:/a/b/c/bar", props);
fService.createSnapshot("main", null, null);
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(3, props.size());
assertEquals(p1.toString(), props.get(n1).toString());
assertEquals(p2.toString(), props.get(n2).toString());
assertEquals(p3.toString(), props.get(n3).toString());
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
fService.deleteNodeProperty("main:/a/b/c/bar", n1);
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(1, results.length());
results.close();
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(2, props.size());
assertEquals(p2.toString(), props.get(n2).toString());
assertEquals(p3.toString(), props.get(n3).toString());
fService.deleteNodeProperties("main:/a/b/c/bar");
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
props = fService.getNodeProperties(-1, "main:/a/b/c/bar");
assertEquals(0, props.size());
fService.removeNode("main:/a/b/c/foo");
fService.setNodeProperty("main:/a/b/c/foo", QName.createQName("silly.uri", "Prop1"), new PropertyValue(
null, 42));
assertEquals(1, fService.getNodeProperties(-1, "main:/a/b/c/foo").size());
fService.createSnapshot("main", null, null);
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1")+":\"" + props.get(n1).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2")+":\"" + props.get(n2).getStringValue() +"\"");
assertEquals(0, results.length());
results.close();
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}
/** /**
* Test properties on stores. * Test properties on stores.
@@ -5197,7 +5199,7 @@ public class AVMServiceTest extends AVMServiceTestBase
fService.removeNode("main:/a/b/c/bar"); fService.removeNode("main:/a/b/c/bar");
fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_TITLED); fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_TITLED);
List<QName> names = fService.getAspects(-1, "main:/a/b/c/foo"); Set<QName> names = fService.getAspects(-1, "main:/a/b/c/foo");
assertEquals(2, names.size()); assertEquals(2, names.size());
assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED));
assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUTHOR)); assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUTHOR));

View File

@@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
@@ -422,7 +423,7 @@ public interface AVMStore
* @param path The path to the node. * @param path The path to the node.
* @return A List of the QNames of the aspects. * @return A List of the QNames of the aspects.
*/ */
public List<QName> getAspects(int version, String path); public Set<QName> getAspects(int version, String path);
/** /**
* Remove an aspect and all its properties from a node. * Remove an aspect and all its properties from a node.

View File

@@ -32,12 +32,12 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel; import org.alfresco.model.WCMModel;
import org.alfresco.repo.avm.AVMAspectName;
import org.alfresco.repo.avm.util.RawServices; import org.alfresco.repo.avm.util.RawServices;
import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.avm.util.SimplePath;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
@@ -1289,16 +1289,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (AVMDAOs.Instance().fAVMAspectNameDAO.exists(node, aspectName)) node.getAspects().add(aspectName);
{
throw new AVMExistsException("Aspect exists.");
}
AVMAspectName newName =
new AVMAspectNameImpl();
newName.setNode(node);
newName.setName(aspectName);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMAspectNameDAO.save(newName);
} }
/** /**
@@ -1307,7 +1299,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
* @param path The path to the node. * @param path The path to the node.
* @return A List of the QNames of the aspects. * @return A List of the QNames of the aspects.
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, true); Lookup lPath = lookup(version, path, false, true);
if (lPath == null) if (lPath == null)
@@ -1315,14 +1307,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
List<AVMAspectName> names = return node.getAspects();
AVMDAOs.Instance().fAVMAspectNameDAO.get(node);
ArrayList<QName> result = new ArrayList<QName>();
for (AVMAspectName name : names)
{
result.add(name.getName());
}
return result;
} }
/** /**
@@ -1338,7 +1323,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
AVMDAOs.Instance().fAVMAspectNameDAO.delete(node, aspectName); node.getAspects().remove(aspectName);
AspectDefinition def = RawServices.Instance().getDictionaryService().getAspect(aspectName); AspectDefinition def = RawServices.Instance().getDictionaryService().getAspect(aspectName);
Map<QName, PropertyDefinition> properties = Map<QName, PropertyDefinition> properties =
def.getProperties(); def.getProperties();
@@ -1364,7 +1349,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return AVMDAOs.Instance().fAVMAspectNameDAO.exists(node, aspectName); return node.getAspects().contains(aspectName);
} }
/** /**
@@ -1447,14 +1432,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
dir.putChild(name, toLink); dir.putChild(name, toLink);
toLink.changeAncestor(child); toLink.changeAncestor(child);
toLink.setVersionID(child.getVersionID() + 1); toLink.setVersionID(child.getVersionID() + 1);
if (AVMDAOs.Instance().fAVMAspectNameDAO.exists(toLink, WCMModel.ASPECT_REVERTED)) // TODO This really shouldn't be here. Leaking layers.
{ toLink.getAspects().add(WCMModel.ASPECT_REVERTED);
AVMDAOs.Instance().fAVMAspectNameDAO.delete(toLink, WCMModel.ASPECT_REVERTED);
}
AVMAspectName aspect = new AVMAspectNameImpl();
aspect.setNode(toLink);
aspect.setName(WCMModel.ASPECT_REVERTED);
AVMDAOs.Instance().fAVMAspectNameDAO.save(aspect);
PropertyValue value = new PropertyValue(null, toRevertTo.getId()); PropertyValue value = new PropertyValue(null, toRevertTo.getId());
toLink.setProperty(WCMModel.PROP_REVERTED_ID, value); toLink.setProperty(WCMModel.PROP_REVERTED_ID, value);
} }

View File

@@ -109,7 +109,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getBasicAttributes(), getBasicAttributes(),
getContentData(lPath), getContentData(lPath),
indirect.getProperties(), indirect.getProperties(),
AVMDAOs.Instance().fAVMAspectNameDAO.get(indirect), indirect.getAspects(),
indirect.getAcl(), indirect.getAcl(),
getVersionID()); getVersionID());
newMe.setAncestor(this); newMe.setAncestor(this);

View File

@@ -308,7 +308,7 @@ public class OrphanReaper
// Get rid of all properties belonging to this node. // Get rid of all properties belonging to this node.
AVMDAOs.Instance().fAVMNodePropertyDAO.deleteAll(node); AVMDAOs.Instance().fAVMNodePropertyDAO.deleteAll(node);
// Get rid of all aspects belonging to this node. // Get rid of all aspects belonging to this node.
AVMDAOs.Instance().fAVMAspectNameDAO.delete(node); // AVMDAOs.Instance().fAVMAspectNameDAO.delete(node);
// Get rid of ACL. // Get rid of ACL.
DbAccessControlList acl = node.getAcl(); DbAccessControlList acl = node.getAcl();
node.setAcl(null); node.setAcl(null);

View File

@@ -23,8 +23,10 @@
package org.alfresco.repo.avm; package org.alfresco.repo.avm;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.alfresco.repo.avm.util.RawServices; import org.alfresco.repo.avm.util.RawServices;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
@@ -117,7 +119,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
BasicAttributes attrs, BasicAttributes attrs,
ContentData content, ContentData content,
Map<QName, PropertyValue> props, Map<QName, PropertyValue> props,
List<AVMAspectName> aspects, Set<QName> aspects,
DbAccessControlList acl, DbAccessControlList acl,
int versionID) int versionID)
{ {
@@ -128,14 +130,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
AVMDAOs.Instance().fAVMNodeDAO.save(this); AVMDAOs.Instance().fAVMNodeDAO.save(this);
AVMDAOs.Instance().fAVMNodeDAO.flush(); AVMDAOs.Instance().fAVMNodeDAO.flush();
setProperties(props); setProperties(props);
for (AVMAspectName name : aspects) setAspects(new HashSet<QName>(aspects));
{
AVMAspectName newName =
new AVMAspectNameImpl();
newName.setName(name.getName());
newName.setNode(this);
AVMDAOs.Instance().fAVMAspectNameDAO.save(newName);
}
if (acl != null) if (acl != null)
{ {
setAcl(acl.getCopy()); setAcl(acl.getCopy());

View File

@@ -46,6 +46,11 @@
<!-- ACL --> <!-- ACL -->
<many-to-one name="acl" column="acl_id" foreign-key="fk_avm_n_acl" <many-to-one name="acl" column="acl_id" foreign-key="fk_avm_n_acl"
class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"/> class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"/>
<set name="aspects" fetch="join" lazy="false" table="avm_aspects_new" cascade="all" optimistic-lock="true">
<cache usage="read-write"/>
<key column="id"/>
<element type="QName" not-null="true" column="name" length="200"/>
</set>
<!-- Deleted nodes --> <!-- Deleted nodes -->
<subclass name="DeletedNodeImpl" <subclass name="DeletedNodeImpl"
proxy="DeletedNode" proxy="DeletedNode"

View File

@@ -23,6 +23,7 @@
package org.alfresco.repo.avm.hibernate; package org.alfresco.repo.avm.hibernate;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.alfresco.repo.avm.AVMAspectName; import org.alfresco.repo.avm.AVMAspectName;
@@ -113,4 +114,15 @@ public class AVMAspectNameDAOHibernate extends HibernateDaoSupport
query.setParameter("name", name); query.setParameter("name", name);
return query.uniqueResult() != null; return query.uniqueResult() != null;
} }
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMAspectNameDAO#iterator()
*/
@SuppressWarnings("unchecked")
public Iterator<AVMAspectName> iterator()
{
Query query =
getSession().createQuery("from AVMAspectNameImpl aa");
return (Iterator<AVMAspectName>)query.iterate();
}
} }

View File

@@ -31,6 +31,7 @@ import java.io.OutputStream;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.deployment.DeploymentReceiverService; import org.alfresco.deployment.DeploymentReceiverService;
@@ -487,7 +488,7 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
Map<QName, PropertyValue> props = fAVMService.getNodeProperties(version, src.getPath()); Map<QName, PropertyValue> props = fAVMService.getNodeProperties(version, src.getPath());
remote.setNodeProperties(dst.getPath(), props); remote.setNodeProperties(dst.getPath(), props);
List<QName> aspects = fAVMService.getAspects(version, src.getPath()); Set<QName> aspects = fAVMService.getAspects(version, src.getPath());
for (QName aspect : aspects) for (QName aspect : aspects)
{ {
if (remote.hasAspect(-1, dst.getPath(), aspect)) if (remote.hasAspect(-1, dst.getPath(), aspect))

View File

@@ -8,6 +8,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -492,7 +493,7 @@ public class AVMRemoteImpl implements AVMRemote
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.remote.AVMRemote#getAspects(int, java.lang.String) * @see org.alfresco.service.cmr.remote.AVMRemote#getAspects(int, java.lang.String)
*/ */
public List<QName> getAspects(int version, String path) public Set<QName> getAspects(int version, String path)
{ {
return fTransport.getAspects(fTicketHolder.getTicket(), version, path); return fTransport.getAspects(fTicketHolder.getTicket(), version, path);
} }

View File

@@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -1131,10 +1132,10 @@ public interface AVMService
* *
* @param version The version to look under. * @param version The version to look under.
* @param path The path to the node. * @param path The path to the node.
* @return A List of the QNames of the aspects. * @return A Set of the QNames of the aspects.
* @throws AVMNotFoundException * @throws AVMNotFoundException
*/ */
public List<QName> getAspects(int version, String path); public Set<QName> getAspects(int version, String path);
/** /**
* Remove an aspect and its properties from a node. * Remove an aspect and its properties from a node.

View File

@@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -457,7 +458,7 @@ public interface AVMRemote
* @return A List of the QNames of the aspects. * @return A List of the QNames of the aspects.
* @throws AVMNotFoundException * @throws AVMNotFoundException
*/ */
public List<QName> getAspects(int version, String path); public Set<QName> getAspects(int version, String path);
/** /**
* Remove an aspect and its properties from a node. * Remove an aspect and its properties from a node.

View File

@@ -6,6 +6,7 @@ package org.alfresco.service.cmr.remote;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
@@ -471,7 +472,7 @@ public interface AVMRemoteTransport
* @return A List of the QNames of the aspects. * @return A List of the QNames of the aspects.
* @throws AVMNotFoundException * @throws AVMNotFoundException
*/ */
public List<QName> getAspects(String ticket, int version, String path); public Set<QName> getAspects(String ticket, int version, String path);
/** /**
* Remove an aspect and its properties from a node. * Remove an aspect and its properties from a node.