mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
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:
94
source/java/org/alfresco/repo/domain/ChildAssoc.java
Normal file
94
source/java/org/alfresco/repo/domain/ChildAssoc.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Represents a special type of association between nodes, that of the
|
||||
* parent-child relationship.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface ChildAssoc extends Comparable<ChildAssoc>
|
||||
{
|
||||
/**
|
||||
* Performs the necessary work on the provided nodes to ensure that a bidirectional
|
||||
* association is properly set up.
|
||||
* <p>
|
||||
* The association attributes still have to be set up.
|
||||
*
|
||||
* @param parentNode
|
||||
* @param childNode
|
||||
*
|
||||
* @see #setName(String)
|
||||
* @see #setIsPrimary(boolean)
|
||||
*/
|
||||
public void buildAssociation(Node parentNode, Node childNode);
|
||||
|
||||
/**
|
||||
* Performs the necessary work on the {@link #getParent() parent} and
|
||||
* {@link #getChild() child} nodes to maintain the inverse association sets
|
||||
*/
|
||||
public void removeAssociation();
|
||||
|
||||
public ChildAssociationRef getChildAssocRef();
|
||||
|
||||
public Long getId();
|
||||
|
||||
public Node getParent();
|
||||
|
||||
public Node getChild();
|
||||
|
||||
/**
|
||||
* @return Returns the qualified name of the association type
|
||||
*/
|
||||
public QName getTypeQName();
|
||||
|
||||
/**
|
||||
* @param assocTypeQName the qualified name of the association type as defined
|
||||
* in the data dictionary
|
||||
*/
|
||||
public void setTypeQName(QName assocTypeQName);
|
||||
|
||||
/**
|
||||
* @return Returns the qualified name of this association
|
||||
*/
|
||||
public QName getQname();
|
||||
|
||||
/**
|
||||
* @param qname the qualified name of the association
|
||||
*/
|
||||
public void setQname(QName qname);
|
||||
|
||||
public boolean getIsPrimary();
|
||||
|
||||
public void setIsPrimary(boolean isPrimary);
|
||||
|
||||
/**
|
||||
* @return Returns the user-assigned index
|
||||
*/
|
||||
public int getIndex();
|
||||
|
||||
/**
|
||||
* Set the index of this association
|
||||
*
|
||||
* @param index the association index
|
||||
*/
|
||||
public void setIndex(int index);
|
||||
}
|
92
source/java/org/alfresco/repo/domain/Node.java
Normal file
92
source/java/org/alfresco/repo/domain/Node.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Interface for persistent <b>node</b> objects.
|
||||
* <p>
|
||||
* Specific instances of nodes are unique, but may share GUIDs across stores.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface Node
|
||||
{
|
||||
/**
|
||||
* @return Returns the unique key for this node
|
||||
*/
|
||||
public NodeKey getKey();
|
||||
|
||||
/**
|
||||
* @param key the unique node key
|
||||
*/
|
||||
public void setKey(NodeKey key);
|
||||
|
||||
public Store getStore();
|
||||
|
||||
public void setStore(Store store);
|
||||
|
||||
public QName getTypeQName();
|
||||
|
||||
public void setTypeQName(QName typeQName);
|
||||
|
||||
/**
|
||||
* Set the status of the node. This is compulsory, but a node
|
||||
* status may exist without a node being present.
|
||||
*
|
||||
* @param nodeStatus
|
||||
*/
|
||||
public void setStatus(NodeStatus nodeStatus);
|
||||
|
||||
/**
|
||||
* Get the mandatory node status object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public NodeStatus getStatus();
|
||||
|
||||
public Set<QName> getAspects();
|
||||
|
||||
/**
|
||||
* @return Returns all the regular associations for which this node is a target
|
||||
*/
|
||||
public Collection<NodeAssoc> getSourceNodeAssocs();
|
||||
|
||||
/**
|
||||
* @return Returns all the regular associations for which this node is a source
|
||||
*/
|
||||
public Collection<NodeAssoc> getTargetNodeAssocs();
|
||||
|
||||
public Collection<ChildAssoc> getChildAssocs();
|
||||
|
||||
public Collection<ChildAssoc> getParentAssocs();
|
||||
|
||||
public Map<QName, PropertyValue> getProperties();
|
||||
|
||||
/**
|
||||
* Convenience method to get the reference to the node
|
||||
*
|
||||
* @return Returns the reference to this node
|
||||
*/
|
||||
public NodeRef getNodeRef();
|
||||
}
|
66
source/java/org/alfresco/repo/domain/NodeAssoc.java
Normal file
66
source/java/org/alfresco/repo/domain/NodeAssoc.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Represents a generic association between two nodes. The association is named
|
||||
* and bidirectional by default.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface NodeAssoc
|
||||
{
|
||||
public long getId();
|
||||
|
||||
/**
|
||||
* Wires up the necessary bits on the source and target nodes so that the association
|
||||
* is immediately bidirectional.
|
||||
* <p>
|
||||
* The association attributes still have to be set.
|
||||
*
|
||||
* @param sourceNode
|
||||
* @param targetNode
|
||||
*
|
||||
* @see #setName(String)
|
||||
*/
|
||||
public void buildAssociation(Node sourceNode, Node targetNode);
|
||||
|
||||
/**
|
||||
* Performs the necessary work on the {@link #getSource()() source} and
|
||||
* {@link #getTarget()() target} nodes to maintain the inverse association sets
|
||||
*/
|
||||
public void removeAssociation();
|
||||
|
||||
public AssociationRef getNodeAssocRef();
|
||||
|
||||
public Node getSource();
|
||||
|
||||
public Node getTarget();
|
||||
|
||||
/**
|
||||
* @return Returns the qualified name of this association type
|
||||
*/
|
||||
public QName getTypeQName();
|
||||
|
||||
/**
|
||||
* @param qname the qualified name of the association type
|
||||
*/
|
||||
public void setTypeQName(QName qname);
|
||||
}
|
123
source/java/org/alfresco/repo/domain/NodeKey.java
Normal file
123
source/java/org/alfresco/repo/domain/NodeKey.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.io.Serializable;
|
||||
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* Compound key for persistence of {@link org.alfresco.repo.domain.Node}
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class NodeKey implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 3258695403221300023L;
|
||||
|
||||
private String guid;
|
||||
private String protocol;
|
||||
private String identifier;
|
||||
|
||||
public NodeKey()
|
||||
{
|
||||
}
|
||||
|
||||
public NodeKey(StoreKey storeKey, String guid)
|
||||
{
|
||||
setGuid(guid);
|
||||
setProtocol(storeKey.getProtocol());
|
||||
setIdentifier(storeKey.getIdentifier());
|
||||
}
|
||||
|
||||
public NodeKey(String protocol, String identifier, String guid)
|
||||
{
|
||||
setGuid(guid);
|
||||
setProtocol(protocol);
|
||||
setIdentifier(identifier);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return ("NodeKey[" +
|
||||
" id=" + guid +
|
||||
", protocol=" + protocol +
|
||||
", identifier=" + identifier +
|
||||
"]");
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.guid.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof NodeKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
NodeKey that = (NodeKey) obj;
|
||||
return (EqualsHelper.nullSafeEquals(this.guid, that.guid) &&
|
||||
EqualsHelper.nullSafeEquals(this.protocol, that.protocol) &&
|
||||
EqualsHelper.nullSafeEquals(this.identifier, that.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
public String getGuid()
|
||||
{
|
||||
return guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tamper-proof method only to be used by introspectors
|
||||
*/
|
||||
private void setGuid(String id)
|
||||
{
|
||||
this.guid = id;
|
||||
}
|
||||
|
||||
public String getProtocol()
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tamper-proof method only to be used by introspectors
|
||||
*/
|
||||
private void setProtocol(String protocol)
|
||||
{
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getIdentifier()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tamper-proof method only to be used by introspectors
|
||||
*/
|
||||
private void setIdentifier(String identifier)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
}
|
||||
}
|
47
source/java/org/alfresco/repo/domain/NodeStatus.java
Normal file
47
source/java/org/alfresco/repo/domain/NodeStatus.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for persistent <b>node status</b> objects.
|
||||
* <p>
|
||||
* The node status records the liveness and change times of a node. It follows
|
||||
* that a <b>node</b> might not exist (have been deleted) when the
|
||||
* <b>node status</b> still exists.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface NodeStatus
|
||||
{
|
||||
/**
|
||||
* @return Returns the unique key for this node status
|
||||
*/
|
||||
public NodeKey getKey();
|
||||
|
||||
/**
|
||||
* @param key the unique key
|
||||
*/
|
||||
public void setKey(NodeKey key);
|
||||
|
||||
public String getChangeTxnId();
|
||||
|
||||
public void setChangeTxnId(String txnId);
|
||||
|
||||
public void setDeleted(boolean deleted);
|
||||
|
||||
public boolean isDeleted();
|
||||
}
|
606
source/java/org/alfresco/repo/domain/PropertyValue.java
Normal file
606
source/java/org/alfresco/repo/domain/PropertyValue.java
Normal file
@@ -0,0 +1,606 @@
|
||||
/*
|
||||
* 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.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Immutable property value storage class.
|
||||
* <p>
|
||||
* The
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class PropertyValue implements Cloneable, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -497902497351493075L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(PropertyValue.class);
|
||||
|
||||
/** potential value types */
|
||||
private static enum ValueType
|
||||
{
|
||||
NULL
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
},
|
||||
BOOLEAN
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Boolean.class, value);
|
||||
}
|
||||
},
|
||||
INTEGER
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.LONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Integer.class, value);
|
||||
}
|
||||
},
|
||||
LONG
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Long.class, value);
|
||||
}
|
||||
},
|
||||
FLOAT
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Float.class, value);
|
||||
}
|
||||
},
|
||||
DOUBLE
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Double.class, value);
|
||||
}
|
||||
},
|
||||
STRING
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
}
|
||||
},
|
||||
DATE
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Date.class, value);
|
||||
}
|
||||
},
|
||||
SERIALIZABLE
|
||||
{
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
},
|
||||
CONTENT
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(ContentData.class, value);
|
||||
}
|
||||
},
|
||||
NODEREF
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(NodeRef.class, value);
|
||||
}
|
||||
},
|
||||
QNAME
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(QName.class, value);
|
||||
}
|
||||
},
|
||||
PATH
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return ValueType.SERIALIZABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(Path.class, value);
|
||||
}
|
||||
};
|
||||
|
||||
/** override if the type gets persisted in a different format */
|
||||
protected ValueType getPersistedType()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DefaultTypeConverter.INSTANCE#convert(Class, Object)
|
||||
*/
|
||||
abstract Serializable convert(Serializable value);
|
||||
|
||||
protected ArrayList<Serializable> convert(Collection collection)
|
||||
{
|
||||
ArrayList<Serializable> arrayList = new ArrayList<Serializable>(collection.size());
|
||||
for (Object object : collection)
|
||||
{
|
||||
Serializable newValue = null;
|
||||
if (object != null)
|
||||
{
|
||||
if (!(object instanceof Serializable))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Collection values must contain Serializable instances: \n" +
|
||||
" value type: " + this + "\n" +
|
||||
" collection: " + collection + "\n" +
|
||||
" value: " + object);
|
||||
}
|
||||
Serializable value = (Serializable) object;
|
||||
newValue = convert(value);
|
||||
}
|
||||
arrayList.add(newValue);
|
||||
}
|
||||
// done
|
||||
return arrayList;
|
||||
}
|
||||
}
|
||||
|
||||
/** a mapping from a property type <code>QName</code> to the corresponding value type */
|
||||
private static Map<QName, ValueType> valueTypesByPropertyType;
|
||||
static
|
||||
{
|
||||
valueTypesByPropertyType = new HashMap<QName, ValueType>(17);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.ANY, ValueType.SERIALIZABLE);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.BOOLEAN, ValueType.BOOLEAN);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.INT, ValueType.INTEGER);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.LONG, ValueType.LONG);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.DOUBLE, ValueType.DOUBLE);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.FLOAT, ValueType.FLOAT);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.DATE, ValueType.DATE);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.DATETIME, ValueType.DATE);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.CATEGORY, ValueType.NODEREF);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.CONTENT, ValueType.CONTENT);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.TEXT, ValueType.STRING);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.NODE_REF, ValueType.NODEREF);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.PATH, ValueType.PATH);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.QNAME, ValueType.QNAME);
|
||||
}
|
||||
|
||||
/** the type of the property, prior to serialization persistence */
|
||||
private ValueType actualType;
|
||||
/** true if the property values are contained in a collection */
|
||||
private boolean isMultiValued;
|
||||
/** the type of persistence used */
|
||||
private ValueType persistedType;
|
||||
|
||||
private Boolean booleanValue;
|
||||
private Long longValue;
|
||||
private Float floatValue;
|
||||
private Double doubleValue;
|
||||
private String stringValue;
|
||||
private Serializable serializableValue;
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public PropertyValue()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new property value.
|
||||
*
|
||||
* @param typeQName the dictionary-defined property type to store the property as
|
||||
* @param value the value to store. This will be converted into a format compatible
|
||||
* with the type given
|
||||
*
|
||||
* @throws java.lang.UnsupportedOperationException if the value cannot be converted to the
|
||||
* type given
|
||||
*/
|
||||
public PropertyValue(QName typeQName, Serializable value)
|
||||
{
|
||||
this.actualType = makeValueType(typeQName);
|
||||
if (value == null)
|
||||
{
|
||||
setPersistedValue(ValueType.NULL, null);
|
||||
setMultiValued(false);
|
||||
}
|
||||
else if (value instanceof Collection)
|
||||
{
|
||||
Collection collection = (Collection) value;
|
||||
ValueType collectionValueType = makeValueType(typeQName);
|
||||
// convert the collection values - we need to do this to ensure that the
|
||||
// values provided conform to the given type
|
||||
ArrayList<Serializable> convertedCollection = collectionValueType.convert(collection);
|
||||
// the persisted type is, nonetheless, a serializable
|
||||
setPersistedValue(ValueType.SERIALIZABLE, convertedCollection);
|
||||
setMultiValued(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the persisted type
|
||||
ValueType valueType = makeValueType(typeQName);
|
||||
ValueType persistedValueType = valueType.getPersistedType();
|
||||
// convert to the persistent type
|
||||
value = persistedValueType.convert(value);
|
||||
setPersistedValue(persistedValueType, value);
|
||||
setMultiValued(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to convert the type <code>QName</code> into a <code>ValueType</code>
|
||||
*
|
||||
* @return Returns the <code>ValueType</code> - never null
|
||||
*/
|
||||
private 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);
|
||||
}
|
||||
return valueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof PropertyValue)
|
||||
{
|
||||
PropertyValue that = (PropertyValue) obj;
|
||||
return (this.actualType.equals(that.actualType) &&
|
||||
EqualsHelper.nullSafeEquals(this.booleanValue, that.booleanValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.longValue, that.longValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.floatValue, that.floatValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.doubleValue, that.doubleValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.serializableValue, that.serializableValue)
|
||||
);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int h = 0;
|
||||
if (actualType != null)
|
||||
h = actualType.hashCode();
|
||||
Serializable persistedValue = getPersistedValue();
|
||||
if (persistedValue != null)
|
||||
h += 17 * persistedValue.hashCode();
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("PropertyValue")
|
||||
.append("[actual-type=").append(actualType)
|
||||
.append(", multi-valued=").append(isMultiValued)
|
||||
.append(", value-type=").append(persistedType)
|
||||
.append(", value=").append(getPersistedValue())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getActualType()
|
||||
{
|
||||
return actualType.toString();
|
||||
}
|
||||
|
||||
public void setActualType(String actualType)
|
||||
{
|
||||
this.actualType = ValueType.valueOf(actualType);
|
||||
}
|
||||
|
||||
public boolean isMultiValued()
|
||||
{
|
||||
return isMultiValued;
|
||||
}
|
||||
|
||||
public void setMultiValued(boolean isMultiValued)
|
||||
{
|
||||
this.isMultiValued = isMultiValued;
|
||||
}
|
||||
|
||||
public String getPersistedType()
|
||||
{
|
||||
return persistedType.toString();
|
||||
}
|
||||
public void setPersistedType(String persistedType)
|
||||
{
|
||||
this.persistedType = ValueType.valueOf(persistedType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the value in the correct slot based on the type of persistence requested.
|
||||
* No conversion is done.
|
||||
*
|
||||
* @param persistedType the value type
|
||||
* @param value the value - it may only be null if the persisted type is {@link ValueType#NULL}
|
||||
*/
|
||||
public void setPersistedValue(ValueType persistedType, Serializable value)
|
||||
{
|
||||
switch (persistedType)
|
||||
{
|
||||
case NULL:
|
||||
if (value != null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Value must be null for persisted type: " + persistedType);
|
||||
}
|
||||
break;
|
||||
case BOOLEAN:
|
||||
this.booleanValue = (Boolean) value;
|
||||
break;
|
||||
case LONG:
|
||||
this.longValue = (Long) value;
|
||||
break;
|
||||
case FLOAT:
|
||||
this.floatValue = (Float) value;
|
||||
break;
|
||||
case DOUBLE:
|
||||
this.doubleValue = (Double) value;
|
||||
break;
|
||||
case STRING:
|
||||
this.stringValue = (String) value;
|
||||
break;
|
||||
case SERIALIZABLE:
|
||||
this.serializableValue = (Serializable) value;
|
||||
break;
|
||||
default:
|
||||
throw new AlfrescoRuntimeException("Unrecognised value type: " + persistedType);
|
||||
}
|
||||
// we store the type that we persisted as
|
||||
this.persistedType = persistedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the persisted value, keying off the persisted value type
|
||||
*/
|
||||
private Serializable getPersistedValue()
|
||||
{
|
||||
switch (persistedType)
|
||||
{
|
||||
case NULL:
|
||||
return null;
|
||||
case BOOLEAN:
|
||||
return this.booleanValue;
|
||||
case LONG:
|
||||
return this.longValue;
|
||||
case FLOAT:
|
||||
return this.floatValue;
|
||||
case DOUBLE:
|
||||
return this.doubleValue;
|
||||
case STRING:
|
||||
return this.stringValue;
|
||||
case SERIALIZABLE:
|
||||
return this.serializableValue;
|
||||
default:
|
||||
throw new AlfrescoRuntimeException("Unrecognised value type: " + persistedType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the value as a desired type. Collections (i.e. multi-valued properties)
|
||||
* will be converted as a whole to ensure that all the values returned within the
|
||||
* collection match the given type.
|
||||
*
|
||||
* @param typeQName the type required for the return value
|
||||
* @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
|
||||
*
|
||||
* @see DataTypeDefinition#ANY The static qualified names for the types
|
||||
*/
|
||||
public Serializable getValue(QName typeQName)
|
||||
{
|
||||
// first check for null
|
||||
|
||||
ValueType requiredType = makeValueType(typeQName);
|
||||
|
||||
// we need to convert
|
||||
Serializable ret = null;
|
||||
if (persistedType == ValueType.NULL)
|
||||
{
|
||||
ret = null;
|
||||
}
|
||||
else if (this.isMultiValued)
|
||||
{
|
||||
// collections are always stored
|
||||
Collection collection = (Collection) this.serializableValue;
|
||||
// convert the collection values - we need to do this to ensure that the
|
||||
// values provided conform to the given type
|
||||
ArrayList<Serializable> convertedCollection = requiredType.convert(collection);
|
||||
ret = convertedCollection;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serializable persistedValue = getPersistedValue();
|
||||
// convert the type
|
||||
ret = requiredType.convert(persistedValue);
|
||||
}
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Fetched value: \n" +
|
||||
" property value: " + this + "\n" +
|
||||
" requested type: " + requiredType + "\n" +
|
||||
" result: " + ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean getBooleanValue()
|
||||
{
|
||||
if (booleanValue == null)
|
||||
return false;
|
||||
else
|
||||
return booleanValue.booleanValue();
|
||||
}
|
||||
public void setBooleanValue(boolean value)
|
||||
{
|
||||
this.booleanValue = Boolean.valueOf(value);
|
||||
}
|
||||
|
||||
public long getLongValue()
|
||||
{
|
||||
if (longValue == null)
|
||||
return 0;
|
||||
else
|
||||
return longValue.longValue();
|
||||
}
|
||||
public void setLongValue(long value)
|
||||
{
|
||||
this.longValue = Long.valueOf(value);
|
||||
}
|
||||
|
||||
public float getFloatValue()
|
||||
{
|
||||
if (floatValue == null)
|
||||
return 0.0F;
|
||||
else
|
||||
return floatValue.floatValue();
|
||||
}
|
||||
public void setFloatValue(float value)
|
||||
{
|
||||
this.floatValue = Float.valueOf(value);
|
||||
}
|
||||
|
||||
public double getDoubleValue()
|
||||
{
|
||||
if (doubleValue == null)
|
||||
return 0.0;
|
||||
else
|
||||
return doubleValue.doubleValue();
|
||||
}
|
||||
public void setDoubleValue(double value)
|
||||
{
|
||||
this.doubleValue = Double.valueOf(value);
|
||||
}
|
||||
|
||||
public String getStringValue()
|
||||
{
|
||||
return stringValue;
|
||||
}
|
||||
public void setStringValue(String value)
|
||||
{
|
||||
this.stringValue = value;
|
||||
}
|
||||
|
||||
public Serializable getSerializableValue()
|
||||
{
|
||||
return serializableValue;
|
||||
}
|
||||
public void setSerializableValue(Serializable value)
|
||||
{
|
||||
this.serializableValue = value;
|
||||
}
|
||||
}
|
54
source/java/org/alfresco/repo/domain/Store.java
Normal file
54
source/java/org/alfresco/repo/domain/Store.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.StoreKey;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
/**
|
||||
* Represents a store entity
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface Store
|
||||
{
|
||||
/**
|
||||
* @return Returns the key for the class
|
||||
*/
|
||||
public StoreKey getKey();
|
||||
|
||||
/**
|
||||
* @param key the key uniquely identifying this store
|
||||
*/
|
||||
public void setKey(StoreKey key);
|
||||
|
||||
/**
|
||||
* @return Returns the root of the store
|
||||
*/
|
||||
public Node getRootNode();
|
||||
|
||||
/**
|
||||
* @param rootNode mandatory association to the root of the store
|
||||
*/
|
||||
public void setRootNode(Node rootNode);
|
||||
|
||||
/**
|
||||
* Convenience method to access the reference
|
||||
* @return Returns the reference to the store
|
||||
*/
|
||||
public StoreRef getStoreRef();
|
||||
}
|
98
source/java/org/alfresco/repo/domain/StoreKey.java
Normal file
98
source/java/org/alfresco/repo/domain/StoreKey.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.io.Serializable;
|
||||
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* Compound key for persistence of {@link org.alfresco.repo.domain.Store}
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class StoreKey implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 3618140052220096569L;
|
||||
|
||||
private String protocol;
|
||||
private String identifier;
|
||||
|
||||
public StoreKey()
|
||||
{
|
||||
}
|
||||
|
||||
public StoreKey(String protocol, String identifier)
|
||||
{
|
||||
setProtocol(protocol);
|
||||
setIdentifier(identifier);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return ("StoreKey[" +
|
||||
" protocol=" + protocol +
|
||||
", identifier=" + identifier +
|
||||
"]");
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (this.protocol.hashCode() + this.identifier.hashCode());
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof StoreKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
StoreKey that = (StoreKey) obj;
|
||||
return (EqualsHelper.nullSafeEquals(this.protocol, that.protocol) &&
|
||||
EqualsHelper.nullSafeEquals(this.identifier, that.identifier));
|
||||
}
|
||||
|
||||
public String getProtocol()
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tamper-proof method only to be used by introspectors
|
||||
*/
|
||||
private void setProtocol(String protocol)
|
||||
{
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getIdentifier()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tamper-proof method only to be used by introspectors
|
||||
*/
|
||||
private void setIdentifier(String identifier)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
}
|
||||
}
|
59
source/java/org/alfresco/repo/domain/VersionCount.java
Normal file
59
source/java/org/alfresco/repo/domain/VersionCount.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Represents a version count entity for a particular store.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface VersionCount
|
||||
{
|
||||
/**
|
||||
* @return Returns the key for the version counter
|
||||
*/
|
||||
public StoreKey getKey();
|
||||
|
||||
/**
|
||||
* @param key the key uniquely identifying this version counter
|
||||
*/
|
||||
public void setKey(StoreKey key);
|
||||
|
||||
/**
|
||||
* Increments and returns the next version counter associated with this
|
||||
* store.
|
||||
*
|
||||
* @return Returns the next version counter in the sequence
|
||||
*
|
||||
* @see #getVersionCount()
|
||||
*/
|
||||
public int incrementVersionCount();
|
||||
|
||||
/**
|
||||
* Reset the store's version counter
|
||||
*/
|
||||
public void resetVersionCount();
|
||||
|
||||
/**
|
||||
* Retrieve the current version counter
|
||||
*
|
||||
* @return Returns a current version counter
|
||||
*
|
||||
* @see #incrementVersionCount()
|
||||
*/
|
||||
public int getVersionCount();
|
||||
}
|
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.ChildAssoc;
|
||||
import org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class ChildAssocImpl implements ChildAssoc
|
||||
{
|
||||
private Long id;
|
||||
private Node parent;
|
||||
private Node child;
|
||||
private QName typeQName;
|
||||
private QName qName;
|
||||
private boolean isPrimary;
|
||||
private int index;
|
||||
private transient ChildAssociationRef childAssocRef;
|
||||
|
||||
public ChildAssocImpl()
|
||||
{
|
||||
setIndex(Integer.MAX_VALUE); // comes last
|
||||
}
|
||||
|
||||
public void buildAssociation(Node parentNode, Node childNode)
|
||||
{
|
||||
// add the forward associations
|
||||
this.setParent(parentNode);
|
||||
this.setChild(childNode);
|
||||
// add the inverse associations
|
||||
parentNode.getChildAssocs().add(this);
|
||||
childNode.getParentAssocs().add(this);
|
||||
}
|
||||
|
||||
public void removeAssociation()
|
||||
{
|
||||
// maintain inverse assoc from parent node to this instance
|
||||
this.getParent().getChildAssocs().remove(this);
|
||||
// maintain inverse assoc from child node to this instance
|
||||
this.getChild().getParentAssocs().remove(this);
|
||||
}
|
||||
|
||||
public synchronized ChildAssociationRef getChildAssocRef()
|
||||
{
|
||||
if (childAssocRef == null)
|
||||
{
|
||||
childAssocRef = new ChildAssociationRef(
|
||||
this.typeQName,
|
||||
getParent().getNodeRef(),
|
||||
this.qName,
|
||||
getChild().getNodeRef(),
|
||||
this.isPrimary,
|
||||
-1);
|
||||
}
|
||||
return childAssocRef;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer(32);
|
||||
sb.append("ChildAssoc")
|
||||
.append("[ parent=").append(parent)
|
||||
.append(", child=").append(child)
|
||||
.append(", name=").append(getQname())
|
||||
.append(", isPrimary=").append(isPrimary)
|
||||
.append("]");
|
||||
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 (this.getIsPrimary() == that.getIsPrimary()
|
||||
&& EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
|
||||
&& EqualsHelper.nullSafeEquals(this.getQname(), that.getQname())
|
||||
&& EqualsHelper.nullSafeEquals(this.getParent(), that.getParent())
|
||||
&& EqualsHelper.nullSafeEquals(this.getChild(), that.getChild()));
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (qName == null ? 0 : qName.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.
|
||||
*/
|
||||
public int compareTo(ChildAssoc another)
|
||||
{
|
||||
if (this == another)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thisIndex = this.getIndex();
|
||||
int anotherIndex = another.getIndex();
|
||||
|
||||
Long thisId = this.getId();
|
||||
Long anotherId = another.getId();
|
||||
|
||||
if (thisId == null) // this ID has not been set, make this instance greater
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (anotherId == null) // other ID has not been set, make this instance lesser
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (thisIndex == anotherIndex) // use the explicit index
|
||||
{
|
||||
return thisId.compareTo(anotherId);
|
||||
}
|
||||
else // fallback on order of creation
|
||||
{
|
||||
return (thisIndex > anotherIndex) ? 1 : -1; // a lower index, make this instance lesser
|
||||
}
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Node getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setParent(Node parentNode)
|
||||
{
|
||||
this.parent = parentNode;
|
||||
}
|
||||
|
||||
public Node getChild()
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setChild(Node node)
|
||||
{
|
||||
child = node;
|
||||
}
|
||||
|
||||
public QName getTypeQName()
|
||||
{
|
||||
return typeQName;
|
||||
}
|
||||
|
||||
public void setTypeQName(QName typeQName)
|
||||
{
|
||||
this.typeQName = typeQName;
|
||||
}
|
||||
|
||||
public QName getQname()
|
||||
{
|
||||
return qName;
|
||||
}
|
||||
|
||||
public void setQname(QName qname)
|
||||
{
|
||||
this.qName = qname;
|
||||
}
|
||||
|
||||
public boolean getIsPrimary()
|
||||
{
|
||||
return isPrimary;
|
||||
}
|
||||
|
||||
public void setIsPrimary(boolean isPrimary)
|
||||
{
|
||||
this.isPrimary = isPrimary;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index)
|
||||
{
|
||||
this.index = index;
|
||||
}
|
||||
}
|
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* 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.Iterator;
|
||||
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.NodeAssoc;
|
||||
import org.alfresco.repo.domain.NodeKey;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.domain.Store;
|
||||
import org.alfresco.repo.domain.StoreKey;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Test persistence and retrieval of Hibernate-specific implementations of the
|
||||
* {@link org.alfresco.repo.domain.Node} interface
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class HibernateNodeTest extends BaseSpringTest
|
||||
{
|
||||
private static final String TEST_NAMESPACE = "http://www.alfresco.org/test/HibernateNodeTest";
|
||||
|
||||
private Store store;
|
||||
|
||||
public HibernateNodeTest()
|
||||
{
|
||||
}
|
||||
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
NodeKey key = new NodeKey("Random Protocol", "Random Identifier", "AAA");
|
||||
// create the node status
|
||||
NodeStatus nodeStatus = new NodeStatusImpl();
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(nodeStatus);
|
||||
// create a new Node
|
||||
Node node = new NodeImpl();
|
||||
node.setKey(key);
|
||||
node.setStore(store); // not meaningful as it contradicts the key
|
||||
node.setTypeQName(ContentModel.TYPE_CONTAINER);
|
||||
node.setStatus(nodeStatus);
|
||||
// persist it
|
||||
try
|
||||
{
|
||||
Serializable id = getSession().save(node);
|
||||
fail("No store exists");
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
// this should not solve the problem
|
||||
node.setStore(store);
|
||||
// persist it
|
||||
try
|
||||
{
|
||||
Serializable id = getSession().save(node);
|
||||
fail("Setting store does not persist protocol and identifier attributes");
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
// fix the key
|
||||
key = new NodeKey(store.getKey().getProtocol(), store.getKey().getIdentifier(), "AAA");
|
||||
node.setKey(key);
|
||||
// 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.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(nodeStatus);
|
||||
|
||||
// it must be able to exist without the node
|
||||
flushAndClear();
|
||||
|
||||
// create a new Node
|
||||
Node node = new NodeImpl();
|
||||
node.setStore(store);
|
||||
node.setKey(key);
|
||||
node.setStore(store); // not meaningful as it contradicts the key
|
||||
node.setTypeQName(ContentModel.TYPE_CONTAINER);
|
||||
node.setStatus(nodeStatus);
|
||||
Serializable id = getSession().save(node);
|
||||
|
||||
// flush
|
||||
flushAndClear();
|
||||
|
||||
// is the status retrievable
|
||||
node = (Node) getSession().get(NodeImpl.class, id);
|
||||
nodeStatus = node.getStatus();
|
||||
// change the values
|
||||
nodeStatus.setChangeTxnId("txn:456");
|
||||
nodeStatus.setDeleted(true);
|
||||
// delete the node
|
||||
getSession().delete(node);
|
||||
|
||||
// flush
|
||||
flushAndClear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that properties can be persisted and retrieved
|
||||
*/
|
||||
public void testProperties() throws Exception
|
||||
{
|
||||
NodeKey key = new NodeKey(store.getKey(), "AAA");
|
||||
// create the node status
|
||||
NodeStatus nodeStatus = new NodeStatusImpl();
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(nodeStatus);
|
||||
// create a new Node
|
||||
Node node = new NodeImpl();
|
||||
node.setKey(key);
|
||||
node.setTypeQName(ContentModel.TYPE_CONTAINER);
|
||||
node.setStatus(nodeStatus);
|
||||
// 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
|
||||
{
|
||||
NodeKey key = new NodeKey(store.getKey(), GUID.generate());
|
||||
// create the node status
|
||||
NodeStatus nodeStatus = new NodeStatusImpl();
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(nodeStatus);
|
||||
// make a real node
|
||||
Node node = new NodeImpl();
|
||||
node.setKey(key);
|
||||
node.setStore(store);
|
||||
node.setTypeQName(ContentModel.TYPE_CMOBJECT);
|
||||
node.setStatus(nodeStatus);
|
||||
|
||||
// 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 testNodeAssoc() throws Exception
|
||||
{
|
||||
NodeKey sourceKey = new NodeKey(store.getKey(), GUID.generate());
|
||||
// make a source node
|
||||
NodeStatus sourceNodeStatus = new NodeStatusImpl();
|
||||
sourceNodeStatus.setKey(sourceKey);
|
||||
sourceNodeStatus.setDeleted(false);
|
||||
sourceNodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(sourceNodeStatus);
|
||||
Node sourceNode = new NodeImpl();
|
||||
sourceNode.setKey(sourceKey);
|
||||
sourceNode.setStore(store);
|
||||
sourceNode.setTypeQName(ContentModel.TYPE_CMOBJECT);
|
||||
sourceNode.setStatus(sourceNodeStatus);
|
||||
Serializable realNodeKey = getSession().save(sourceNode);
|
||||
|
||||
// make a container node
|
||||
NodeKey targetKey = new NodeKey(store.getKey(), GUID.generate());
|
||||
NodeStatus targetNodeStatus = new NodeStatusImpl();
|
||||
targetNodeStatus.setKey(targetKey);
|
||||
targetNodeStatus.setDeleted(false);
|
||||
targetNodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(targetNodeStatus);
|
||||
Node targetNode = new NodeImpl();
|
||||
targetNode.setKey(targetKey);
|
||||
targetNode.setStore(store);
|
||||
targetNode.setTypeQName(ContentModel.TYPE_CONTAINER);
|
||||
targetNode.setStatus(targetNodeStatus);
|
||||
Serializable containerNodeKey = getSession().save(targetNode);
|
||||
|
||||
// create an association between them
|
||||
NodeAssoc assoc = new NodeAssocImpl();
|
||||
assoc.setTypeQName(QName.createQName("next"));
|
||||
assoc.buildAssociation(sourceNode, targetNode);
|
||||
getSession().save(assoc);
|
||||
|
||||
// make another association between the same two nodes
|
||||
assoc = new NodeAssocImpl();
|
||||
assoc.setTypeQName(QName.createQName("helper"));
|
||||
assoc.buildAssociation(sourceNode, targetNode);
|
||||
getSession().save(assoc);
|
||||
|
||||
// flush and clear the session
|
||||
getSession().flush();
|
||||
getSession().clear();
|
||||
|
||||
// reload the source
|
||||
sourceNode = (Node) getSession().get(NodeImpl.class, sourceKey);
|
||||
assertNotNull("Source node not found", sourceNode);
|
||||
// check that the associations are present
|
||||
assertEquals("Expected exactly 2 target assocs", 2, sourceNode.getTargetNodeAssocs().size());
|
||||
|
||||
// reload the target
|
||||
targetNode = (Node) getSession().get(NodeImpl.class, targetKey);
|
||||
assertNotNull("Target node not found", targetNode);
|
||||
// check that the associations are present
|
||||
assertEquals("Expected exactly 2 source assocs", 2, targetNode.getSourceNodeAssocs().size());
|
||||
}
|
||||
|
||||
public void testChildAssoc() throws Exception
|
||||
{
|
||||
// make a content node
|
||||
NodeKey key = new NodeKey(store.getKey(), GUID.generate());
|
||||
NodeStatus contentNodeStatus = new NodeStatusImpl();
|
||||
contentNodeStatus.setKey(key);
|
||||
contentNodeStatus.setDeleted(false);
|
||||
contentNodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(contentNodeStatus);
|
||||
Node contentNode = new NodeImpl();
|
||||
contentNode.setKey(key);
|
||||
contentNode.setStore(store);
|
||||
contentNode.setTypeQName(ContentModel.TYPE_CONTENT);
|
||||
contentNode.setStatus(contentNodeStatus);
|
||||
Serializable contentNodeKey = getSession().save(contentNode);
|
||||
|
||||
// make a container node
|
||||
key = new NodeKey(store.getKey(), GUID.generate());
|
||||
NodeStatus containerNodeStatus = new NodeStatusImpl();
|
||||
containerNodeStatus.setKey(key);
|
||||
containerNodeStatus.setDeleted(false);
|
||||
containerNodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(containerNodeStatus);
|
||||
Node containerNode = new NodeImpl();
|
||||
containerNode.setKey(key);
|
||||
containerNode.setStore(store);
|
||||
containerNode.setTypeQName(ContentModel.TYPE_CONTAINER);
|
||||
containerNode.setStatus(containerNodeStatus);
|
||||
Serializable containerNodeKey = 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.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, "type1"));
|
||||
assoc2.setQname(QName.createQName(null, "number2"));
|
||||
assoc2.buildAssociation(containerNode, contentNode);
|
||||
getSession().save(assoc2);
|
||||
|
||||
assertFalse("Hashcode incorrent", assoc2.hashCode() == 0);
|
||||
assertNotSame("Assoc equals failure", assoc1, assoc2);
|
||||
|
||||
// flushAndClear();
|
||||
|
||||
// reload the container
|
||||
containerNode = (Node) getSession().get(NodeImpl.class, containerNodeKey);
|
||||
assertNotNull("Node not found", containerNode);
|
||||
// check
|
||||
assertEquals("Expected exactly 2 children", 2, containerNode.getChildAssocs().size());
|
||||
for (Iterator iterator = containerNode.getChildAssocs().iterator(); iterator.hasNext(); /**/)
|
||||
{
|
||||
ChildAssoc assoc = (ChildAssoc) iterator.next();
|
||||
// the node id must be known
|
||||
assertNotNull("Node not populated on assoc", assoc.getChild());
|
||||
assertEquals("Node key on child assoc is incorrect", contentNodeKey,
|
||||
assoc.getChild().getKey());
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
NodeKey key = new NodeKey(store.getKey(), GUID.generate());
|
||||
|
||||
// make a node
|
||||
NodeStatus nodeStatus = new NodeStatusImpl();
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId("txn:123");
|
||||
getSession().save(nodeStatus);
|
||||
Node node = new NodeImpl();
|
||||
node.setKey(key);
|
||||
node.setStore(store);
|
||||
node.setTypeQName(ContentModel.TYPE_CONTENT);
|
||||
node.setStatus(nodeStatus);
|
||||
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, key);
|
||||
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));
|
||||
// assertTrue("Property value instance retrieved not the same", checkProperties)
|
||||
|
||||
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, key);
|
||||
assertNotNull(checkNode);
|
||||
checkAspects = checkNode.getAspects();
|
||||
|
||||
// assertTrue("Node retrieved was not same instance", checkNode == node);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
txn.rollback();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
333
source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml
Normal file
333
source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml
Normal file
@@ -0,0 +1,333 @@
|
||||
<?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>
|
||||
|
||||
<typedef class="org.alfresco.repo.domain.hibernate.QNameUserType" name="QName" />
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
proxy="org.alfresco.repo.domain.Node"
|
||||
table="node"
|
||||
dynamic-update="false"
|
||||
dynamic-insert="false"
|
||||
select-before-update="false"
|
||||
lazy="true"
|
||||
optimistic-lock="version" >
|
||||
<!-- composite PK -->
|
||||
<composite-id name="key" class="org.alfresco.repo.domain.NodeKey">
|
||||
<key-property name="protocol" length="50" />
|
||||
<key-property name="identifier" length="100" />
|
||||
<key-property name="guid" length="36"/>
|
||||
</composite-id>
|
||||
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
|
||||
<!-- forward assoc to node status -->
|
||||
<one-to-one
|
||||
name="status"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeStatusImpl"
|
||||
constrained="true"
|
||||
lazy="no-proxy"
|
||||
fetch="select">
|
||||
</one-to-one>
|
||||
<!-- forward assoc to properties -->
|
||||
<map
|
||||
name="properties"
|
||||
table="node_properties"
|
||||
lazy="false"
|
||||
fetch="join"
|
||||
sort="unsorted"
|
||||
inverse="false"
|
||||
optimistic-lock="true"
|
||||
cascade="delete" >
|
||||
<key>
|
||||
<column name="protocol" length="50" />
|
||||
<column name="identifier" length="100" />
|
||||
<column name="guid" length="36" />
|
||||
</key>
|
||||
<map-key column="qname" type="QName" length="128" />
|
||||
<composite-element class="org.alfresco.repo.domain.PropertyValue" >
|
||||
<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"/>
|
||||
</composite-element>
|
||||
</map>
|
||||
<!-- forward assoc to aspects -->
|
||||
<set
|
||||
name="aspects"
|
||||
table="node_aspects"
|
||||
lazy="true"
|
||||
sort="unsorted"
|
||||
inverse="false"
|
||||
fetch="select"
|
||||
optimistic-lock="true"
|
||||
cascade="delete" >
|
||||
<key>
|
||||
<column name="protocol" length="50" />
|
||||
<column name="identifier" length="100" />
|
||||
<column name="guid" length="36" />
|
||||
</key>
|
||||
<element column="qname" type="QName" length="128"/>
|
||||
</set>
|
||||
<!-- forward assoc to store -->
|
||||
<many-to-one
|
||||
name="store"
|
||||
class="org.alfresco.repo.domain.hibernate.StoreImpl"
|
||||
not-null="true"
|
||||
insert="false"
|
||||
update="false"
|
||||
lazy="no-proxy"
|
||||
optimistic-lock="true"
|
||||
fetch="select">
|
||||
<column name="protocol" />
|
||||
<column name="identifier" />
|
||||
</many-to-one>
|
||||
<!-- inverse assoc to parent childassocs -->
|
||||
<bag
|
||||
name="parentAssocs"
|
||||
lazy="true"
|
||||
inverse="true"
|
||||
cascade="none"
|
||||
optimistic-lock="true"
|
||||
fetch="select" >
|
||||
<key>
|
||||
<column name="child_protocol" />
|
||||
<column name="child_identifier" />
|
||||
<column name="child_guid" length="36" />
|
||||
</key>
|
||||
<one-to-many class="org.alfresco.repo.domain.hibernate.ChildAssocImpl" />
|
||||
</bag>
|
||||
<!-- inverse assoc to child childassocs -->
|
||||
<bag
|
||||
name="childAssocs"
|
||||
inverse="true"
|
||||
lazy="true"
|
||||
cascade="none"
|
||||
optimistic-lock="true"
|
||||
fetch="select" >
|
||||
<key>
|
||||
<column name="parent_protocol" />
|
||||
<column name="parent_identifier" />
|
||||
<column name="parent_guid" length="36" />
|
||||
</key>
|
||||
<one-to-many class="org.alfresco.repo.domain.hibernate.ChildAssocImpl" />
|
||||
|
||||
</bag>
|
||||
<!-- inverse assoc to source nodeassocs -->
|
||||
<bag
|
||||
name="sourceNodeAssocs"
|
||||
inverse="true"
|
||||
cascade="none"
|
||||
optimistic-lock="true" >
|
||||
<key>
|
||||
<column name="target_protocol" />
|
||||
<column name="target_identifier" />
|
||||
<column name="target_guid" length="36" />
|
||||
</key>
|
||||
<one-to-many class="org.alfresco.repo.domain.hibernate.NodeAssocImpl" />
|
||||
</bag>
|
||||
<!-- inverse assoc to target nodeassocs -->
|
||||
<bag
|
||||
name="targetNodeAssocs"
|
||||
inverse="true"
|
||||
cascade="none"
|
||||
optimistic-lock="true" >
|
||||
<key>
|
||||
<column name="source_protocol" />
|
||||
<column name="source_identifier" />
|
||||
<column name="source_guid" length="36" />
|
||||
</key>
|
||||
<one-to-many class="org.alfresco.repo.domain.hibernate.NodeAssocImpl" />
|
||||
</bag>
|
||||
</class>
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.NodeStatusImpl"
|
||||
proxy="org.alfresco.repo.domain.NodeStatus"
|
||||
table="node_status"
|
||||
dynamic-update="false"
|
||||
dynamic-insert="false"
|
||||
select-before-update="false"
|
||||
lazy="true"
|
||||
optimistic-lock="version" >
|
||||
<!-- composite PK -->
|
||||
<composite-id name="key" class="org.alfresco.repo.domain.NodeKey">
|
||||
<key-property name="protocol" length="50" />
|
||||
<key-property name="identifier" length="100" />
|
||||
<key-property name="guid" length="36"/>
|
||||
</composite-id>
|
||||
<property name="changeTxnId" column="change_txn_id" type="string" length="56" not-null="true" />
|
||||
<property name="deleted" column="deleted" type="boolean" not-null="true" />
|
||||
</class>
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.ChildAssocImpl"
|
||||
proxy="org.alfresco.repo.domain.ChildAssoc"
|
||||
dynamic-insert="false"
|
||||
dynamic-update="false"
|
||||
lazy="true"
|
||||
optimistic-lock="version"
|
||||
table="child_assoc" >
|
||||
<id
|
||||
name="id"
|
||||
column="id"
|
||||
type="long" >
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
|
||||
<property name="qname" column="qname" type="QName" length="255" not-null="true" />
|
||||
<property name="isPrimary" />
|
||||
<property name="index" column="assoc_index" />
|
||||
<!-- forward assoc to parent node -->
|
||||
<many-to-one
|
||||
name="parent"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
lazy="false"
|
||||
fetch="join"
|
||||
optimistic-lock="true"
|
||||
not-null="true" >
|
||||
<column name="parent_protocol" />
|
||||
<column name="parent_identifier" />
|
||||
<column name="parent_guid" length="36" />
|
||||
</many-to-one>
|
||||
<!-- forward assoc to child node -->
|
||||
<many-to-one
|
||||
name="child"
|
||||
lazy="false"
|
||||
fetch="join"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
optimistic-lock="true"
|
||||
not-null="true" >
|
||||
<column name="child_protocol" />
|
||||
<column name="child_identifier" />
|
||||
<column name="child_guid" length="36" />
|
||||
</many-to-one>
|
||||
</class>
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.NodeAssocImpl"
|
||||
proxy="org.alfresco.repo.domain.NodeAssoc"
|
||||
table="node_assoc" >
|
||||
<id
|
||||
name="id"
|
||||
column="id"
|
||||
type="long" >
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
|
||||
<!-- forward assoc to source node -->
|
||||
<many-to-one
|
||||
name="source"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
not-null="true" >
|
||||
<column name="source_protocol" />
|
||||
<column name="source_identifier" />
|
||||
<column name="source_guid" length="36" />
|
||||
</many-to-one>
|
||||
<!-- forward assoc to target node -->
|
||||
<many-to-one
|
||||
name="target"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
not-null="true" >
|
||||
<column name="target_protocol" />
|
||||
<column name="target_identifier" />
|
||||
<column name="target_guid" length="36" />
|
||||
</many-to-one>
|
||||
</class>
|
||||
|
||||
<query name="store.GetAllStores">
|
||||
select
|
||||
store
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.StoreImpl as store
|
||||
</query>
|
||||
|
||||
<query name="node.GetNodeAssoc">
|
||||
select
|
||||
assoc
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeImpl as source
|
||||
join source.targetNodeAssocs as assoc
|
||||
join assoc.target as target
|
||||
where
|
||||
source.key.protocol = :sourceKeyProtocol and
|
||||
source.key.identifier = :sourceKeyIdentifier and
|
||||
source.key.guid = :sourceKeyGuid and
|
||||
assoc.typeQName = :assocTypeQName and
|
||||
target.key.protocol = :targetKeyProtocol and
|
||||
target.key.identifier = :targetKeyIdentifier and
|
||||
target.key.guid = :targetKeyGuid
|
||||
</query>
|
||||
|
||||
<query name="node.GetNodeAssocTargets">
|
||||
select
|
||||
target
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeImpl as source
|
||||
join source.targetNodeAssocs as assoc
|
||||
join assoc.target as target
|
||||
where
|
||||
source.key.protocol = :sourceKeyProtocol and
|
||||
source.key.identifier = :sourceKeyIdentifier and
|
||||
source.key.guid = :sourceKeyGuid and
|
||||
assoc.typeQName = :assocTypeQName
|
||||
</query>
|
||||
|
||||
<query name="node.GetNodeAssocSources">
|
||||
select
|
||||
source
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeImpl as target
|
||||
join target.sourceNodeAssocs as assoc
|
||||
join assoc.source as source
|
||||
where
|
||||
target.key.protocol = :targetKeyProtocol and
|
||||
target.key.identifier = :targetKeyIdentifier and
|
||||
target.key.guid = :targetKeyGuid and
|
||||
assoc.typeQName = :assocTypeQName
|
||||
</query>
|
||||
|
||||
<query name="node.GetNextChangeTxnIds">
|
||||
select distinct
|
||||
status.changeTxnId
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
|
||||
where
|
||||
status.changeTxnId > :currentTxnId
|
||||
order by
|
||||
status.changeTxnId
|
||||
</query>
|
||||
|
||||
<query name="node.GetChangedNodeStatusesCount">
|
||||
select
|
||||
count(status.changeTxnId)
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
|
||||
where
|
||||
status.key.protocol = :storeProtocol and
|
||||
status.key.identifier = :storeIdentifier and
|
||||
status.deleted = :deleted and
|
||||
status.changeTxnId = :changeTxnId
|
||||
</query>
|
||||
|
||||
<query name="node.GetChangedNodeStatuses">
|
||||
select
|
||||
status
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
|
||||
where
|
||||
status.key.protocol = :storeProtocol and
|
||||
status.key.identifier = :storeIdentifier and
|
||||
status.deleted = :deleted and
|
||||
status.changeTxnId = :changeTxnId
|
||||
</query>
|
||||
|
||||
</hibernate-mapping>
|
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.NodeAssoc;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* Hibernate-specific implementation of the generic node association
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class NodeAssocImpl implements NodeAssoc
|
||||
{
|
||||
private long id;
|
||||
private Node source;
|
||||
private Node target;
|
||||
private QName typeQName;
|
||||
private transient AssociationRef nodeAssocRef;
|
||||
|
||||
public NodeAssocImpl()
|
||||
{
|
||||
}
|
||||
|
||||
public void buildAssociation(Node sourceNode, Node targetNode)
|
||||
{
|
||||
// add the forward associations
|
||||
this.setTarget(targetNode);
|
||||
this.setSource(sourceNode);
|
||||
// add the inverse associations
|
||||
sourceNode.getTargetNodeAssocs().add(this);
|
||||
targetNode.getSourceNodeAssocs().add(this);
|
||||
}
|
||||
|
||||
public void removeAssociation()
|
||||
{
|
||||
// maintain inverse assoc from source node to this instance
|
||||
this.getSource().getTargetNodeAssocs().remove(this);
|
||||
// maintain inverse assoc from target node to this instance
|
||||
this.getTarget().getSourceNodeAssocs().remove(this);
|
||||
}
|
||||
|
||||
public synchronized AssociationRef getNodeAssocRef()
|
||||
{
|
||||
if (nodeAssocRef == null)
|
||||
{
|
||||
nodeAssocRef = new AssociationRef(getSource().getNodeRef(),
|
||||
this.typeQName,
|
||||
getTarget().getNodeRef());
|
||||
}
|
||||
return nodeAssocRef;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer(32);
|
||||
sb.append("NodeAssoc")
|
||||
.append("[ source=").append(source)
|
||||
.append(", target=").append(target)
|
||||
.append(", name=").append(getTypeQName())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof NodeAssoc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
NodeAssoc that = (NodeAssoc) obj;
|
||||
return (EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
|
||||
&& EqualsHelper.nullSafeEquals(this.getTarget(), that.getTarget())
|
||||
&& EqualsHelper.nullSafeEquals(this.getSource(), that.getSource()));
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (typeQName == null ? 0 : typeQName.hashCode());
|
||||
}
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Node getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use
|
||||
*/
|
||||
private void setSource(Node source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Node getTarget()
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use
|
||||
*/
|
||||
private void setTarget(Node target)
|
||||
{
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public QName getTypeQName()
|
||||
{
|
||||
return typeQName;
|
||||
}
|
||||
|
||||
public void setTypeQName(QName typeQName)
|
||||
{
|
||||
this.typeQName = typeQName;
|
||||
}
|
||||
}
|
228
source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java
Normal file
228
source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* 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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.domain.ChildAssoc;
|
||||
import org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.NodeAssoc;
|
||||
import org.alfresco.repo.domain.NodeKey;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.domain.Store;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.hibernate.mapping.Bag;
|
||||
|
||||
/**
|
||||
* Bean containing all the persistence data representing a <b>node</b>.
|
||||
* <p>
|
||||
* This implementation of the {@link org.alfresco.repo.domain.Node Node} interface is
|
||||
* Hibernate specific.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class NodeImpl implements Node
|
||||
{
|
||||
private NodeKey key;
|
||||
private Store store;
|
||||
private QName typeQName;
|
||||
private NodeStatus status;
|
||||
private Set<QName> aspects;
|
||||
private Collection<NodeAssoc> sourceNodeAssocs;
|
||||
private Collection<NodeAssoc> targetNodeAssocs;
|
||||
private Collection<ChildAssoc> parentAssocs;
|
||||
private Collection<ChildAssoc> childAssocs;
|
||||
private Map<QName, PropertyValue> properties;
|
||||
private transient NodeRef nodeRef;
|
||||
|
||||
public NodeImpl()
|
||||
{
|
||||
aspects = new HashSet<QName>(5);
|
||||
sourceNodeAssocs = new ArrayList<NodeAssoc>(3);
|
||||
targetNodeAssocs = new ArrayList<NodeAssoc>(3);
|
||||
parentAssocs = new ArrayList<ChildAssoc>(3);
|
||||
childAssocs = new ArrayList<ChildAssoc>(3);
|
||||
properties = new HashMap<QName, PropertyValue>(5);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof Node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Node that = (Node) obj;
|
||||
return (this.getKey().equals(that.getKey()));
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return getKey().hashCode();
|
||||
}
|
||||
|
||||
public NodeKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(NodeKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Store getStore()
|
||||
{
|
||||
return store;
|
||||
}
|
||||
|
||||
public synchronized void setStore(Store store)
|
||||
{
|
||||
this.store = store;
|
||||
this.nodeRef = null;
|
||||
}
|
||||
|
||||
public QName getTypeQName()
|
||||
{
|
||||
return typeQName;
|
||||
}
|
||||
|
||||
public void setTypeQName(QName typeQName)
|
||||
{
|
||||
this.typeQName = typeQName;
|
||||
}
|
||||
|
||||
public NodeStatus getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(NodeStatus status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Set<QName> getAspects()
|
||||
{
|
||||
return aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setAspects(Set<QName> aspects)
|
||||
{
|
||||
this.aspects = aspects;
|
||||
}
|
||||
|
||||
public Collection<NodeAssoc> getSourceNodeAssocs()
|
||||
{
|
||||
return sourceNodeAssocs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setSourceNodeAssocs(Collection<NodeAssoc> sourceNodeAssocs)
|
||||
{
|
||||
this.sourceNodeAssocs = sourceNodeAssocs;
|
||||
}
|
||||
|
||||
public Collection<NodeAssoc> getTargetNodeAssocs()
|
||||
{
|
||||
return targetNodeAssocs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setTargetNodeAssocs(Collection<NodeAssoc> targetNodeAssocs)
|
||||
{
|
||||
this.targetNodeAssocs = targetNodeAssocs;
|
||||
}
|
||||
|
||||
public Collection<ChildAssoc> getParentAssocs()
|
||||
{
|
||||
return parentAssocs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setParentAssocs(Collection<ChildAssoc> parentAssocs)
|
||||
{
|
||||
this.parentAssocs = parentAssocs;
|
||||
}
|
||||
|
||||
public Collection<ChildAssoc> getChildAssocs()
|
||||
{
|
||||
return childAssocs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setChildAssocs(Collection<ChildAssoc> childAssocs)
|
||||
{
|
||||
this.childAssocs = childAssocs;
|
||||
}
|
||||
|
||||
public Map<QName, PropertyValue> getProperties()
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setProperties(Map<QName, PropertyValue> properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread-safe caching of the reference is provided
|
||||
*/
|
||||
public synchronized NodeRef getNodeRef()
|
||||
{
|
||||
if (nodeRef == null && key != null)
|
||||
{
|
||||
nodeRef = new NodeRef(getStore().getStoreRef(), getKey().getGuid());
|
||||
}
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getNodeRef()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getNodeRef().toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.NodeKey;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* Hibernate implementation of a <b>node status</b>
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class NodeStatusImpl implements NodeStatus
|
||||
{
|
||||
private NodeKey key;
|
||||
private String changeTxnId;
|
||||
private boolean deleted;
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (key == null) ? 0 : key.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
else if (obj == null)
|
||||
return false;
|
||||
else if (!(obj instanceof NodeStatusImpl))
|
||||
return false;
|
||||
NodeStatus that = (NodeStatus) obj;
|
||||
return (EqualsHelper.nullSafeEquals(this.key, that.getKey())) &&
|
||||
(EqualsHelper.nullSafeEquals(this.changeTxnId, that.getChangeTxnId())) &&
|
||||
(this.deleted == that.isDeleted());
|
||||
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
sb.append("NodeStatus")
|
||||
.append("[key=").append(key)
|
||||
.append(", txn=").append(changeTxnId)
|
||||
.append(", deleted=").append(deleted)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public NodeKey getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(NodeKey key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getChangeTxnId()
|
||||
{
|
||||
return changeTxnId;
|
||||
}
|
||||
|
||||
public void setChangeTxnId(String txnId)
|
||||
{
|
||||
this.changeTxnId = txnId;
|
||||
}
|
||||
|
||||
public boolean isDeleted()
|
||||
{
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void setDeleted(boolean deleted)
|
||||
{
|
||||
this.deleted = deleted;
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
/**
|
||||
* Custom type to hide the persistence of {@link org.alfresco.service.namespace.QName qname}
|
||||
* instances.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class QNameUserType implements UserType
|
||||
{
|
||||
private static int[] SQL_TYPES = new int[] {Types.VARCHAR};
|
||||
|
||||
public Class returnedClass()
|
||||
{
|
||||
return QName.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #SQL_TYPES
|
||||
*/
|
||||
public int[] sqlTypes()
|
||||
{
|
||||
return SQL_TYPES;
|
||||
}
|
||||
|
||||
public boolean isMutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(Object x, Object y) throws HibernateException
|
||||
{
|
||||
return EqualsHelper.nullSafeEquals(x, y);
|
||||
}
|
||||
|
||||
public int hashCode(Object x) throws HibernateException
|
||||
{
|
||||
return x.hashCode();
|
||||
}
|
||||
|
||||
public Object deepCopy(Object value) throws HibernateException
|
||||
{
|
||||
// the qname is immutable
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException
|
||||
{
|
||||
String qnameStr = rs.getString(names[0]);
|
||||
if (qnameStr == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
QName qname = QName.createQName(qnameStr);
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
|
||||
public void nullSafeSet(PreparedStatement stmt, Object value, int index) throws HibernateException, SQLException
|
||||
{
|
||||
// convert the qname to a string
|
||||
stmt.setString(index, value.toString());
|
||||
}
|
||||
|
||||
public Object replace(Object original, Object target, Object owner) throws HibernateException
|
||||
{
|
||||
// qname is immutable
|
||||
return original;
|
||||
}
|
||||
|
||||
public Object assemble(Serializable cached, Object owner) throws HibernateException
|
||||
{
|
||||
// qname is serializable
|
||||
return cached;
|
||||
}
|
||||
|
||||
public Serializable disassemble(Object value) throws HibernateException
|
||||
{
|
||||
// qname is serializable
|
||||
return (QName) value;
|
||||
}
|
||||
}
|
35
source/java/org/alfresco/repo/domain/hibernate/Store.hbm.xml
Normal file
35
source/java/org/alfresco/repo/domain/hibernate/Store.hbm.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?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>
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.StoreImpl"
|
||||
proxy="org.alfresco.repo.domain.Store"
|
||||
table="store"
|
||||
dynamic-update="false"
|
||||
dynamic-insert="false"
|
||||
select-before-update="false"
|
||||
optimistic-lock="version" >
|
||||
<!-- composite PK -->
|
||||
<composite-id name="key" class="org.alfresco.repo.domain.StoreKey">
|
||||
<key-property name="protocol" length="100" />
|
||||
<key-property name="identifier" length="100" />
|
||||
</composite-id>
|
||||
<!-- forward assoc to root node -->
|
||||
<many-to-one
|
||||
name="rootNode"
|
||||
not-null="false"
|
||||
lazy="false"
|
||||
class="org.alfresco.repo.domain.hibernate.NodeImpl"
|
||||
fetch="join" >
|
||||
<column name="root_protocol" />
|
||||
<column name="root_identifier" />
|
||||
<column name="root_guid" />
|
||||
</many-to-one>
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
106
source/java/org/alfresco/repo/domain/hibernate/StoreImpl.java
Normal file
106
source/java/org/alfresco/repo/domain/hibernate/StoreImpl.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.Store;
|
||||
import org.alfresco.repo.domain.StoreKey;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
/**
|
||||
* Hibernate-specific implementation of the domain entity <b>store</b>.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class StoreImpl implements Store
|
||||
{
|
||||
private StoreKey key;
|
||||
private Node rootNode;
|
||||
private transient StoreRef storeRef;
|
||||
|
||||
public StoreImpl()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof Node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Node that = (Node) obj;
|
||||
return (this.getKey().equals(that.getKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return getKey().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStoreRef()()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getStoreRef().toString();
|
||||
}
|
||||
|
||||
public StoreKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public synchronized void setKey(StoreKey key) {
|
||||
this.key = key;
|
||||
this.storeRef = null;
|
||||
}
|
||||
|
||||
public Node getRootNode()
|
||||
{
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
public void setRootNode(Node rootNode)
|
||||
{
|
||||
this.rootNode = rootNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily constructs <code>StoreRef</code> instance referencing this entity
|
||||
*/
|
||||
public synchronized StoreRef getStoreRef()
|
||||
{
|
||||
if (storeRef == null && key != null)
|
||||
{
|
||||
storeRef = new StoreRef(key.getProtocol(), key.getIdentifier());
|
||||
}
|
||||
return storeRef;
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
<?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>
|
||||
|
||||
<class
|
||||
name="org.alfresco.repo.domain.hibernate.VersionCountImpl"
|
||||
proxy="org.alfresco.repo.domain.VersionCount"
|
||||
table="version_count"
|
||||
dynamic-update="false"
|
||||
dynamic-insert="false"
|
||||
select-before-update="false"
|
||||
optimistic-lock="version" >
|
||||
<!-- composite PK -->
|
||||
<composite-id name="key" class="org.alfresco.repo.domain.StoreKey">
|
||||
<key-property name="protocol" length="100" />
|
||||
<key-property name="identifier" length="100" />
|
||||
</composite-id>
|
||||
<property name="versionCount" column="version_count" type="int" not-null="true" />
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.StoreKey;
|
||||
import org.alfresco.repo.domain.VersionCount;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
/**
|
||||
* Hibernate-specific implementation of the domain entity <b>versioncounter</b>.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class VersionCountImpl implements VersionCount
|
||||
{
|
||||
private StoreKey key;
|
||||
private int versionCount;
|
||||
private transient StoreRef storeRef;
|
||||
|
||||
public VersionCountImpl()
|
||||
{
|
||||
versionCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(obj instanceof Node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Node that = (Node) obj;
|
||||
return (this.getKey().equals(that.getKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return getKey().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getKey().toString();
|
||||
}
|
||||
|
||||
public StoreKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public synchronized void setKey(StoreKey key) {
|
||||
this.key = key;
|
||||
this.storeRef = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate use
|
||||
*/
|
||||
private void setVersionCount(int versionCount)
|
||||
{
|
||||
this.versionCount = versionCount;
|
||||
}
|
||||
|
||||
public int incrementVersionCount()
|
||||
{
|
||||
return ++versionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset back to 0
|
||||
*/
|
||||
public void resetVersionCount()
|
||||
{
|
||||
setVersionCount(0);
|
||||
}
|
||||
|
||||
public int getVersionCount()
|
||||
{
|
||||
return versionCount;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user