Moved dangerous helper methods out of AVMService.

Reworked handling of path lookup failures to not throw exceptions
internally, to improve performance of certain layered directory
operations.  Unfortunately there remains at least one scenario,
handling of bulk loads, and promotions of deeply nested directories in
layered contexts, in which performance is considerably less than
ideal. 

Made AVMService.createBranch() and AVMSyncService.update() perform
implicit snapshots of source tree's stores before proceeding.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3812 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-09-17 20:05:27 +00:00
parent f5e509c18b
commit 90d171b913
11 changed files with 545 additions and 181 deletions

View File

@@ -1058,6 +1058,9 @@
<property name="avmService"> <property name="avmService">
<ref bean="avmService"/> <ref bean="avmService"/>
</property> </property>
<property name="avmRepository">
<ref bean="avmRepository"/>
</property>
</bean> </bean>
<bean id="AVMSyncService_descriptor" parent="AlfrescoServiceDescriptor"> <bean id="AVMSyncService_descriptor" parent="AlfrescoServiceDescriptor">

View File

@@ -105,8 +105,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
return rep.createFile(pathParts[1], name); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.createFile(pathParts[1], name);
} }
/** /**
@@ -119,8 +123,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
rep.createFile(pathParts[1], name, data); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.createFile(pathParts[1], name, data);
} }
/** /**
@@ -132,8 +140,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
rep.createDirectory(pathParts[1], name); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.createDirectory(pathParts[1], name);
} }
/** /**
@@ -157,6 +169,10 @@ public class AVMRepository
// We need the store to do anything so... // We need the store to do anything so...
String [] pathParts = SplitPath(parent.getPath()); String [] pathParts = SplitPath(parent.getPath());
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
DirectoryNode dir = (DirectoryNode)node; DirectoryNode dir = (DirectoryNode)node;
DirectoryNode child = null; DirectoryNode child = null;
if (dir instanceof LayeredDirectoryNode) if (dir instanceof LayeredDirectoryNode)
@@ -188,9 +204,12 @@ public class AVMRepository
} }
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(dstPath); String[] pathParts = SplitPath(dstPath);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
// fSession.get().lock(rep, LockMode.UPGRADE); if (store == null)
rep.createLayeredDirectory(srcPath, pathParts[1], name); {
throw new AVMNotFoundException("Store not found.");
}
store.createLayeredDirectory(srcPath, pathParts[1], name);
} }
/** /**
@@ -203,8 +222,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(dstPath); String[] pathParts = SplitPath(dstPath);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
rep.createLayeredFile(srcPath, pathParts[1], name); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.createLayeredFile(srcPath, pathParts[1], name);
} }
/** /**
@@ -213,15 +236,10 @@ public class AVMRepository
*/ */
public void createAVMStore(String name) public void createAVMStore(String name)
{ {
try if (getAVMStoreByName(name) != null)
{ {
getAVMStoreByName(name);
throw new AVMExistsException("AVMStore exists: " + name); throw new AVMExistsException("AVMStore exists: " + name);
} }
catch (AVMNotFoundException anf)
{
// Do nothing.
}
// Newing up the object causes it to be written to the db. // Newing up the object causes it to be written to the db.
@SuppressWarnings("unused") @SuppressWarnings("unused")
AVMStore rep = new AVMStoreImpl(this, name); AVMStore rep = new AVMStoreImpl(this, name);
@@ -246,12 +264,32 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(srcPath); String [] pathParts = SplitPath(srcPath);
AVMStore srcRepo = getAVMStoreByName(pathParts[0]); AVMStore srcRepo = getAVMStoreByName(pathParts[0]);
if (srcRepo == null)
{
throw new AVMNotFoundException("Store not found.");
}
if (version < 0)
{
version = srcRepo.createSnapshot();
}
Lookup sPath = srcRepo.lookup(version, pathParts[1], false, false); Lookup sPath = srcRepo.lookup(version, pathParts[1], false, false);
if (sPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
// Lookup the destination directory. // Lookup the destination directory.
fLookupCount.set(1); fLookupCount.set(1);
pathParts = SplitPath(dstPath); pathParts = SplitPath(dstPath);
AVMStore dstRepo = getAVMStoreByName(pathParts[0]); AVMStore dstRepo = getAVMStoreByName(pathParts[0]);
if (dstRepo == null)
{
throw new AVMNotFoundException("Store not found.");
}
Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true);
if (dPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode(); DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode();
AVMNode srcNode = sPath.getCurrentNode(); AVMNode srcNode = sPath.getCurrentNode();
AVMNode dstNode = null; AVMNode dstNode = null;
@@ -291,8 +329,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore rep = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
return rep.getOutputStream(pathParts[1]); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getOutputStream(pathParts[1]);
} }
/** /**
@@ -313,7 +355,15 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(srcPath); String [] pathParts = SplitPath(srcPath);
AVMStore srcRepo = getAVMStoreByName(pathParts[0]); AVMStore srcRepo = getAVMStoreByName(pathParts[0]);
if (srcRepo == null)
{
throw new AVMNotFoundException("Store not found.");
}
Lookup sPath = srcRepo.lookupDirectory(-1, pathParts[1], true); Lookup sPath = srcRepo.lookupDirectory(-1, pathParts[1], true);
if (sPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode srcDir = (DirectoryNode)sPath.getCurrentNode(); DirectoryNode srcDir = (DirectoryNode)sPath.getCurrentNode();
AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1, true, false); AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1, true, false);
if (srcNode == null) if (srcNode == null)
@@ -323,7 +373,15 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
pathParts = SplitPath(dstPath); pathParts = SplitPath(dstPath);
AVMStore dstRepo = getAVMStoreByName(pathParts[0]); AVMStore dstRepo = getAVMStoreByName(pathParts[0]);
if (dstRepo == null)
{
throw new AVMNotFoundException("Store not found.");
}
Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true);
if (dPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode(); DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode();
AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1, true, false); AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1, true, false);
if (dstNode != null) if (dstNode != null)
@@ -425,8 +483,12 @@ public class AVMRepository
{ {
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(dirPath); String [] pathParts = SplitPath(dirPath);
AVMStore repo = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
repo.uncover(pathParts[1], name); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.uncover(pathParts[1], name);
} }
/** /**
@@ -439,8 +501,12 @@ public class AVMRepository
List<Integer> result = new ArrayList<Integer>(); List<Integer> result = new ArrayList<Integer>();
for (String repName : repositories) for (String repName : repositories)
{ {
AVMStore repo = getAVMStoreByName(repName); AVMStore store = getAVMStoreByName(repName);
result.add(repo.createSnapshot()); if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
result.add(store.createSnapshot());
} }
return result; return result;
} }
@@ -453,6 +519,10 @@ public class AVMRepository
public int createSnapshot(String storeName) public int createSnapshot(String storeName)
{ {
AVMStore store = getAVMStoreByName(storeName); AVMStore store = getAVMStoreByName(storeName);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.createSnapshot(); return store.createSnapshot();
} }
@@ -466,6 +536,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.removeNode(pathParts[1], name); store.removeNode(pathParts[1], name);
} }
@@ -478,6 +552,10 @@ public class AVMRepository
public void purgeAVMStore(String name) public void purgeAVMStore(String name)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
AVMNode root = store.getRoot(); AVMNode root = store.getRoot();
root.setIsRoot(false); root.setIsRoot(false);
VersionRootDAO vrDAO = AVMContext.fgInstance.fVersionRootDAO; VersionRootDAO vrDAO = AVMContext.fgInstance.fVersionRootDAO;
@@ -505,6 +583,10 @@ public class AVMRepository
public void purgeVersion(String name, int version) public void purgeVersion(String name, int version)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.purgeVersion(version); store.purgeVersion(version);
} }
@@ -519,6 +601,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getInputStream(version, pathParts[1]); return store.getInputStream(version, pathParts[1]);
} }
@@ -535,6 +621,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getListing(version, pathParts[1], includeDeleted); return store.getListing(version, pathParts[1], includeDeleted);
} }
@@ -550,6 +640,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getListingDirect(version, pathParts[1], includeDeleted); return store.getListingDirect(version, pathParts[1], includeDeleted);
} }
@@ -612,6 +706,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getDeleted(version, pathParts[1]); return store.getDeleted(version, pathParts[1]);
} }
@@ -639,6 +737,10 @@ public class AVMRepository
public AVMStoreDescriptor getAVMStore(String name) public AVMStoreDescriptor getAVMStore(String name)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
return null;
}
return store.getDescriptor(); return store.getDescriptor();
} }
@@ -650,6 +752,10 @@ public class AVMRepository
public List<VersionDescriptor> getAVMStoreVersions(String name) public List<VersionDescriptor> getAVMStoreVersions(String name)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getVersions(); return store.getVersions();
} }
@@ -664,6 +770,10 @@ public class AVMRepository
public List<VersionDescriptor> getAVMStoreVersions(String name, Date from, Date to) public List<VersionDescriptor> getAVMStoreVersions(String name, Date from, Date to)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getVersions(from, to); return store.getVersions(from, to);
} }
@@ -696,6 +806,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getIndirectionPath(version, pathParts[1]); return store.getIndirectionPath(version, pathParts[1]);
} }
@@ -707,6 +821,10 @@ public class AVMRepository
public int getLatestVersionID(String name) public int getLatestVersionID(String name)
{ {
AVMStore store = getAVMStoreByName(name); AVMStore store = getAVMStoreByName(name);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getNextVersionID(); return store.getNextVersionID();
} }
@@ -717,12 +835,7 @@ public class AVMRepository
*/ */
private AVMStore getAVMStoreByName(String name) private AVMStore getAVMStoreByName(String name)
{ {
AVMStore store = AVMContext.fgInstance.fAVMStoreDAO.getByName(name); return AVMContext.fgInstance.fAVMStoreDAO.getByName(name);
if (store == null)
{
throw new AVMNotFoundException("AVMStore not found: " + name);
}
return store;
} }
/** /**
@@ -768,8 +881,11 @@ public class AVMRepository
} }
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
Lookup result = store.lookup(version, pathParts[1], false, includeDeleted); if (store == null)
return result; {
return null;
}
return store.lookup(version, pathParts[1], false, includeDeleted);
} }
finally finally
{ {
@@ -780,6 +896,7 @@ public class AVMRepository
} }
} }
// TODO This should really return null for not found.
/** /**
* Lookup a descriptor from a directory descriptor. * Lookup a descriptor from a directory descriptor.
* @param dir The directory descriptor. * @param dir The directory descriptor.
@@ -814,7 +931,15 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
Lookup lookup = store.lookup(version, pathParts[1], false, false); Lookup lookup = store.lookup(version, pathParts[1], false, false);
if (lookup == null)
{
throw new AVMNotFoundException("Path not found.");
}
return new LayeringDescriptor(!lookup.getDirectlyContained(), return new LayeringDescriptor(!lookup.getDirectlyContained(),
lookup.getAVMStore().getDescriptor(), lookup.getAVMStore().getDescriptor(),
lookup.getFinalStore().getDescriptor()); lookup.getFinalStore().getDescriptor());
@@ -834,6 +959,10 @@ public class AVMRepository
} }
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
return null;
}
return store.lookupDirectory(version, pathParts[1], false); return store.lookupDirectory(version, pathParts[1], false);
} }
@@ -861,6 +990,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.makePrimary(pathParts[1]); store.makePrimary(pathParts[1]);
} }
@@ -874,6 +1007,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.retargetLayeredDirectory(pathParts[1], target); store.retargetLayeredDirectory(pathParts[1], target);
} }
@@ -918,6 +1055,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String[] pathParts = SplitPath(path); String[] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.setOpacity(pathParts[1], opacity); store.setOpacity(pathParts[1], opacity);
} }
@@ -932,6 +1073,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.setNodeProperty(pathParts[1], name, value); store.setNodeProperty(pathParts[1], name, value);
} }
@@ -945,6 +1090,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.setNodeProperties(pathParts[1], properties); store.setNodeProperties(pathParts[1], properties);
} }
@@ -960,6 +1109,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getNodeProperty(version, pathParts[1], name); return store.getNodeProperty(version, pathParts[1], name);
} }
@@ -974,6 +1127,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getNodeProperties(version, pathParts[1]); return store.getNodeProperties(version, pathParts[1]);
} }
@@ -987,6 +1144,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.deleteNodeProperty(pathParts[1], name); store.deleteNodeProperty(pathParts[1], name);
} }
@@ -999,6 +1160,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.deleteNodeProperties(pathParts[1]); store.deleteNodeProperties(pathParts[1]);
} }
@@ -1010,7 +1175,12 @@ public class AVMRepository
*/ */
public void setStoreProperty(String store, QName name, PropertyValue value) public void setStoreProperty(String store, QName name, PropertyValue value)
{ {
getAVMStoreByName(store).setProperty(name, value); AVMStore st = getAVMStoreByName(store);
if (st == null)
{
throw new AVMNotFoundException("Store not found.");
}
st.setProperty(name, value);
} }
/** /**
@@ -1020,7 +1190,12 @@ public class AVMRepository
*/ */
public void setStoreProperties(String store, Map<QName, PropertyValue> props) public void setStoreProperties(String store, Map<QName, PropertyValue> props)
{ {
getAVMStoreByName(store).setProperties(props); AVMStore st = getAVMStoreByName(store);
if (st == null)
{
throw new AVMNotFoundException("Store not found.");
}
st.setProperties(props);
} }
/** /**
@@ -1031,7 +1206,16 @@ public class AVMRepository
*/ */
public PropertyValue getStoreProperty(String store, QName name) public PropertyValue getStoreProperty(String store, QName name)
{ {
return getAVMStoreByName(store).getProperty(name); if (store == null)
{
throw new AVMBadArgumentException("Null store name.");
}
AVMStore st = getAVMStoreByName(store);
if (st == null)
{
throw new AVMNotFoundException("Store not found.");
}
return st.getProperty(name);
} }
/** /**
@@ -1042,8 +1226,13 @@ public class AVMRepository
*/ */
public Map<QName, PropertyValue> queryStorePropertyKey(String store, QName keyPattern) public Map<QName, PropertyValue> queryStorePropertyKey(String store, QName keyPattern)
{ {
AVMStore st = getAVMStoreByName(store);
if (st == null)
{
throw new AVMNotFoundException("Store not found.");
}
List<AVMStoreProperty> matches = List<AVMStoreProperty> matches =
AVMContext.fgInstance.fAVMStorePropertyDAO.queryByKeyPattern(getAVMStoreByName(store), AVMContext.fgInstance.fAVMStorePropertyDAO.queryByKeyPattern(st,
keyPattern); keyPattern);
Map<QName, PropertyValue> results = new HashMap<QName, PropertyValue>(); Map<QName, PropertyValue> results = new HashMap<QName, PropertyValue>();
for (AVMStoreProperty prop : matches) for (AVMStoreProperty prop : matches)
@@ -1086,7 +1275,16 @@ public class AVMRepository
*/ */
public Map<QName, PropertyValue> getStoreProperties(String store) public Map<QName, PropertyValue> getStoreProperties(String store)
{ {
return getAVMStoreByName(store).getProperties(); if (store == null)
{
throw new AVMBadArgumentException("Null store name.");
}
AVMStore st = getAVMStoreByName(store);
if (st == null)
{
throw new AVMNotFoundException("Store not found.");
}
return st.getProperties();
} }
/** /**
@@ -1096,17 +1294,12 @@ public class AVMRepository
*/ */
public void deleteStoreProperty(String store, QName name) public void deleteStoreProperty(String store, QName name)
{ {
getAVMStoreByName(store).deleteProperty(name); AVMStore st = getAVMStoreByName(store);
} if (st == null)
{
/** throw new AVMNotFoundException("Store not found.");
* Get the AVMStoreDescriptor for an AVMStore. }
* @param name The name of the AVMStore. st.deleteProperty(name);
* @return The descriptor.
*/
public AVMStoreDescriptor getAVMStoreDescriptor(String name)
{
return getAVMStoreByName(name).getDescriptor();
} }
/** /**
@@ -1179,6 +1372,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getContentDataForWrite(pathParts[1]); return store.getContentDataForWrite(pathParts[1]);
} }
@@ -1192,6 +1389,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.setContentData(pathParts[1], data); store.setContentData(pathParts[1], data);
} }
@@ -1214,6 +1415,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.addAspect(pathParts[1], aspectName); store.addAspect(pathParts[1], aspectName);
} }
@@ -1228,6 +1433,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getAspects(version, pathParts[1]); return store.getAspects(version, pathParts[1]);
} }
@@ -1241,6 +1450,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.removeAspect(pathParts[1], aspectName); store.removeAspect(pathParts[1], aspectName);
} }
@@ -1256,6 +1469,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.hasAspect(version, pathParts[1], aspectName); return store.hasAspect(version, pathParts[1], aspectName);
} }
@@ -1269,6 +1486,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.setACL(pathParts[1], acl); store.setACL(pathParts[1], acl);
} }
@@ -1283,6 +1504,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
return store.getACL(version, pathParts[1]); return store.getACL(version, pathParts[1]);
} }
@@ -1297,6 +1522,10 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(parentPath); String [] pathParts = SplitPath(parentPath);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
store.link(pathParts[1], name, toLink); store.link(pathParts[1], name, toLink);
} }
@@ -1353,8 +1582,16 @@ public class AVMRepository
fLookupCount.set(1); fLookupCount.set(1);
String [] pathParts = SplitPath(path); String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
// Just force a copy if needed by looking up in write mode. // Just force a copy if needed by looking up in write mode.
Lookup lPath = store.lookup(-1, pathParts[1], true, false); Lookup lPath = store.lookup(-1, pathParts[1], true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getDescriptor(lPath); return node.getDescriptor(lPath);
} }

View File

@@ -307,22 +307,6 @@ public class AVMServiceImpl implements AVMService
fAVMRepository.createDirectory(path, name); fAVMRepository.createDirectory(path, name);
} }
/**
* Create a new directory, in an already copy on written node.
* This should only be used if you really know what you're doing.
* @param parent The parent node.
* @param name The name of the new directory.
* @return A descriptor for the newly created directory.
*/
public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name)
{
if (parent == null || name == null)
{
throw new AVMBadArgumentException("Illegal null argument.");
}
return fAVMRepository.createDirectory(parent, name);
}
/** /**
* Create a new layered file. It must not exist. * Create a new layered file. It must not exist.
* @param srcPath The src path. Ie the target for the layering. * @param srcPath The src path. Ie the target for the layering.
@@ -511,6 +495,10 @@ public class AVMServiceImpl implements AVMService
try try
{ {
Lookup lookup = fAVMRepository.lookup(version, path, includeDeleted); Lookup lookup = fAVMRepository.lookup(version, path, includeDeleted);
if (lookup == null)
{
return null;
}
return lookup.getCurrentNode().getDescriptor(lookup); return lookup.getCurrentNode().getDescriptor(lookup);
} }
catch (AVMNotFoundException e) catch (AVMNotFoundException e)
@@ -1082,42 +1070,6 @@ public class AVMServiceImpl implements AVMService
fAVMRepository.link(parentPath, name, toLink); fAVMRepository.link(parentPath, name, toLink);
} }
/**
* This is a more dangerous version of link, which assumes
* that copy on write has occurred for the parent node. This is
* an internal call. Don't use it if you don't know precisely
* what you are doing.
* @param parent The parent node.
* @param name The name to give the child.
* @param child The child node to link.
*/
public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child)
{
if (parent == null || child == null)
{
throw new AVMBadArgumentException("Illegal Null Argument.");
}
fAVMRepository.link(parent, name, child);
}
/**
* Flatten a direct child of a layered directory. This does
* the equivalent of removing the given child from the directory
* and then doing an uncover. This routine makes many dangerous
* assumptions and is only for use by AVMSyncService. Don't use it
* if you don't know precisely what you are doing.
* @param lDir The layered directory node.
* @param name The name to flatten.
*/
public void flatten(AVMNodeDescriptor lDir, String name)
{
if (lDir == null || name == null)
{
throw new AVMBadArgumentException("Illegal Null Argument.");
}
fAVMRepository.flatten(lDir, name);
}
/** /**
* Force copy on write of a path. * Force copy on write of a path.
* @param path The path to force. * @param path The path to force.

View File

@@ -59,6 +59,61 @@ import org.alfresco.service.transaction.TransactionService;
*/ */
public class AVMServiceTest extends AVMServiceTestBase public class AVMServiceTest extends AVMServiceTestBase
{ {
/**
* Test that an update forces a snapshot on the source.
*/
public void testUpdateSnapshot()
{
try
{
setupBasicTree();
fService.createAVMStore("branch");
fService.createBranch(-1, "main:/", "branch:/", "branch");
// Modify some things in the branch.
fService.createFile("branch:/branch/a/b", "fing").close();
fService.getFileOutputStream("branch:/branch/a/b/c/foo").close();
fService.removeNode("branch:/branch/a/b/c", "bar");
List<AVMDifference> diffs =
fSyncService.compare(-1, "branch:/branch", -1, "main:/");
assertEquals(3, diffs.size());
// Now update.
fSyncService.update(diffs, false, false, false, false);
diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/");
assertEquals(0, diffs.size());
fService.getFileOutputStream("branch:/branch/a/b/fing").close();
assertTrue(fService.lookup(-1, "branch:/branch/a/b/fing").getId() !=
fService.lookup(-1, "main:/a/b/fing").getId());
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
/**
* Test that branching forces a snapshot on the source repository.
*/
public void testBranchSnapshot()
{
try
{
setupBasicTree();
fService.getFileOutputStream("main:/a/b/c/foo").close();
fService.createBranch(-1, "main:/a", "main:/", "abranch");
assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(),
fService.lookup(-1, "main:/abranch/b/c/foo").getId());
fService.getFileOutputStream("main:/a/b/c/foo").close();
assertTrue(fService.lookup(-1, "main:/a/b/c/foo").getId() !=
fService.lookup(-1, "main:/abranch/b/c/foo").getId());
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
/** /**
* Test bulk update. * Test bulk update.
*/ */

View File

@@ -141,7 +141,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
// If the root isn't new, we can't take a snapshot since nothing has changed. // If the root isn't new, we can't take a snapshot since nothing has changed.
if (!fRoot.getIsNew()) if (!fRoot.getIsNew())
{ {
throw new AVMExistsException("Already snapshotted."); // So we just return the most recent snapshot.
return AVMContext.fgInstance.fVersionRootDAO.getMaxVersionID(this);
} }
// Clear out the new nodes. // Clear out the new nodes.
List<AVMNode> newInRep = AVMContext.fgInstance.fAVMNodeDAO.getNewInStore(this); List<AVMNode> newInRep = AVMContext.fgInstance.fAVMNodeDAO.getNewInStore(this);
@@ -150,11 +151,16 @@ public class AVMStoreImpl implements AVMStore, Serializable
newGuy.setStoreNew(null); newGuy.setStoreNew(null);
} }
// Make up a new version record. // Make up a new version record.
String user = AVMContext.fgInstance.getAuthenticationComponent().getCurrentUserName();
if (user == null)
{
user = AVMContext.fgInstance.getAuthenticationComponent().getSystemUserName();
}
VersionRoot versionRoot = new VersionRootImpl(this, VersionRoot versionRoot = new VersionRootImpl(this,
fRoot, fRoot,
fNextVersionID, fNextVersionID,
System.currentTimeMillis(), System.currentTimeMillis(),
"britt"); user);
AVMContext.fgInstance.fVersionRootDAO.save(versionRoot); AVMContext.fgInstance.fVersionRootDAO.save(versionRoot);
// Increment the version id. // Increment the version id.
fNextVersionID++; fNextVersionID++;
@@ -169,6 +175,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void createDirectory(String path, String name) public void createDirectory(String path, String name)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) != null) if (dir.lookupChild(lPath, name, -1, true, false) != null)
{ {
@@ -202,6 +212,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
String name) String name)
{ {
Lookup lPath = lookupDirectory(-1, dstPath, true); Lookup lPath = lookupDirectory(-1, dstPath, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) != null) if (dir.lookupChild(lPath, name, -1, true, false) != null)
{ {
@@ -236,6 +250,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public OutputStream createFile(String path, String name) public OutputStream createFile(String path, String name)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) != null) if (dir.lookupChild(lPath, name, -1, true, false) != null)
{ {
@@ -262,6 +280,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void createFile(String path, String name, File data) public void createFile(String path, String name, File data)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) != null) if (dir.lookupChild(lPath, name, -1, true, false) != null)
{ {
@@ -288,6 +310,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void createLayeredFile(String srcPath, String dstPath, String name) public void createLayeredFile(String srcPath, String dstPath, String name)
{ {
Lookup lPath = lookupDirectory(-1, dstPath, true); Lookup lPath = lookupDirectory(-1, dstPath, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) != null) if (dir.lookupChild(lPath, name, -1, true, false) != null)
{ {
@@ -354,6 +380,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
boolean includeDeleted) boolean includeDeleted)
{ {
Lookup lPath = lookupDirectory(version, path, false); Lookup lPath = lookupDirectory(version, path, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
Map<String, AVMNode> listing = dir.getListing(lPath, includeDeleted); Map<String, AVMNode> listing = dir.getListing(lPath, includeDeleted);
return translateListing(listing, lPath); return translateListing(listing, lPath);
@@ -369,6 +399,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
boolean includeDeleted) boolean includeDeleted)
{ {
Lookup lPath = lookupDirectory(version, path, false); Lookup lPath = lookupDirectory(version, path, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY) if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY)
{ {
@@ -407,6 +441,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public List<String> getDeleted(int version, String path) public List<String> getDeleted(int version, String path)
{ {
Lookup lPath = lookupDirectory(version, path, false); Lookup lPath = lookupDirectory(version, path, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
return dir.getDeletedNames(); return dir.getDeletedNames();
} }
@@ -443,6 +481,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void removeNode(String path, String name) public void removeNode(String path, String name)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (dir.lookupChild(lPath, name, -1, true, false) == null) if (dir.lookupChild(lPath, name, -1, true, false) == null)
{ {
@@ -460,6 +502,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void uncover(String dirPath, String name) public void uncover(String dirPath, String name)
{ {
Lookup lPath = lookup(-1, dirPath, true, false); Lookup lPath = lookup(-1, dirPath, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (node.getType() != AVMNodeType.LAYERED_DIRECTORY) if (node.getType() != AVMNodeType.LAYERED_DIRECTORY)
{ {
@@ -540,7 +586,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
Lookup result = new Lookup(this, fName); Lookup result = new Lookup(this, fName);
if (path.length() == 0) if (path.length() == 0)
{ {
throw new AVMException("Invalid path: " + path); return null;
} }
while (path.startsWith("/")) while (path.startsWith("/"))
{ {
@@ -576,13 +622,13 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode child = dir.lookupChild(result, pathElements[i], version, write, includeDeleted); AVMNode child = dir.lookupChild(result, pathElements[i], version, write, includeDeleted);
if (child == null) if (child == null)
{ {
throw new AVMNotFoundException("Not found: " + pathElements[i]); return null;
} }
// Every element that is not the last needs to be a directory. // Every element that is not the last needs to be a directory.
if (child.getType() != AVMNodeType.PLAIN_DIRECTORY && if (child.getType() != AVMNodeType.PLAIN_DIRECTORY &&
child.getType() != AVMNodeType.LAYERED_DIRECTORY) child.getType() != AVMNodeType.LAYERED_DIRECTORY)
{ {
throw new AVMNotFoundException("Not a directory: " + pathElements[i]); return null;
} }
result.add(child, pathElements[i], write); result.add(child, pathElements[i], write);
dir = (DirectoryNode)result.getCurrentNode(); dir = (DirectoryNode)result.getCurrentNode();
@@ -592,7 +638,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
includeDeleted); includeDeleted);
if (child == null) if (child == null)
{ {
throw new AVMNotFoundException("Not found: " + pathElements[pathElements.length - 1]); return null;
} }
result.add(child, pathElements[pathElements.length - 1], write); result.add(child, pathElements[pathElements.length - 1], write);
return result; return result;
@@ -629,10 +675,14 @@ public class AVMStoreImpl implements AVMStore, Serializable
// Just do a regular lookup and assert that the last element // Just do a regular lookup and assert that the last element
// is a directory. // is a directory.
Lookup lPath = lookup(version, path, write, false); Lookup lPath = lookup(version, path, write, false);
if (lPath == null)
{
return null;
}
if (lPath.getCurrentNode().getType() != AVMNodeType.PLAIN_DIRECTORY && if (lPath.getCurrentNode().getType() != AVMNodeType.PLAIN_DIRECTORY &&
lPath.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY) lPath.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY)
{ {
throw new AVMWrongTypeException("Not a directory: " + path); return null;
} }
return lPath; return lPath;
} }
@@ -646,6 +696,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public String getIndirectionPath(int version, String path) public String getIndirectionPath(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) if (node.getType() == AVMNodeType.LAYERED_DIRECTORY)
{ {
@@ -665,7 +719,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void makePrimary(String path) public void makePrimary(String path)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
// lPath.acquireLocks(); if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!lPath.isLayered()) if (!lPath.isLayered())
{ {
@@ -683,7 +740,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void retargetLayeredDirectory(String path, String target) public void retargetLayeredDirectory(String path, String target)
{ {
Lookup lPath = lookupDirectory(-1, path, true); Lookup lPath = lookupDirectory(-1, path, true);
// lPath.acquireLocks(); if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!lPath.isLayered()) if (!lPath.isLayered())
{ {
@@ -844,6 +904,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void setOpacity(String path, boolean opacity) public void setOpacity(String path, boolean opacity)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!(node instanceof LayeredDirectoryNode)) if (!(node instanceof LayeredDirectoryNode))
{ {
@@ -863,6 +927,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void setNodeProperty(String path, QName name, PropertyValue value) public void setNodeProperty(String path, QName name, PropertyValue value)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setProperty(name, value); node.setProperty(name, value);
} }
@@ -875,6 +943,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void setNodeProperties(String path, Map<QName, PropertyValue> properties) public void setNodeProperties(String path, Map<QName, PropertyValue> properties)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setProperties(properties); node.setProperties(properties);
} }
@@ -889,6 +961,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public PropertyValue getNodeProperty(int version, String path, QName name) public PropertyValue getNodeProperty(int version, String path, QName name)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getProperty(name); return node.getProperty(name);
} }
@@ -902,6 +978,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public Map<QName, PropertyValue> getNodeProperties(int version, String path) public Map<QName, PropertyValue> getNodeProperties(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getProperties(); return node.getProperties();
} }
@@ -914,6 +994,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void deleteNodeProperty(String path, QName name) public void deleteNodeProperty(String path, QName name)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.deleteProperty(name); node.deleteProperty(name);
} }
@@ -925,6 +1009,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void deleteNodeProperties(String path) public void deleteNodeProperties(String path)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.deleteProperties(); node.deleteProperties();
} }
@@ -999,6 +1087,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public ContentData getContentDataForRead(int version, String path) public ContentData getContentDataForRead(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!(node instanceof FileNode)) if (!(node instanceof FileNode))
{ {
@@ -1015,6 +1107,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public ContentData getContentDataForWrite(String path) public ContentData getContentDataForWrite(String path)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!(node instanceof FileNode)) if (!(node instanceof FileNode))
{ {
@@ -1031,6 +1127,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void setContentData(String path, ContentData data) public void setContentData(String path, ContentData data)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!(node instanceof FileNode)) if (!(node instanceof FileNode))
{ {
@@ -1047,6 +1147,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void addAspect(String path, QName aspectName) public void addAspect(String path, QName aspectName)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName)) if (AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName))
{ {
@@ -1068,6 +1172,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public List<QName> getAspects(int version, String path) public List<QName> getAspects(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
List<AVMAspectName> names = List<AVMAspectName> names =
AVMContext.fgInstance.fAVMAspectNameDAO.get(node); AVMContext.fgInstance.fAVMAspectNameDAO.get(node);
@@ -1087,6 +1195,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void removeAspect(String path, QName aspectName) public void removeAspect(String path, QName aspectName)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
AVMContext.fgInstance.fAVMAspectNameDAO.delete(node, aspectName); AVMContext.fgInstance.fAVMAspectNameDAO.delete(node, aspectName);
AspectDefinition def = AVMContext.fgInstance.getDictionaryService().getAspect(aspectName); AspectDefinition def = AVMContext.fgInstance.getDictionaryService().getAspect(aspectName);
@@ -1108,6 +1220,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public boolean hasAspect(int version, String path, QName aspectName) public boolean hasAspect(int version, String path, QName aspectName)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName); return AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName);
} }
@@ -1120,6 +1236,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void setACL(String path, DbAccessControlList acl) public void setACL(String path, DbAccessControlList acl)
{ {
Lookup lPath = lookup(-1, path, true, false); Lookup lPath = lookup(-1, path, true, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setAcl(acl); node.setAcl(acl);
} }
@@ -1133,6 +1253,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public DbAccessControlList getACL(int version, String path) public DbAccessControlList getACL(int version, String path)
{ {
Lookup lPath = lookup(version, path, false, false); Lookup lPath = lookup(version, path, false, false);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
return lPath.getCurrentNode().getAcl(); return lPath.getCurrentNode().getAcl();
} }
@@ -1145,6 +1269,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
public void link(String parentPath, String name, AVMNodeDescriptor toLink) public void link(String parentPath, String name, AVMNodeDescriptor toLink)
{ {
Lookup lPath = lookupDirectory(-1, parentPath, true); Lookup lPath = lookupDirectory(-1, parentPath, true);
if (lPath == null)
{
throw new AVMNotFoundException("Path not found.");
}
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
dir.link(lPath, name, toLink); dir.link(lPath, name, toLink);
} }

View File

@@ -46,6 +46,11 @@ public class AVMSyncServiceImpl implements AVMSyncService
*/ */
private AVMService fAVMService; private AVMService fAVMService;
/**
* The AVMRepository.
*/
private AVMRepository fAVMRepository;
/** /**
* Do nothing constructor. * Do nothing constructor.
*/ */
@@ -54,10 +59,7 @@ public class AVMSyncServiceImpl implements AVMSyncService
} }
/** /**
* Set the AVM Service. For Spring. For now, at least, * Set the AVM Service. For Spring.
* it's important to wire this using the unintercepted AVMServiceImpl,
* as AVMServiceImpl uses Runtime Exceptions for handling valid states
* that should not cause rollbacks.
* @param avmService The AVMService reference. * @param avmService The AVMService reference.
*/ */
public void setAvmService(AVMService avmService) public void setAvmService(AVMService avmService)
@@ -65,6 +67,11 @@ public class AVMSyncServiceImpl implements AVMSyncService
fAVMService = avmService; fAVMService = avmService;
} }
public void setAvmRepository(AVMRepository avmRepository)
{
fAVMRepository = avmRepository;
}
/** /**
* Get a difference list between two corresponding node trees. * Get a difference list between two corresponding node trees.
* @param srcVersion The version id for the source tree. * @param srcVersion The version id for the source tree.
@@ -280,7 +287,14 @@ public class AVMSyncServiceImpl implements AVMSyncService
{ {
throw new AVMSyncException("Malformed AVMDifference."); throw new AVMSyncException("Malformed AVMDifference.");
} }
AVMNodeDescriptor srcDesc = fAVMService.lookup(diff.getSourceVersion(), int colonOff = diff.getSourcePath().indexOf(':');
if (colonOff == -1)
{
throw new AVMBadArgumentException("Invalid path.");
}
String storeName = diff.getSourcePath().substring(0, colonOff);
int version = fAVMService.createSnapshot(storeName);
AVMNodeDescriptor srcDesc = fAVMService.lookup(version,
diff.getSourcePath(), true); diff.getSourcePath(), true);
if (srcDesc == null) if (srcDesc == null)
{ {
@@ -385,8 +399,6 @@ public class AVMSyncServiceImpl implements AVMSyncService
fAVMService.link(parentPath, name, toLink); fAVMService.link(parentPath, name, toLink);
} }
// TODO doesn't handle copies from non head nodes.
/** /**
* Recursively copy a node into the given position. * Recursively copy a node into the given position.
* @param parentPath The place to put it. * @param parentPath The place to put it.
@@ -417,12 +429,12 @@ public class AVMSyncServiceImpl implements AVMSyncService
// If it's a file or deleted simply link it in. // If it's a file or deleted simply link it in.
if (toCopy.isFile() || toCopy.isDeleted() || toCopy.isPlainDirectory()) if (toCopy.isFile() || toCopy.isDeleted() || toCopy.isPlainDirectory())
{ {
fAVMService.link(parent, name, toCopy); fAVMRepository.link(parent, name, toCopy);
return; return;
} }
// Otherwise make a directory in the target parent, and recursiveCopy all the source // Otherwise make a directory in the target parent, and recursiveCopy all the source
// children into it. // children into it.
AVMNodeDescriptor newParentDesc = fAVMService.createDirectory(parent, name); AVMNodeDescriptor newParentDesc = fAVMRepository.createDirectory(parent, name);
fgLogger.error(newParentDesc); fgLogger.error(newParentDesc);
Map<String, AVMNodeDescriptor> children = Map<String, AVMNodeDescriptor> children =
fAVMService.getDirectoryListing(toCopy, true); fAVMService.getDirectoryListing(toCopy, true);
@@ -613,14 +625,14 @@ public class AVMSyncServiceImpl implements AVMSyncService
// We've found an identity so flatten it. // We've found an identity so flatten it.
if (topNode.getId() == bottomNode.getId()) if (topNode.getId() == bottomNode.getId())
{ {
fAVMService.flatten(layer, name); fAVMRepository.flatten(layer, name);
} }
else else
{ {
// Otherwise recursively flatten the children. // Otherwise recursively flatten the children.
if (flatten(topNode, bottomNode)) if (flatten(topNode, bottomNode))
{ {
fAVMService.flatten(layer, name); fAVMRepository.flatten(layer, name);
} }
else else
{ {

View File

@@ -25,7 +25,6 @@ import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.alfresco.service.cmr.avm.AVMBadArgumentException; import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMCycleException;
import org.alfresco.service.cmr.avm.AVMException; import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMExistsException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -316,18 +315,14 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
} }
else else
{ {
try Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
if (lookup != null)
{ {
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
listing = dir.getListing(lookup, includeDeleted); listing = dir.getListing(lookup, includeDeleted);
} }
catch (AVMException re) else
{ {
if (re instanceof AVMCycleException)
{
throw re;
}
// It's OK for an indirection to dangle. // It's OK for an indirection to dangle.
listing = new HashMap<String, AVMNode>(); listing = new HashMap<String, AVMNode>();
} }
@@ -406,9 +401,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
// If we are not opaque, get the underlying base listing. // If we are not opaque, get the underlying base listing.
if (!fOpacity) if (!fOpacity)
{ {
try Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection());
if (lookup != null)
{ {
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection());
DirectoryNode dirNode = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dirNode = (DirectoryNode)lookup.getCurrentNode();
Map<String, AVMNode> listing = dirNode.getListing(lookup, includeDeleted); Map<String, AVMNode> listing = dirNode.getListing(lookup, includeDeleted);
for (String name : listing.keySet()) for (String name : listing.keySet())
@@ -418,13 +413,6 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
lookup.getCurrentIndirection())); lookup.getCurrentIndirection()));
} }
} }
catch (AVMException e)
{
if (e instanceof AVMCycleException)
{
throw e;
}
}
} }
List<ChildEntry> children = AVMContext.fgInstance.fChildEntryDAO.getByParent(this); List<ChildEntry> children = AVMContext.fgInstance.fChildEntryDAO.getByParent(this);
for (ChildEntry child : children) for (ChildEntry child : children)
@@ -489,20 +477,16 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
return null; return null;
} }
// Not here so check our indirection. // Not here so check our indirection.
try Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
if (lookup != null)
{ {
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
AVMNode retVal = dir.lookupChild(lookup, name, -1, false, includeDeleted); AVMNode retVal = dir.lookupChild(lookup, name, -1, false, includeDeleted);
lPath.setFinalStore(lookup.getFinalStore()); lPath.setFinalStore(lookup.getFinalStore());
return retVal; return retVal;
} }
catch (AVMException re) else
{ {
if (re instanceof AVMCycleException)
{
throw re;
}
return null; return null;
} }
} }
@@ -535,9 +519,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
return null; return null;
} }
try Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, mine.getIndirection());
if (lookup != null)
{ {
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, mine.getIndirection());
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
AVMNode child = dir.lookupChild(lookup, name, -1, false, includeDeleted); AVMNode child = dir.lookupChild(lookup, name, -1, false, includeDeleted);
if (child == null) if (child == null)
@@ -546,12 +530,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
} }
return child.getDescriptor(lookup); return child.getDescriptor(lookup);
} }
catch (AVMException e) else
{ {
if (e instanceof AVMCycleException)
{
throw e;
}
return null; return null;
} }
} }

View File

@@ -79,6 +79,10 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
{ {
// LayeredFileNodes are always copied. // LayeredFileNodes are always copied.
Lookup lookup = AVMRepository.GetInstance().lookup(-1, fIndirection, false); Lookup lookup = AVMRepository.GetInstance().lookup(-1, fIndirection, false);
if (lookup == null)
{
throw new AVMException("Unbacked layered file node.");
}
AVMNode indirect = lookup.getCurrentNode(); AVMNode indirect = lookup.getCurrentNode();
if (indirect.getType() != AVMNodeType.LAYERED_FILE && if (indirect.getType() != AVMNodeType.LAYERED_FILE &&
indirect.getType() != AVMNodeType.PLAIN_FILE) indirect.getType() != AVMNodeType.PLAIN_FILE)
@@ -250,6 +254,10 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
public ContentData getContentData(Lookup lPath) public ContentData getContentData(Lookup lPath)
{ {
Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(-1, getIndirection(), false); Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(-1, getIndirection(), false);
if (lookup == null)
{
throw new AVMException("Invalid target.");
}
AVMNode node = lookup.getCurrentNode(); AVMNode node = lookup.getCurrentNode();
if (!(node instanceof FileNode)) if (!(node instanceof FileNode))
{ {

View File

@@ -68,4 +68,11 @@ public interface VersionRootDAO
* @return The highest numbered version. * @return The highest numbered version.
*/ */
public VersionRoot getMaxVersion(AVMStore store); public VersionRoot getMaxVersion(AVMStore store);
/**
* Get the highest numbered id from all the versions in a store.
* @param store The store.
* @return The highest numbered id.
*/
public Integer getMaxVersionID(AVMStore store);
} }

View File

@@ -141,4 +141,17 @@ class VersionRootDAOHibernate extends HibernateDaoSupport implements
"(select max(v.versionID) from VersionRootImpl v)"); "(select max(v.versionID) from VersionRootImpl v)");
return (VersionRoot)query.uniqueResult(); return (VersionRoot)query.uniqueResult();
} }
/**
* Get the highest numbered id from all the versions in a store.
* @param store The store.
* @return The highest numbered id.
*/
public Integer getMaxVersionID(AVMStore store)
{
Query query = getSession().createQuery("select max(vr.versionID) from VersionRootImpl vr " +
"where vr.avmStore = :store");
query.setEntity("store", store);
return (Integer)query.uniqueResult();
}
} }

View File

@@ -192,15 +192,6 @@ public interface AVMService
*/ */
public void createDirectory(String path, String name); public void createDirectory(String path, String name);
/**
* Create a new directory, in an already copy on written node.
* This should only be used if you really know what you're doing.
* @param parent The parent node.
* @param name The name of the new directory.
* @return A descriptor for the newly created directory.
*/
public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name);
/** /**
* Create a new layered file. * Create a new layered file.
* @param targetPath The simple absolute path that the new file will point at. * @param targetPath The simple absolute path that the new file will point at.
@@ -695,28 +686,6 @@ public interface AVMService
*/ */
public void link(String parentPath, String name, AVMNodeDescriptor toLink); public void link(String parentPath, String name, AVMNodeDescriptor toLink);
/**
* This is a more dangerous version of link, which assumes
* that copy on write has occurred for the parent node. This is
* an internal call. Don't use it if you don't know precisely
* what you are doing.
* @param parent The parent node.
* @param name The name to give the child.
* @param child The child node to link.
*/
public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child);
/**
* Flatten a direct child of a layered directory. This does
* the equivalent of removing the given child from the directory
* and then doing an uncover. This routine makes many dangerous
* assumptions and is only for use by AVMSyncService. Don't use it
* if you don't know precisely what you are doing.
* @param lDir The layered directory node.
* @param name The name to flatten.
*/
public void flatten(AVMNodeDescriptor lDir, String name);
/** /**
* Force copy on write of a path. * Force copy on write of a path.
* @param path The path to force. * @param path The path to force.