mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged all the AVM mapping files into one medium file. I find it easier to follow.
Purged the pointless FileContentFactory class. If everything else were working file reading and writing would now work. Various other cleanups and some richer internal documentation. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2904 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -153,15 +153,18 @@ public abstract class AVMNode
|
||||
*/
|
||||
public AVMNode copyOnWrite(Lookup lPath)
|
||||
{
|
||||
// Call the subclass's copy on write logic.
|
||||
AVMNode newMe = possiblyCopy(lPath);
|
||||
String myName = lPath.getName();
|
||||
lPath.upCurrentNode();
|
||||
// No copying needed, so short circuit.
|
||||
if (newMe == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
Repository repos = getRepository();
|
||||
String myName = lPath.getName();
|
||||
lPath.upCurrentNode();
|
||||
Repository repos = lPath.getRepository();
|
||||
newMe.setVersion(repos.getLatestVersion() + 1);
|
||||
// Get our parent directory if we have one.
|
||||
DirectoryNode parent = null;
|
||||
if (getParent() != null)
|
||||
{
|
||||
@@ -169,6 +172,7 @@ public abstract class AVMNode
|
||||
}
|
||||
if (parent != null)
|
||||
{
|
||||
// Recursive invocation.
|
||||
DirectoryNode newParent =
|
||||
(DirectoryNode)parent.copyOnWrite(lPath);
|
||||
newParent.putChild(myName, newMe);
|
||||
@@ -176,15 +180,14 @@ public abstract class AVMNode
|
||||
}
|
||||
else // Null parent means root of repository.
|
||||
{
|
||||
newMe.setRepository(getRepository());
|
||||
repos.setNewRoot((DirectoryNode)newMe);
|
||||
}
|
||||
newMe.setRepository(repos);
|
||||
newMe.setShouldBeCopied(false);
|
||||
repos.setNew(newMe);
|
||||
return newMe;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Possibly copy ourselves.
|
||||
* @param lPath The Lookup for this node.
|
||||
|
@@ -24,7 +24,8 @@ import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean;
|
||||
import org.alfresco.repo.avm.hibernate.PlainFileNodeBean;
|
||||
|
||||
/**
|
||||
* Responsible for instantiating AVMNode implementations.
|
||||
* Responsible for instantiating AVMNode concrete subclasses from
|
||||
* underlying data beans.
|
||||
* @author britt
|
||||
*/
|
||||
public class AVMNodeFactory
|
||||
|
@@ -25,8 +25,8 @@ import java.util.Set;
|
||||
/**
|
||||
* This is the service interface for the [Alfresco|Addled|Advanced|Apotheosed] Versioning
|
||||
* Model. It specifies methods that are close in functionality to the underlying
|
||||
* implementation, and is intended, for now, as an internal interface to build a different
|
||||
* implementation of NodeService and others.
|
||||
* implementation, and is intended as both a first class Alfresco service and an
|
||||
* aid in creating new implementations of existing services.
|
||||
* @author britt
|
||||
*/
|
||||
public interface AVMService
|
||||
|
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
import org.alfresco.repo.avm.hibernate.DirectoryEntry;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for Directories.
|
||||
* @author britt
|
||||
*/
|
||||
public abstract class DirectoryNode extends AVMNode
|
||||
|
@@ -17,11 +17,15 @@
|
||||
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Formatter;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.avm.hibernate.ContentBean;
|
||||
@@ -38,6 +42,16 @@ public class FileContent
|
||||
*/
|
||||
private ContentBean fData;
|
||||
|
||||
/**
|
||||
* The name of the file.
|
||||
*/
|
||||
private String fName;
|
||||
|
||||
/**
|
||||
* The directory path of the file.
|
||||
*/
|
||||
private String fPath;
|
||||
|
||||
/**
|
||||
* Make one from a bean.
|
||||
* @param data The Bean with the data.
|
||||
@@ -45,6 +59,7 @@ public class FileContent
|
||||
public FileContent(ContentBean data)
|
||||
{
|
||||
fData = data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,6 +69,17 @@ public class FileContent
|
||||
public FileContent(SuperRepository superRepo)
|
||||
{
|
||||
fData = new ContentBeanImpl(superRepo.issueContentID());
|
||||
BufferedOutputStream out = new BufferedOutputStream(getOutputStream(superRepo));
|
||||
// Make an empty file.
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
catch (IOException ie)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Couldn't close file.", ie);
|
||||
}
|
||||
superRepo.getSession().save(fData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +90,25 @@ public class FileContent
|
||||
public FileContent(FileContent other, SuperRepository superRepo)
|
||||
{
|
||||
fData = new ContentBeanImpl(superRepo.issueContentID());
|
||||
// TODO Something.
|
||||
// Copy the contents from other to this.
|
||||
BufferedInputStream in = new BufferedInputStream(other.getInputStream(superRepo));
|
||||
BufferedOutputStream out = new BufferedOutputStream(this.getOutputStream(superRepo));
|
||||
try
|
||||
{
|
||||
byte [] buff = new byte[4096]; // Nyah, nyah.
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buff)) != -1)
|
||||
{
|
||||
out.write(buff, 0, bytesRead);
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
catch (IOException ie)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("I/O failure in Copy on Write.", ie);
|
||||
}
|
||||
superRepo.getSession().save(fData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,8 +136,14 @@ public class FileContent
|
||||
*/
|
||||
public InputStream getInputStream(SuperRepository superRepo)
|
||||
{
|
||||
// TODO Something.
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return new FileInputStream(getContentPath(superRepo));
|
||||
}
|
||||
catch (IOException ie)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Could not open for reading: " + getContentPath(superRepo), ie);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,8 +153,19 @@ public class FileContent
|
||||
*/
|
||||
public OutputStream getOutputStream(SuperRepository superRepo)
|
||||
{
|
||||
// TODO Something.
|
||||
return null;
|
||||
try
|
||||
{
|
||||
File dir = new File(getDirectoryPath(superRepo));
|
||||
if (!dir.exists())
|
||||
{
|
||||
dir.mkdirs();
|
||||
}
|
||||
return new FileOutputStream(getContentPath(superRepo));
|
||||
}
|
||||
catch (IOException ie)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Could not open for writing: " + getContentPath(superRepo), ie);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,4 +176,51 @@ public class FileContent
|
||||
{
|
||||
return fData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the full path for this content.
|
||||
* @param superRepo
|
||||
* @return The full path for this content.
|
||||
*/
|
||||
private String getContentPath(SuperRepository superRepo)
|
||||
{
|
||||
if (fName == null)
|
||||
{
|
||||
calcPathData(superRepo);
|
||||
}
|
||||
return fName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directory path for this content.
|
||||
* @param superRepo
|
||||
* @return The directory path.
|
||||
*/
|
||||
private String getDirectoryPath(SuperRepository superRepo)
|
||||
{
|
||||
if (fPath == null)
|
||||
{
|
||||
calcPathData(superRepo);
|
||||
}
|
||||
return fPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the path data.
|
||||
*/
|
||||
private void calcPathData(SuperRepository superRepo)
|
||||
{
|
||||
long id = fData.getId();
|
||||
Formatter form = new Formatter(new StringBuilder());
|
||||
form.format("%016x", id);
|
||||
String name = form.toString();
|
||||
form = new Formatter(new StringBuilder());
|
||||
form.format("/%02x/%02x/%02x",
|
||||
(id & 0xff000000) >> 24,
|
||||
(id & 0xff0000) >> 16,
|
||||
(id & 0xff00) >> 8);
|
||||
String dir = form.toString();
|
||||
fPath = superRepo.getStorageRoot() + dir;
|
||||
fName = fPath + "/" + name;
|
||||
}
|
||||
}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import org.alfresco.repo.avm.hibernate.ContentBean;
|
||||
|
||||
/**
|
||||
* Static method for making FileContent instances from beans.
|
||||
* @author britt
|
||||
*/
|
||||
public class FileContentFactory
|
||||
{
|
||||
/**
|
||||
* Make A FileContent object from a ContentBean.
|
||||
* @param bean The bean with the data.
|
||||
*/
|
||||
public static FileContent CreateFileContentFromBean(ContentBean bean)
|
||||
{
|
||||
return new FileContent(bean);
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
/**
|
||||
* Interface for file objects.
|
||||
* Base class for file objects.
|
||||
* @author britt
|
||||
*/
|
||||
public abstract class FileNode extends AVMNode
|
||||
|
@@ -18,7 +18,6 @@
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@@ -30,7 +29,11 @@ import org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBean;
|
||||
import org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBeanImpl;
|
||||
|
||||
/**
|
||||
* Interface for a layered directory node. Stub.
|
||||
* A layered directory node. A layered directory node points at
|
||||
* an underlying directory, which may or may not exist. The visible
|
||||
* contents of a layered directory node is the contents of the underlying node
|
||||
* pointed at plus those nodes added to or modified in the layered directory node minus
|
||||
* those nodes which have been deleted in the layered directory node.
|
||||
* @author britt
|
||||
*/
|
||||
public class LayeredDirectoryNode extends DirectoryNode implements Layered
|
||||
@@ -57,7 +60,9 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
|
||||
*/
|
||||
public LayeredDirectoryNode(String indirection, Repository repos)
|
||||
{
|
||||
// Set up basic attributes for this node.
|
||||
long time = System.currentTimeMillis();
|
||||
// TODO We'll fix this up when Britt understands user management.
|
||||
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",
|
||||
"britt",
|
||||
"britt",
|
||||
|
@@ -30,7 +30,6 @@ public class Lookup
|
||||
/**
|
||||
* The Repository.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Repository fRepository;
|
||||
|
||||
/**
|
||||
@@ -287,4 +286,13 @@ public class Lookup
|
||||
{
|
||||
return fTopLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repository that this path is in.
|
||||
* @return The repository.
|
||||
*/
|
||||
public Repository getRepository()
|
||||
{
|
||||
return fRepository;
|
||||
}
|
||||
}
|
||||
|
@@ -145,7 +145,7 @@ public class PlainFileNode extends FileNode
|
||||
*/
|
||||
public FileContent getContentForRead(int version)
|
||||
{
|
||||
return FileContentFactory.CreateFileContentFromBean(fData.getContent());
|
||||
return new FileContent(fData.getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,6 +159,6 @@ public class PlainFileNode extends FileNode
|
||||
fData.setContent(new ContentBeanImpl(repo.getSuperRepository().issueContentID()));
|
||||
// Need to copy the underlying file data.
|
||||
}
|
||||
return FileContentFactory.CreateFileContentFromBean(fData.getContent());
|
||||
return new FileContent(fData.getContent());
|
||||
}
|
||||
}
|
||||
|
@@ -237,4 +237,10 @@ public interface SuperRepository
|
||||
* @return The Lookup.
|
||||
*/
|
||||
public Lookup lookupDirectory(int version, String path);
|
||||
|
||||
/**
|
||||
* Get the root directory in which file data is stored.
|
||||
* @return The root directory of storage.
|
||||
*/
|
||||
public String getStorageRoot();
|
||||
}
|
||||
|
206
source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
Normal file
206
source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
Normal file
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
<hibernate-mapping package="org.alfresco.repo.avm.hibernate">
|
||||
<!-- AVMNodeBean is the abstract base for filesystem like objects.
|
||||
We're using the one table per class hierarchy strategy to implement
|
||||
polymorphism. -->
|
||||
<class table="avm_nodes" lazy="true" abstract="true"
|
||||
name="AVMNodeBeanImpl"
|
||||
proxy="AVMNodeBean"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write"/>
|
||||
<!-- The id is set programmatically using an Issuer. See below. -->
|
||||
<id name="id" column="id" type="long"/>
|
||||
<!-- I suppose this would be more efficient to encode type by an int.
|
||||
We'll see if using a string makes a difference. -->
|
||||
<discriminator column="class_type" type="string" length="20"/>
|
||||
<!-- We're using hibernate's own versioning scheme for concurrency control.
|
||||
I don't know how well that will play with a full Spring-JTA stack. -->
|
||||
<version column="vers" name="vers" type="long"/>
|
||||
<!-- BasicAttributes are attributes that pretty much all AVMNodes will
|
||||
have. -->
|
||||
<many-to-one name="basicAttributes" column="basic_attrs"
|
||||
class="BasicAttributesBeanImpl" unique="true" cascade="all"/>
|
||||
<many-to-one name="ancestor" column="ancestor_id"
|
||||
class="AVMNodeBeanImpl"/>
|
||||
<!-- Nothing does anything with this yet. We'll need it for
|
||||
complete versioning semantics. -->
|
||||
<many-to-one name="mergedFrom" column="merged_from"
|
||||
class="AVMNodeBeanImpl"/>
|
||||
<!-- Parent is a very specific notion of containment. The parent
|
||||
of an AVMNode is the parent in which that node was created. -->
|
||||
<many-to-one name="parent" column="parent_id"
|
||||
class="DirectoryNodeBeanImpl"/>
|
||||
<!-- This should really be not null, but I haven't figured out
|
||||
the right way to build the relation so that nullability constraints
|
||||
won't cause violations in the db during saves. -->
|
||||
<many-to-one name="repository" column="repository"
|
||||
class="RepositoryBeanImpl" cascade="save-update"/>
|
||||
<property name="versionID" type="long" column="version_id"
|
||||
not-null="true"/>
|
||||
<!-- The branch id is always 0 for nodes that are not part of
|
||||
a branch. -->
|
||||
<property name="branchID" type="long" column="branch_id"
|
||||
not-null="true"/>
|
||||
<!-- This is, in fact a duplication of data, but an extremely
|
||||
convenient one. -->
|
||||
<property name="isNew" column="is_new" type="boolean"
|
||||
not-null="true"/>
|
||||
<!-- Directories, two flavors. -->
|
||||
<subclass name="DirectoryNodeBeanImpl"
|
||||
proxy="DirectoryNodeBean"
|
||||
abstract="true">
|
||||
<!-- A Layered Directory is our smart symlink thingy. -->
|
||||
<subclass
|
||||
name="LayeredDirectoryNodeBeanImpl"
|
||||
proxy="LayeredDirectoryNodeBean" discriminator-value="layereddirectory">
|
||||
<!-- The layer id is an implementation trick to disambiguate
|
||||
exactly what layer is being refered to in various circumstances. -->
|
||||
<property name="layerID" column="layer_id" type="long" not-null="true"/>
|
||||
<!-- The is the moral equivalent of the value of a symlink. -->
|
||||
<property name="indirection" column="indirection" type="string"
|
||||
length="511"/>
|
||||
<!-- This marks a layered directory as either knowing itself what
|
||||
it points at (true) or inheriting what it points at from its
|
||||
container (false). -->
|
||||
<property name="primaryIndirection" column="primary_indirection" type="boolean"/>
|
||||
<!-- Map of names to DirectoryEntries. -->
|
||||
<map name="added" cascade="all">
|
||||
<key column="directory_id"/>
|
||||
<map-key type="string" column="name"/>
|
||||
<!-- A DirectoryEntry is a (node)type AVMNode reference pair.
|
||||
Should probably convert type into an integer code. -->
|
||||
<composite-element class="DirectoryEntry">
|
||||
<property name="type" column="type_name"
|
||||
type="string" length="30" not-null="true"/>
|
||||
<many-to-one name="child"
|
||||
class="AVMNodeBeanImpl"
|
||||
cascade="save-update" not-null="true">
|
||||
</many-to-one>
|
||||
</composite-element>
|
||||
</map>
|
||||
<!-- This is just the set of names of children deleted (and therefore
|
||||
hidden) in this layer. -->
|
||||
<set name="deleted" table="deleted_children"
|
||||
fetch="join" cascade="all">
|
||||
<key column="directory_id"/>
|
||||
<element type="string" column="name"/>
|
||||
</set>
|
||||
</subclass>
|
||||
<!-- Just plain directories. -->
|
||||
<subclass name="PlainDirectoryNodeBeanImpl"
|
||||
discriminator-value="plaindirectory" proxy="PlainDirectoryNodeBean">
|
||||
<!-- For reference count based garbage collection of purged nodes
|
||||
to work we need to specially mark the root directory of
|
||||
a Repository as special so that its absence of parents will
|
||||
not cause it to be vacuumed away. TODO: for ease of queries,
|
||||
this probably wants to be in the base class. -->
|
||||
<property name="isRoot" column="is_root" type="boolean"/>
|
||||
<!-- A map of names to DirectoryEntries. In the AVM world, it makes sense
|
||||
that nodes don't know there own names, only there containers do. -->
|
||||
<map name="children" cascade="all">
|
||||
<key column="directory_id"/>
|
||||
<map-key type="string" column="name"/>
|
||||
<composite-element class="org.alfresco.repo.avm.hibernate.DirectoryEntry">
|
||||
<property name="type" type="string" not-null="true" length="30"
|
||||
column="type_name"/>
|
||||
<many-to-one name="child"
|
||||
class="org.alfresco.repo.avm.hibernate.AVMNodeBeanImpl"
|
||||
not-null="true" cascade="save-update">
|
||||
</many-to-one>
|
||||
</composite-element>
|
||||
</map>
|
||||
</subclass>
|
||||
</subclass>
|
||||
<!-- There are two kinds of files, plain and symlinky. -->
|
||||
<subclass name="FileNodeBeanImpl"
|
||||
proxy="FileNodeBean"
|
||||
abstract="true">
|
||||
<!-- Plain files just have a reference to a Content object. -->
|
||||
<subclass discriminator-value="plainfile"
|
||||
name="PlainFileNodeBeanImpl"
|
||||
proxy="PlainFileNodeBean">
|
||||
<many-to-one name="content" column="content_id"
|
||||
class="ContentBeanImpl" fetch="join" cascade="save-update">
|
||||
</many-to-one>
|
||||
</subclass>
|
||||
<!-- Layered files are almost exactly copy on write symlinks. -->
|
||||
<subclass name="LayeredFileNodeBeanImpl"
|
||||
discriminator-value="layeredfile" proxy="LayeredFileNodeBean">
|
||||
<property name="indirection" type="string" length="511" column="indirection"/>
|
||||
</subclass>
|
||||
</subclass>
|
||||
</class>
|
||||
<!-- BasicAttributes are a glom of all the properties that (nearly) all filesystem like
|
||||
nodes have. -->
|
||||
<class name="BasicAttributesBeanImpl" proxy="BasicAttributesBean"
|
||||
lazy="true" optimistic-lock="version" table="basic_attributes">
|
||||
<id name="id" type="long">
|
||||
<generator class="native"></generator>
|
||||
</id>
|
||||
<version column="vers" name="vers" type="long"/>
|
||||
<property name="creator" type="string" not-null="true"/>
|
||||
<property name="owner" type="string" not-null="true"/>
|
||||
<property name="lastModifier" type="string" not-null="true"/>
|
||||
<property name="createDate" type="long" not-null="true"/>
|
||||
<property name="modDate" type="long" not-null="true"/>
|
||||
<property name="accessDate" type="long" not-null="true"/>
|
||||
</class>
|
||||
<!-- Contents are objects to hang actual bytestreams off. They are explicitly reference
|
||||
counted. -->
|
||||
<class table="contents" name="ContentBeanImpl" proxy="ContentBean"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="id" column="id" type="long"/>
|
||||
<version name="vers" column="vers" type="long"/>
|
||||
<!-- The reference count. Contents are explicitly reference counted for now,
|
||||
however it make sense to fold this into a generalized garbage collection
|
||||
scheme. -->
|
||||
<property name="refCount" column="ref_count" type="int"
|
||||
not-null="true"/>
|
||||
</class>
|
||||
<!-- Issuers issue ids. They are explicit primary key generators. They seem more
|
||||
convenient than using 'native' generators, and may be more efficient. Come
|
||||
to think of it I'm not convinced that this is true. However I had a reason for
|
||||
doing things this way... -->
|
||||
<class name="Issuer" table="issuers" lazy="false"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="name" column="name" type="string" length="20"/>
|
||||
<version name="vers" column="vers" type="long"/>
|
||||
<property name="next" column="next" type="long"
|
||||
not-null="true"/>
|
||||
</class>
|
||||
<!-- A Repository is the what we used to call a virtual repository.
|
||||
Each Repository has it's own branch ids and layer ids but shares node ids
|
||||
with other repositories. The physical repository is structured this way
|
||||
for better scaling. -->
|
||||
<class table="repositories" name="RepositoryBeanImpl"
|
||||
proxy="RepositoryBean" optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="name" column="name" type="string"/>
|
||||
<version name="vers" column="vers" type="long"/>
|
||||
<property type="long" name="nextVersionID"
|
||||
column="next_version_id" not-null="true"/>
|
||||
<!-- Every Repository has a root directory that is the current root directory. -->
|
||||
<!-- This should be not-null but hibernate (or my own idiocy) makes that difficult. -->
|
||||
<many-to-one name="root" class="DirectoryNodeBeanImpl"
|
||||
column="current_root_id" unique="true" cascade="save-update">
|
||||
</many-to-one>
|
||||
<!-- In addition to the current root directory, a Repository maintains a set
|
||||
of versioned root directories. -->
|
||||
<map name="roots" table="repository_roots">
|
||||
<key column="repository_id"/>
|
||||
<map-key type="long" column="version_id"/>
|
||||
<many-to-many class="DirectoryNodeBeanImpl"
|
||||
column="directory_id"/>
|
||||
</map>
|
||||
<!-- NewNodes keeps track of those nodes created since the last
|
||||
'snapshot' operation. -->
|
||||
<set table="new_nodes" name="newNodes" cascade="all">
|
||||
<key column="repository_id"/>
|
||||
<many-to-many class="AVMNodeBeanImpl"
|
||||
column="new_node_id"/>
|
||||
</set>
|
||||
</class>
|
||||
</hibernate-mapping>
|
@@ -1,114 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
<hibernate-mapping package="org.alfresco.repo.avm.hibernate">
|
||||
<class table="avm_nodes" lazy="true" abstract="true"
|
||||
name="AVMNodeBeanImpl"
|
||||
proxy="AVMNodeBean"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write"/>
|
||||
<id name="id" column="id" type="long">
|
||||
</id>
|
||||
<discriminator column="class_type" type="string" length="20"></discriminator>
|
||||
<version column="vers" name="vers" type="long"></version>
|
||||
<many-to-one name="basicAttributes" column="basic_attrs"
|
||||
class="BasicAttributesBeanImpl" unique="true" cascade="all">
|
||||
</many-to-one>
|
||||
<many-to-one name="ancestor" column="ancestor_id"
|
||||
class="AVMNodeBeanImpl">
|
||||
</many-to-one>
|
||||
<many-to-one name="mergedFrom" column="merged_from"
|
||||
class="AVMNodeBeanImpl">
|
||||
</many-to-one>
|
||||
<many-to-one name="parent" column="parent_id"
|
||||
class="DirectoryNodeBeanImpl">
|
||||
</many-to-one>
|
||||
<!-- This should really be not null, but hibernate doesn't provide
|
||||
a way of saving both a RepositoryBean and an AVMNodeBean,
|
||||
that refer to new instances of each other. -->
|
||||
<many-to-one name="repository" column="repository"
|
||||
class="RepositoryBeanImpl" cascade="save-update">
|
||||
</many-to-one>
|
||||
<property name="versionID" type="long" column="version_id"
|
||||
not-null="true">
|
||||
</property>
|
||||
<property name="branchID" type="long" column="branch_id"
|
||||
not-null="true">
|
||||
</property>
|
||||
<property name="isNew" column="is_new" type="boolean"
|
||||
not-null="true">
|
||||
</property>
|
||||
<subclass name="DirectoryNodeBeanImpl"
|
||||
proxy="DirectoryNodeBean"
|
||||
abstract="true">
|
||||
<subclass
|
||||
name="LayeredDirectoryNodeBeanImpl"
|
||||
proxy="LayeredDirectoryNodeBean" discriminator-value="layereddirectory">
|
||||
<property name="layerID" column="layer_id" type="long"></property>
|
||||
<property name="indirection" column="indirection" type="string" length="511"></property>
|
||||
<property name="primaryIndirection" column="primary_indirection" type="boolean"></property>
|
||||
<map name="added" cascade="all">
|
||||
<key column="directory_id"></key>
|
||||
<map-key type="string" column="name"></map-key>
|
||||
<composite-element class="org.alfresco.repo.avm.hibernate.DirectoryEntry">
|
||||
<property name="type" column="type_name"
|
||||
type="string" length="30" not-null="true">
|
||||
</property>
|
||||
<many-to-one name="child"
|
||||
class="org.alfresco.repo.avm.hibernate.AVMNodeBeanImpl"
|
||||
cascade="save-update" not-null="true">
|
||||
</many-to-one>
|
||||
</composite-element>
|
||||
</map>
|
||||
<set name="deleted" table="deleted_children"
|
||||
fetch="join" cascade="all">
|
||||
<key column="directory_id"></key>
|
||||
<element type="string" column="name"></element>
|
||||
</set>
|
||||
</subclass>
|
||||
<subclass name="PlainDirectoryNodeBeanImpl"
|
||||
discriminator-value="plaindirectory" proxy="PlainDirectoryNodeBean">
|
||||
<property name="isRoot" column="is_root" type="boolean"/>
|
||||
<map name="children" cascade="all">
|
||||
<key column="directory_id"></key>
|
||||
<map-key type="string" column="name"></map-key>
|
||||
<composite-element class="org.alfresco.repo.avm.hibernate.DirectoryEntry">
|
||||
<property name="type" type="string" not-null="true" length="30" column="type_name">
|
||||
</property>
|
||||
<many-to-one name="child"
|
||||
class="org.alfresco.repo.avm.hibernate.AVMNodeBeanImpl"
|
||||
not-null="true" cascade="save-update">
|
||||
</many-to-one>
|
||||
</composite-element>
|
||||
</map>
|
||||
</subclass>
|
||||
</subclass>
|
||||
<subclass name="FileNodeBeanImpl"
|
||||
proxy="FileNodeBean"
|
||||
abstract="true">
|
||||
<subclass discriminator-value="plainfile"
|
||||
name="PlainFileNodeBeanImpl"
|
||||
proxy="PlainFileNodeBean">
|
||||
<many-to-one name="content" column="content_id"
|
||||
class="ContentBeanImpl" fetch="join" cascade="save-update">
|
||||
</many-to-one>
|
||||
</subclass>
|
||||
<subclass name="LayeredFileNodeBeanImpl"
|
||||
discriminator-value="layeredfile" proxy="LayeredFileNodeBean">
|
||||
<property name="indirection" type="string" length="511" column="indirection"></property>
|
||||
</subclass>
|
||||
</subclass>
|
||||
</class>
|
||||
<class name="BasicAttributesBeanImpl" proxy="BasicAttributesBean"
|
||||
lazy="true" optimistic-lock="version" table="basic_attributes">
|
||||
<id name="id" type="long">
|
||||
<generator class="native"></generator>
|
||||
</id>
|
||||
<version column="vers" name="vers" type="long"></version>
|
||||
<property name="creator" type="string" not-null="true"></property>
|
||||
<property name="owner" type="string" not-null="true"></property>
|
||||
<property name="lastModifier" type="string" not-null="true"></property>
|
||||
<property name="createDate" type="long" not-null="true"></property>
|
||||
<property name="modDate" type="long" not-null="true"></property>
|
||||
<property name="accessDate" type="long" not-null="true"></property>
|
||||
</class>
|
||||
</hibernate-mapping>
|
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
<hibernate-mapping package="org.alfresco.repo.avm.hibernate">
|
||||
<class table="contents" name="ContentBeanImpl" proxy="ContentBean"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="id" column="id" type="long">
|
||||
</id>
|
||||
<version name="vers" column="vers" type="long"></version>
|
||||
<property name="refCount" column="ref_count" type="int"
|
||||
not-null="true">
|
||||
</property>
|
||||
</class>
|
||||
</hibernate-mapping>
|
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
<hibernate-mapping package="org.alfresco.repo.avm.hibernate">
|
||||
<class name="Issuer" table="issuers" lazy="false"
|
||||
optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="name" column="name" type="string" length="20"></id>
|
||||
<version name="vers" column="vers" type="long"></version>
|
||||
<property name="next" column="next" type="long"
|
||||
not-null="true">
|
||||
</property>
|
||||
</class>
|
||||
</hibernate-mapping>
|
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
<hibernate-mapping package="org.alfresco.repo.avm.hibernate">
|
||||
<class table="repositories" name="RepositoryBeanImpl"
|
||||
proxy="RepositoryBean" optimistic-lock="version">
|
||||
<cache usage="read-write" />
|
||||
<id name="name" column="name" type="string"></id>
|
||||
<version name="vers" column="vers" type="long"></version>
|
||||
<property type="long" name="nextVersionID"
|
||||
column="next_version_id" not-null="true">
|
||||
</property>
|
||||
<!-- This should be not-null but hibernate makes that difficult. -->
|
||||
<many-to-one name="root" class="DirectoryNodeBeanImpl"
|
||||
column="current_root_id" unique="true" cascade="save-update">
|
||||
</many-to-one>
|
||||
<map name="roots" table="repository_roots">
|
||||
<key column="repository_id"></key>
|
||||
<map-key type="long" column="version_id"></map-key>
|
||||
<many-to-many class="DirectoryNodeBeanImpl"
|
||||
column="directory_id">
|
||||
</many-to-many>
|
||||
</map>
|
||||
<set table="new_nodes" name="newNodes" cascade="all">
|
||||
<key column="repository_id"></key>
|
||||
<many-to-many class="AVMNodeBeanImpl"
|
||||
column="new_node_id">
|
||||
</many-to-many>
|
||||
</set>
|
||||
</class>
|
||||
</hibernate-mapping>
|
@@ -201,6 +201,7 @@ public class TestPopulate extends TestCase
|
||||
{
|
||||
assertEquals(AVMNodeType.PLAIN_FILE, entry.getEntryType());
|
||||
}
|
||||
assertEquals("britt", root.getBasicAttributes().getCreator());
|
||||
}
|
||||
});
|
||||
assertTrue(result);
|
||||
|
@@ -54,6 +54,11 @@ public class AVMServiceImpl implements AVMService
|
||||
*/
|
||||
private ThreadLocal<SuperRepository> fSuperRepository;
|
||||
|
||||
/**
|
||||
* The storage directory.
|
||||
*/
|
||||
private String fStorage;
|
||||
|
||||
/**
|
||||
* Basic constructor for the service.
|
||||
*/
|
||||
@@ -63,6 +68,15 @@ public class AVMServiceImpl implements AVMService
|
||||
fTransaction = new HibernateTxn(fSessionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of file storage.
|
||||
* @param storage
|
||||
*/
|
||||
public void setStorage(String storage)
|
||||
{
|
||||
fStorage = storage;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.avm.AVMService#getFileInputStream(int, java.lang.String)
|
||||
*/
|
||||
@@ -74,7 +88,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
in = fSuperRepository.get().getInputStream(version, path);
|
||||
}
|
||||
};
|
||||
@@ -94,7 +108,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
out = fSuperRepository.get().getOutputStream(path);
|
||||
}
|
||||
};
|
||||
@@ -114,7 +128,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
listing = fSuperRepository.get().getListing(version, path);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +146,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createFile(path, name);
|
||||
}
|
||||
}
|
||||
@@ -149,7 +163,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createDirectory(path, name);
|
||||
}
|
||||
}
|
||||
@@ -166,7 +180,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createLayeredFile(srcPath, parent, name);
|
||||
}
|
||||
}
|
||||
@@ -183,7 +197,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createLayeredDirectory(srcPath, parent, name);
|
||||
}
|
||||
}
|
||||
@@ -200,7 +214,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createRepository(name);
|
||||
}
|
||||
}
|
||||
@@ -218,7 +232,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createBranch(version, srcPath, dstPath, name);
|
||||
}
|
||||
}
|
||||
@@ -235,7 +249,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().remove(parent, name);
|
||||
}
|
||||
}
|
||||
@@ -253,7 +267,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().rename(srcParent, srcName, dstParent, dstName);
|
||||
}
|
||||
}
|
||||
@@ -271,7 +285,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().slide(srcParent, srcName, dstParent, dstName);
|
||||
}
|
||||
}
|
||||
@@ -290,7 +304,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
latestVersionID = fSuperRepository.get().getLatestVersionID(repName);
|
||||
}
|
||||
}
|
||||
@@ -308,7 +322,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().createSnapshot(repositories);
|
||||
}
|
||||
}
|
||||
@@ -327,7 +341,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
lookup = fSuperRepository.get().lookup(version, path);
|
||||
}
|
||||
}
|
||||
@@ -345,7 +359,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().destroyRepository(name);
|
||||
}
|
||||
}
|
||||
@@ -362,7 +376,7 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
fSuperRepository.get().purgeVersion(name, version);
|
||||
}
|
||||
}
|
||||
@@ -381,7 +395,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
indirectionPath = fSuperRepository.get().getIndirectionPath(version, path);
|
||||
}
|
||||
}
|
||||
@@ -401,7 +415,7 @@ public class AVMServiceImpl implements AVMService
|
||||
|
||||
public void perform(Session session)
|
||||
{
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session));
|
||||
fSuperRepository.set(new SuperRepositoryImpl(session, fStorage));
|
||||
versions = fSuperRepository.get().getRepositoryVersions(name);
|
||||
}
|
||||
}
|
||||
|
@@ -70,14 +70,21 @@ public class SuperRepositoryImpl implements SuperRepository
|
||||
* The layer id issuer.
|
||||
*/
|
||||
private Issuer fLayerIssuer;
|
||||
|
||||
/**
|
||||
* The file storage directory.
|
||||
*/
|
||||
private String fStorage;
|
||||
|
||||
/**
|
||||
* Make a new one, initialized with the session.
|
||||
* @param session The session for this operation.
|
||||
* @param storage Where file data gets stored.
|
||||
*/
|
||||
public SuperRepositoryImpl(Session session)
|
||||
public SuperRepositoryImpl(Session session, String storage)
|
||||
{
|
||||
fSession = session;
|
||||
fStorage = storage;
|
||||
fNodeIssuer = (Issuer)fSession.get(Issuer.class, "node");
|
||||
fContentIssuer = (Issuer)fSession.get(Issuer.class, "content");
|
||||
fBranchIssuer = (Issuer)fSession.get(Issuer.class, "branch");
|
||||
@@ -506,4 +513,12 @@ public class SuperRepositoryImpl implements SuperRepository
|
||||
}
|
||||
return pathParts;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.avm.SuperRepository#getStorageRoot()
|
||||
*/
|
||||
public String getStorageRoot()
|
||||
{
|
||||
return fStorage;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user