Extended the content model to include relevant avm specific types.

cm:avmcontent and cm:avmfolder are 'abstract'.  cm:avmplaincontent is derived
from cm:avmcontent and is just a plain file. cm:avmlayeredcontent is derived
from cm:avmcontent and is (surprise) a layered file and has a d:noderef mandatory
property, cm:avmfileindirection, that is the (possibly non-existent) file that
the layered file is transparent to.  cm:avmplainfolder is derived from 
cm:avmfolder and is just a plain directory.  cm:avmlayeredfolder is a layered
directory and has a property, cm:avmdirinderection, that is the (possibly
non-existent) directory that the layered directory is transparent to.
The ContentModel QName constants are.
TYPE_AVM_PLAIN_FOLDER
TYPE_AVM_LAYERED_FOLDER
TYPE_AVM_PLAIN_CONTENT
TYPE_AVM_LAYERED_CONTENT
PROP_AVM_DIR_INDIRECTION
PROP_AVM_FILE_INDIRECTION
One can now create all four flavors of avm nodes through 
AVMNodeService.createNode().  The advantage of using these over the
corresponding AVMService methods is that since (for now) AVMService, is
permission and indexing unaware.
Backed out cm:mounted aspect and dispatching code in DbNodeServiceImpl.  
(Dave and Derek, you may now relax) as we are implementing the UI with
AVM dedicated screens.
Finally, beginning interface for AVM node tree synchronization and comparison.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3764 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-09-12 03:16:10 +00:00
parent 979ca93112
commit be6a222554
8 changed files with 256 additions and 108 deletions

View File

@@ -98,6 +98,12 @@ public interface ContentModel
static final QName TYPE_CONTENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
static final QName PROP_CONTENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
static final QName TYPE_AVM_CONTENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmcontent");
static final QName TYPE_AVM_PLAIN_CONTENT =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmplaincontent");
static final QName TYPE_AVM_LAYERED_CONTENT =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmlayeredcontent");
static final QName PROP_AVM_FILE_INDIRECTION =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmfileindirection");
// title aspect
static final QName ASPECT_TITLED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "titled");
@@ -133,8 +139,8 @@ public interface ContentModel
public final static QName PROP_EXPIRY_DATE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "expiryDate");
// version aspect
static final QName ASPECT_VERSIONABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "versionable");
static final QName PROP_VERSION_LABEL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "versionLabel");
static final QName ASPECT_VERSIONABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "versionable");
static final QName PROP_VERSION_LABEL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "versionLabel");
static final QName PROP_INITIAL_VERSION = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "initialVersion");
static final QName PROP_AUTO_VERSION = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "autoVersion");
@@ -144,6 +150,12 @@ public interface ContentModel
/** child association type supported by {@link #TYPE_FOLDER} */
static final QName ASSOC_CONTAINS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "contains");
static final QName TYPE_AVM_FOLDER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmfolder");
static final QName TYPE_AVM_PLAIN_FOLDER =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmplainfolder");
static final QName TYPE_AVM_LAYERED_FOLDER =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmlayeredfolder");
static final QName PROP_AVM_DIR_INDIRECTION =
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "avmdirindirection");
// person
static final QName TYPE_PERSON = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "person");

View File

@@ -437,48 +437,6 @@ public class AVMInterpreter
AVMNodeDescriptor ca = fService.getCommonAncestor(left, right);
out.println(ca);
}
else if (command[0].equals("mount"))
{
if (command.length != 5)
{
return "Syntax Error.";
}
int version = Integer.parseInt(command[1]);
String avmPath = command[2];
String alfPath = command[3];
String mountName = command[4];
String [] components = alfPath.split("/");
NodeRef nodeRef = fNodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"));
for (String name : components)
{
fgLogger.error(name);
List<ChildAssociationRef> children =
fNodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef child : children)
{
fgLogger.error(" " + child.getQName());
if (child.getQName().getLocalName().equals(name))
{
nodeRef = child.getChildRef();
break;
}
}
}
Map<QName, Serializable> properties =
new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_NAME, mountName);
ChildAssociationRef childRef =
fNodeService.createNode(nodeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.APP_MODEL_1_0_URI, mountName),
ContentModel.TYPE_FOLDER,
properties);
properties.clear();
properties.put(ContentModel.PROP_MOUNTPOINT,
AVMNodeConverter.ToNodeRef(version, avmPath));
fNodeService.addAspect(childRef.getChildRef(),
ContentModel.ASPECT_MOUNTED,
properties);
}
else
{
return "Syntax Error.";

View File

@@ -268,16 +268,36 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
// Do the creates for supported types, or error out.
try
{
if (nodeTypeQName.equals(ContentModel.TYPE_AVM_FOLDER) ||
if (nodeTypeQName.equals(ContentModel.TYPE_AVM_PLAIN_FOLDER) ||
nodeTypeQName.equals(ContentModel.TYPE_FOLDER))
{
fAVMService.createDirectory(avmPath, nodeName);
}
else if (nodeTypeQName.equals(ContentModel.TYPE_AVM_CONTENT)
else if (nodeTypeQName.equals(ContentModel.TYPE_AVM_PLAIN_CONTENT)
||nodeTypeQName.equals(ContentModel.TYPE_CONTENT))
{
fAVMService.createFile(avmPath, nodeName);
}
else if (nodeTypeQName.equals(ContentModel.TYPE_AVM_LAYERED_CONTENT))
{
NodeRef indirection = (NodeRef)properties.get(ContentModel.PROP_AVM_FILE_INDIRECTION);
if (indirection == null)
{
throw new InvalidTypeException("No Indirection Property", nodeTypeQName);
}
Object [] indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection);
fAVMService.createLayeredFile((String)indVersionPath[1], avmPath, nodeName);
}
else if (nodeTypeQName.equals(ContentModel.TYPE_AVM_LAYERED_FOLDER))
{
NodeRef indirection = (NodeRef)properties.get(ContentModel.PROP_AVM_DIR_INDIRECTION);
if (indirection == null)
{
throw new InvalidTypeException("No Indirection Property.", nodeTypeQName);
}
Object [] indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection);
fAVMService.createLayeredDirectory((String)indVersionPath[1], avmPath, nodeName);
}
else
{
throw new InvalidTypeException("Invalid node type for AVM.", nodeTypeQName);
@@ -450,14 +470,23 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
{
AVMNodeDescriptor desc = fAVMService.lookup((Integer)avmVersionPath[0],
(String)avmVersionPath[1]);
if (desc.isDirectory())
if (desc.isPlainDirectory())
{
return ContentModel.TYPE_AVM_FOLDER;
return ContentModel.TYPE_AVM_PLAIN_FOLDER;
}
else if (desc.isPlainFile())
{
return ContentModel.TYPE_AVM_PLAIN_CONTENT;
}
else if (desc.isLayeredDirectory())
{
return ContentModel.TYPE_AVM_LAYERED_FOLDER;
}
else
{
return ContentModel.TYPE_AVM_CONTENT;
return ContentModel.TYPE_AVM_LAYERED_CONTENT;
}
}
catch (AVMNotFoundException e)
{
@@ -845,6 +874,16 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
result.put(ContentModel.PROP_NODE_DBID, new Long(desc.getId()));
result.put(ContentModel.PROP_STORE_PROTOCOL, "avm");
result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
if (desc.isLayeredDirectory())
{
result.put(ContentModel.PROP_AVM_DIR_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()));
}
if (desc.isLayeredFile())
{
result.put(ContentModel.PROP_AVM_FILE_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()));
}
if (desc.isFile())
{
try
@@ -969,6 +1008,22 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
{
return nodeRef.getStoreRef().getIdentifier();
}
else if (qName.equals(ContentModel.PROP_AVM_DIR_INDIRECTION))
{
if (desc.isLayeredDirectory())
{
return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection());
}
return null;
}
else if (qName.equals(ContentModel.PROP_AVM_FILE_INDIRECTION))
{
if (desc.isLayeredFile())
{
return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection());
}
return null;
}
else
{
fgLogger.error("Invalid Built In Property: " + qName);
@@ -1002,14 +1057,17 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
Map<QName, PropertyValue> values = new HashMap<QName, PropertyValue>();
for (QName qName : properties.keySet())
{
// TODO This is until modification of built-in properties
// For AVM nodes is in place.
if (isBuiltInProperty(qName))
{
if (qName.equals(ContentModel.PROP_CONTENT))
{
fAVMService.setContentData((String)avmVersionPath[1],
(ContentData)properties.get(qName));
AVMNodeDescriptor desc = fAVMService.lookup(-1, (String)avmVersionPath[1]);
if (desc.isPlainFile())
{
fAVMService.setContentData((String)avmVersionPath[1],
(ContentData)properties.get(qName));
}
}
}
values.put(qName, new PropertyValue(null, properties.get(qName)));
@@ -1036,7 +1094,9 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi
ContentModel.PROP_NODE_UUID,
ContentModel.PROP_NODE_DBID,
ContentModel.PROP_STORE_PROTOCOL,
ContentModel.PROP_STORE_IDENTIFIER
ContentModel.PROP_STORE_IDENTIFIER,
ContentModel.PROP_AVM_FILE_INDIRECTION,
ContentModel.PROP_AVM_DIR_INDIRECTION
};
/**

View File

@@ -21,6 +21,7 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -41,8 +42,10 @@ import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.avm.LayeringDescriptor;
import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
@@ -2304,7 +2307,30 @@ public class AVMServiceTest extends AVMServiceTestBase
setupBasicTree();
FileFolderService ffs = (FileFolderService)fContext.getBean("FileFolderService");
assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c"),
"banana", ContentModel.TYPE_AVM_CONTENT) != null);
"banana", ContentModel.TYPE_AVM_PLAIN_CONTENT) != null);
assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c"),
"apples", ContentModel.TYPE_AVM_PLAIN_FOLDER) != null);
NodeService ns = (NodeService)fContext.getBean("NodeService");
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_AVM_DIR_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, "main:/a"));
assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"),
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "layer"),
ContentModel.TYPE_AVM_LAYERED_FOLDER,
properties) != null);
assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/layer"),
ContentModel.PROP_AVM_DIR_INDIRECTION) != null);
properties.clear();
properties.put(ContentModel.PROP_AVM_FILE_INDIRECTION,
AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"));
assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"),
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "foo"),
ContentModel.TYPE_AVM_LAYERED_CONTENT,
properties) != null);
assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/foo"),
ContentModel.PROP_AVM_FILE_INDIRECTION) != null);
fService.createSnapshot("main");
System.out.println(recursiveList("main", -1, true));
}

View File

@@ -31,7 +31,6 @@ import java.util.Stack;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMContext;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeAssoc;
@@ -253,20 +252,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
Assert.notNull(assocTypeQName);
Assert.notNull(assocQName);
// get the parent node
Node parentNode = getNodeNotNull(parentRef);
if (parentNode.getAspects().contains(ContentModel.ASPECT_MOUNTED))
{
NodeRef mounted = (NodeRef)parentNode.getProperties().get(ContentModel.PROP_MOUNTPOINT).
getValue(DataTypeDefinition.NODE_REF);
return AVMContext.fgInstance.getNodeService().createNode(mounted,
assocTypeQName,
assocQName,
nodeTypeQName,
properties);
}
// null property map is allowed
if (properties == null)
{
@@ -317,6 +302,9 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
propertiesAfter = setPropertiesImpl(childNode, properties);
}
// get the parent node
Node parentNode = getNodeNotNull(parentRef);
// create the association
ChildAssoc childAssoc = nodeDaoService.newChildAssoc(
parentNode,
@@ -724,15 +712,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
{
Node parentNode = getNodeNotNull(parentRef);
if (parentNode.getAspects().contains(ContentModel.ASPECT_MOUNTED))
{
NodeRef mounted =
(NodeRef)parentNode.getProperties().get(ContentModel.PROP_MOUNTPOINT).
getValue(DataTypeDefinition.NODE_REF);
AVMContext.fgInstance.getNodeService().removeChild(mounted, childRef);
return;
}
Node childNode = getNodeNotNull(childRef);
Long childNodeId = childNode.getId();
@@ -1017,14 +996,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public List<ChildAssociationRef> getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern)
{
Node node = getNodeNotNull(nodeRef);
if (node.getAspects().contains(ContentModel.ASPECT_MOUNTED))
{
NodeRef mounted = (NodeRef)node.getProperties().get(ContentModel.PROP_MOUNTPOINT).
getValue(DataTypeDefinition.NODE_REF);
return AVMContext.fgInstance.getNodeService().getChildAssocs(mounted,
typeQNamePattern,
qnamePattern);
}
// get the assocs pointing from it
Collection<ChildAssociationRef> childAssocRefs = nodeDaoService.getChildAssocRefs(node);
// shortcut if there are no assocs
@@ -1061,14 +1032,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public NodeRef getChildByName(NodeRef nodeRef, QName assocTypeQName, String childName)
{
Node node = getNodeNotNull(nodeRef);
if (node.getAspects().contains(ContentModel.ASPECT_MOUNTED))
{
NodeRef mounted = (NodeRef)node.getProperties().get(ContentModel.PROP_MOUNTPOINT).
getValue(DataTypeDefinition.NODE_REF);
return AVMContext.fgInstance.getNodeService().getChildByName(mounted,
assocTypeQName,
childName);
}
ChildAssoc childAssoc = nodeDaoService.getChildAssoc(node, assocTypeQName, childName);
if (childAssoc != null)
{

View File

@@ -0,0 +1,28 @@
/*
* 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.service.cmr.avmsync;
/**
* Represents the difference between corresponding nodes
* in parallel avm node trees. It it indicates for the difference
* whether the source is older, newer, or in conflict with the destination.
* @author britt
*/
public class AVMDifference
{
}

View File

@@ -0,0 +1,75 @@
/*
* 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.service.cmr.avmsync;
import java.util.List;
/**
* This service handles comparisons and synchronizations between
* corresponding avm node trees.
* @author britt
*/
public interface AvmSyncService
{
/**
* Get a difference list between two corresponding node trees.
* @param srcVersion The version id for the source tree.
* @param srcPath The avm path to the source tree.
* @param dstVersion The version id for the destination tree.
* @param dstPath The avm path to the destination tree.
* @return A List of AVMDifference structs which can be used for
* the update operation.
*/
public List<AVMDifference> compare(int srcVersion, String srcPath,
int dstVersion, String dstPath);
/**
* Updates the destination nodes in the AVMDifferences
* with the source nodes. Normally any conflicts or cases in
* which the source of an AVMDifference is older than the destination
* will cause the transaction to roll back.
* @param diffList A List of AVMDifference structs.
* @param ignoreConflicts If this is true the update will skip those
* AVMDifferences which are in conflict or for which the source is older than
* the destination.
* @param overrideConflicts If this is true the update will override conflicting
* AVMDifferences and replace the destination with the conflicting source.
* @param overrideOlder If this is true the update will override AVMDifferences
* in which the source is older than the destination and overwrite the destination.
*/
public void update(List<AVMDifference> diffList, boolean ignoreConflicts,
boolean overrideConflicts, boolean overrideOlder);
/**
* Flattens a layer so that all all nodes under and including
* <code>layerPath</code> become translucent to any nodes in the
* corresponding location under and including <code>underlyingPath</code>
* that are the same version.
* @param layerPath The overlying layer path.
* @param underlyingPath The underlying path.
*/
public void flatten(String layerPath, String underlyingPath);
/**
* Takes a layer, deletes it and recreates it pointing at the same underlying
* node. Any changes in the layer are lost (except to history if the layer has been
* snapshotted.)
* @param layerPath
*/
public void resetLayer(String layerPath);
}