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

View File

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

View File

@@ -43,6 +43,7 @@ public class LayeredFileNode extends FileNode implements Layered
setDataBean(fData); setDataBean(fData);
} }
// TODO Is this ever used?
/** /**
* Basically a copy constructor. * Basically a copy constructor.
* @param other The file to make a copy of. * @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) 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, public LayeredFileNode(FileNode file,
Repository repos, Repository repos,
Lookup srcLookup, Lookup srcLookup,
String name) 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) public AVMNode possiblyCopy(Lookup lPath)
{ {
// LayeredFileNodes are always copied. // 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()); PlainFileNode newMe = new PlainFileNode(getRepository());
newMe.setAncestor(this); newMe.setAncestor(this);
return newMe; return newMe;

View File

@@ -75,7 +75,9 @@ public class Lookup
private int fPosition; 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) 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() public void upCurrentNode()
{ {
@@ -178,6 +181,8 @@ public class Lookup
{ {
return true; return true;
} }
// Walk up the containment chain and determine if each parent-child
// relationship is one of direct containment.
while (pos > 1) while (pos > 1)
{ {
DirectoryNode dir = (DirectoryNode)fComponents.get(pos - 1).getNode(); DirectoryNode dir = (DirectoryNode)fComponents.get(pos - 1).getNode();
@@ -248,19 +253,17 @@ public class Lookup
} }
LayeredDirectoryNode oNode = LayeredDirectoryNode oNode =
(LayeredDirectoryNode)node; (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("/");
builder.append(oNode.getUnderlying()); builder.append(fComponents.get(i).getName());
for (int i = pos + 1; i <= fPosition; i++)
{
builder.append("/");
builder.append(fComponents.get(i).getName());
}
return builder.toString();
} }
return builder.toString();
} }
} }
// TODO This is gross. There has to be a neater way to do this. // 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; import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl;
/** /**
* A plain directory. No monkey tricks except for possiblyCopy.
* @author britt * @author britt
*
*/ */
public class PlainDirectoryNode extends DirectoryNode public class PlainDirectoryNode extends DirectoryNode
{ {
@@ -44,7 +44,9 @@ public class PlainDirectoryNode extends DirectoryNode
*/ */
public PlainDirectoryNode(Repository repo) public PlainDirectoryNode(Repository repo)
{ {
// Make up initial BasicAttributes.
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
// TODO figure out how to get user information from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
"britt", "britt",
"britt", "britt",
@@ -62,10 +64,12 @@ public class PlainDirectoryNode extends DirectoryNode
attrs, attrs,
false); false);
repo.getSuperRepository().getSession().save(fData); 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. * @param data The bean data.
*/ */
public PlainDirectoryNode(PlainDirectoryNodeBean data) public PlainDirectoryNode(PlainDirectoryNodeBean data)
@@ -82,11 +86,15 @@ public class PlainDirectoryNode extends DirectoryNode
public PlainDirectoryNode(PlainDirectoryNode other, public PlainDirectoryNode(PlainDirectoryNode other,
Repository repos) Repository repos)
{ {
// Make up appropriate BasicAttributes.
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
// TODO Need to figure out how to get user information from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes()); BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes());
attrs.setModDate(time); attrs.setModDate(time);
attrs.setCreateDate(time); attrs.setCreateDate(time);
attrs.setAccessDate(time); attrs.setAccessDate(time);
attrs.setCreator("britt");
attrs.setLastModifier("britt");
repos.getSuperRepository().getSession().save(attrs); repos.getSuperRepository().getSession().save(attrs);
fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1, -1,
@@ -110,6 +118,8 @@ public class PlainDirectoryNode extends DirectoryNode
*/ */
public boolean addChild(String name, AVMNode child, Lookup lPath) 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)) if (fData.getChildren().containsKey(name))
{ {
return false; return false;
@@ -117,7 +127,7 @@ public class PlainDirectoryNode extends DirectoryNode
DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath); DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath);
toModify.putChild(name, child); toModify.putChild(name, child);
child.setParent(toModify); child.setParent(toModify);
child.setRepository(toModify.getRepository()); child.setRepository(lPath.getRepository());
return true; return true;
} }
@@ -128,10 +138,11 @@ public class PlainDirectoryNode extends DirectoryNode
*/ */
public boolean directlyContains(AVMNode node) 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. * Get a directory listing.
* @param lPath The lookup path. * @param lPath The lookup path.
@@ -140,6 +151,8 @@ public class PlainDirectoryNode extends DirectoryNode
*/ */
public Map<String, DirectoryEntry> getListing(Lookup lPath, int version) 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()); return new TreeMap<String, DirectoryEntry>(fData.getChildren());
} }
@@ -177,6 +190,7 @@ public class PlainDirectoryNode extends DirectoryNode
*/ */
public boolean removeChild(String name, Lookup lPath) public boolean removeChild(String name, Lookup lPath)
{ {
// Can't remove it if it's not there.
if (!fData.getChildren().containsKey(name)) if (!fData.getChildren().containsKey(name))
{ {
return false; return false;
@@ -196,6 +210,8 @@ public class PlainDirectoryNode extends DirectoryNode
fData.getChildren().put(name, new DirectoryEntry(node.getType(), node.getDataBean())); 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. * Set repository after copy on write.
* @param parent The parent 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. // Otherwise do an actual copy.
DirectoryNode newMe = null; DirectoryNode newMe = null;
long newBranchID = lPath.getHighestBranch(); long newBranchID = lPath.getHighestBranch();
// In a layered context a copy on write creates a new
// layered directory.
if (lPath.isLayered()) if (lPath.isLayered())
{ {
newMe = new LayeredDirectoryNode(this, getRepository(), lPath); newMe = new LayeredDirectoryNode(this, lPath.getRepository(), lPath);
} }
else else
{ {
newMe = new PlainDirectoryNode(this, getRepository()); newMe = new PlainDirectoryNode(this, lPath.getRepository());
} }
newMe.setAncestor(this); newMe.setAncestor(this);
newMe.setBranchID(newBranchID); newMe.setBranchID(newBranchID);

View File

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

View File

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

View File

@@ -105,4 +105,39 @@ public class DirectoryEntry
{ {
return fType.name(); 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); fData = new RepositoryBeanImpl(name, null);
fSuper.getSession().save(fData); fSuper.getSession().save(fData);
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
// TODO Obviously we have to figure out how to get users from context.
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
"britt", "britt",
"britt", "britt",
@@ -175,7 +176,6 @@ public class RepositoryImpl implements Repository
{ {
newDir = new PlainDirectoryNode(this); newDir = new PlainDirectoryNode(this);
} }
// TODO Untangle when you are going to set a new version id.
newDir.setVersion(getLatestVersion() + 1); newDir.setVersion(getLatestVersion() + 1);
this.setNew(newDir); this.setNew(newDir);
dir.addChild(name, newDir, lPath); dir.addChild(name, newDir, lPath);
@@ -197,11 +197,15 @@ public class RepositoryImpl implements Repository
new LayeredDirectoryNode(srcPath, this); new LayeredDirectoryNode(srcPath, this);
if (lPath.isLayered()) 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(); LayeredDirectoryNode top = lPath.getTopLayer();
newDir.setLayerID(top.getLayerID()); newDir.setLayerID(top.getLayerID());
} }
else else
{ {
// Otherwise we issue a brand new layer id.
newDir.setLayerID(fSuper.issueLayerID()); newDir.setLayerID(fSuper.issueLayerID());
} }
dir.addChild(name, newDir, lPath); dir.addChild(name, newDir, lPath);
@@ -237,6 +241,7 @@ public class RepositoryImpl implements Repository
{ {
throw new AlfrescoRuntimeException("Child exists: " + name); throw new AlfrescoRuntimeException("Child exists: " + name);
} }
// TODO Reexamine decision to not check validity of srcPath.
LayeredFileNode newFile = LayeredFileNode newFile =
new LayeredFileNode(srcPath, this); new LayeredFileNode(srcPath, this);
dir.addChild(dstPath, newFile, lPath); dir.addChild(dstPath, newFile, lPath);
@@ -291,6 +296,7 @@ public class RepositoryImpl implements Repository
throw new AlfrescoRuntimeException("Not a file: " + path); throw new AlfrescoRuntimeException("Not a file: " + path);
} }
FileNode file = (FileNode)node; FileNode file = (FileNode)node;
file = (FileNode)file.copyOnWrite(lPath);
FileContent content = file.getContentForWrite(this); FileContent content = file.getContentForWrite(this);
return content.getOutputStream(fSuper); return content.getOutputStream(fSuper);
} }
@@ -356,13 +362,17 @@ public class RepositoryImpl implements Repository
// Make a new version of source directly to be slid. // Make a new version of source directly to be slid.
LayeredDirectoryNode dstNode = LayeredDirectoryNode dstNode =
new LayeredDirectoryNode((LayeredDirectoryNode)srcNode, this); 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); dPath = lookup(-1, dstPath);
dstDir = (DirectoryNode)dPath.getCurrentNode(); dstDir = (DirectoryNode)dPath.getCurrentNode();
dstDir.addChild(dstName, dstNode, dPath); 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) /* (non-Javadoc)
* @see org.alfresco.repo.avm.Repository#getVersions() * @see org.alfresco.repo.avm.Repository#getVersions()
*/ */
@@ -392,13 +402,16 @@ public class RepositoryImpl implements Repository
*/ */
public Lookup lookup(int version, String path) public Lookup lookup(int version, String path)
{ {
// Make up a Lookup to hold the results.
Lookup result = new Lookup(this, fData.getName()); Lookup result = new Lookup(this, fData.getName());
if (path.length() == 0) if (path.length() == 0)
{ {
throw new AlfrescoRuntimeException("Invalid path: " + path); throw new AlfrescoRuntimeException("Invalid path: " + path);
} }
String[] pathElements = path.split("/"); String[] pathElements = path.split("/");
// Grab the root node to start the lookup.
DirectoryNode dir = null; DirectoryNode dir = null;
// Versions less than 0 mean get current.
if (version < 0) if (version < 0)
{ {
dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(fData.getRoot()); dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(fData.getRoot());
@@ -412,11 +425,14 @@ public class RepositoryImpl implements Repository
} }
dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(bean); dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(bean);
} }
// Add an entry for the root.
result.add(dir, ""); result.add(dir, "");
if (pathElements.length == 0) if (pathElements.length == 0)
{ {
return result; 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++) for (int i = 0; i < pathElements.length - 1; i++)
{ {
AVMNode child = dir.lookupChild(result, pathElements[i], version); AVMNode child = dir.lookupChild(result, pathElements[i], version);
@@ -424,6 +440,7 @@ public class RepositoryImpl implements Repository
{ {
throw new AlfrescoRuntimeException("Not found: " + pathElements[i]); throw new AlfrescoRuntimeException("Not found: " + pathElements[i]);
} }
// Every element that is not the last needs to be a directory.
if (!(child instanceof DirectoryNode)) if (!(child instanceof DirectoryNode))
{ {
throw new AlfrescoRuntimeException("Not a directory: " + pathElements[i]); throw new AlfrescoRuntimeException("Not a directory: " + pathElements[i]);
@@ -431,6 +448,7 @@ public class RepositoryImpl implements Repository
dir = (DirectoryNode)child; dir = (DirectoryNode)child;
result.add(dir, pathElements[i]); result.add(dir, pathElements[i]);
} }
// Now look up the last element.
AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version); AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version);
if (child == null) if (child == null)
{ {
@@ -445,6 +463,8 @@ public class RepositoryImpl implements Repository
*/ */
public Lookup lookupDirectory(int version, String path) 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); Lookup lPath = lookup(version, path);
if (!(lPath.getCurrentNode() instanceof DirectoryNode)) if (!(lPath.getCurrentNode() instanceof DirectoryNode))
{ {

View File

@@ -76,6 +76,8 @@ public class SuperRepositoryImpl implements SuperRepository
*/ */
private String fStorage; 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. * Make a new one, initialized with the session.
* @param session The session for this operation. * @param session The session for this operation.