More cleanup, fixing, and general futzing. A checkpoint.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2920 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-05-18 18:18:46 +00:00
parent 80215dd3a0
commit 1b4c08d1d4
11 changed files with 218 additions and 49 deletions

View File

@@ -59,7 +59,6 @@ public class FileContent
public FileContent(ContentBean data)
{
fData = data;
}
/**
@@ -69,6 +68,7 @@ public class FileContent
public FileContent(SuperRepository superRepo)
{
fData = new ContentBeanImpl(superRepo.issueContentID());
fData.setRefCount(1);
BufferedOutputStream out = new BufferedOutputStream(getOutputStream(superRepo));
// Make an empty file.
try
@@ -90,6 +90,7 @@ public class FileContent
public FileContent(FileContent other, SuperRepository superRepo)
{
fData = new ContentBeanImpl(superRepo.issueContentID());
fData.setRefCount(1);
// Copy the contents from other to this.
BufferedInputStream in = new BufferedInputStream(other.getInputStream(superRepo));
BufferedOutputStream out = new BufferedOutputStream(this.getOutputStream(superRepo));

View File

@@ -93,8 +93,10 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
Repository repos)
{
LayeredDirectoryNodeBean thatBean = (LayeredDirectoryNodeBean)other.getDataBean();
// Copy the basic attributes and update.
BasicAttributesBean attrs = new BasicAttributesBeanImpl(thatBean.getBasicAttributes());
long time = System.currentTimeMillis();
attrs.setCreateDate(time);
attrs.setModDate(time);
attrs.setAccessDate(time);
attrs.setLastModifier("britt");
@@ -109,6 +111,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
attrs,
-1,
other.getUnderlying());
setDataBean(fData);
fData.setAdded(thatBean.getAdded());
fData.setDeleted(thatBean.getDeleted());
fData.setPrimaryIndirection(thatBean.getPrimaryIndirection());
@@ -141,24 +144,48 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
attrs,
-1,
null);
// TODO Is this right?
fData.setAdded(other.getListing(lPath, -1));
setDataBean(fData);
// TODO Is this right? I don't think so.
// fData.setAdded(other.getListing(lPath, -1));
fData.setPrimaryIndirection(false);
repos.getSuperRepository().getSession().save(fData);
}
// TODO Something.
/**
* Create a new layered directory based on a directory we are being named from
* that is in not in the layer of the source lookup.
* @param dir The directory
* @param repo The repository
* @param srcLookup The source lookup.
* @param name The name of the target.
*/
public LayeredDirectoryNode(DirectoryNode dir,
Repository repo,
Lookup srcLookup,
String name)
{
/*
fAdded = new HashMap<String, RepoNode>();
fDeleted = new HashSet<String>();
fProxied = srcLookup.getIndirectionPath() + "/" + name;
fIsPrimaryIndirection = true;
*/
// Make BasicAttributes and set them correctly.
BasicAttributesBean attrs = new BasicAttributesBeanImpl(dir.getDataBean().getBasicAttributes());
long time = System.currentTimeMillis();
attrs.setCreateDate(time);
attrs.setModDate(time);
attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repo.getSuperRepository().getSession().save(attrs);
fData = new LayeredDirectoryNodeBeanImpl(repo.getSuperRepository().issueID(),
-1,
-1,
null,
null,
null,
repo.getDataBean(),
attrs,
-1,
srcLookup.getIndirectionPath() + "/" + name);
setDataBean(fData);
fData.setPrimaryIndirection(true);
repo.getSuperRepository().getSession().save(fData);
}
/**
@@ -229,7 +256,6 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
{
LayeredDirectoryNode dir = (LayeredDirectoryNode)parent;
setLayerID(dir.getLayerID());
// TODO Is this right?
setRepository(parent.getRepository());
}
}
@@ -245,6 +271,8 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
{
return null;
}
// Capture the repository.
Repository repo = lPath.getRepository();
// Otherwise we do an actual copy.
LayeredDirectoryNode newMe = null;
long newBranchID = lPath.getHighestBranch();
@@ -253,19 +281,19 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
if (hasPrimaryIndirection())
{
newMe = new LayeredDirectoryNode(lPath.getIndirectionPath(),
getRepository());
repo);
}
else
{
newMe = new LayeredDirectoryNode((String)null,
getRepository());
repo);
newMe.setPrimaryIndirection(false);
}
}
else
{
newMe = new LayeredDirectoryNode(this,
getRepository());
repo);
newMe.setLayerID(getLayerID());
}
@@ -274,6 +302,8 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
return newMe;
}
// TODO Start around here.
/**
* Insert a child node without COW.
* @param name The name to give the child.

View File

@@ -43,6 +43,7 @@ public class LayeredFileNode extends FileNode implements Layered
setDataBean(fData);
}
// TODO Is this ever used?
/**
* Basically a copy constructor.
* @param other The file to make a copy of.
@@ -50,15 +51,65 @@ public class LayeredFileNode extends FileNode implements Layered
*/
public LayeredFileNode(LayeredFileNode other, Repository repo)
{
// TODO Something.
long time = System.currentTimeMillis();
BasicAttributesBean attrs =
new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes());
attrs.setCreateDate(time);
attrs.setModDate(time);
attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repo.getSuperRepository().getSession().save(attrs);
fData =
new LayeredFileNodeBeanImpl(repo.getSuperRepository().issueID(),
-1L,
-1L,
null,
null,
null,
repo.getDataBean(),
attrs,
other.fData.getIndirection());
repo.getSuperRepository().getSession().save(fData);
setDataBean(fData);
}
// TODO I'm not at all sure that these are the right semantics.
/**
* Create a new one in a layered context, when it is the result of
* a renaming.
* @param file The node we are being made from.
* @param repos The Repository.
* @param srcLookup The lookup for the source parent directory. We
* need this to get calculate the correct indirection information.
* @param name The name
*/
public LayeredFileNode(FileNode file,
Repository repos,
Lookup srcLookup,
String name)
Repository repos,
Lookup srcLookup,
String name)
{
// TODO Something.
long time = System.currentTimeMillis();
BasicAttributesBean attrs =
new BasicAttributesBeanImpl(file.getDataBean().getBasicAttributes());
attrs.setCreateDate(time);
attrs.setModDate(time);
attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repos.getSuperRepository().getSession().save(attrs);
fData =
new LayeredFileNodeBeanImpl(repos.getSuperRepository().issueID(),
-1L,
-1L,
null,
null,
null,
repos.getDataBean(),
attrs,
srcLookup.getIndirectionPath() + "/" + name);
repos.getSuperRepository().getSession().save(fData);
setDataBean(fData);
}
/**
@@ -108,6 +159,8 @@ public class LayeredFileNode extends FileNode implements Layered
public AVMNode possiblyCopy(Lookup lPath)
{
// LayeredFileNodes are always copied.
// TODO This is busted. Need to set the PlainFileNode contents
// to share with underlying file node.
PlainFileNode newMe = new PlainFileNode(getRepository());
newMe.setAncestor(this);
return newMe;

View File

@@ -75,7 +75,9 @@ public class Lookup
private int fPosition;
/**
* Create a new instance.
* Create a new one.
* @param repository The Repository that's being looked in.
* @param repName The name of that Repsository.
*/
public Lookup(Repository repository, String repName)
{
@@ -145,7 +147,8 @@ public class Lookup
}
/**
* Set the current node to one higher in the lookup.
* Set the current node to one higher in the lookup. This is used
* repeatedly during copy on write.
*/
public void upCurrentNode()
{
@@ -178,6 +181,8 @@ public class Lookup
{
return true;
}
// Walk up the containment chain and determine if each parent-child
// relationship is one of direct containment.
while (pos > 1)
{
DirectoryNode dir = (DirectoryNode)fComponents.get(pos - 1).getNode();
@@ -248,19 +253,17 @@ public class Lookup
}
LayeredDirectoryNode oNode =
(LayeredDirectoryNode)node;
if (oNode.getLayerID() == fTopLayer.getLayerID())
if (oNode.getLayerID() == fTopLayer.getLayerID() &&
oNode.hasPrimaryIndirection())
{
if (oNode.hasPrimaryIndirection())
StringBuilder builder = new StringBuilder();
builder.append(oNode.getUnderlying());
for (int i = pos + 1; i <= fPosition; i++)
{
StringBuilder builder = new StringBuilder();
builder.append(oNode.getUnderlying());
for (int i = pos + 1; i <= fPosition; i++)
{
builder.append("/");
builder.append(fComponents.get(i).getName());
}
return builder.toString();
builder.append("/");
builder.append(fComponents.get(i).getName());
}
return builder.toString();
}
}
// TODO This is gross. There has to be a neater way to do this.

View File

@@ -28,8 +28,8 @@ import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean;
import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl;
/**
* A plain directory. No monkey tricks except for possiblyCopy.
* @author britt
*
*/
public class PlainDirectoryNode extends DirectoryNode
{
@@ -44,7 +44,9 @@ public class PlainDirectoryNode extends DirectoryNode
*/
public PlainDirectoryNode(Repository repo)
{
// Make up initial BasicAttributes.
long time = System.currentTimeMillis();
// TODO figure out how to get user information from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
"britt",
"britt",
@@ -62,10 +64,12 @@ public class PlainDirectoryNode extends DirectoryNode
attrs,
false);
repo.getSuperRepository().getSession().save(fData);
setDataBean(fData);
}
/**
* Make one up from its bean data.
* Make one up from its bean data. Used when a PlainDirectory is
* restored from the database.
* @param data The bean data.
*/
public PlainDirectoryNode(PlainDirectoryNodeBean data)
@@ -82,11 +86,15 @@ public class PlainDirectoryNode extends DirectoryNode
public PlainDirectoryNode(PlainDirectoryNode other,
Repository repos)
{
// Make up appropriate BasicAttributes.
long time = System.currentTimeMillis();
// TODO Need to figure out how to get user information from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes());
attrs.setModDate(time);
attrs.setCreateDate(time);
attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repos.getSuperRepository().getSession().save(attrs);
fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
@@ -110,6 +118,8 @@ public class PlainDirectoryNode extends DirectoryNode
*/
public boolean addChild(String name, AVMNode child, Lookup lPath)
{
// No, if a child with the given name exists. Note that uniqueness
// of names is built into the AVM, as opposed to being configurable.
if (fData.getChildren().containsKey(name))
{
return false;
@@ -117,7 +127,7 @@ public class PlainDirectoryNode extends DirectoryNode
DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath);
toModify.putChild(name, child);
child.setParent(toModify);
child.setRepository(toModify.getRepository());
child.setRepository(lPath.getRepository());
return true;
}
@@ -128,10 +138,11 @@ public class PlainDirectoryNode extends DirectoryNode
*/
public boolean directlyContains(AVMNode node)
{
return fData.getChildren().containsValue(node.getDataBean());
// TODO This is inefficient; maybe use a two way map.
DirectoryEntry entry = new DirectoryEntry(node.getType(), node.getDataBean());
return fData.getChildren().containsValue(entry);
}
/**
* Get a directory listing.
* @param lPath The lookup path.
@@ -140,6 +151,8 @@ public class PlainDirectoryNode extends DirectoryNode
*/
public Map<String, DirectoryEntry> getListing(Lookup lPath, int version)
{
// Maybe this is pointless, but it's nice to be able to iterate
// over entries in a defined order.
return new TreeMap<String, DirectoryEntry>(fData.getChildren());
}
@@ -177,6 +190,7 @@ public class PlainDirectoryNode extends DirectoryNode
*/
public boolean removeChild(String name, Lookup lPath)
{
// Can't remove it if it's not there.
if (!fData.getChildren().containsKey(name))
{
return false;
@@ -196,6 +210,8 @@ public class PlainDirectoryNode extends DirectoryNode
fData.getChildren().put(name, new DirectoryEntry(node.getType(), node.getDataBean()));
}
// TODO I don't think this is at all necessary in the world without
// mounted VirtualRepositories.
/**
* Set repository after copy on write.
* @param parent The parent after copy on write.
@@ -222,13 +238,15 @@ public class PlainDirectoryNode extends DirectoryNode
// Otherwise do an actual copy.
DirectoryNode newMe = null;
long newBranchID = lPath.getHighestBranch();
// In a layered context a copy on write creates a new
// layered directory.
if (lPath.isLayered())
{
newMe = new LayeredDirectoryNode(this, getRepository(), lPath);
newMe = new LayeredDirectoryNode(this, lPath.getRepository(), lPath);
}
else
{
newMe = new PlainDirectoryNode(this, getRepository());
newMe = new PlainDirectoryNode(this, lPath.getRepository());
}
newMe.setAncestor(this);
newMe.setBranchID(newBranchID);

View File

@@ -25,8 +25,8 @@ import org.alfresco.repo.avm.hibernate.PlainFileNodeBean;
import org.alfresco.repo.avm.hibernate.PlainFileNodeBeanImpl;
/**
* A plain old file. Contains a Content object.
* @author britt
*
*/
public class PlainFileNode extends FileNode
{
@@ -47,11 +47,12 @@ public class PlainFileNode extends FileNode
/**
* Make one from just a repository.
* This is the constructor used when a brand new plain file is being made.
* @param repos A Repository.
*/
public PlainFileNode(Repository repos)
{
ContentBean content = new ContentBeanImpl(repos.getSuperRepository().issueContentID());
FileContent content = new FileContent(repos.getSuperRepository());
long time = System.currentTimeMillis();
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
"britt",
@@ -68,7 +69,7 @@ public class PlainFileNode extends FileNode
null,
repos.getDataBean(),
attrs,
content);
content.getDataBean());
content.setRefCount(1);
// Transitive persistence should take care of content.
repos.getSuperRepository().getSession().save(fData);
@@ -83,11 +84,15 @@ public class PlainFileNode extends FileNode
public PlainFileNode(PlainFileNode other,
Repository repos)
{
// Setup sensible BasicAttributes.
long time = System.currentTimeMillis();
// TODO Figure out how to get user from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes());
attrs.setCreateDate(time);
attrs.setModDate(time);
attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repos.getSuperRepository().getSession().save(attrs);
fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
@@ -103,6 +108,7 @@ public class PlainFileNode extends FileNode
setDataBean(fData);
}
// TODO I believe this is unnecessary (bhp)
/**
* Handle setting repository after a COW.
* @param parent The possibly new parent directory.
@@ -154,11 +160,12 @@ public class PlainFileNode extends FileNode
*/
public FileContent getContentForWrite(Repository repo)
{
FileContent fc = new FileContent(fData.getContent());
if (fData.getContent().getRefCount() > 1)
{
fData.setContent(new ContentBeanImpl(repo.getSuperRepository().issueContentID()));
// Need to copy the underlying file data.
fc = new FileContent(fc, repo.getSuperRepository());
fData.setContent(fc.getDataBean());
}
return new FileContent(fData.getContent());
return fc;
}
}

View File

@@ -28,7 +28,7 @@ import org.hibernate.Session;
* A SuperRepository is responsible for the high level implemenation of all
* operations on Repositories. It is responsible for issuing Node ids, branch ids,
* and layer ids. Repositories themselves are responsible for issuing version ids.
* Paths in super repositories are of the form "repositoryname:/a/b/c/d
* Paths in super repositories are of the form "repositoryname:a/b/c/d".
* @author britt
*/
public interface SuperRepository

View File

@@ -19,8 +19,8 @@ package org.alfresco.repo.avm.hibernate;
/**
* Shared Content between files.
* @author britt
*
*/
public class ContentBeanImpl implements ContentBean
{

View File

@@ -105,4 +105,39 @@ public class DirectoryEntry
{
return fType.name();
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof DirectoryEntry))
{
return false;
}
return fChild.equals(((DirectoryEntry)obj).fChild);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fChild.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "[" + fType.name() + "] " + fChild.getId();
}
}

View File

@@ -76,6 +76,7 @@ public class RepositoryImpl implements Repository
fData = new RepositoryBeanImpl(name, null);
fSuper.getSession().save(fData);
long time = System.currentTimeMillis();
// TODO Obviously we have to figure out how to get users from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
"britt",
"britt",
@@ -175,7 +176,6 @@ public class RepositoryImpl implements Repository
{
newDir = new PlainDirectoryNode(this);
}
// TODO Untangle when you are going to set a new version id.
newDir.setVersion(getLatestVersion() + 1);
this.setNew(newDir);
dir.addChild(name, newDir, lPath);
@@ -197,11 +197,15 @@ public class RepositoryImpl implements Repository
new LayeredDirectoryNode(srcPath, this);
if (lPath.isLayered())
{
// When a layered directory is made inside of a layered context,
// it gets its layer id from the topmost layer in its lookup
// path.
LayeredDirectoryNode top = lPath.getTopLayer();
newDir.setLayerID(top.getLayerID());
}
else
{
// Otherwise we issue a brand new layer id.
newDir.setLayerID(fSuper.issueLayerID());
}
dir.addChild(name, newDir, lPath);
@@ -237,6 +241,7 @@ public class RepositoryImpl implements Repository
{
throw new AlfrescoRuntimeException("Child exists: " + name);
}
// TODO Reexamine decision to not check validity of srcPath.
LayeredFileNode newFile =
new LayeredFileNode(srcPath, this);
dir.addChild(dstPath, newFile, lPath);
@@ -291,6 +296,7 @@ public class RepositoryImpl implements Repository
throw new AlfrescoRuntimeException("Not a file: " + path);
}
FileNode file = (FileNode)node;
file = (FileNode)file.copyOnWrite(lPath);
FileContent content = file.getContentForWrite(this);
return content.getOutputStream(fSuper);
}
@@ -356,13 +362,17 @@ public class RepositoryImpl implements Repository
// Make a new version of source directly to be slid.
LayeredDirectoryNode dstNode =
new LayeredDirectoryNode((LayeredDirectoryNode)srcNode, this);
// Relookup the destination.
// Relookup the destination, since the lookup have been invalidated
// by the src copy on write.
dPath = lookup(-1, dstPath);
dstDir = (DirectoryNode)dPath.getCurrentNode();
dstDir.addChild(dstName, dstNode, dPath);
}
// TODO Should this be propagated out to SuperRepository.
// TODO This is problematic. As time goes on this returns
// larger and larger data sets. Perhaps what we should do is
// provide methods for getting versions by date range, n most
// recent etc.
/* (non-Javadoc)
* @see org.alfresco.repo.avm.Repository#getVersions()
*/
@@ -392,13 +402,16 @@ public class RepositoryImpl implements Repository
*/
public Lookup lookup(int version, String path)
{
// Make up a Lookup to hold the results.
Lookup result = new Lookup(this, fData.getName());
if (path.length() == 0)
{
throw new AlfrescoRuntimeException("Invalid path: " + path);
}
String[] pathElements = path.split("/");
// Grab the root node to start the lookup.
DirectoryNode dir = null;
// Versions less than 0 mean get current.
if (version < 0)
{
dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(fData.getRoot());
@@ -412,11 +425,14 @@ public class RepositoryImpl implements Repository
}
dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(bean);
}
// Add an entry for the root.
result.add(dir, "");
if (pathElements.length == 0)
{
return result;
}
// Now look up each path element in sequence up to one
// before the end.
for (int i = 0; i < pathElements.length - 1; i++)
{
AVMNode child = dir.lookupChild(result, pathElements[i], version);
@@ -424,6 +440,7 @@ public class RepositoryImpl implements Repository
{
throw new AlfrescoRuntimeException("Not found: " + pathElements[i]);
}
// Every element that is not the last needs to be a directory.
if (!(child instanceof DirectoryNode))
{
throw new AlfrescoRuntimeException("Not a directory: " + pathElements[i]);
@@ -431,6 +448,7 @@ public class RepositoryImpl implements Repository
dir = (DirectoryNode)child;
result.add(dir, pathElements[i]);
}
// Now look up the last element.
AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version);
if (child == null)
{
@@ -445,6 +463,8 @@ public class RepositoryImpl implements Repository
*/
public Lookup lookupDirectory(int version, String path)
{
// Just do a regular lookup and assert that the last element
// is a directory.
Lookup lPath = lookup(version, path);
if (!(lPath.getCurrentNode() instanceof DirectoryNode))
{

View File

@@ -76,6 +76,8 @@ public class SuperRepositoryImpl implements SuperRepository
*/
private String fStorage;
// TODO Issuers are handled in a repugnant manner here. Something better
// would be nice.
/**
* Make a new one, initialized with the session.
* @param session The session for this operation.