Heinous merge from HEAD. Seems to basically work. Be on guard however.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4137 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-10-18 02:24:36 +00:00
parent 6441f470f5
commit 111296d4dc
156 changed files with 18940 additions and 14167 deletions

View File

@@ -1,83 +1,83 @@
/*
* 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.domain;
import java.util.Set;
import org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl;
/**
* The interface to support persistence of node access control entries in hibernate
*
* @author andyh
*/
public interface DbAccessControlList
{
public long getId();
/**
*
* @return Returns the access control entries for this access control list
*/
public Set<DbAccessControlEntry> getEntries();
/**
* Get inheritance behaviour
* @return Returns the inheritance status of this list
*/
public boolean getInherits();
/**
* Set inheritance behaviour
* @param inherits true to set the permissions to inherit
*/
public void setInherits(boolean inherits);
public int deleteEntriesForAuthority(String authorityKey);
public int deleteEntriesForPermission(DbPermissionKey permissionKey);
public int deleteEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Delete the entries related to this access control list
*
* @return Returns the number of entries deleted
*/
public int deleteEntries();
public DbAccessControlEntry getEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Factory method to create an entry and wire it up.
* Note that the returned value may still be transient. Saving it should be fine, but
* is not required.
*
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority. Must not be transient.
* @param allowed allowed or disallowed. Must not be transient.
* @return Returns the new entry
*/
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
/**
* Make a copy of this ACL (persistently)
* @return The copy.
*/
public DbAccessControlList getCopy();
}
/*
* 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.domain;
import java.util.Set;
import org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl;
/**
* The interface to support persistence of node access control entries in hibernate
*
* @author andyh
*/
public interface DbAccessControlList
{
public long getId();
/**
*
* @return Returns the access control entries for this access control list
*/
public Set<DbAccessControlEntry> getEntries();
/**
* Get inheritance behaviour
* @return Returns the inheritance status of this list
*/
public boolean getInherits();
/**
* Set inheritance behaviour
* @param inherits true to set the permissions to inherit
*/
public void setInherits(boolean inherits);
public int deleteEntriesForAuthority(String authorityKey);
public int deleteEntriesForPermission(DbPermissionKey permissionKey);
public int deleteEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Delete the entries related to this access control list
*
* @return Returns the number of entries deleted
*/
public int deleteEntries();
public DbAccessControlEntry getEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Factory method to create an entry and wire it up.
* Note that the returned value may still be transient. Saving it should be fine, but
* is not required.
*
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority. Must not be transient.
* @param allowed allowed or disallowed. Must not be transient.
* @return Returns the new entry
*/
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
/**
* Make a copy of this ACL (persistently)
* @return The copy.
*/
public DbAccessControlList getCopy();
}

View File

@@ -19,6 +19,7 @@ package org.alfresco.repo.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -438,19 +439,32 @@ public class PropertyValue implements Cloneable, Serializable
*
* @return Returns the <code>ValueType</code> - never null
*/
private ValueType makeValueType(QName typeQName)
private static ValueType makeValueType(QName typeQName)
{
ValueType valueType = valueTypesByPropertyType.get(typeQName);
if (valueType == null)
{
throw new AlfrescoRuntimeException(
"Property type not recognised: \n" +
" type: " + typeQName + "\n" +
" property: " + this);
" type: " + typeQName);
}
return valueType;
}
/**
* Given an actual type qualified name, returns the <tt>String</tt> that represents it in
* the database.
*
* @param typeQName the type qualified name
* @return Returns the <tt>String</tt> representation of the type,
* e.g. <b>CONTENT</b> for type <b>d:content</b>.
*/
public static String getActualTypeString(QName typeQName)
{
ValueType valueType = makeValueType(typeQName);
return valueType.toString();
}
@Override
public boolean equals(Object obj)
{
@@ -632,15 +646,16 @@ public class PropertyValue implements Cloneable, Serializable
* @return Returns the value of this property as the desired type, or a <code>Collection</code>
* of values of the required type
*
* @throws java.lang.UnsupportedOperationException if the value cannot be converted to the
* type given
* @throws AlfrescoRuntimeException
* if the type given is not recognized
* @throws org.alfresco.service.cmr.repository.datatype.TypeConversionException
* if the conversion to the required type fails
*
* @see DataTypeDefinition#ANY The static qualified names for the types
*/
public Serializable getValue(QName typeQName)
{
// first check for null
ValueType requiredType = makeValueType(typeQName);
if (requiredType == ValueType.SERIALIZABLE)
{
@@ -680,6 +695,24 @@ public class PropertyValue implements Cloneable, Serializable
return ret;
}
/**
* Gets the value or values as a guaranteed collection.
*
* @see #getValue(QName)
*/
public Collection<Serializable> getCollection(QName typeQName)
{
Serializable value = getValue(typeQName);
if (value instanceof Collection)
{
return (Collection<Serializable>) value;
}
else
{
return Collections.singletonList(value);
}
}
public boolean getBooleanValue()
{
if (booleanValue == null)

View File

@@ -133,29 +133,6 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
return sb.toString();
}
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
else if (obj == this)
{
return true;
}
else if (!(obj instanceof ChildAssoc))
{
return false;
}
ChildAssoc that = (ChildAssoc) obj;
return EqualsHelper.nullSafeEquals(id, that.getId());
}
public int hashCode()
{
return (id == null ? 0 : id.hashCode());
}
/**
* Orders the child associations by ID. A smaller ID has a higher priority.
* This may change once we introduce a changeable index against which to order.

View File

@@ -1,250 +1,250 @@
/*
* 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.domain.hibernate;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
/**
* The hibernate persisted class for node permission entries.
*
* @author andyh
*/
public class DbAccessControlListImpl extends LifecycleAdapter
implements DbAccessControlList, Serializable
{
private static final long serialVersionUID = 3123277428227075648L;
private static Log logger = LogFactory.getLog(DbAccessControlListImpl.class);
private long id;
private Set<DbAccessControlEntry> entries;
private boolean inherits;
public DbAccessControlListImpl()
{
entries = new HashSet<DbAccessControlEntry>(5);
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(128);
sb.append("DbAccessControlListImpl")
.append("[ id=").append(id)
.append(", entries=").append(entries.size())
.append(", inherits=").append(inherits)
.append("]");
return sb.toString();
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof DbAccessControlList))
{
return false;
}
DbAccessControlList other = (DbAccessControlList) o;
return (this.inherits == other.getInherits());
}
@Override
public int hashCode()
{
return (inherits == false ? 0 : 17);
}
public long getId()
{
return id;
}
/**
* Hibernate use
*/
@SuppressWarnings("unused")
private void setId(long id)
{
this.id = id;
}
public Set<DbAccessControlEntry> getEntries()
{
return entries;
}
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setEntries(Set<DbAccessControlEntry> entries)
{
this.entries = entries;
}
public boolean getInherits()
{
return inherits;
}
public void setInherits(boolean inherits)
{
this.inherits = inherits;
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForAuthority(String authority)
{
return deleteEntry(authority, null);
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForPermission(DbPermissionKey permissionKey)
{
return deleteEntry(null, permissionKey);
}
public int deleteEntry(String authority, DbPermissionKey permissionKey)
{
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(2);
for (DbAccessControlEntry entry : entries)
{
if (authority != null && !authority.equals(entry.getAuthority().getRecipient()))
{
// authority is not a match
continue;
}
else if (permissionKey != null && !permissionKey.equals(entry.getPermission().getKey()))
{
// permission is not a match
continue;
}
toDelete.add(entry);
}
// delete them
for (DbAccessControlEntry entry : toDelete)
{
// remove from the entry list
entry.delete();
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + toDelete.size() + " access entries: \n" +
" access control list: " + id + "\n" +
" authority: " + authority + "\n" +
" permission: " + permissionKey);
}
return toDelete.size();
}
public int deleteEntries()
{
/*
* We don't do the full delete-remove-from-set thing here. Just delete each child entity
* and then clear the entry set.
*/
Session session = getSession();
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(entries);
// delete each entry
for (DbAccessControlEntry entry : toDelete)
{
session.delete(entry);
}
// clear the list
int count = entries.size();
entries.clear();
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
public DbAccessControlEntry getEntry(String authority, DbPermissionKey permissionKey)
{
for (DbAccessControlEntry entry : entries)
{
DbAuthority authorityEntity = entry.getAuthority();
DbPermission permissionEntity = entry.getPermission();
// check for a match
if (authorityEntity.getRecipient().equals(authority)
&& permissionEntity.getKey().equals(permissionKey))
{
// found it
return entry;
}
}
return null;
}
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
// fill
accessControlEntry.setAccessControlList(this);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
// save it
getSession().save(accessControlEntry);
// maintain inverse set on the acl
getEntries().add(accessControlEntry);
// done
return accessControlEntry;
}
/**
* Make a copy of this ACL.
* @return The copy.
*/
public DbAccessControlList getCopy()
{
DbAccessControlList newAcl =
new DbAccessControlListImpl();
getSession().save(newAcl);
for (DbAccessControlEntry entry : entries)
{
newAcl.newEntry(entry.getPermission(), entry.getAuthority(), entry.isAllowed());
}
return newAcl;
}
}
/*
* 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.domain.hibernate;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
/**
* The hibernate persisted class for node permission entries.
*
* @author andyh
*/
public class DbAccessControlListImpl extends LifecycleAdapter
implements DbAccessControlList, Serializable
{
private static final long serialVersionUID = 3123277428227075648L;
private static Log logger = LogFactory.getLog(DbAccessControlListImpl.class);
private long id;
private Set<DbAccessControlEntry> entries;
private boolean inherits;
public DbAccessControlListImpl()
{
entries = new HashSet<DbAccessControlEntry>(5);
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(128);
sb.append("DbAccessControlListImpl")
.append("[ id=").append(id)
.append(", entries=").append(entries.size())
.append(", inherits=").append(inherits)
.append("]");
return sb.toString();
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof DbAccessControlList))
{
return false;
}
DbAccessControlList other = (DbAccessControlList) o;
return (this.inherits == other.getInherits());
}
@Override
public int hashCode()
{
return (inherits == false ? 0 : 17);
}
public long getId()
{
return id;
}
/**
* Hibernate use
*/
@SuppressWarnings("unused")
private void setId(long id)
{
this.id = id;
}
public Set<DbAccessControlEntry> getEntries()
{
return entries;
}
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setEntries(Set<DbAccessControlEntry> entries)
{
this.entries = entries;
}
public boolean getInherits()
{
return inherits;
}
public void setInherits(boolean inherits)
{
this.inherits = inherits;
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForAuthority(String authority)
{
return deleteEntry(authority, null);
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForPermission(DbPermissionKey permissionKey)
{
return deleteEntry(null, permissionKey);
}
public int deleteEntry(String authority, DbPermissionKey permissionKey)
{
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(2);
for (DbAccessControlEntry entry : entries)
{
if (authority != null && !authority.equals(entry.getAuthority().getRecipient()))
{
// authority is not a match
continue;
}
else if (permissionKey != null && !permissionKey.equals(entry.getPermission().getKey()))
{
// permission is not a match
continue;
}
toDelete.add(entry);
}
// delete them
for (DbAccessControlEntry entry : toDelete)
{
// remove from the entry list
entry.delete();
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + toDelete.size() + " access entries: \n" +
" access control list: " + id + "\n" +
" authority: " + authority + "\n" +
" permission: " + permissionKey);
}
return toDelete.size();
}
public int deleteEntries()
{
/*
* We don't do the full delete-remove-from-set thing here. Just delete each child entity
* and then clear the entry set.
*/
Session session = getSession();
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(entries);
// delete each entry
for (DbAccessControlEntry entry : toDelete)
{
session.delete(entry);
}
// clear the list
int count = entries.size();
entries.clear();
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
public DbAccessControlEntry getEntry(String authority, DbPermissionKey permissionKey)
{
for (DbAccessControlEntry entry : entries)
{
DbAuthority authorityEntity = entry.getAuthority();
DbPermission permissionEntity = entry.getPermission();
// check for a match
if (authorityEntity.getRecipient().equals(authority)
&& permissionEntity.getKey().equals(permissionKey))
{
// found it
return entry;
}
}
return null;
}
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
// fill
accessControlEntry.setAccessControlList(this);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
// save it
getSession().save(accessControlEntry);
// maintain inverse set on the acl
getEntries().add(accessControlEntry);
// done
return accessControlEntry;
}
/**
* Make a copy of this ACL.
* @return The copy.
*/
public DbAccessControlList getCopy()
{
DbAccessControlList newAcl =
new DbAccessControlListImpl();
getSession().save(newAcl);
for (DbAccessControlEntry entry : entries)
{
newAcl.newEntry(entry.getPermission(), entry.getAuthority(), entry.isAllowed());
}
return newAcl;
}
}

View File

@@ -1,456 +1,462 @@
/*
* 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.domain.hibernate;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.repo.domain.NodeStatus;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Server;
import org.alfresco.repo.domain.Store;
import org.alfresco.repo.domain.StoreKey;
import org.alfresco.repo.domain.Transaction;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.hibernate.CacheMode;
import org.hibernate.exception.ConstraintViolationException;
/**
* Test persistence and retrieval of Hibernate-specific implementations of the
* {@link org.alfresco.repo.domain.Node} interface
*
* @author Derek Hulley
*/
@SuppressWarnings("unused")
public class HibernateNodeTest extends BaseSpringTest
{
private static final String TEST_NAMESPACE = "http://www.alfresco.org/test/HibernateNodeTest";
private static int i = 0;
private Store store;
private Server server;
private Transaction transaction;
public HibernateNodeTest()
{
}
protected void onSetUpInTransaction() throws Exception
{
store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + System.currentTimeMillis() + " - " + System.nanoTime());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
getSession().save(transaction);
}
protected void onTearDownInTransaction()
{
// force a flush to ensure that the database updates succeed
getSession().flush();
getSession().clear();
}
public void testSetUp() throws Exception
{
assertNotNull("Workspace not initialised", store);
}
public void testGetStore() throws Exception
{
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
// now it should work
Serializable id = getSession().save(node);
// throw the reference away and get the a new one for the id
node = (Node) getSession().load(NodeImpl.class, id);
assertNotNull("Node not found", node);
// check that the store has been loaded
Store loadedStore = node.getStore();
assertNotNull("Store not present on node", loadedStore);
assertEquals("Incorrect store key", store, loadedStore);
}
public void testNodeStatus()
{
NodeKey key = new NodeKey(store.getKey(), "AAA");
// create the node status
NodeStatus nodeStatus = new NodeStatusImpl();
nodeStatus.setKey(key);
nodeStatus.setTransaction(transaction);
getSession().save(nodeStatus);
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
Serializable nodeId = getSession().save(node);
// This should all be fine. The node does not HAVE to have a status.
flushAndClear();
// set the node
nodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, key);
nodeStatus.setNode(node);
flushAndClear();
// is the node retrievable?
nodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, key);
node = nodeStatus.getNode();
assertNotNull("Node was not attached to status", node);
// change the values
transaction.setChangeTxnId("txn:456");
// delete the node
getSession().delete(node);
try
{
flushAndClear();
fail("Node status may not refer to non-existent node");
}
catch(ConstraintViolationException e)
{
// expected
}
}
/**
* Check that properties can be persisted and retrieved
*/
public void testProperties() throws Exception
{
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
// give it a property map
Map<QName, PropertyValue> propertyMap = new HashMap<QName, PropertyValue>(5);
QName propertyQName = QName.createQName("{}A");
PropertyValue propertyValue = new PropertyValue(DataTypeDefinition.TEXT, "AAA");
propertyMap.put(propertyQName, propertyValue);
node.getProperties().putAll(propertyMap);
// persist it
Serializable id = getSession().save(node);
// throw the reference away and get the a new one for the id
node = (Node) getSession().load(NodeImpl.class, id);
assertNotNull("Node not found", node);
// extract the Map
propertyMap = node.getProperties();
assertNotNull("Map not persisted", propertyMap);
// ensure that the value is present
assertNotNull("Property value not present in map", QName.createQName("{}A"));
}
/**
* Check that aspect qnames can be added and removed from a node and that they
* are persisted correctly
*/
public void testAspects() throws Exception
{
// make a real node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CMOBJECT);
// add some aspects
QName aspect1 = QName.createQName(TEST_NAMESPACE, "1");
QName aspect2 = QName.createQName(TEST_NAMESPACE, "2");
QName aspect3 = QName.createQName(TEST_NAMESPACE, "3");
QName aspect4 = QName.createQName(TEST_NAMESPACE, "4");
Set<QName> aspects = node.getAspects();
aspects.add(aspect1);
aspects.add(aspect2);
aspects.add(aspect3);
aspects.add(aspect4);
assertFalse("Set did not eliminate duplicate aspect qname", aspects.add(aspect4));
// persist
Serializable id = getSession().save(node);
// flush and clear
flushAndClear();
// get node and check aspects
node = (Node) getSession().get(NodeImpl.class, id);
assertNotNull("Node not persisted", node);
aspects = node.getAspects();
assertEquals("Not all aspects persisted", 4, aspects.size());
}
public void testChildAssoc() throws Exception
{
// make a content node
Node contentNode = new NodeImpl();
contentNode.setStore(store);
contentNode.setUuid(GUID.generate());
contentNode.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable contentNodeId = getSession().save(contentNode);
// make a container node
Node containerNode = new NodeImpl();
containerNode.setStore(store);
containerNode.setUuid(GUID.generate());
containerNode.setTypeQName(ContentModel.TYPE_CONTAINER);
Serializable containerNodeId = getSession().save(containerNode);
// create an association to the content
ChildAssoc assoc1 = new ChildAssocImpl();
assoc1.setIsPrimary(true);
assoc1.setTypeQName(QName.createQName(null, "type1"));
assoc1.setQname(QName.createQName(null, "number1"));
assoc1.setChildNodeName("number1");
assoc1.setChildNodeNameCrc(1);
getSession().save(assoc1);
assoc1.buildAssociation(containerNode, contentNode);
// make another association between the same two parent and child nodes
ChildAssoc assoc2 = new ChildAssocImpl();
assoc2.setIsPrimary(true);
assoc2.setTypeQName(QName.createQName(null, "type2"));
assoc2.setQname(QName.createQName(null, "number2"));
assoc2.setChildNodeName("number2");
assoc2.setChildNodeNameCrc(2);
getSession().save(assoc2);
assoc2.buildAssociation(containerNode, contentNode);
assertFalse("Hashcode incorrent", assoc2.hashCode() == 0);
assertNotSame("Assoc equals failure", assoc1, assoc2);
// reload the container
containerNode = (Node) getSession().get(NodeImpl.class, containerNodeId);
assertNotNull("Node not found", containerNode);
// check that we can traverse the association from the child
Collection<ChildAssoc> parentAssocs = contentNode.getParentAssocs();
assertEquals("Expected exactly 2 parent assocs", 2, parentAssocs.size());
parentAssocs = new HashSet<ChildAssoc>(parentAssocs);
for (ChildAssoc assoc : parentAssocs)
{
// maintain inverse assoc sets
assoc.removeAssociation();
// remove the assoc
getSession().delete(assoc);
}
// check that the child now has zero parents
parentAssocs = contentNode.getParentAssocs();
assertEquals("Expected exactly 0 parent assocs", 0, parentAssocs.size());
}
/**
* Allows tracing of L2 cache
*/
public void testCaching() throws Exception
{
// make a node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable nodeId = getSession().save(node);
// add some aspects to the node
Set<QName> aspects = node.getAspects();
aspects.add(ContentModel.ASPECT_AUDITABLE);
// add some properties
Map<QName, PropertyValue> properties = node.getProperties();
properties.put(ContentModel.PROP_NAME, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
// check that the session hands back the same instance
Node checkNode = (Node) getSession().get(NodeImpl.class, nodeId);
assertNotNull(checkNode);
assertTrue("Node retrieved was not same instance", checkNode == node);
Set<QName> checkAspects = checkNode.getAspects();
assertTrue("Aspect set retrieved was not the same instance", checkAspects == aspects);
assertEquals("Incorrect number of aspects", 1, checkAspects.size());
QName checkQName = (QName) checkAspects.toArray()[0];
assertTrue("QName retrieved was not the same instance", checkQName == ContentModel.ASPECT_AUDITABLE);
Map<QName, PropertyValue> checkProperties = checkNode.getProperties();
assertTrue("Propery map retrieved was not the same instance", checkProperties == properties);
assertTrue("Property not found", checkProperties.containsKey(ContentModel.PROP_NAME));
flushAndClear();
// commit the transaction
setComplete();
endTransaction();
TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionComponent");
UserTransaction txn = transactionService.getUserTransaction();
try
{
txn.begin();
// check that the L2 cache hands back the same instance
checkNode = (Node) getSession().get(NodeImpl.class, nodeId);
assertNotNull(checkNode);
checkAspects = checkNode.getAspects();
txn.commit();
}
catch (Throwable e)
{
txn.rollback();
}
}
/**
* Create some simple parent-child relationships and flush them. Then read them back in without
* using the L2 cache.
*/
public void testQueryJoins() throws Exception
{
getSession().setCacheMode(CacheMode.IGNORE);
// make a container node
Node containerNode = new NodeImpl();
containerNode.setStore(store);
containerNode.setUuid(GUID.generate());
containerNode.setTypeQName(ContentModel.TYPE_CONTAINER);
containerNode.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
containerNode.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
containerNode.getAspects().add(ContentModel.ASPECT_AUDITABLE);
Serializable containerNodeId = getSession().save(containerNode);
NodeKey containerNodeKey = new NodeKey(containerNode.getNodeRef());
NodeStatus containerNodeStatus = new NodeStatusImpl();
containerNodeStatus.setKey(containerNodeKey);
containerNodeStatus.setNode(containerNode);
containerNodeStatus.setTransaction(transaction);
getSession().save(containerNodeStatus);
// make content node 1
Node contentNode1 = new NodeImpl();
contentNode1.setStore(store);
contentNode1.setUuid(GUID.generate());
contentNode1.setTypeQName(ContentModel.TYPE_CONTENT);
contentNode1.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode1.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode1.getAspects().add(ContentModel.ASPECT_AUDITABLE);
Serializable contentNode1Id = getSession().save(contentNode1);
NodeKey contentNodeKey1 = new NodeKey(contentNode1.getNodeRef());
NodeStatus contentNodeStatus1 = new NodeStatusImpl();
contentNodeStatus1.setKey(contentNodeKey1);
contentNodeStatus1.setNode(contentNode1);
contentNodeStatus1.setTransaction(transaction);
getSession().save(contentNodeStatus1);
// make content node 2
Node contentNode2 = new NodeImpl();
contentNode2.setStore(store);
contentNode2.setUuid(GUID.generate());
contentNode2.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable contentNode2Id = getSession().save(contentNode2);
contentNode2.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode2.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode2.getAspects().add(ContentModel.ASPECT_AUDITABLE);
NodeKey contentNodeKey2 = new NodeKey(contentNode2.getNodeRef());
NodeStatus contentNodeStatus2 = new NodeStatusImpl();
contentNodeStatus2.setKey(contentNodeKey2);
contentNodeStatus2.setNode(contentNode2);
contentNodeStatus2.setTransaction(transaction);
getSession().save(contentNodeStatus2);
// create an association to content 1
ChildAssoc assoc1 = new ChildAssocImpl();
assoc1.setIsPrimary(true);
assoc1.setTypeQName(QName.createQName(null, "type1"));
assoc1.setQname(QName.createQName(null, "number1"));
assoc1.setChildNodeName("number1");
assoc1.setChildNodeNameCrc(1);
assoc1.buildAssociation(containerNode, contentNode1);
getSession().save(assoc1);
// create an association to content 2
ChildAssoc assoc2 = new ChildAssocImpl();
assoc2.setIsPrimary(true);
assoc2.setTypeQName(QName.createQName(null, "type2"));
assoc2.setQname(QName.createQName(null, "number2"));
assoc2.setChildNodeName("number2");
assoc2.setChildNodeNameCrc(2);
assoc2.buildAssociation(containerNode, contentNode2);
getSession().save(assoc2);
// make sure that there are no entities cached in either L1 or L2
getSession().flush();
getSession().clear();
// now read the structure back in from the container down
containerNodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, containerNodeKey);
containerNode = containerNodeStatus.getNode();
// clear out again
getSession().clear();
// expect that just the specific property gets removed in the delete statement
getSession().flush();
getSession().clear();
// Create a second association to content 2
// create an association to content 2
containerNodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, containerNodeKey);
containerNode = containerNodeStatus.getNode();
contentNodeStatus2 = (NodeStatus) getSession().get(NodeStatusImpl.class, contentNodeKey2);
contentNode2 = contentNodeStatus2.getNode();
ChildAssoc assoc3 = new ChildAssocImpl();
assoc3.setIsPrimary(false);
assoc3.setTypeQName(QName.createQName(null, "type3"));
assoc3.setQname(QName.createQName(null, "number3"));
assoc3.setChildNodeName("number3");
assoc3.setChildNodeNameCrc(2);
assoc3.buildAssociation(containerNode, contentNode2); // check whether the children are pulled in for this
getSession().save(assoc3);
// flush it
getSession().flush();
getSession().clear();
}
}
/*
* 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.domain.hibernate;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.repo.domain.NodeStatus;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Server;
import org.alfresco.repo.domain.Store;
import org.alfresco.repo.domain.StoreKey;
import org.alfresco.repo.domain.Transaction;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.hibernate.CacheMode;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.GenericJDBCException;
/**
* Test persistence and retrieval of Hibernate-specific implementations of the
* {@link org.alfresco.repo.domain.Node} interface
*
* @author Derek Hulley
*/
@SuppressWarnings("unused")
public class HibernateNodeTest extends BaseSpringTest
{
private static final String TEST_NAMESPACE = "http://www.alfresco.org/test/HibernateNodeTest";
private static int i = 0;
private Store store;
private Server server;
private Transaction transaction;
public HibernateNodeTest()
{
}
protected void onSetUpInTransaction() throws Exception
{
store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + System.currentTimeMillis() + " - " + System.nanoTime());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
getSession().save(transaction);
}
protected void onTearDownInTransaction()
{
// force a flush to ensure that the database updates succeed
getSession().flush();
getSession().clear();
}
public void testSetUp() throws Exception
{
assertNotNull("Workspace not initialised", store);
}
public void testGetStore() throws Exception
{
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
// now it should work
Serializable id = getSession().save(node);
// throw the reference away and get the a new one for the id
node = (Node) getSession().load(NodeImpl.class, id);
assertNotNull("Node not found", node);
// check that the store has been loaded
Store loadedStore = node.getStore();
assertNotNull("Store not present on node", loadedStore);
assertEquals("Incorrect store key", store, loadedStore);
}
public void testNodeStatus()
{
NodeKey key = new NodeKey(store.getKey(), "AAA");
// create the node status
NodeStatus nodeStatus = new NodeStatusImpl();
nodeStatus.setKey(key);
nodeStatus.setTransaction(transaction);
getSession().save(nodeStatus);
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
Serializable nodeId = getSession().save(node);
// This should all be fine. The node does not HAVE to have a status.
flushAndClear();
// set the node
nodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, key);
nodeStatus.setNode(node);
flushAndClear();
// is the node retrievable?
nodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, key);
node = nodeStatus.getNode();
assertNotNull("Node was not attached to status", node);
// change the values
transaction.setChangeTxnId("txn:456");
// delete the node
getSession().delete(node);
try
{
flushAndClear();
fail("Node status may not refer to non-existent node");
}
catch(ConstraintViolationException e)
{
// expected
}
catch(GenericJDBCException e)
{
// Sybase
// expected
}
}
/**
* Check that properties can be persisted and retrieved
*/
public void testProperties() throws Exception
{
// create a new Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTAINER);
// give it a property map
Map<QName, PropertyValue> propertyMap = new HashMap<QName, PropertyValue>(5);
QName propertyQName = QName.createQName("{}A");
PropertyValue propertyValue = new PropertyValue(DataTypeDefinition.TEXT, "AAA");
propertyMap.put(propertyQName, propertyValue);
node.getProperties().putAll(propertyMap);
// persist it
Serializable id = getSession().save(node);
// throw the reference away and get the a new one for the id
node = (Node) getSession().load(NodeImpl.class, id);
assertNotNull("Node not found", node);
// extract the Map
propertyMap = node.getProperties();
assertNotNull("Map not persisted", propertyMap);
// ensure that the value is present
assertNotNull("Property value not present in map", QName.createQName("{}A"));
}
/**
* Check that aspect qnames can be added and removed from a node and that they
* are persisted correctly
*/
public void testAspects() throws Exception
{
// make a real node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CMOBJECT);
// add some aspects
QName aspect1 = QName.createQName(TEST_NAMESPACE, "1");
QName aspect2 = QName.createQName(TEST_NAMESPACE, "2");
QName aspect3 = QName.createQName(TEST_NAMESPACE, "3");
QName aspect4 = QName.createQName(TEST_NAMESPACE, "4");
Set<QName> aspects = node.getAspects();
aspects.add(aspect1);
aspects.add(aspect2);
aspects.add(aspect3);
aspects.add(aspect4);
assertFalse("Set did not eliminate duplicate aspect qname", aspects.add(aspect4));
// persist
Serializable id = getSession().save(node);
// flush and clear
flushAndClear();
// get node and check aspects
node = (Node) getSession().get(NodeImpl.class, id);
assertNotNull("Node not persisted", node);
aspects = node.getAspects();
assertEquals("Not all aspects persisted", 4, aspects.size());
}
public void testChildAssoc() throws Exception
{
// make a content node
Node contentNode = new NodeImpl();
contentNode.setStore(store);
contentNode.setUuid(GUID.generate());
contentNode.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable contentNodeId = getSession().save(contentNode);
// make a container node
Node containerNode = new NodeImpl();
containerNode.setStore(store);
containerNode.setUuid(GUID.generate());
containerNode.setTypeQName(ContentModel.TYPE_CONTAINER);
Serializable containerNodeId = getSession().save(containerNode);
// create an association to the content
ChildAssoc assoc1 = new ChildAssocImpl();
assoc1.setIsPrimary(true);
assoc1.setTypeQName(QName.createQName(null, "type1"));
assoc1.setQname(QName.createQName(null, "number1"));
assoc1.setChildNodeName("number1");
assoc1.setChildNodeNameCrc(1);
assoc1.buildAssociation(containerNode, contentNode);
getSession().save(assoc1);
// make another association between the same two parent and child nodes
ChildAssoc assoc2 = new ChildAssocImpl();
assoc2.setIsPrimary(true);
assoc2.setTypeQName(QName.createQName(null, "type2"));
assoc2.setQname(QName.createQName(null, "number2"));
assoc2.setChildNodeName("number2");
assoc2.setChildNodeNameCrc(2);
assoc2.buildAssociation(containerNode, contentNode);
getSession().save(assoc2);
assertFalse("Hashcode incorrent", assoc2.hashCode() == 0);
assertNotSame("Assoc equals failure", assoc1, assoc2);
// reload the container
containerNode = (Node) getSession().get(NodeImpl.class, containerNodeId);
assertNotNull("Node not found", containerNode);
// check that we can traverse the association from the child
Collection<ChildAssoc> parentAssocs = contentNode.getParentAssocs();
assertEquals("Expected exactly 2 parent assocs", 2, parentAssocs.size());
parentAssocs = new HashSet<ChildAssoc>(parentAssocs);
for (ChildAssoc assoc : parentAssocs)
{
// maintain inverse assoc sets
assoc.removeAssociation();
// remove the assoc
getSession().delete(assoc);
}
// check that the child now has zero parents
parentAssocs = contentNode.getParentAssocs();
assertEquals("Expected exactly 0 parent assocs", 0, parentAssocs.size());
}
/**
* Allows tracing of L2 cache
*/
public void testCaching() throws Exception
{
// make a node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(GUID.generate());
node.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable nodeId = getSession().save(node);
// add some aspects to the node
Set<QName> aspects = node.getAspects();
aspects.add(ContentModel.ASPECT_AUDITABLE);
// add some properties
Map<QName, PropertyValue> properties = node.getProperties();
properties.put(ContentModel.PROP_NAME, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
// check that the session hands back the same instance
Node checkNode = (Node) getSession().get(NodeImpl.class, nodeId);
assertNotNull(checkNode);
assertTrue("Node retrieved was not same instance", checkNode == node);
Set<QName> checkAspects = checkNode.getAspects();
assertTrue("Aspect set retrieved was not the same instance", checkAspects == aspects);
assertEquals("Incorrect number of aspects", 1, checkAspects.size());
QName checkQName = (QName) checkAspects.toArray()[0];
assertTrue("QName retrieved was not the same instance", checkQName == ContentModel.ASPECT_AUDITABLE);
Map<QName, PropertyValue> checkProperties = checkNode.getProperties();
assertTrue("Propery map retrieved was not the same instance", checkProperties == properties);
assertTrue("Property not found", checkProperties.containsKey(ContentModel.PROP_NAME));
flushAndClear();
// commit the transaction
setComplete();
endTransaction();
TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionComponent");
UserTransaction txn = transactionService.getUserTransaction();
try
{
txn.begin();
// check that the L2 cache hands back the same instance
checkNode = (Node) getSession().get(NodeImpl.class, nodeId);
assertNotNull(checkNode);
checkAspects = checkNode.getAspects();
txn.commit();
}
catch (Throwable e)
{
txn.rollback();
}
}
/**
* Create some simple parent-child relationships and flush them. Then read them back in without
* using the L2 cache.
*/
public void testQueryJoins() throws Exception
{
getSession().setCacheMode(CacheMode.IGNORE);
// make a container node
Node containerNode = new NodeImpl();
containerNode.setStore(store);
containerNode.setUuid(GUID.generate());
containerNode.setTypeQName(ContentModel.TYPE_CONTAINER);
containerNode.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
containerNode.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
containerNode.getAspects().add(ContentModel.ASPECT_AUDITABLE);
Serializable containerNodeId = getSession().save(containerNode);
NodeKey containerNodeKey = new NodeKey(containerNode.getNodeRef());
NodeStatus containerNodeStatus = new NodeStatusImpl();
containerNodeStatus.setKey(containerNodeKey);
containerNodeStatus.setNode(containerNode);
containerNodeStatus.setTransaction(transaction);
getSession().save(containerNodeStatus);
// make content node 1
Node contentNode1 = new NodeImpl();
contentNode1.setStore(store);
contentNode1.setUuid(GUID.generate());
contentNode1.setTypeQName(ContentModel.TYPE_CONTENT);
contentNode1.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode1.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode1.getAspects().add(ContentModel.ASPECT_AUDITABLE);
Serializable contentNode1Id = getSession().save(contentNode1);
NodeKey contentNodeKey1 = new NodeKey(contentNode1.getNodeRef());
NodeStatus contentNodeStatus1 = new NodeStatusImpl();
contentNodeStatus1.setKey(contentNodeKey1);
contentNodeStatus1.setNode(contentNode1);
contentNodeStatus1.setTransaction(transaction);
getSession().save(contentNodeStatus1);
// make content node 2
Node contentNode2 = new NodeImpl();
contentNode2.setStore(store);
contentNode2.setUuid(GUID.generate());
contentNode2.setTypeQName(ContentModel.TYPE_CONTENT);
Serializable contentNode2Id = getSession().save(contentNode2);
contentNode2.getProperties().put(ContentModel.PROP_AUTHOR, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode2.getProperties().put(ContentModel.PROP_ARCHIVED_BY, new PropertyValue(DataTypeDefinition.TEXT, "ABC"));
contentNode2.getAspects().add(ContentModel.ASPECT_AUDITABLE);
NodeKey contentNodeKey2 = new NodeKey(contentNode2.getNodeRef());
NodeStatus contentNodeStatus2 = new NodeStatusImpl();
contentNodeStatus2.setKey(contentNodeKey2);
contentNodeStatus2.setNode(contentNode2);
contentNodeStatus2.setTransaction(transaction);
getSession().save(contentNodeStatus2);
// create an association to content 1
ChildAssoc assoc1 = new ChildAssocImpl();
assoc1.setIsPrimary(true);
assoc1.setTypeQName(QName.createQName(null, "type1"));
assoc1.setQname(QName.createQName(null, "number1"));
assoc1.setChildNodeName("number1");
assoc1.setChildNodeNameCrc(1);
assoc1.buildAssociation(containerNode, contentNode1);
getSession().save(assoc1);
// create an association to content 2
ChildAssoc assoc2 = new ChildAssocImpl();
assoc2.setIsPrimary(true);
assoc2.setTypeQName(QName.createQName(null, "type2"));
assoc2.setQname(QName.createQName(null, "number2"));
assoc2.setChildNodeName("number2");
assoc2.setChildNodeNameCrc(2);
assoc2.buildAssociation(containerNode, contentNode2);
getSession().save(assoc2);
// make sure that there are no entities cached in either L1 or L2
getSession().flush();
getSession().clear();
// now read the structure back in from the container down
containerNodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, containerNodeKey);
containerNode = containerNodeStatus.getNode();
// clear out again
getSession().clear();
// expect that just the specific property gets removed in the delete statement
getSession().flush();
getSession().clear();
// Create a second association to content 2
// create an association to content 2
containerNodeStatus = (NodeStatus) getSession().get(NodeStatusImpl.class, containerNodeKey);
containerNode = containerNodeStatus.getNode();
contentNodeStatus2 = (NodeStatus) getSession().get(NodeStatusImpl.class, contentNodeKey2);
contentNode2 = contentNodeStatus2.getNode();
ChildAssoc assoc3 = new ChildAssocImpl();
assoc3.setIsPrimary(false);
assoc3.setTypeQName(QName.createQName(null, "type3"));
assoc3.setQname(QName.createQName(null, "number3"));
assoc3.setChildNodeName("number3");
assoc3.setChildNodeNameCrc(2);
assoc3.buildAssociation(containerNode, contentNode2); // check whether the children are pulled in for this
getSession().save(assoc3);
// flush it
getSession().flush();
getSession().clear();
}
}

View File

@@ -314,65 +314,19 @@
assoc.target.id = :targetId
</query>
<query name="node.GetNextChangeTxnIds">
select distinct
transaction.changeTxnId
from
org.alfresco.repo.domain.hibernate.TransactionImpl as transaction
where
transaction.changeTxnId > :currentTxnId
order by
transaction.changeTxnId
</query>
<query name="node.GetChangedNodeStatusesCount">
<query name="node.GetNodesWithPropertyValuesByActualType">
select
count(transaction.changeTxnId)
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as transaction
where
status.key.protocol = :storeProtocol and
status.key.identifier = :storeIdentifier and
status.node.id is not null and
transaction.changeTxnId = :changeTxnId
</query>
<query name="node.GetChangedNodeStatuses">
select
status
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as transaction
where
status.key.protocol = :storeProtocol and
status.key.identifier = :storeIdentifier and
status.node.id is not null and
transaction.changeTxnId = :changeTxnId
</query>
<query name="node.GetDeletedNodeStatuses">
select
status
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as transaction
where
status.key.protocol = :storeProtocol and
status.key.identifier = :storeIdentifier and
status.node.id is null and
transaction.changeTxnId = :changeTxnId
</query>
<query name="node.GetContentDataStrings">
select distinct
props.stringValue
node
from
org.alfresco.repo.domain.hibernate.NodeImpl as node
join
node.properties props
node.properties prop
where
props.stringValue like 'contentUrl%'
(
prop.actualType = :actualTypeString or
prop.actualType = 'SERIALIZABLE'
) and
prop.persistedType != 'NULL'
</query>
<query name="node.patch.GetNodesWithPersistedSerializableProperties">

View File

@@ -59,4 +59,81 @@
server.ipAddress = :ipAddress
</query>
<query name="txn.GetLastTxnIdForStore">
select
max(txn.id)
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as txn
where
status.key.protocol = :protocol and
status.key.identifier = :identifier
</query>
<query name="txn.CountTransactions">
select
count(txn.id)
from
org.alfresco.repo.domain.hibernate.TransactionImpl as txn
</query>
<query name="txn.GetNextTxns">
<![CDATA[
select
txn
from
org.alfresco.repo.domain.hibernate.TransactionImpl as txn
where
txn.id > :lastTxnId
order by
txn.id
]]>
</query>
<query name="txn.GetTxnUpdateCountForStore">
select
count(status.key.guid)
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as txn
where
txn.id = :txnId and
status.node is not null and
status.key.protocol = :protocol and
status.key.identifier = :identifier
</query>
<query name="txn.GetTxnDeleteCountForStore">
select
count(status.key.guid)
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
join status.transaction as txn
where
txn.id = :txnId and
status.node is null and
status.key.protocol = :protocol and
status.key.identifier = :identifier
</query>
<query name="txn.GetTxnChangesForStore">
select
status
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
where
status.transaction.id = :txnId and
status.key.protocol = :protocol and
status.key.identifier = :identifier
</query>
<query name="txn.GetTxnChanges">
select
status
from
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
where
status.transaction.id = :txnId
</query>
</hibernate-mapping>