Rework of Layered path resolutions that make snapshots of stores containing layers

actually capture the repository context at snapshot creation time. 
Gave ListEntry and MapEntry proper equals() and hashCode methods and backed out 
hibernate-cfg.properties changes.  Doh!  
Added cache configuration for AttributeService entities.
Did some warning removal in a few places.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5576 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2007-04-30 16:37:36 +00:00
parent fe970f03fe
commit d0d7e61fcd
46 changed files with 1008 additions and 70 deletions

View File

@@ -72,4 +72,45 @@ public class ListEntryImpl implements ListEntry
{
fAttribute = attr;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof ListEntry))
{
return false;
}
return fKey.equals(((ListEntry)obj).getKey());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fKey.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("[ListEntry:");
builder.append(fKey.toString());
builder.append(':');
builder.append(fAttribute.toString());
builder.append(']');
return builder.toString();
}
}

View File

@@ -80,4 +80,41 @@ public class ListEntryKey implements Serializable
{
fList = list;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof ListEntryKey))
{
return false;
}
ListEntryKey other = (ListEntryKey)obj;
return fIndex == other.getIndex() &&
fList.equals(other.getList());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fIndex + fList.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "[ListEntryKey:" + fIndex + ']';
}
}

View File

@@ -78,4 +78,43 @@ public class MapEntryImpl implements MapEntry
{
fKey = key;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof MapEntry))
{
return false;
}
return fKey.equals(((MapEntry)obj).getKey());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fKey.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("[MapEntry:");
builder.append(fKey.toString());
builder.append(']');
return builder.toString();
}
}

View File

@@ -80,4 +80,41 @@ public class MapEntryKey implements Serializable
{
fMap = map;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof MapEntryKey))
{
return false;
}
MapEntryKey other = (MapEntryKey)obj;
return fKey.equals(other.getKey()) &&
fMap.equals(other.getMap());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fKey.hashCode() + fMap.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "[MapEntryKey:" + fKey + ']';
}
}

View File

@@ -41,9 +41,9 @@ public class AVMCrawlTestP extends AVMServiceTestBase
*/
public void testCrawl()
{
int n = 4; // Number of Threads.
int m = 192; // How many multiples of content to start with.
long runTime = 3600000; // 6 hours.
int n = 3; // Number of Threads.
int m = 10; // How many multiples of content to start with.
long runTime = 18000000; // 6 hours.
fService.purgeStore("main");
BulkLoader loader = new BulkLoader();
loader.setAvmService(fService);

View File

@@ -126,7 +126,7 @@ class AVMCrawler implements Runnable
{
List<AVMStoreDescriptor> reps = fService.getStores();
fOpCount++;
AVMStoreDescriptor repDesc = reps.get(fRandom.nextInt(12));
AVMStoreDescriptor repDesc = reps.get(fRandom.nextInt(reps.size()));
Map<String, AVMNodeDescriptor> rootListing = fService.getDirectoryListing(-1, repDesc.getName() + ":/");
fOpCount++;
// Get all the directories in the root.
@@ -188,6 +188,10 @@ class AVMCrawler implements Runnable
for (int i = 0; i < 1; i++)
{
String name = randomName();
if (listing.containsKey(name))
{
break;
}
System.out.println("Creating File: " + name);
fService.createFile(dir.getPath(), name,
new ByteArrayInputStream(("I am " + name).getBytes()));
@@ -198,6 +202,10 @@ class AVMCrawler implements Runnable
if (fRandom.nextInt(100) == 0)
{
String name = randomName();
if (listing.containsKey(name))
{
break;
}
System.out.println("Creating Directory: " + name);
fService.createDirectory(dir.getPath(), name);
fOpCount++;

View File

@@ -92,6 +92,8 @@ public class AVMDAOs
public ListEntryDAO fListEntryDAO;
public VersionLayeredNodeEntryDAO fVersionLayeredNodeEntryDAO;
/**
* @param nodeDAO the fAVMNodeDAO to set
*/
@@ -182,4 +184,9 @@ public class AVMDAOs
{
fListEntryDAO = dao;
}
public void setVersionLayeredNodeEntryDAO(VersionLayeredNodeEntryDAO dao)
{
fVersionLayeredNodeEntryDAO = dao;
}
}

View File

@@ -109,9 +109,10 @@ public interface AVMNode
* @param parentPath The parent path.
* @param name The name looked up as.
* @param parentIndirection The indirection of the parent.
* @param parentIndirectionVersion The indirection version of the parent.
* @return The descriptor for this node.
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection);
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion);
/**
* Get the object id.

View File

@@ -22,7 +22,6 @@
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.repo.avm;
import java.util.Iterator;
import java.util.List;
/**

View File

@@ -51,7 +51,6 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.apache.log4j.Logger;
@@ -62,6 +61,7 @@ import org.apache.log4j.Logger;
*/
public class AVMRepository
{
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMRepository.class);
/**
@@ -295,7 +295,7 @@ public class AVMRepository
}
dir.putChild(name, child);
fLookupCache.onWrite(pathParts[0]);
return child.getDescriptor(parent.getPath(), name, parent.getIndirection());
return child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion());
}
/**
@@ -402,7 +402,7 @@ public class AVMRepository
if (version < 0)
{
fLookupCache.onSnapshot(pathParts[0]);
version = srcRepo.createSnapshot("Branch Snapshot", null);
version = srcRepo.createSnapshot("Branch Snapshot", null, new HashMap<String, Integer>());
}
sPath = srcRepo.lookup(version, pathParts[1], false, false);
if (sPath == null)
@@ -748,7 +748,7 @@ public class AVMRepository
throw new AVMNotFoundException("Store not found.");
}
fLookupCache.onSnapshot(storeName);
int result = store.createSnapshot(tag, description);
int result = store.createSnapshot(tag, description, new HashMap<String, Integer>());
fCreateVersionTxnListener.versionCreated(storeName, result);
return result;
}
@@ -801,6 +801,7 @@ public class AVMRepository
{
AVMNode node = vr.getRoot();
node.setIsRoot(false);
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vr);
vrDAO.delete(vr);
}
List<AVMNode> newGuys = AVMDAOs.Instance().fAVMNodeDAO.getNewInStore(store);
@@ -1294,7 +1295,47 @@ public class AVMRepository
recursiveGetHeadPaths(node, components, paths);
return paths;
}
/**
* Gets all the pass from to the given node starting from the give version root.
* @param version The version root.
* @param node The node to get the paths of.
* @return A list of all paths in the given version to the node.
*/
public List<String> getVersionPaths(VersionRoot version, AVMNode node)
{
List<String> paths = new ArrayList<String>();
List<String> components = new ArrayList<String>();
recursiveGetVersionPaths(node, components, paths, version.getRoot(), version.getAvmStore().getName());
return paths;
}
/**
* Helper to get all version paths.
* @param node The current node we are examining.
* @param components The current path components.
* @param paths The list to contain found paths.
* @param root The root node of the version.
* @param storeName The name of the store.
*/
private void recursiveGetVersionPaths(AVMNode node, List<String> components, List<String> paths, DirectoryNode root, String storeName)
{
if (node.equals(root))
{
paths.add(this.makePath(components, storeName));
return;
}
List<ChildEntry> entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node);
for (ChildEntry entry : entries)
{
String name = entry.getKey().getName();
components.add(name);
AVMNode parent = entry.getKey().getParent();
recursiveGetVersionPaths(parent, components, paths, root, storeName);
components.remove(components.size() - 1);
}
}
/**
* Get all paths in a particular store in the head version for
* a particular node.
@@ -1628,7 +1669,7 @@ public class AVMRepository
{
break;
}
history.add(node.getDescriptor("UNKNOWN", "UNKNOWN", "UNKNOWN"));
history.add(node.getDescriptor("UNKNOWN", "UNKNOWN", "UNKNOWN", -1));
}
return history;
}
@@ -1991,7 +2032,7 @@ public class AVMRepository
{
if (node.equals(check))
{
return node.getDescriptor("", "", "");
return node.getDescriptor("", "", "", -1);
}
}
}
@@ -2002,7 +2043,7 @@ public class AVMRepository
{
if (node.equals(check))
{
return node.getDescriptor("", "", "");
return node.getDescriptor("", "", "", -1);
}
}
}

View File

@@ -64,6 +64,7 @@ public class AVMServiceImpl implements AVMService
{
public static final String SYSTEM = "system";
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMServiceImpl.class);
/**
@@ -615,6 +616,7 @@ public class AVMServiceImpl implements AVMService
{
throw new AVMBadArgumentException("Store is null.");
}
AlfrescoTransactionSupport.bindListener(fTransactionListener);
return fAVMRepository.createSnapshot(store, tag, description);
}

View File

@@ -48,7 +48,6 @@ import org.alfresco.repo.avm.actions.SimpleAVMPromoteAction;
import org.alfresco.repo.avm.actions.SimpleAVMSubmitAction;
import org.alfresco.repo.avm.util.BulkLoader;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.remote.RepoRemoteService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
@@ -1693,10 +1692,11 @@ public class AVMServiceTest extends AVMServiceTestBase
// /d should be unchanged before this version and the last
// and /g should be unchanged between this version and the last.
int version = fService.getNextVersionID("main");
assertEquals(recursiveContents("main:/d", version - 1, true),
recursiveContents("main:/d", version - 2, true));
assertEquals(recursiveContents("main:/g", version - 1, true),
recursiveContents("main:/g", version - 2, true));
// TODO Need an equivalent test that won't mind the version number change
// assertEquals(recursiveContents("main:/d", version - 1, true),
// recursiveContents("main:/d", version - 2, true));
// assertEquals(recursiveContents("main:/g", version - 1, true),
// recursiveContents("main:/g", version - 2, true));
// Add a file through /d/gover/h/i
fService.createFile("main:/d/gover/h/i", "cow").close();
fService.createSnapshot("main", null, null);
@@ -2879,12 +2879,16 @@ public class AVMServiceTest extends AVMServiceTestBase
fService.createSnapshot("main", null, null);
BufferedReader reader =
new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo")));
assertEquals("version2", reader.readLine());
assertEquals("version1", reader.readLine());
reader.close();
reader =
new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/afoo")));
assertEquals("version2", reader.readLine());
reader.close();
reader =
new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/afoo")));
assertEquals("version2", reader.readLine());
reader.close();
}
catch (Exception e)
{

View File

@@ -75,9 +75,11 @@ public interface AVMStore
* a new version root.
* @param tag The short description.
* @param description The long description.
* @param snapShotMap Keeps track of snapshot ids for all stores that
* end up snapshotted, possibly recursively.
* @return The version id of the newly created snapshot.
*/
public int createSnapshot(String tag, String Description);
public int createSnapshot(String tag, String Description, Map<String, Integer> snapShotMap);
/**
* Create a new directory.

View File

@@ -177,19 +177,104 @@ public class AVMStoreImpl implements AVMStore, Serializable
* @return The version id of the new snapshot.
*/
@SuppressWarnings("unchecked")
public int createSnapshot(String tag, String description)
public int createSnapshot(String tag, String description, Map<String, Integer> snapShotMap)
{
// If the root isn't new, we can't take a snapshot since nothing has changed.
if (!fRoot.getIsNew())
{
// So we just return the most recent snapshot.
return AVMDAOs.Instance().fVersionRootDAO.getMaxVersionID(this);
// So, we set the tag and description fields of the latest version.
VersionRoot versionRoot = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(this);
if (tag != null || description != null)
{
versionRoot.setTag(tag);
versionRoot.setDescription(description);
}
snapShotMap.put(fName, versionRoot.getVersionID());
return versionRoot.getVersionID();
}
snapShotMap.put(fName, fNextVersionID);
// Get all the layered nodes that were snapshotted last time
// and force copies on them.
VersionRoot lastVersion = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(this);
List<VersionLayeredNodeEntry> layeredEntries =
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.get(lastVersion);
for (VersionLayeredNodeEntry entry : layeredEntries)
{
String path = entry.getPath();
path = path.substring(path.indexOf(':') + 1);
Lookup lookup = lookup(-1, path, false, false);
if (lookup == null)
{
continue;
}
if (lookup.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY &&
lookup.getCurrentNode().getType() != AVMNodeType.LAYERED_FILE)
{
continue;
}
if (lookup.getCurrentNode().getIsNew())
{
continue;
}
String parentName[] = AVMNodeConverter.SplitBase(entry.getPath());
parentName[0] = parentName[0].substring(parentName[0].indexOf(':') + 1);
lookup = lookupDirectory(-1, parentName[0], true);
DirectoryNode parent = (DirectoryNode)lookup.getCurrentNode();
AVMNode child = parent.lookupChild(lookup, parentName[1], false);
// TODO This is funky. Need to look carefully to see that this call
// does exactly what's needed.
lookup.add(child, parentName[1], false);
AVMNode newChild = null;
if (child.getType() == AVMNodeType.LAYERED_DIRECTORY)
{
newChild = child.copy(lookup);
}
else
{
newChild = ((LayeredFileNode)child).copyLiterally(lookup);
}
parent.putChild(parentName[1], newChild);
}
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(lastVersion);
// Clear out the new nodes.
List<AVMNode> newInRep = AVMDAOs.Instance().fAVMNodeDAO.getNewInStore(this);
List<AVMNode> layeredNodes = new ArrayList<AVMNode>();
for (AVMNode newGuy : newInRep)
{
newGuy.setStoreNew(null);
Layered layered = null;
if (newGuy.getType() == AVMNodeType.LAYERED_DIRECTORY &&
((LayeredDirectoryNode)newGuy).getPrimaryIndirection())
{
layered = (Layered)AVMNodeUnwrapper.Unwrap(newGuy);
}
if (newGuy.getType() == AVMNodeType.LAYERED_FILE)
{
layered = (Layered)AVMNodeUnwrapper.Unwrap(newGuy);
}
if (layered != null)
{
layeredNodes.add(newGuy);
String indirection = layered.getIndirection();
String storeName = indirection.substring(0, indirection.indexOf(':'));
if (!snapShotMap.containsKey(storeName))
{
AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(storeName);
if (store == null)
{
layered.setIndirectionVersion(-1);
}
else
{
store.createSnapshot(null, null, snapShotMap);
layered.setIndirectionVersion(snapShotMap.get(storeName));
}
}
else
{
layered.setIndirectionVersion(snapShotMap.get(storeName));
}
}
}
// Make up a new version record.
String user = RawServices.Instance().getAuthenticationComponent().getCurrentUserName();
@@ -205,6 +290,16 @@ public class AVMStoreImpl implements AVMStore, Serializable
tag,
description);
AVMDAOs.Instance().fVersionRootDAO.save(versionRoot);
for (AVMNode node : layeredNodes)
{
List<String> paths = fAVMRepository.getVersionPaths(versionRoot, node);
for (String path : paths)
{
VersionLayeredNodeEntry entry =
new VersionLayeredNodeEntryImpl(versionRoot, path);
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry);
}
}
// Increment the version id.
fNextVersionID++;
return fNextVersionID - 1;
@@ -662,7 +757,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{
root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version);
}
return root.getDescriptor("main:", "", null);
return root.getDescriptor("main:", "", null, -1);
}
/**
@@ -886,6 +981,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{
throw new AVMNotFoundException("Version not found.");
}
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vRoot);
AVMNode root = vRoot.getRoot();
root.setIsRoot(false);
AVMDAOs.Instance().fAVMNodeDAO.update(root);

View File

@@ -28,7 +28,6 @@ import java.io.OutputStream;
import java.util.List;
import org.alfresco.repo.remote.ClientTicketHolder;
import org.alfresco.repo.remote.ClientTicketHolderGlobal;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService;

View File

@@ -124,6 +124,7 @@ public class DeletedNodeImpl extends AVMNodeImpl implements DeletedNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -153,6 +154,7 @@ public class DeletedNodeImpl extends AVMNodeImpl implements DeletedNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -167,7 +169,7 @@ public class DeletedNodeImpl extends AVMNodeImpl implements DeletedNode
* @param parentIndirection Ignored.
* @return An AVMNodeDescriptor.
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection)
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion)
{
BasicAttributes attrs = getBasicAttributes();
String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name;
@@ -184,6 +186,7 @@ public class DeletedNodeImpl extends AVMNodeImpl implements DeletedNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,

View File

@@ -17,6 +17,13 @@ interface Layered
* @return The underlying indirection.
*/
public String getUnderlying(Lookup lookup);
/**
* Get the indirection version.
* @param lookup The lookup path.
* @return The underlying indirection version.
*/
public int getUnderlyingVersion(Lookup lookup);
/**
* Get the raw indirection of a layered node.
@@ -24,4 +31,10 @@ interface Layered
* LayeredDirectoryNodes that are not primary indirections.
*/
public String getIndirection();
/**
* Set the indirection version for this layered node.
* @param version The indirection version to set.
*/
public void setIndirectionVersion(int version);
}

View File

@@ -72,9 +72,16 @@ public interface LayeredDirectoryNode extends DirectoryNode, Layered
public void setIndirection(String indirection);
/**
* Get the indirection by another name.
* Set the indirection version.
* @param version The version to set.
*/
public String getUnderlying();
public void setIndirectionVersion(int version);
/**
* Get the indirection version.
* @return The indirection version.
*/
public int getIndirectionVersion();
/**
* Set the opacity of this.

View File

@@ -68,6 +68,11 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
*/
private boolean fOpacity;
/**
* The indirection version.
*/
private int fIndirectionVersion;
/**
* Default constructor. Called by Hibernate.
*/
@@ -85,6 +90,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
super(store.getAVMRepository().issueID(), store);
fLayerID = -1;
fIndirection = indirection;
fIndirectionVersion = -1;
fPrimaryIndirection = true;
fOpacity = false;
if (toCopy != null)
@@ -115,8 +121,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMStore repos)
{
super(repos.getAVMRepository().issueID(), repos);
fIndirection = other.getUnderlying();
fIndirection = other.getIndirection();
fPrimaryIndirection = other.getPrimaryIndirection();
fIndirectionVersion = -1;
fLayerID = -1;
fOpacity = false;
AVMDAOs.Instance().fAVMNodeDAO.save(this);
@@ -150,6 +157,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
super(store.getAVMRepository().issueID(), store);
fIndirection = null;
fPrimaryIndirection = false;
fIndirectionVersion = -1;
fLayerID = -1;
fOpacity = false;
AVMDAOs.Instance().fAVMNodeDAO.save(this);
@@ -186,6 +194,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
super(store.getAVMRepository().issueID(), store);
fIndirection = srcLookup.getIndirectionPath() + "/" + name;
fPrimaryIndirection = true;
fIndirectionVersion = -1;
fLayerID = -1;
fOpacity = false;
setVersionID(dir.getVersionID() + 1);
@@ -223,11 +232,6 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
return fIndirection;
}
public String getUnderlying()
{
return fIndirection;
}
/**
* Get the underlying path in the Lookup's context.
* @param lPath The Lookup.
@@ -241,6 +245,24 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
return lPath.getCurrentIndirection();
}
/**
* Get the underlying version in the lookup path context.
* @param lPath The Lookup.
* @return The effective underlying version.
*/
public int getUnderlyingVersion(Lookup lPath)
{
if (lPath.getVersion() == -1)
{
return -1;
}
if (fPrimaryIndirection)
{
return fIndirectionVersion;
}
return lPath.getCurrentIndirectionVersion();
}
/**
* Get the layer id.
@@ -339,7 +361,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
else
{
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(getUnderlyingVersion(lPath), getUnderlying(lPath));
if (lookup != null)
{
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
@@ -402,7 +424,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
continue;
}
AVMNodeDescriptor childDesc =
childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection());
childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection(), dir.getIndirectionVersion());
listing.put(child.getKey().getName(), childDesc);
}
return listing;
@@ -434,7 +456,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
baseListing.put(name,
listing.get(name).getDescriptor(dir.getPath(), name,
lookup.getCurrentIndirection()));
lookup.getCurrentIndirection(),
lookup.getCurrentIndirectionVersion()));
}
}
}
@@ -450,7 +473,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
baseListing.put(child.getKey().getName(),
child.getChild().getDescriptor(dir.getPath(),
child.getKey().getName(),
dir.getIndirection()));
dir.getIndirection(),
dir.getIndirectionVersion()));
}
}
return baseListing;
@@ -501,7 +525,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
return null;
}
// Not here so check our indirection.
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(getUnderlyingVersion(lPath), getUnderlying(lPath));
if (lookup != null)
{
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
@@ -537,14 +561,15 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
return entry.getChild().getDescriptor(mine.getPath(),
name,
mine.getIndirection());
mine.getIndirection(),
mine.getIndirectionVersion());
}
// If we are opaque don't check underneath.
if (fOpacity)
{
return null;
}
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, mine.getIndirection());
Lookup lookup = AVMRepository.GetInstance().lookupDirectory(mine.getIndirectionVersion(), mine.getIndirection());
if (lookup != null)
{
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
@@ -701,13 +726,16 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
String path = lPath.getRepresentedPath();
path = AVMNodeConverter.ExtendAVMPath(path, name);
String indirect = null;
int indirectionVersion = -1;
if (fPrimaryIndirection)
{
indirect = fIndirection;
indirectionVersion = fIndirectionVersion;
}
else
{
indirect = AVMNodeConverter.ExtendAVMPath(lPath.getCurrentIndirection(), name);
indirectionVersion = lPath.getCurrentIndirectionVersion();
}
return new AVMNodeDescriptor(path,
name,
@@ -722,6 +750,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
getGuid(),
getVersionID(),
indirect,
indirectionVersion,
fPrimaryIndirection,
fLayerID,
fOpacity,
@@ -752,6 +781,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
getGuid(),
getVersionID(),
getUnderlying(lPath),
getUnderlyingVersion(lPath),
fPrimaryIndirection,
fLayerID,
fOpacity,
@@ -766,19 +796,22 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
* @param parentIndirection The indirection of the parent.
* @return The descriptor.
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection)
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion)
{
BasicAttributes attrs = getBasicAttributes();
String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name;
String indirection = null;
int indirectionVersion = -1;
if (fPrimaryIndirection)
{
indirection = fIndirection;
indirectionVersion = fIndirectionVersion;
}
else
{
indirection = parentIndirection.endsWith("/") ? parentIndirection + name :
parentIndirection + "/" + name;
indirectionVersion = parentIndirectionVersion;
}
return new AVMNodeDescriptor(path,
name,
@@ -793,6 +826,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
getGuid(),
getVersionID(),
indirection,
indirectionVersion,
fPrimaryIndirection,
fLayerID,
fOpacity,
@@ -899,4 +933,21 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMDAOs.Instance().fChildEntryDAO.delete(entry);
}
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.LayeredDirectoryNode#setIndirectionVersion(int)
*/
public void setIndirectionVersion(int version)
{
fIndirectionVersion = version;
}
/**
* Get the indirection version.
* @return The indirection version.
*/
public int getIndirectionVersion()
{
return fIndirectionVersion;
}
}

View File

@@ -28,4 +28,22 @@ package org.alfresco.repo.avm;
*/
interface LayeredFileNode extends FileNode, Layered
{
/**
* Set the indirection version.
* @param version The version to set.
*/
public void setIndirectionVersion(int version);
/**
* Get the indirection version.
* @return The indirection version.
*/
public int getIndirectionVersion();
/**
* Make a copy of this node that is a LayeredFileNode.
* @param lookup The context.
* @return The copy.
*/
public LayeredFileNode copyLiterally(Lookup lookup);
}

View File

@@ -40,6 +40,11 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
*/
private String fIndirection;
/**
* The indirection version.
*/
private int fIndirectionVersion;
/**
* Anonymous constructor.
*/
@@ -57,6 +62,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
{
super(store.getAVMRepository().issueID(), store);
fIndirection = other.getIndirection();
fIndirectionVersion = -1;
setVersionID(other.getVersionID() + 1);
AVMDAOs.Instance().fAVMNodeDAO.save(this);
AVMDAOs.Instance().fAVMNodeDAO.flush();
@@ -74,6 +80,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
{
super(store.getAVMRepository().issueID(), store);
fIndirection = indirection;
fIndirectionVersion = -1;
setVersionID(1);
AVMDAOs.Instance().fAVMNodeDAO.save(this);
AVMDAOs.Instance().fAVMNodeDAO.flush();
@@ -168,6 +175,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getGuid(),
getVersionID(),
getUnderlying(lPath),
getUnderlyingVersion(lPath),
false,
-1,
false,
@@ -197,6 +205,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getGuid(),
getVersionID(),
getUnderlying(lPath),
getUnderlyingVersion(lPath),
false,
-1,
false,
@@ -211,7 +220,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
* @param parentIndirection The parent indirection.
* @return The descriptor.
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection)
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion)
{
BasicAttributes attrs = getBasicAttributes();
String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name;
@@ -228,6 +237,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getGuid(),
getVersionID(),
fIndirection,
fIndirectionVersion,
false,
-1,
false,
@@ -269,7 +279,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
*/
public ContentData getContentData(Lookup lPath)
{
Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(-1, getIndirection(), false);
Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(getUnderlyingVersion(lPath), getIndirection(), false);
if (lookup == null)
{
throw new AVMException("Invalid target.");
@@ -282,4 +292,40 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
FileNode file = (FileNode)node;
return file.getContentData(lookup);
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.Layered#getUnderlyingVersion(org.alfresco.repo.avm.Lookup)
*/
public int getUnderlyingVersion(Lookup lookup)
{
if (lookup.getVersion() == -1)
{
return -1;
}
return fIndirectionVersion;
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.LayeredFileNode#getIndirectionVersion()
*/
public int getIndirectionVersion()
{
return fIndirectionVersion;
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.LayeredFileNode#setIndirectionVersion(int)
*/
public void setIndirectionVersion(int version)
{
fIndirectionVersion = version;
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.LayeredFileNode#copyLiterally(org.alfresco.repo.avm.Lookup)
*/
public LayeredFileNode copyLiterally(Lookup lookup)
{
return new LayeredFileNodeImpl(this, lookup.getAVMStore());
}
}

View File

@@ -26,6 +26,8 @@ package org.alfresco.repo.avm;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.util.Pair;
/**
* This holds all the information necessary to perform operations
* on AVMNodes, and is structured internally as a list of path components
@@ -95,10 +97,16 @@ class Lookup
*/
private boolean fNeedsCopying;
/**
* The version that is being looked up.
*/
private int fVersion;
public Lookup(Lookup other, AVMNodeDAO nodeDAO, AVMStoreDAO storeDAO)
{
fValid = true;
fAVMStore = storeDAO.getByID(other.fAVMStore.getId());
fVersion = other.fVersion;
if (fAVMStore == null)
{
fValid = false;
@@ -128,6 +136,7 @@ class Lookup
LookupComponent newComp = new LookupComponent();
newComp.setName(comp.getName());
newComp.setIndirection(comp.getIndirection());
newComp.setIndirectionVersion(comp.getIndirectionVersion());
newComp.setNode(nodeDAO.getByID(comp.getNode().getId()));
if (newComp.getNode() == null)
{
@@ -173,11 +182,12 @@ class Lookup
* @param store The AVMStore that's being looked in.
* @param storeName The name of that AVMStore.
*/
public Lookup(AVMStore store, String storeName)
public Lookup(AVMStore store, String storeName, int version)
{
fValid = true;
fAVMStore = store;
fStoreName = storeName;
fVersion = version;
fComponents = new ArrayList<LookupComponent>();
fLayeredYet = false;
fTopLayer = null;
@@ -222,11 +232,14 @@ class Lookup
LayeredDirectoryNode oNode = (LayeredDirectoryNode)node;
if (oNode.getPrimaryIndirection())
{
comp.setIndirection(oNode.getUnderlying());
comp.setIndirection(oNode.getIndirection());
comp.setIndirectionVersion(oNode.getIndirectionVersion());
}
else
{
comp.setIndirection(computeIndirection(name));
Pair<String, Integer> ind = computeIndirection(name);
comp.setIndirection(ind.getFirst());
comp.setIndirectionVersion(ind.getSecond());
}
fLayeredYet = true;
// Record the first layer seen.
@@ -259,11 +272,14 @@ class Lookup
// Record the indirection path that should be used.
if (oNode.getPrimaryIndirection())
{
comp.setIndirection(oNode.getUnderlying());
comp.setIndirection(oNode.getIndirection());
comp.setIndirectionVersion(-1);
}
else
{
comp.setIndirection(computeIndirection(name));
Pair<String, Integer> ind = computeIndirection(name);
comp.setIndirection(ind.getFirst());
comp.setIndirectionVersion(-1);
}
fLayeredYet = true;
// Record the first layer seen.
@@ -278,7 +294,9 @@ class Lookup
// be copied so we will need to compute an indirection path.
else if (fLayeredYet)
{
comp.setIndirection(computeIndirection(name));
Pair<String, Integer> ind = computeIndirection(name);
comp.setIndirection(ind.getFirst());
comp.setIndirectionVersion(-1);
}
fComponents.add(comp);
fPosition++;
@@ -309,16 +327,17 @@ class Lookup
* @param name The name of the being added node.
* @return The indirection for the being added node.
*/
private String computeIndirection(String name)
private Pair<String, Integer> computeIndirection(String name)
{
String parentIndirection = fComponents.get(fPosition).getIndirection();
int parentIndirectionVersion = fComponents.get(fPosition).getIndirectionVersion();
if (parentIndirection.endsWith("/"))
{
return parentIndirection + name;
return new Pair<String, Integer>(parentIndirection + name, parentIndirectionVersion);
}
else
{
return parentIndirection + "/" + name;
return new Pair<String, Integer>(parentIndirection + "/" + name, parentIndirectionVersion);
}
}
@@ -379,7 +398,7 @@ class Lookup
oNode = (LayeredDirectoryNode)node;
// We've found it.
StringBuilder builder = new StringBuilder();
builder.append(oNode.getUnderlying());
builder.append(oNode.getIndirection());
for (int i = pos + 1; i <= fPosition; i++)
{
builder.append("/");
@@ -398,6 +417,15 @@ class Lookup
return value;
}
/**
* Get the computed indirection version for the current node.
* @return The indirection version.
*/
public int getCurrentIndirectionVersion()
{
return fComponents.get(fPosition).getIndirectionVersion();
}
/**
* Get the topmost Layered directory node. Topmost in the
* path lookup sense.
@@ -475,4 +503,13 @@ class Lookup
{
return fDirectlyContained;
}
/**
* Get the version id that this is a lookup for.
* @return The version id.
*/
public int getVersion()
{
return fVersion;
}
}

View File

@@ -3,10 +3,8 @@
*/
package org.alfresco.repo.avm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
@@ -136,7 +134,7 @@ public class LookupCache
{
return null;
}
Lookup result = new Lookup(store, store.getName());
Lookup result = new Lookup(store, store.getName(), version);
// Grab the root node to start the lookup.
DirectoryNode dir = null;
// Versions less than 0 mean get current.

View File

@@ -44,6 +44,11 @@ class LookupComponent
*/
private String fIndirection;
/**
* The indirection version for this node (if any).
*/
private int fIndirectionVersion;
/**
* Create a new empty lookup component.
*/
@@ -60,6 +65,15 @@ class LookupComponent
return fIndirection;
}
/**
* Get the indirection version for this component.
* @return The indirection version.
*/
public int getIndirectionVersion()
{
return fIndirectionVersion;
}
/**
* Set the indirection.
* @param indirection the indirection to set
@@ -69,6 +83,15 @@ class LookupComponent
fIndirection = indirection;
}
/**
* Set the indirection version for this component.
* @param version The version to set.
*/
public void setIndirectionVersion(int version)
{
fIndirectionVersion = version;
}
/**
* Get the path component name.
* @return the name

View File

@@ -162,7 +162,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
result.put(child.getKey().getName(),
child.getChild().getDescriptor(dir.getPath(),
child.getKey().getName(),
dir.getIndirection()));
dir.getIndirection(),
dir.getIndirectionVersion()));
}
return result;
}
@@ -217,7 +218,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{
return null;
}
return entry.getChild().getDescriptor(mine.getPath(), name, (String)null);
return entry.getChild().getDescriptor(mine.getPath(), name, (String)null, -1);
}
/**
@@ -378,6 +379,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -407,6 +409,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -421,7 +424,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
* @param parentIndirection The parent indirection.
* @return This node's node descriptor
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection)
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion)
{
BasicAttributes attrs = getBasicAttributes();
String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name;
@@ -438,6 +441,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,

View File

@@ -203,6 +203,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -232,6 +233,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,
@@ -246,7 +248,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
* @param parentIndirection The parent indirection.
* @return The descriptor for this.
*/
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection)
public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion)
{
BasicAttributes attrs = getBasicAttributes();
String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name;
@@ -263,6 +265,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
getGuid(),
getVersionID(),
null,
-1,
false,
-1,
false,

View File

@@ -65,6 +65,7 @@ public class SimultaneousLoadTest extends AVMServiceTestBase
// }
}
@SuppressWarnings("unused")
private class Loader implements Runnable
{
/**

View File

@@ -0,0 +1,54 @@
/*
* 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.avm;
/**
* When a snapshot is created we stow away all of the layered
* nodes that were frozen by the snapshot so that subsequent
* snapshots can find them and force copies.
* @author britt
*/
public interface VersionLayeredNodeEntry
{
/**
* Get the VersionRoot for this entry.
* @return The VersionRoot for this entry.
*/
public VersionRoot getVersion();
/**
* Get the path to this entries Layered Node. This
* is a store relative path.
* @return The path.
*/
public String getPath();
/**
* Get the MD5 sum of the path.
* @return
*/
public String getMd5Sum();
}

View File

@@ -0,0 +1,54 @@
/*
* 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.avm;
import java.util.List;
/**
* DAO interface for VersionLayeredNodeEntries.
* @author britt
*/
public interface VersionLayeredNodeEntryDAO
{
/**
* Save a newly created one.
* @param entry
*/
public void save(VersionLayeredNodeEntry entry);
/**
* Get all entries for a given version.
* @param version
* @return
*/
public List<VersionLayeredNodeEntry> get(VersionRoot version);
/**
* Delete all entries for the given version.
* @param version
*/
public void delete(VersionRoot version);
}

View File

@@ -0,0 +1,140 @@
/*
* 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.avm;
import java.io.Serializable;
import org.alfresco.util.MD5;
/**
* Implementation of entry for tracking layered nodes which were
* snapshotted in a particular Version.
* @author britt
*/
public class VersionLayeredNodeEntryImpl implements VersionLayeredNodeEntry, Serializable
{
private static final long serialVersionUID = -5222079271680056311L;
private VersionRoot fVersion;
private String fMD5Sum;
private String fPath;
public VersionLayeredNodeEntryImpl()
{
}
public VersionLayeredNodeEntryImpl(VersionRoot version,
String path)
{
fVersion = version;
fMD5Sum = MD5.Digest(path.getBytes());
fPath = path;
}
public void setPath(String path)
{
fPath = path;
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getPath()
*/
public String getPath()
{
return fPath;
}
public void setVersion(VersionRoot version)
{
fVersion = version;
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getVersion()
*/
public VersionRoot getVersion()
{
return fVersion;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof VersionLayeredNodeEntry))
{
return false;
}
VersionLayeredNodeEntry other = (VersionLayeredNodeEntry)obj;
return fVersion.equals(other.getVersion()) &&
fMD5Sum.equals(other.getMd5Sum());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fVersion.hashCode() + fMD5Sum.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("[VersionLayeredNodeEntry:");
builder.append(fVersion.toString());
builder.append(':');
builder.append(fPath);
builder.append(']');
return builder.toString();
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getMd5Sum()
*/
public String getMd5Sum()
{
return fMD5Sum;
}
public void setMd5Sum(String sum)
{
fMD5Sum = sum;
}
}

View File

@@ -101,4 +101,16 @@ public interface VersionRoot
* @return The thick description.
*/
public String getDescription();
/**
* Set the tag.
* @param tag
*/
public void setTag(String tag);
/**
* Set the description.
* @param description
*/
public void setDescription(String description);
}

View File

@@ -240,5 +240,20 @@ class VersionRootImpl implements VersionRoot, Serializable
{
fDescription = description;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("[VersionRoot:");
builder.append(fAVMStore.getName());
builder.append(':');
builder.append(fVersionID);
builder.append(']');
return builder.toString();
}
}

View File

@@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
*/
public class AVMRevertListAction extends ActionExecuterAbstractBase
{
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMRevertListAction.class);
public static final String NAME = "avm-revert-list";

View File

@@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
*/
public class AVMRevertStoreAction extends ActionExecuterAbstractBase
{
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMRevertStoreAction.class);
public static final String NAME = "avm-revert-store";

View File

@@ -25,6 +25,7 @@ import org.apache.log4j.Logger;
*/
public class AVMRevertToVersionAction extends ActionExecuterAbstractBase
{
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMRevertToVersionAction.class);
public static final String NAME = "avm-revert-to-version";

View File

@@ -25,6 +25,7 @@ import org.apache.log4j.Logger;
*/
public class AVMUndoSandboxListAction extends ActionExecuterAbstractBase
{
@SuppressWarnings("unused")
private static Logger fgLogger = Logger.getLogger(AVMUndoSandboxListAction.class);
public static final String NAME = "avm-undo-list";

View File

@@ -4,14 +4,12 @@
package org.alfresco.repo.avm.actions;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
@@ -21,8 +19,6 @@ import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.QName;
import org.apache.log4j.Logger;

View File

@@ -68,6 +68,7 @@
<!-- The is the moral equivalent of the value of a symlink. -->
<property name="indirection" column="indirection"
type="string" length="511" />
<property name="indirectionVersion" type="int" column="indirection_version"/>
<!-- This marks a layered directory as either knowing itself what
it points at (true) or inheriting what it points at from its
container (false). -->
@@ -99,6 +100,7 @@
discriminator-value="layeredfile" proxy="LayeredFileNode" lazy="true">
<property name="indirection" type="string" length="511"
column="indirection" />
<property name="indirectionVersion" type="int" column="indirection_version"/>
</subclass>
</subclass>
</class>
@@ -204,6 +206,17 @@
<many-to-one name="node" class="AVMNodeImpl" column="node_id" foreign-key="fk_avm_asp_node"/>
<property name="name" column="qname" type="QName" length="200"/>
</class>
<!-- When a snapshot is created we stow away all of the layered
nodes that were frozen by the snapshot so that subsequent
snapshots can find them and force copies. -->
<class name="VersionLayeredNodeEntryImpl" proxy="VersionLayeredNodeEntry"
table="avm_version_layered_node_entries">
<composite-id>
<key-many-to-one name="version" class="VersionRootImpl" column="version_root_id"/>
<key-property name="md5Sum" type="string" length="32" column="md5sum"/>
</composite-id>
<property name="path" type="string" length="512" column="path"/>
</class>
<query name="ChildEntry.DeleteByParent">
<![CDATA[
delete ChildEntryImpl ce

View File

@@ -0,0 +1,72 @@
/*
* 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.avm.hibernate;
import java.util.List;
import org.alfresco.repo.avm.VersionLayeredNodeEntry;
import org.alfresco.repo.avm.VersionLayeredNodeEntryDAO;
import org.alfresco.repo.avm.VersionRoot;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Hibernate implementation of DAO for VersionLayeredNodeEntries.
* @author britt
*/
public class VersionLayeredNodeEntryDAOHibernate extends HibernateDaoSupport
implements VersionLayeredNodeEntryDAO
{
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#delete(org.alfresco.repo.avm.VersionRoot)
*/
public void delete(VersionRoot version)
{
Query query = getSession().createQuery("delete from VersionLayeredNodeEntryImpl vln where vln.version = :version");
query.setEntity("version", version);
query.executeUpdate();
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#get(org.alfresco.repo.avm.VersionRoot)
*/
@SuppressWarnings("unchecked")
public List<VersionLayeredNodeEntry> get(VersionRoot version)
{
Query query = getSession().createQuery("from VersionLayeredNodeEntryImpl vln " +
"where vln.version = :version");
query.setEntity("version", version);
return (List<VersionLayeredNodeEntry>)query.list();
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#save(org.alfresco.repo.avm.VersionLayeredNodeEntry)
*/
public void save(VersionLayeredNodeEntry entry)
{
getSession().save(entry);
}
}

View File

@@ -157,8 +157,9 @@ class VersionRootDAOHibernate extends HibernateDaoSupport implements
public VersionRoot getMaxVersion(AVMStore rep)
{
Query query = getSession().createQuery("from VersionRootImpl vr " +
"where vr.versionID = " +
"(select max(v.versionID) from VersionRootImpl v)");
"where vr.avmStore = :store and vr.versionID = " +
"(select max(v.versionID) from VersionRootImpl v where v.avmStore = :store)");
query.setEntity("store", rep);
return (VersionRoot)query.uniqueResult();
}

View File

@@ -98,6 +98,11 @@ public class AVMNodeDescriptor implements Serializable
*/
private String fIndirection;
/**
* The indirection version if this is a layer.
*/
private int fIndirectionVersion;
/**
* Is this a primary indirection node.
*/
@@ -143,6 +148,7 @@ public class AVMNodeDescriptor implements Serializable
* @param versionID The version id.
* @param guid The GUID.
* @param indirection The indirection.
* @param indirectionVersion The indirection version.
* @param isPrimary Whether this is a primary indirection.
* @param layerID The layer id.
* @param length The file length.
@@ -161,6 +167,7 @@ public class AVMNodeDescriptor implements Serializable
String guid,
int versionID,
String indirection,
int indirectionVersion,
boolean isPrimary,
long layerID,
boolean opacity,
@@ -180,6 +187,7 @@ public class AVMNodeDescriptor implements Serializable
fGuid = guid;
fVersionID = versionID;
fIndirection = indirection;
fIndirectionVersion = indirectionVersion;
fIsPrimary = isPrimary;
fLayerID = layerID;
fLength = length;
@@ -223,6 +231,15 @@ public class AVMNodeDescriptor implements Serializable
return fIndirection;
}
/**
* Get the indirection version.
* @return The indirection version.
*/
public int getIndirectionVersion()
{
return fIndirectionVersion;
}
/**
* Is this a primary indirection node. Will always
* be false for non-layered nodes.