Moving to root below branch label

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2005-12-08 07:13:07 +00:00
commit e1e6508fec
1095 changed files with 230566 additions and 0 deletions

View File

@@ -0,0 +1,281 @@
/*
* Copyright (C) 2005 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.version.common;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.policy.ClassPolicyDelegate;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.policy.PolicyScope;
import org.alfresco.repo.version.VersionServicePolicies;
import org.alfresco.repo.version.VersionServicePolicies.BeforeCreateVersionPolicy;
import org.alfresco.repo.version.VersionServicePolicies.CalculateVersionLabelPolicy;
import org.alfresco.repo.version.VersionServicePolicies.OnCreateVersionPolicy;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionServiceException;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
/**
* Abstract version service implementation.
*
* @author Roy Wetherall
*/
public abstract class AbstractVersionServiceImpl
{
/**
* The common node service
*/
protected NodeService nodeService ;
/**
* Policy component
*/
protected PolicyComponent policyComponent;
/**
* The dictionary service
*/
protected DictionaryService dictionaryService;
/**
* Policy delegates
*/
private ClassPolicyDelegate<BeforeCreateVersionPolicy> beforeCreateVersionDelegate;
private ClassPolicyDelegate<OnCreateVersionPolicy> onCreateVersionDelegate;
private ClassPolicyDelegate<CalculateVersionLabelPolicy> calculateVersionLabelDelegate;
/**
* Sets the general node service
*
* @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Sets the policy component
*
* @param policyComponent the policy component
*/
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
/**
* Sets the dictionary service
*
* @param dictionaryService the dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Initialise method
*/
public void initialise()
{
// Register the policies
this.beforeCreateVersionDelegate = this.policyComponent.registerClassPolicy(VersionServicePolicies.BeforeCreateVersionPolicy.class);
this.onCreateVersionDelegate = this.policyComponent.registerClassPolicy(VersionServicePolicies.OnCreateVersionPolicy.class);
this.calculateVersionLabelDelegate = this.policyComponent.registerClassPolicy(VersionServicePolicies.CalculateVersionLabelPolicy.class);
}
/**
* Invokes the before create version policy behaviour
*
* @param nodeRef the node being versioned
*/
protected void invokeBeforeCreateVersion(NodeRef nodeRef)
{
// invoke for node type
QName nodeTypeQName = nodeService.getType(nodeRef);
this.beforeCreateVersionDelegate.get(nodeTypeQName).beforeCreateVersion(nodeRef);
// invoke for node aspects
Set<QName> nodeAspectQNames = nodeService.getAspects(nodeRef);
this.beforeCreateVersionDelegate.get(nodeAspectQNames).beforeCreateVersion(nodeRef);
}
/**
* Invoke the on create version policy behaviour
*
*/
protected void invokeOnCreateVersion(
NodeRef nodeRef,
Map<String, Serializable> versionProperties,
PolicyScope nodeDetails)
{
// Sort out the policies for the node type
QName classRef = this.nodeService.getType(nodeRef);
invokeOnCreateVersion(classRef, nodeRef, versionProperties, nodeDetails);
// Sort out the policies for the aspects
Collection<QName> aspects = this.nodeService.getAspects(nodeRef);
for (QName aspect : aspects)
{
invokeOnCreateVersion(aspect, nodeRef, versionProperties, nodeDetails);
}
}
/**
* Invokes the on create version policy behaviour for a given type
*
* @param classRef
* @param nodeDetails
* @param nodeRef
* @param versionProperties
*/
private void invokeOnCreateVersion(
QName classRef,
NodeRef nodeRef,
Map<String, Serializable> versionProperties,
PolicyScope nodeDetails)
{
Collection<OnCreateVersionPolicy> policies = this.onCreateVersionDelegate.getList(classRef);
if (policies.size() == 0)
{
// Call the default implementation
defaultOnCreateVersion(
classRef,
nodeRef,
versionProperties,
nodeDetails);
}
else
{
// Call the policy definitions
for (VersionServicePolicies.OnCreateVersionPolicy policy : policies)
{
policy.onCreateVersion(
classRef,
nodeRef,
versionProperties,
nodeDetails);
}
}
}
/**
* Default implementation of the on create version policy. Called if no behaviour is registered for the
* policy for the specified type.
*
* @param nodeRef
* @param versionProperties
* @param nodeDetails
*/
protected void defaultOnCreateVersion(
QName classRef,
NodeRef nodeRef,
Map<String, Serializable> versionProperties,
PolicyScope nodeDetails)
{
ClassDefinition classDefinition = this.dictionaryService.getClass(classRef);
if (classDefinition != null)
{
// Copy the properties
Map<QName,PropertyDefinition> propertyDefinitions = classDefinition.getProperties();
for (QName propertyName : propertyDefinitions.keySet())
{
Serializable propValue = this.nodeService.getProperty(nodeRef, propertyName);
nodeDetails.addProperty(classRef, propertyName, propValue);
}
// Version the associations (child and target)
Map<QName, AssociationDefinition> assocDefs = classDefinition.getAssociations();
// TODO: Need way of getting child assocs of a given type
if (classDefinition.isContainer())
{
List<ChildAssociationRef> childAssocRefs = this.nodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef childAssocRef : childAssocRefs)
{
if (assocDefs.containsKey(childAssocRef.getTypeQName()))
{
nodeDetails.addChildAssociation(classDefinition.getName(), childAssocRef);
}
}
}
// TODO: Need way of getting assocs of a given type
List<AssociationRef> nodeAssocRefs = this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
for (AssociationRef nodeAssocRef : nodeAssocRefs)
{
if (assocDefs.containsKey(nodeAssocRef.getTypeQName()))
{
nodeDetails.addAssociation(classDefinition.getName(), nodeAssocRef);
}
}
}
}
/**
* Invoke the calculate version label policy behaviour
*
* @param classRef
* @param preceedingVersion
* @param versionNumber
* @param versionProperties
* @return
*/
protected String invokeCalculateVersionLabel(
QName classRef,
Version preceedingVersion,
int versionNumber,
Map<String, Serializable>versionProperties)
{
String versionLabel = null;
Collection<CalculateVersionLabelPolicy> behaviours = this.calculateVersionLabelDelegate.getList(classRef);
if (behaviours.size() == 0)
{
// Default the version label to the version numbder
versionLabel = Integer.toString(versionNumber);
}
else if (behaviours.size() == 1)
{
// Call the policy behaviour
CalculateVersionLabelPolicy[] arr = behaviours.toArray(new CalculateVersionLabelPolicy[]{});
versionLabel = arr[0].calculateVersionLabel(classRef, preceedingVersion, versionNumber, versionProperties);
}
else
{
// Error since we can only deal with a single caculate version label policy
throw new VersionServiceException("More than one CalculateVersionLabelPolicy behaviour has been registered for the type " + classRef.toString());
}
return versionLabel;
}
}

View File

@@ -0,0 +1,195 @@
/*
* Copyright (C) 2005 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.version.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionDoesNotExistException;
import org.alfresco.service.cmr.version.VersionHistory;
import org.alfresco.service.cmr.version.VersionServiceException;
/**
* Version History implementation.
*
* @author Roy Wetherall
*/
public class VersionHistoryImpl implements VersionHistory
{
/*
* Serial version UID
*/
private static final long serialVersionUID = 3257001051558326840L;
/*
* Error message(s)
*/
private static final String ERR_MSG = "The root version must be specified when creating a version history object.";
/*
* The root version label
*/
private String rootVersionLabel = null;
/*
* Version history tree structure map
*/
private HashMap<String, String> versionHistory = null;
/*
* Label to version object map
*/
private HashMap<String, Version> versions = null;
private Version rootVersion;
/**
* Constructor, ensures the root version is set.
*
* @param rootVersion the root version, can not be null.
*/
public VersionHistoryImpl(Version rootVersion)
{
if (rootVersion == null)
{
// Exception - a version history can not be created unless
// a root version is specified
throw new VersionServiceException(VersionHistoryImpl.ERR_MSG);
}
this.versionHistory = new HashMap<String, String>();
this.versions = new HashMap<String, Version>();
this.rootVersion = rootVersion;
this.rootVersionLabel = rootVersion.getVersionLabel();
addVersion(rootVersion, null);
}
/**
* Gets the root (or initial) version of the version history.
*
* @return the root version
*/
public Version getRootVersion()
{
return this.rootVersion;
}
/**
* Gets a collection containing all the versions within the
* version history.
* <p>
* The order of the versions is not guarenteed.
*
* @return collection containing all the versions
*/
public Collection<Version> getAllVersions()
{
return this.versions.values();
}
/**
* Gets the predecessor of a specified version
*
* @param version the version object
* @return the predeceeding version, null if root version
*/
public Version getPredecessor(Version version)
{
Version result = null;
if (version != null)
{
result = getVersion(this.versionHistory.get(version.getVersionLabel()));
}
return result;
}
/**
* Gets the succeeding versions of a specified version.
*
* @param version the version object
* @return a collection containing the succeeding version, empty is none
*/
public Collection<Version> getSuccessors(Version version)
{
ArrayList<Version> result = new ArrayList<Version>();
if (version != null)
{
String versionLabel = version.getVersionLabel();
if (this.versionHistory.containsValue(versionLabel) == true)
{
for (String key : this.versionHistory.keySet())
{
if (this.versionHistory.get(key) == versionLabel)
{
result.add(getVersion(key));
}
}
}
}
return result;
}
/**
* Gets a version with a specified version label. The version label is guarenteed
* unique within the version history.
*
* @param versionLabel the version label
* @return the version object
* @throws VersionDoesNotExistException indicates requested version does not exisit
*/
public Version getVersion(String versionLabel)
{
Version result = null;
if (versionLabel != null)
{
result = this.versions.get(versionLabel);
if (result == null)
{
// Throw exception indicating that the version does not exit
throw new VersionDoesNotExistException(versionLabel);
}
}
return result;
}
/**
* Add a version to the version history.
* <p>
* Used internally to build the version history tree.
*
* @param version the version object
* @param predecessor the preceeding version
*/
public void addVersion(Version version, Version predecessor)
{
// TODO cope with exception case where duplicate version labels have been specified
this.versions.put(version.getVersionLabel(), version);
if (predecessor != null)
{
this.versionHistory.put(version.getVersionLabel(), predecessor.getVersionLabel());
}
}
}

View File

@@ -0,0 +1,255 @@
/*
* Copyright (C) 2005 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.version.common;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import junit.framework.TestCase;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionDoesNotExistException;
import org.alfresco.service.cmr.version.VersionServiceException;
/**
* VersionHistoryImpl Unit Test Class
*
* @author Roy Wetherall
*/
public class VersionHistoryImplTest extends TestCase
{
/**
* Data used in the tests
*/
private Version rootVersion = null;
private Version childVersion1 = null;
private Version childVersion2 = null;
/**
* Set up
*/
protected void setUp() throws Exception
{
super.setUp();
// Create dummy node ref
NodeRef nodeRef = new NodeRef(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "test"), "test");
HashMap<String, Serializable> versionProperties1 = new HashMap<String, Serializable>();
versionProperties1.put(VersionModel.PROP_VERSION_LABEL, "1");
versionProperties1.put(VersionModel.PROP_CREATED_DATE, new Date());
versionProperties1.put("testProperty", "testValue");
this.rootVersion = new VersionImpl(versionProperties1, nodeRef);
HashMap<String, Serializable> versionProperties2 = new HashMap<String, Serializable>();
versionProperties2.put(VersionModel.PROP_VERSION_LABEL, "2");
versionProperties2.put(VersionModel.PROP_CREATED_DATE, new Date());
versionProperties2.put("testProperty", "testValue");
this.childVersion1 = new VersionImpl(versionProperties2, nodeRef);
HashMap<String, Serializable> versionProperties3 = new HashMap<String, Serializable>();
versionProperties3.put(VersionModel.PROP_VERSION_LABEL, "3");
versionProperties3.put(VersionModel.PROP_CREATED_DATE, new Date());
versionProperties3.put("testProperty", "testValue");
this.childVersion2 = new VersionImpl(versionProperties3, nodeRef);
}
/**
* Test constructor
*/
public void testConstructor()
{
testContructorImpl();
}
/**
* Test construtor helper
*
* @return new version history
*/
private VersionHistoryImpl testContructorImpl()
{
VersionHistoryImpl vh = new VersionHistoryImpl(this.rootVersion);
assertNotNull(vh);
return vh;
}
/**
* Exception case - a root version must be specified when creating a
* version history object
*/
public void testRootVersionSpecified()
{
try
{
new VersionHistoryImpl(null);
fail();
}
catch(VersionServiceException exception)
{
}
}
/**
* Test getRootVersion
*
*@return root version
*/
public void testGetRootVersion()
{
VersionHistoryImpl vh = testContructorImpl();
Version rootVersion = vh.getRootVersion();
assertNotNull(rootVersion);
assertEquals(rootVersion, this.rootVersion);
}
/**
* Test getAllVersions
*/
public void testGetAllVersions()
{
VersionHistoryImpl vh = testAddVersionImpl();
Collection<Version> allVersions = vh.getAllVersions();
assertNotNull(allVersions);
assertEquals(3, allVersions.size());
}
/**
* Test addVersion
*
* @return version history
*/
public void testAddVersion()
{
testAddVersionImpl();
}
/**
* Test addVersion helper
*
* @return version history with version tree built
*/
private VersionHistoryImpl testAddVersionImpl()
{
VersionHistoryImpl vh = testContructorImpl();
Version rootVersion = vh.getRootVersion();
vh.addVersion(this.childVersion1, rootVersion);
vh.addVersion(this.childVersion2, rootVersion);
return vh;
}
/**
* TODO Exception case - add version that has already been added
*/
/**
* TODO Exception case - add a version with a duplicate version label
*/
/**
* Test getPredecessor
*/
public void testGetPredecessor()
{
VersionHistoryImpl vh = testAddVersionImpl();
Version version1 = vh.getPredecessor(this.childVersion1);
assertEquals(version1.getVersionLabel(), this.rootVersion.getVersionLabel());
Version version2 = vh.getPredecessor(this.childVersion2);
assertEquals(version2.getVersionLabel(), this.rootVersion.getVersionLabel());
Version version3 = vh.getPredecessor(this.rootVersion);
assertNull(version3);
try
{
Version version4 = vh.getPredecessor(null);
assertNull(version4);
}
catch (Exception exception)
{
fail("Should continue by returning null.");
}
}
/**
* Test getSuccessors
*/
public void testGetSuccessors()
{
VersionHistoryImpl vh = testAddVersionImpl();
Collection<Version> versions1 = vh.getSuccessors(this.rootVersion);
assertNotNull(versions1);
assertEquals(versions1.size(), 2);
for (Version version : versions1)
{
String versionLabel = version.getVersionLabel();
if (!(versionLabel == "2" || versionLabel == "3"))
{
fail("There is a version in this collection that should not be here.");
}
}
Collection versions2 = vh.getSuccessors(this.childVersion1);
assertNotNull(versions2);
assertTrue(versions2.isEmpty());
Collection versions3 = vh.getSuccessors(this.childVersion2);
assertNotNull(versions3);
assertTrue(versions3.isEmpty());
}
/**
* Test getVersion
*/
public void testGetVersion()
{
VersionHistoryImpl vh = testAddVersionImpl();
Version version1 = vh.getVersion("1");
assertEquals(version1.getVersionLabel(), this.rootVersion.getVersionLabel());
Version version2 = vh.getVersion("2");
assertEquals(version2.getVersionLabel(), this.childVersion1.getVersionLabel());
Version version3 = vh.getVersion("3");
assertEquals(version3.getVersionLabel(), this.childVersion2.getVersionLabel());
try
{
vh.getVersion("invalidLabel");
fail("An exception should have been thrown if the version can not be retrieved.");
}
catch (VersionDoesNotExistException exception)
{
System.out.println("Error message: " + exception.getMessage());
}
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (C) 2005 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.version.common;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConverter;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionServiceException;
import org.alfresco.service.cmr.version.VersionType;
/**
* Version class implementation.
*
* Used to represent the data about a version stored in a version store.
*
* @author Roy Wetherall
*/
public class VersionImpl implements Version
{
/**
* Serial version UID
*/
private static final long serialVersionUID = 3257567304324888881L;
/**
* Error message(s)
*/
private static final String ERR_NO_NODE_REF = "A valid node reference must be supplied when creating a verison.";
/**
* The properties of the version
*/
private Map<String, Serializable> versionProperties = null;
/**
* The node reference that represents the frozen state of the versioned object
*/
private NodeRef nodeRef = null;
/**
* Constructor that initialises the state of the version object.
*
* @param versionProperties the version properties
* @param nodeRef the forzen state node reference
*/
public VersionImpl(
Map<String, Serializable> versionProperties,
NodeRef nodeRef)
{
if (nodeRef == null)
{
// Exception - a node ref must be specified
throw new VersionServiceException(VersionImpl.ERR_NO_NODE_REF);
}
this.versionProperties = versionProperties;
this.nodeRef = nodeRef;
}
/**
* Helper method to get the created date from the version property data.
*
* @return the date the version was created
*/
public Date getCreatedDate()
{
return (Date)this.versionProperties.get(VersionModel.PROP_CREATED_DATE);
}
public String getCreator()
{
return (String)this.versionProperties.get(VersionModel.PROP_CREATOR);
}
/**
* Helper method to get the version label from the version property data.
*
* @return the version label
*/
public String getVersionLabel()
{
return (String)this.versionProperties.get(VersionModel.PROP_VERSION_LABEL);
}
/**
* Helper method to get the version type.
*
* @return the value of the version type as an enum value
*/
public VersionType getVersionType()
{
return (VersionType)this.versionProperties.get(VersionModel.PROP_VERSION_TYPE);
}
/**
* Helper method to get the version description.
*
* @return the version description
*/
public String getDescription()
{
return (String)this.versionProperties.get(PROP_DESCRIPTION);
}
/**
* @see org.alfresco.service.cmr.version.Version#getVersionProperties()
*/
public Map<String, Serializable> getVersionProperties()
{
return this.versionProperties;
}
/**
* @see org.alfresco.service.cmr.version.Version#getVersionProperty(java.lang.String)
*/
public Serializable getVersionProperty(String name)
{
Serializable result = null;
if (this.versionProperties != null)
{
result = this.versionProperties.get(name);
}
return result;
}
/**
* @see org.alfresco.service.cmr.version.Version#getVersionedNodeRef()
*/
public NodeRef getVersionedNodeRef()
{
String storeProtocol = (String)this.versionProperties.get(VersionModel.PROP_FROZEN_NODE_STORE_PROTOCOL);
String storeId = (String)this.versionProperties.get(VersionModel.PROP_FROZEN_NODE_STORE_ID);
String nodeId = (String)this.versionProperties.get(VersionModel.PROP_FROZEN_NODE_ID);
return new NodeRef(new StoreRef(storeProtocol, storeId), nodeId);
}
/**
* @see org.alfresco.service.cmr.version.Version#getFrozenStateNodeRef()
*/
public NodeRef getFrozenStateNodeRef()
{
return this.nodeRef;
}
/**
* Static block to register the version type converters
*/
static
{
DefaultTypeConverter.INSTANCE.addConverter(
String.class,
VersionType.class,
new TypeConverter.Converter<String, VersionType>()
{
public VersionType convert(String source)
{
return VersionType.valueOf(source);
}
});
DefaultTypeConverter.INSTANCE.addConverter(
VersionType.class,
String.class,
new TypeConverter.Converter<VersionType, String>()
{
public String convert(VersionType source)
{
return source.toString();
}
});
}
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2005 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.version.common;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionServiceException;
import org.alfresco.service.cmr.version.VersionType;
import junit.framework.TestCase;
/**
* VersionImpl Unit Test
*
* @author Roy Wetherall
*/
public class VersionImplTest extends TestCase
{
/**
* Property names and values
*/
private final static String PROP_1 = "prop1";
private final static String PROP_2 = "prop2";
private final static String PROP_3 = "prop3";
private final static String VALUE_1 = "value1";
private final static String VALUE_2 = "value2";
private final static String VALUE_3 = "value3";
private final static String VALUE_DESCRIPTION = "This string describes the version details.";
private final static VersionType VERSION_TYPE = VersionType.MINOR;
private final static String USER_NAME = "userName";
/**
* Version labels
*/
private final static String VERSION_1 = "1";
/**
* Data used during tests
*/
private VersionImpl version = null;
private NodeRef nodeRef = null;
private Map<String, Serializable> versionProperties = null;
private Date createdDate = new Date();
/**
* Test case set up
*/
protected void setUp() throws Exception
{
super.setUp();
// Create the node reference
this.nodeRef = new NodeRef(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "testWS"), "testID");
assertNotNull(this.nodeRef);
// Create the version property map
this.versionProperties = new HashMap<String, Serializable>();
this.versionProperties.put(VersionModel.PROP_VERSION_LABEL, VERSION_1);
this.versionProperties.put(VersionModel.PROP_CREATED_DATE, this.createdDate);
this.versionProperties.put(VersionModel.PROP_CREATOR, USER_NAME);
this.versionProperties.put(Version.PROP_DESCRIPTION, VALUE_DESCRIPTION);
this.versionProperties.put(VersionModel.PROP_VERSION_TYPE, VERSION_TYPE);
this.versionProperties.put(PROP_1, VALUE_1);
this.versionProperties.put(PROP_2, VALUE_2);
this.versionProperties.put(PROP_3, VALUE_3);
// Create the root version
this.version = new VersionImpl(this.versionProperties, this.nodeRef);
assertNotNull(this.version);
}
/**
* Test getCreatedDate()
*/
public void testGetCreatedDate()
{
Date createdDate1 = this.version.getCreatedDate();
assertEquals(this.createdDate, createdDate1);
}
/**
* Test getCreator
*/
public void testGetCreator()
{
assertEquals(USER_NAME, this.version.getCreator());
}
/**
* Test getVersionLabel()
*/
public void testGetVersionLabel()
{
String versionLabel1 = this.version.getVersionLabel();
assertEquals(VersionImplTest.VERSION_1, versionLabel1);
}
/**
* Test getDescription
*/
public void testGetDescription()
{
String description = this.version.getDescription();
assertEquals(VALUE_DESCRIPTION, description);
}
/**
* Test getVersionType
*/
public void testGetVersionType()
{
VersionType versionType = this.version.getVersionType();
assertEquals(VERSION_TYPE, versionType);
}
/**
* Test getVersionProperties
*
*/
public void testGetVersionProperties()
{
Map<String, Serializable> versionProperties = version.getVersionProperties();
assertNotNull(versionProperties);
assertEquals(this.versionProperties.size(), versionProperties.size());
}
/**
* Test getVersionProperty
*/
public void testGetVersionProperty()
{
String value1 = (String)version.getVersionProperty(VersionImplTest.PROP_1);
assertEquals(value1, VersionImplTest.VALUE_1);
String value2 = (String)version.getVersionProperty(VersionImplTest.PROP_2);
assertEquals(value2, VersionImplTest.VALUE_2);
String value3 = (String)version.getVersionProperty(VersionImplTest.PROP_3);
assertEquals(value3, VersionImplTest.VALUE_3);
}
/**
* Test getNodeRef()
*/
public void testGetNodeRef()
{
NodeRef nodeRef = this.version.getFrozenStateNodeRef();
assertNotNull(nodeRef);
assertEquals(nodeRef.toString(), this.nodeRef.toString());
}
/**
* Exception case - no node ref supplied when creating a verison
*/
public void testNoNodeRefOnVersionCreate()
{
try
{
new VersionImpl(this.versionProperties, null);
fail("It is invalid to create a version object without a node ref specified.");
}
catch (VersionServiceException exception)
{
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2005 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.version.common;
import java.util.Collection;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.version.ReservedVersionNameException;
/**
* Helper class containing helper methods for the versioning services.
*
* @author Roy Wetherall
*/
public class VersionUtil
{
/**
* Reserved property names
*/
public static final String[] RESERVED_PROPERTY_NAMES = new String[]{
VersionModel.PROP_CREATED_DATE,
VersionModel.PROP_FROZEN_NODE_ID,
VersionModel.PROP_FROZEN_NODE_STORE_ID,
VersionModel.PROP_FROZEN_NODE_STORE_PROTOCOL,
VersionModel.PROP_FROZEN_NODE_TYPE,
VersionModel.PROP_FROZEN_ASPECTS,
VersionModel.PROP_VERSION_LABEL,
VersionModel.PROP_VERSION_NUMBER};
/**
* Checks that the names of the additional version properties are valid and that they do not clash
* with the reserved properties.
*
* @param versionProperties the property names
* @return true is the names are considered valid, false otherwise
* @throws ReservedVersionNameException
*/
public static void checkVersionPropertyNames(Collection<String> names)
throws ReservedVersionNameException
{
for (String name : RESERVED_PROPERTY_NAMES)
{
if (names.contains(name) == true)
{
throw new ReservedVersionNameException(name);
}
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005 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.version.common.counter;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* Version counter DAO service interface.
*
* @author Roy Wetherall
*/
public interface VersionCounterDaoService
{
/**
* Get the next available version number for the specified store.
*
* @param storeRef the store reference
* @return the next version number
*/
public int nextVersionNumber(StoreRef storeRef);
/**
* Gets the current version number for the specified store.
*
* @param storeRef the store reference
* @return the current versio number
*/
public int currentVersionNumber(StoreRef storeRef);
/**
* Resets the version number for a the specified store.
*
* WARNING: calling this method will completely reset the current
* version count for the specified store and cannot be undone.
*
* @param storeRef the store reference
*/
public void resetVersionNumber(StoreRef storeRef);
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2005 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.version.common.counter;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.BaseSpringTest;
/**
* @author Roy Wetherall
*/
public class VersionCounterDaoServiceTest extends BaseSpringTest
{
/*
* Test store id's
*/
private final static String STORE_ID_1 = "test1_" + System.currentTimeMillis();
private final static String STORE_ID_2 = "test2_" + System.currentTimeMillis();
private static final String STORE_NONE = "test3_" + System.currentTimeMillis();;
private NodeService nodeService;
private VersionCounterDaoService counter;
@Override
public void onSetUpInTransaction()
{
nodeService = (NodeService) applicationContext.getBean("dbNodeService");
counter = (VersionCounterDaoService) applicationContext.getBean("versionCounterDaoService");
}
public void testSetUp() throws Exception
{
assertNotNull(nodeService);
assertNotNull(counter);
}
/**
* Test nextVersionNumber
*/
public void testNextVersionNumber()
{
// Create the store references
StoreRef store1 = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionCounterDaoServiceTest.STORE_ID_1);
StoreRef store2 = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionCounterDaoServiceTest.STORE_ID_2);
StoreRef storeNone = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionCounterDaoServiceTest.STORE_NONE);
int store1Version0 = this.counter.nextVersionNumber(store1);
assertEquals(store1Version0, 1);
int store1Version1 = this.counter.nextVersionNumber(store1);
assertEquals(store1Version1, 2);
int store2Version0 = this.counter.nextVersionNumber(store2);
assertEquals(store2Version0, 1);
int store1Version2 = this.counter.nextVersionNumber(store1);
assertEquals(store1Version2, 3);
int store2Version1 = this.counter.nextVersionNumber(store2);
assertEquals(store2Version1, 2);
int store1Current = this.counter.currentVersionNumber(store1);
assertEquals(store1Current, 3);
int store2Current = this.counter.currentVersionNumber(store2);
assertEquals(store2Current, 2);
int storeNoneCurrent = this.counter.currentVersionNumber(storeNone);
assertEquals(storeNoneCurrent, 0);
// Need to clean-up since the version counter works in its own transaction
this.counter.resetVersionNumber(store1);
this.counter.resetVersionNumber(store2);
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2005 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.version.common.counter.hibernate;
import java.util.concurrent.locks.Lock;
import org.alfresco.repo.domain.StoreKey;
import org.alfresco.repo.domain.VersionCount;
import org.alfresco.repo.domain.hibernate.VersionCountImpl;
import org.alfresco.repo.version.common.counter.VersionCounterDaoService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Version counter DAO service implemtation using Hibernate.
* <p>
* The object should execute within its own transaction, and is limited to single-thread
* entry. If it becomes a bottleneck, the transaction synchronization should be moved
* over to reentrant locks and/or the hibernate mappings should be optimized for better
* read-write access.
*
* @author Derek Hulley
*/
public class HibernateVersionCounterDaoServiceImpl extends HibernateDaoSupport implements VersionCounterDaoService
{
private Lock countReadLock;
private Lock countWriteLock;
/**
* Retrieves or creates a version counter
*
* @param storeKey
* @return Returns a current or new version counter
*/
private VersionCount getVersionCounter(StoreRef storeRef)
{
StoreKey storeKey = new StoreKey(storeRef.getProtocol(), storeRef.getIdentifier());
// get the version counter
VersionCount versionCounter = (VersionCount) getHibernateTemplate().get(VersionCountImpl.class, storeKey);
// check if it exists
if (versionCounter == null)
{
// create a new one
versionCounter = new VersionCountImpl();
getHibernateTemplate().save(versionCounter, storeKey);
}
return versionCounter;
}
/**
* Get the next available version number for the specified store.
*
* @param storeRef the version store id
* @return the next version number
*/
public synchronized int nextVersionNumber(StoreRef storeRef)
{
// get the version counter
VersionCount versionCounter = getVersionCounter(storeRef);
// get an incremented count
return versionCounter.incrementVersionCount();
}
/**
* Gets the current version number for the specified store.
*
* @param storeRef the store reference
* @return the current version number, zero if no version yet allocated.
*/
public synchronized int currentVersionNumber(StoreRef storeRef)
{
// get the version counter
VersionCount versionCounter = getVersionCounter(storeRef);
// get an incremented count
return versionCounter.getVersionCount();
}
/**
* Resets the version number for a the specified store.
*
* WARNING: calling this method will completely reset the current
* version count for the specified store and cannot be undone.
*
* @param storeRef the store reference
*/
public synchronized void resetVersionNumber(StoreRef storeRef)
{
// get the version counter
VersionCount versionCounter = getVersionCounter(storeRef);
// get an incremented count
versionCounter.resetVersionCount();
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2005 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.version.common.versionlabel;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionType;
import org.alfresco.service.namespace.QName;
/**
* The serial version label policy.
*
* @author Roy Wetherall
*/
public class SerialVersionLabelPolicy
{
// TODO need to add support for branches into this labeling policy
/**
* Get the version label value base on the data provided.
*
* @param preceedingVersion the preceeding version, null if none
* @param versionNumber the new version number
* @param versionProperties the version property values
* @return the version label
*/
public String calculateVersionLabel(
QName classRef,
Version preceedingVersion,
int versionNumber,
Map<String, Serializable> versionProperties)
{
SerialVersionLabel serialVersionNumber = null;
if (preceedingVersion != null)
{
serialVersionNumber = new SerialVersionLabel(preceedingVersion.getVersionLabel());
VersionType versionType = (VersionType)versionProperties.get(VersionModel.PROP_VERSION_TYPE);
if (VersionType.MAJOR.equals(versionType) == true)
{
serialVersionNumber.majorIncrement();
}
else
{
serialVersionNumber.minorIncrement();
}
}
else
{
serialVersionNumber = new SerialVersionLabel(null);
}
return serialVersionNumber.toString();
}
/**
* Inner class encapsulating the notion of the serial version number.
*
* @author Roy Wetherall
*/
private class SerialVersionLabel
{
/**
* The version number delimiter
*/
private static final String DELIMITER = ".";
/**
* The major revision number
*/
private int majorRevisionNumber = 1;
/**
* The minor revision number
*/
private int minorRevisionNumber = 0;
/**
* Constructor
*
* @param version the vesion to take the version from
*/
public SerialVersionLabel(String versionLabel)
{
if (versionLabel != null && versionLabel.length() != 0)
{
int iIndex = versionLabel.indexOf(DELIMITER);
String majorString = versionLabel.substring(0, iIndex);
String minorString = versionLabel.substring(iIndex+1);
this.majorRevisionNumber = Integer.parseInt(majorString);
this.minorRevisionNumber = Integer.parseInt(minorString);
}
}
/**
* Increments the major revision numebr and sets the minor to
* zero.
*/
public void majorIncrement()
{
this.majorRevisionNumber += 1;
this.minorRevisionNumber = 0;
}
/**
* Increments only the minor revision number
*/
public void minorIncrement()
{
this.minorRevisionNumber += 1;
}
/**
* Converts the serial version number into a string
*/
public String toString()
{
return this.majorRevisionNumber + DELIMITER + this.minorRevisionNumber;
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2005 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.version.common.versionlabel;
import java.io.Serializable;
import java.util.HashMap;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.repo.version.common.VersionImpl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionType;
/**
* Unit test class for SerialVersionLabelPolicy class
*
* @author Roy Wetherall
*/
public class SerialVersionLabelPolicyTest extends TestCase
{
/**
* Test getVersionLabelValue
*/
public void testGetVersionLabelValue()
{
SerialVersionLabelPolicy policy = new SerialVersionLabelPolicy();
NodeRef dummyNodeRef = new NodeRef(new StoreRef("", ""), "");
HashMap<String, Serializable> versionProp1 = new HashMap<String, Serializable>();
versionProp1.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
String initialVersion = policy.calculateVersionLabel(
ContentModel.TYPE_CMOBJECT,
null,
0,
versionProp1);
assertEquals("1.0", initialVersion);
HashMap<String, Serializable> versionProp2 = new HashMap<String, Serializable>();
versionProp2.put(VersionModel.PROP_VERSION_LABEL, "1.0");
Version version1 = new VersionImpl(versionProp2, dummyNodeRef);
String verisonLabel1 = policy.calculateVersionLabel(
ContentModel.TYPE_CMOBJECT,
version1,
1,
versionProp1);
assertEquals("1.1", verisonLabel1);
HashMap<String, Serializable> versionProp3 = new HashMap<String, Serializable>();
versionProp3.put(VersionModel.PROP_VERSION_LABEL, "1.1");
Version version2 = new VersionImpl(versionProp3, dummyNodeRef);
HashMap<String, Serializable> versionProp4 = new HashMap<String, Serializable>();
versionProp4.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
String verisonLabel2 = policy.calculateVersionLabel(
ContentModel.TYPE_CMOBJECT,
version2,
1,
versionProp4);
assertEquals("2.0", verisonLabel2);
}
}