Added QName indexed Properties to AVMNodes.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3357 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-07-19 22:15:09 +00:00
parent e5eb45da0f
commit e2eec832f1
20 changed files with 700 additions and 0 deletions

View File

@@ -70,6 +70,11 @@ public class AVMContext
*/
public NewInAVMStoreDAO fNewInAVMStoreDAO;
/**
* The AVMNodePropertyDAO
*/
public AVMNodePropertyDAO fAVMNodePropertyDAO;
/**
* @param nodeDAO the fAVMNodeDAO to set
*/
@@ -149,4 +154,9 @@ public class AVMContext
{
fNewInAVMStoreDAO = newInAVMStoreDAO;
}
public void setAvmNodePropertyDAO(AVMNodePropertyDAO avmNodePropertyDAO)
{
fAVMNodePropertyDAO = avmNodePropertyDAO;
}
}

View File

@@ -16,6 +16,11 @@
*/
package org.alfresco.repo.avm;
import java.util.Map;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* The Interface for versionable objects.
* @author britt
@@ -129,4 +134,24 @@ public interface AVMNode
* Update the modification time of this node.
*/
public void updateModTime();
/**
* Set a property.
* @param name The name of the property.
* @param value The value to set.
*/
public void setProperty(QName name, PropertyValue value);
/**
* Get a property by name.
* @param name The name of the property to get.
* @return A PropertyValue
*/
public PropertyValue getProperty(QName name);
/**
* Get all the properties associated with this node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties();
}

View File

@@ -18,6 +18,12 @@
package org.alfresco.repo.avm;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* Base class for all repository file system like objects.
@@ -261,4 +267,72 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
{
fBasicAttributes.setModDate(System.currentTimeMillis());
}
/**
* Copy all properties from another node.
* @param other The other node.
*/
protected void copyProperties(AVMNode other)
{
Map<QName, PropertyValue> properties = other.getProperties();
for (QName name : properties.keySet())
{
AVMNodeProperty newProp = new AVMNodePropertyImpl();
newProp.setNode(this);
newProp.setName(name);
newProp.setValue(properties.get(name));
AVMContext.fgInstance.fAVMNodePropertyDAO.save(newProp);
}
}
/**
* Set a property on a node. Overwrite it if it exists.
* @param name The name of the property.
* @param value The value to set.
*/
public void setProperty(QName name, PropertyValue value)
{
AVMNodeProperty prop = AVMContext.fgInstance.fAVMNodePropertyDAO.get(this, name);
if (prop != null)
{
prop.setValue(value);
AVMContext.fgInstance.fAVMNodePropertyDAO.update(prop);
return;
}
prop = new AVMNodePropertyImpl();
prop.setNode(this);
prop.setName(name);
prop.setValue(value);
AVMContext.fgInstance.fAVMNodePropertyDAO.save(prop);
}
/**
* Get a property by name.
* @param name The name of the property.
* @return The PropertyValue or null if non-existent.
*/
public PropertyValue getProperty(QName name)
{
AVMNodeProperty prop = AVMContext.fgInstance.fAVMNodePropertyDAO.get(this, name);
if (prop == null)
{
return null;
}
return prop.getValue();
}
/**
* Get all the properties associated with this node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties()
{
Map<QName, PropertyValue> retVal = new HashMap<QName, PropertyValue>();
List<AVMNodeProperty> props = AVMContext.fgInstance.fAVMNodePropertyDAO.get(this);
for (AVMNodeProperty prop : props)
{
retVal.put(prop.getName(), prop.getValue());
}
return retVal;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.avm;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* Alfresco Properties for AVM..
* @author britt
*/
public interface AVMNodeProperty
{
/**
* Set the node that owns this property.
* @param node The AVMNode.
*/
public void setNode(AVMNode node);
/**
* Get the node that owns this property.
* @return An AVMNode.
*/
public AVMNode getNode();
/**
* Get the name for this property.
* @return A QName.
*/
public QName getName();
/**
* Set the name for the property.
* @param id A QName.
*/
public void setName(QName id);
/**
* Get the actual property value.
* @return A PropertyValue.
*/
public PropertyValue getValue();
/**
* Set the value of this property.
* @param value A PropertyValue.
*/
public void setValue(PropertyValue value);
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.avm;
import java.util.List;
import org.alfresco.service.namespace.QName;
/**
* DAO for AVMNodeProperty.
* @author britt
*/
public interface AVMNodePropertyDAO
{
/**
* Save the given AVMNodeProperty.
* @param prop
*/
public void save(AVMNodeProperty prop);
/**
* Get an AVMNodeProperty by owner and name.
* @param owner An AVMNode.
* @param name The QName.
* @return The found AVMNodeProperty or null if not found.
*/
public AVMNodeProperty get(AVMNode node, QName name);
/**
* Get a List of all properties for an owning node.
* @param node The owning node.
* @return A List of properties belonging to the given node.
*/
public List<AVMNodeProperty> get(AVMNode node);
/**
* Update a property entry.
* @param prop The property.
*/
public void update(AVMNodeProperty prop);
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.avm;
import java.io.Serializable;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* @author britt
*
*/
public class AVMNodePropertyImpl implements AVMNodeProperty, Serializable
{
private static final long serialVersionUID = -7194228119659288619L;
/**
* The node that owns this.
*/
private AVMNode fNode;
/**
* The QName of this property.
*/
private QName fName;
/**
* The PropertyValue.
*/
private PropertyValue fValue;
/**
* Default constructor.
*/
public AVMNodePropertyImpl()
{
}
/**
* Get the owning node.
* @return The AVMNode.
*/
public AVMNode getNode()
{
return fNode;
}
/**
* Set the owning node.
* @param node The AVMNode to set.
*/
public void setNode(AVMNode node)
{
fNode = node;
}
/**
* Get the name, a QName
* @return A QName.
*/
public QName getName()
{
return fName;
}
/**
* Set the name, a QName.
* @param name The QName.
*/
public void setName(QName name)
{
fName = name;
}
/**
* Get the value.
* @return A PropertyValue
*/
public PropertyValue getValue()
{
return fValue;
}
/**
* Set the value.
* @param value A PropertyValue.
*/
public void setValue(PropertyValue value)
{
fValue = value;
}
}

View File

@@ -24,8 +24,12 @@ import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* This or AVMStore are
* the implementors of the operations specified by AVMService.
@@ -861,6 +865,49 @@ class AVMRepository
store.setOpacity(pathParts[1], opacity);
}
/**
* Set a property on a node.
* @param path The path to the node.
* @param name The name of the property.
* @param value The value of the property.
*/
public void setProperty(String path, QName name, PropertyValue value)
{
fLookupCount.set(1);
String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0], true);
store.setProperty(pathParts[1], name, value);
}
/**
* Get a property by name for a node.
* @param version The version to look under.
* @param path The path to the node.
* @param name The name of the property.
* @return The PropertyValue or null if it does not exist.
*/
public PropertyValue getProperty(int version, String path, QName name)
{
fLookupCount.set(1);
String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0], false);
return store.getProperty(version, pathParts[1], name);
}
/**
* Get a Map of all the properties of a node.
* @param version The version to look under.
* @param path The path to the node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties(int version, String path)
{
fLookupCount.set(1);
String [] pathParts = SplitPath(path);
AVMStore store = getAVMStoreByName(pathParts[0], false);
return store.getProperties(version, pathParts[1]);
}
/**
* Get the AVMStoreDescriptor for an AVMStore.
* @param name The name of the AVMStore.

View File

@@ -22,8 +22,12 @@ import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* This is the service interface for the [Alfresco|Addled|Advanced|Aleatoric|Apotheosed|Awful]
* Versioning Model. It specifies methods that are close in functionality to the underlying
@@ -306,4 +310,29 @@ public interface AVMService
* @return A LayeringDescriptor.
*/
public LayeringDescriptor getLayeringInfo(int version, String path);
/**
* Set a property on a node.
* @param path The path to the node to set the property on.
* @param name The QName of the property.
* @param value The property to set.
*/
public void setProperty(String path, QName name, PropertyValue value);
/**
* Get a property of a node by QName.
* @param version The version to look under.
* @param path The path to the node.
* @param name The QName.
* @return The PropertyValue or null if it doesn't exist.
*/
public PropertyValue getProperty(int version, String path, QName name);
/**
* Get all the properties associated with a node.
* @param version The version to look under.
* @param path The path to the node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties(int version, String path);
}

View File

@@ -25,9 +25,12 @@ import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
import org.apache.log4j.Logger;
/**
@@ -1028,4 +1031,79 @@ public class AVMServiceImpl implements AVMService
fTransaction.perform(doit, false);
return doit.ancestor;
}
/**
* Set a property on a node.
* @param path The path to the node to set the property on.
* @param name The QName of the property.
* @param value The property to set.
*/
public void setProperty(final String path, final QName name, final PropertyValue value)
{
if (path == null || name == null || value == null)
{
throw new AVMBadArgumentException("Illegal null argument.");
}
class TxnCallback implements RetryingTransactionCallback
{
public void perform()
{
fAVMRepository.setProperty(path, name, value);
}
}
TxnCallback doit = new TxnCallback();
fTransaction.perform(doit, true);
}
/**
* Get a property of a node by QName.
* @param version The version to look under.
* @param path The path to the node.
* @param name The QName.
* @return The PropertyValue or null if it doesn't exist.
*/
public PropertyValue getProperty(final int version, final String path, final QName name)
{
if (path == null || name == null)
{
throw new AVMBadArgumentException("Illegal null argument.");
}
class TxnCallback implements RetryingTransactionCallback
{
public PropertyValue value;
public void perform()
{
value = fAVMRepository.getProperty(version, path, name);
}
}
TxnCallback doit = new TxnCallback();
fTransaction.perform(doit, false);
return doit.value;
}
/**
* Get all the properties associated with a node.
* @param version The version to look under.
* @param path The path to the node.
* @return A List of AVMNodeProperties.
*/
public Map<QName, PropertyValue> getProperties(final int version, final String path)
{
if (path == null)
{
throw new AVMBadArgumentException("Null path.");
}
class TxnCallback implements RetryingTransactionCallback
{
public Map<QName, PropertyValue> properties;
public void perform()
{
properties = fAVMRepository.getProperties(version, path);
}
}
TxnCallback doit = new TxnCallback();
fTransaction.perform(doit, false);
return doit.properties;
}
}

View File

@@ -29,6 +29,8 @@ import java.util.Map;
import java.util.TreeMap;
import org.alfresco.repo.avm.util.BulkLoader;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* Big test of AVM behavior.
@@ -2018,4 +2020,28 @@ public class AVMServiceTest extends AVMServiceTestBase
fail();
}
}
/**
* Test properties.
*/
public void testProperties()
{
try
{
setupBasicTree();
QName name = QName.createQName("silly.uri", "SillyProperty");
PropertyValue value = new PropertyValue(name, "Silly Property Value");
fService.setProperty("main:/a/b/c/foo", name, value);
fService.createSnapshot("main");
PropertyValue returned = fService.getProperty(-1, "main:/a/b/c/foo", name);
assertEquals(value.toString(), returned.toString());
Map<QName, PropertyValue> props = fService.getProperties(-1, "main:/a/b/c/foo");
assertEquals(1, props.size());
assertEquals(value.toString(), props.get(name).toString());
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}
}

View File

@@ -22,8 +22,12 @@ import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* The store interface. Methods for filesystem like, versioning,
* and layering operations.
@@ -263,4 +267,29 @@ public interface AVMStore
* @param opacity True is opaque; false is not.
*/
public void setOpacity(String path, boolean opacity);
/**
* Set a property on a node.
* @param path The path to the node.
* @param name The name of the property.
* @param value The value to set.
*/
public void setProperty(String path, QName name, PropertyValue value);
/**
* Get a property by name.
* @param version The version to look under.
* @param path The path to the node.
* @param name The name of the property.
* @return A PropertyValue or null if not found.
*/
public PropertyValue getProperty(int version, String path, QName name);
/**
* Get all the properties associated with a node.
* @param version The version to look under.
* @param path The path to the node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties(int version, String path);
}

View File

@@ -29,6 +29,9 @@ import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.QName;
/**
* A Repository contains a current root directory and a list of
* root versions. Each root version corresponds to a separate snapshot
@@ -823,4 +826,44 @@ public class AVMStoreImpl implements AVMStore, Serializable
((LayeredDirectoryNode)node).setOpacity(opacity);
node.updateModTime();
}
/**
* Set a property on a node.
* @param path The path to the node.
* @param name The name of the property.
* @param value The value to set.
*/
public void setProperty(String path, QName name, PropertyValue value)
{
Lookup lPath = lookup(-1, path, true);
AVMNode node = lPath.getCurrentNode();
node.setProperty(name, value);
}
/**
* Get a property by name.
* @param version The version to lookup.
* @param path The path to the node.
* @param name The name of the property.
* @return A PropertyValue or null if not found.
*/
public PropertyValue getProperty(int version, String path, QName name)
{
Lookup lPath = lookup(version, path, false);
AVMNode node = lPath.getCurrentNode();
return node.getProperty(name);
}
/**
* Get all the properties associated with a node.
* @param version The version to lookup.
* @param path The path to the node.
* @return A Map of QNames to PropertyValues.
*/
public Map<QName, PropertyValue> getProperties(int version, String path)
{
Lookup lPath = lookup(version, path, false);
AVMNode node = lPath.getCurrentNode();
return node.getProperties();
}
}

View File

@@ -109,6 +109,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(repos, this));
copyProperties(other);
}
/**
@@ -142,6 +143,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
copyProperties(other);
}
/**
@@ -165,6 +167,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
copyProperties(dir);
}
/**

View File

@@ -50,6 +50,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
copyProperties(other);
}
/**

View File

@@ -69,6 +69,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
}
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
copyProperties(other);
}
/**

View File

@@ -82,6 +82,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
copyProperties(other);
}
/**

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.alfresco.repo.avm">
<typedef class="org.alfresco.repo.domain.hibernate.QNameUserType" name="QName"/>
<!-- AVMNodeBean is the abstract base for filesystem like objects.
We're using the one table per class hierarchy strategy to implement
polymorphism. -->
@@ -177,6 +180,23 @@
<key-many-to-one name="node" class="AVMNodeImpl" column="node_id"/>
</composite-id>
</class>
<class name="AVMNodePropertyImpl" proxy="AVMNodeProperty" table="avm_node_properties">
<composite-id>
<key-many-to-one name="node" class="AVMNodeImpl" column="node_id"/>
<key-property name="name" column="qname" type="QName" length="200"/>
</composite-id>
<component class="org.alfresco.repo.domain.PropertyValue" name="value">
<property name="actualType" column="actual_type" type="string" length="15" not-null="true" />
<property name="multiValued" column="multi_valued" type="boolean" not-null="true" />
<property name="persistedType" column="persisted_type" type="string" length="15" not-null="true" />
<property name="booleanValue" column="boolean_value" type="boolean" />
<property name="longValue" column="long_value" type="long" />
<property name="floatValue" column="float_value" type="float" />
<property name="doubleValue" column="double_value" type="double" />
<property name="stringValue" column="string_value" type="string" length="1024"/>
<property name="serializableValue" column="serializable_value" type="serializable" length="16384"/>
</component>
</class>
<query name="ChildEntry.ByNameParent">
<![CDATA[
from ChildEntryImpl ce

View File

@@ -0,0 +1,67 @@
package org.alfresco.repo.avm.hibernate;
import java.util.List;
import org.alfresco.repo.avm.AVMNode;
import org.alfresco.repo.avm.AVMNodeProperty;
import org.alfresco.repo.avm.AVMNodePropertyDAO;
import org.alfresco.service.namespace.QName;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Hibernate implemenation for DAO for AVMNodeProperties.
* @author britt
*/
public class AVMNodePropertyDAOHibernate extends HibernateDaoSupport
implements AVMNodePropertyDAO
{
/**
* Get a property by node and name.
* @param node The AVMNode.
* @param name The QName.
* @return The found property or null.
*/
public AVMNodeProperty get(AVMNode node, QName name)
{
Query query =
getSession().createQuery(
"from AVMNodePropertyImpl anp where anp.node = :node and anp.name = :name");
query.setEntity("node", node);
query.setParameter("name", name);
return (AVMNodeProperty)query.uniqueResult();
}
/**
* Get all properties owned by the given node.
* @param node The AVMNode.
* @return A List of properties.
*/
@SuppressWarnings("unchecked")
public List<AVMNodeProperty> get(AVMNode node)
{
Query query =
getSession().createQuery(
"from AVMNodePropertyImpl anp where anp.node = :node");
query.setEntity("node", node);
return (List<AVMNodeProperty>)query.list();
}
/**
* Save a property.
* @param prop The property to save.
*/
public void save(AVMNodeProperty prop)
{
getSession().save(prop);
}
/**
* Update a property entry.
* @param prop The property.
*/
public void update(AVMNodeProperty prop)
{
// Do nothing for Hibernate.
}
}