You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2008/05/02 18:24:09 UTC
svn commit: r652800 - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core:
AbstractNodeData.java NodeImpl.java PropertyImpl.java
Author: stefan
Date: Fri May 2 09:24:09 2008
New Revision: 652800
URL: http://svn.apache.org/viewvc?rev=652800&view=rev
Log:
JCR-1104 - JSR 283 support
- improved Node#setPrimaryType implementation
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java?rev=652800&r1=652799&r2=652800&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java Fri May 2 09:24:09 2008
@@ -62,13 +62,22 @@
/**
* Return the associated node defintion.
*
- * @return node defintion
+ * @return node definition
*/
public NodeDefinition getNodeDefinition() {
return (NodeDefinition) getDefinition();
}
/**
+ * Sets the associated node defintion.
+ *
+ * @param definition new node definition
+ */
+ public void setNodeDefinition(NodeDefinition definition) {
+ setDefinition(definition);
+ }
+
+ /**
* Return the parent id of this node. Every shareable node in a shared set
* has a different parent.
*
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=652800&r1=652799&r2=652800&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri May 2 09:24:09 2008
@@ -105,12 +105,6 @@
private static Logger log = LoggerFactory.getLogger(NodeImpl.class);
- /** same as ((NodeState) state).getNodeTypeName(); cached to avoid type casts */
- protected final Name primaryTypeName;
-
- /** the definition of this node */
- protected NodeDefinition definition;
-
// flag set in status passed to getOrCreateProperty if property was created
protected static final short CREATED = 0;
@@ -130,16 +124,14 @@
// paranoid sanity check
NodeTypeRegistry ntReg = session.getNodeTypeManager().getNodeTypeRegistry();
final NodeState state = data.getNodeState();
- if (ntReg.isRegistered(state.getNodeTypeName())) {
- primaryTypeName = state.getNodeTypeName();
- } else {
+ if (!ntReg.isRegistered(state.getNodeTypeName())) {
/**
* todo need proper way of handling inconsistent/corrupt node type references
* e.g. 'flag' nodes that refer to non-registered node types
*/
log.warn("Fallback to nt:unstructured due to unknown node type '"
+ state.getNodeTypeName() + "' of node " + safeGetJCRPath());
- primaryTypeName = NameConstants.NT_UNSTRUCTURED;
+ data.getNodeState().setNodeTypeName(NameConstants.NT_UNSTRUCTURED);
}
}
@@ -347,7 +339,7 @@
// nt:base node type
if (name.equals(NameConstants.JCR_PRIMARYTYPE)) {
// jcr:primaryType property
- genValues = new InternalValue[]{InternalValue.create(primaryTypeName)};
+ genValues = new InternalValue[]{InternalValue.create(thisState.getNodeTypeName())};
} else if (name.equals(NameConstants.JCR_MIXINTYPES)) {
// jcr:mixinTypes property
Set mixins = thisState.getMixinTypeNames();
@@ -874,7 +866,7 @@
Name[] types = new Name[mixins.size() + 1];
mixins.toArray(types);
// primary type
- types[types.length - 1] = primaryTypeName;
+ types[types.length - 1] = data.getNodeState().getNodeTypeName();
try {
return ntReg.getEffectiveNodeType(types);
} catch (NodeTypeConflictException ntce) {
@@ -966,6 +958,8 @@
// copy state from transient state:
// parent id's
persistentState.setParentId(transientState.getParentId());
+ // primary type
+ persistentState.setNodeTypeName(transientState.getNodeTypeName());
// mixin types
persistentState.setMixinTypeNames(transientState.getMixinTypeNames());
// id of definition
@@ -1003,6 +997,7 @@
}
// re-apply transient changes
thisState.setParentId(transientState.getParentId());
+ thisState.setNodeTypeName(transientState.getNodeTypeName());
thisState.setMixinTypeNames(transientState.getMixinTypeNames());
thisState.setDefinitionId(transientState.getDefinitionId());
thisState.setChildNodeEntries(transientState.getChildNodeEntries());
@@ -1046,6 +1041,7 @@
throw new RepositoryException(mixinName + ": not a mixin node type");
}
+ final Name primaryTypeName = data.getNodeState().getNodeTypeName();
NodeTypeImpl primaryType = ntMgr.getNodeType(primaryTypeName);
if (primaryType.isDerivedFrom(mixinName)) {
// new mixin is already included in primary type
@@ -1172,7 +1168,7 @@
// remaining mixin's
HashSet set = new HashSet(remainingMixins);
// primary type
- set.add(primaryTypeName);
+ set.add(state.getNodeTypeName());
// build effective node type representing primary type including remaining mixin's
entRemaining = ntReg.getEffectiveNodeType((Name[]) set.toArray(new Name[set.size()]));
} catch (NodeTypeConflictException ntce) {
@@ -1260,7 +1256,7 @@
sanityCheck();
// first do trivial checks without using type hierarchy
- if (ntName.equals(primaryTypeName)) {
+ if (ntName.equals(data.getNodeState().getNodeTypeName())) {
return true;
}
Set mixins = data.getNodeState().getMixinTypeNames();
@@ -2763,7 +2759,8 @@
// check state of this instance
sanityCheck();
- return session.getNodeTypeManager().getNodeType(primaryTypeName);
+ return session.getNodeTypeManager().getNodeType(
+ data.getNodeState().getNodeTypeName());
}
/**
@@ -2852,6 +2849,9 @@
if (!mixin.isMixin()) {
return false;
}
+
+ final Name primaryTypeName = data.getNodeState().getNodeTypeName();
+
NodeTypeImpl primaryType = ntMgr.getNodeType(primaryTypeName);
if (primaryType.isDerivedFrom(ntName)) {
return false;
@@ -4224,7 +4224,7 @@
}
// check primary type
- if (!freeze.getFrozenPrimaryType().equals(primaryTypeName)) {
+ if (!freeze.getFrozenPrimaryType().equals(data.getNodeState().getNodeTypeName())) {
// todo: check with spec what should happen here
throw new ItemExistsException("Unable to restore version of " + safeGetJCRPath() + ". PrimaryType changed.");
}
@@ -4759,7 +4759,7 @@
"invalid node type name: " + nodeTypeName, e);
}
- if (ntName.equals(primaryTypeName)) {
+ if (ntName.equals(state.getNodeTypeName())) {
return;
}
@@ -4774,7 +4774,7 @@
EffectiveNodeType entNew, entOld;
try {
entNew = ntReg.getEffectiveNodeType(ntName);
- entOld = ntReg.getEffectiveNodeType(primaryTypeName);
+ entOld = ntReg.getEffectiveNodeType(state.getNodeTypeName());
// existing mixin's
HashSet set = new HashSet(state.getMixinTypeNames());
@@ -4801,14 +4801,10 @@
onRedefine(defId);
}
-
- // build change set: removed/added child items
Set oldDefs = new HashSet(Arrays.asList(entOld.getAllItemDefs()));
Set newDefs = new HashSet(Arrays.asList(entNew.getAllItemDefs()));
- Set removedDefs = new HashSet(oldDefs);
- removedDefs.removeAll(newDefs);
-
+ // added child item definitions
Set addedDefs = new HashSet(newDefs);
addedDefs.removeAll(oldDefs);
@@ -4836,42 +4832,107 @@
// set jcr:primaryType property
internalSetProperty(NameConstants.JCR_PRIMARYTYPE, InternalValue.create(ntName));
- // walk through properties and child nodes and remove those that
- // are not included in the new node type
- if (!removedDefs.isEmpty()) {
- // use temp set to avoid ConcurrentModificationException
- HashSet set = new HashSet(thisState.getPropertyNames());
- for (Iterator iter = set.iterator(); iter.hasNext();) {
- Name propName = (Name) iter.next();
- try {
- PropertyState propState =
- (PropertyState) stateMgr.getItemState(
- new PropertyId(thisState.getNodeId(), propName));
- if (removedDefs.contains(ntReg.getPropDef(propState.getDefinitionId()))) {
+ // walk through properties and child nodes and change definition as necessary
+
+ // use temp set to avoid ConcurrentModificationException
+ HashSet set = new HashSet(thisState.getPropertyNames());
+ for (Iterator iter = set.iterator(); iter.hasNext();) {
+ Name propName = (Name) iter.next();
+ try {
+ PropertyState propState =
+ (PropertyState) stateMgr.getItemState(
+ new PropertyId(thisState.getNodeId(), propName));
+ if (!newDefs.contains(ntReg.getPropDef(propState.getDefinitionId()))) {
+ // try to find new applicable definition first and
+ // redefine property if possible
+
+ PropertyDefinitionImpl pdi = null;
+ try {
+ PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
+ pdi = getApplicablePropertyDefinition(
+ propName, propState.getType(),
+ propState.isMultiValued(), false);
+ if (pdi.getRequiredType() != PropertyType.UNDEFINED
+ && pdi.getRequiredType() != propState.getType()) {
+ // value conversion required
+ if (propState.isMultiValued()) {
+ // convert value
+ Value[] values =
+ ValueHelper.convert(
+ prop.getValues(),
+ pdi.getRequiredType(),
+ session.getValueFactory());
+ // redefine property
+ prop.onRedefine(pdi.unwrap().getId());
+ // set converted values
+ prop.setValue(values);
+ } else {
+ // convert value
+ Value value =
+ ValueHelper.convert(
+ prop.getValue(),
+ pdi.getRequiredType(),
+ session.getValueFactory());
+ // redefine property
+ prop.onRedefine(pdi.unwrap().getId());
+ // set converted values
+ prop.setValue(value);
+ }
+ } else {
+ // redefine property
+ prop.onRedefine(pdi.unwrap().getId());
+ }
+ // update collection of added definitions
+ addedDefs.remove(pdi.unwrap());
+ } catch (ValueFormatException vfe) {
+ // value conversion failed,
+ // remove it
+ removeChildProperty(propName);
+ } catch (ConstraintViolationException cve) {
+ // no suitable definition found for this property,
+ // remove it
removeChildProperty(propName);
}
- } catch (ItemStateException ise) {
- String msg = propName + ": failed to retrieve property state";
- log.error(msg, ise);
- throw new RepositoryException(msg, ise);
}
+ } catch (ItemStateException ise) {
+ String msg = propName + ": failed to retrieve property state";
+ log.error(msg, ise);
+ throw new RepositoryException(msg, ise);
}
- // use temp array to avoid ConcurrentModificationException
- ArrayList list = new ArrayList(thisState.getChildNodeEntries());
- // start from tail to avoid problems with same-name siblings
- for (int i = list.size() - 1; i >= 0; i--) {
- NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) list.get(i);
- try {
- NodeState nodeState =
- (NodeState) stateMgr.getItemState(entry.getId());
- if (removedDefs.contains(ntReg.getNodeDef(nodeState.getDefinitionId()))) {
+ }
+
+ // use temp array to avoid ConcurrentModificationException
+ ArrayList list = new ArrayList(thisState.getChildNodeEntries());
+ // start from tail to avoid problems with same-name siblings
+ for (int i = list.size() - 1; i >= 0; i--) {
+ NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) list.get(i);
+ try {
+ NodeState nodeState =
+ (NodeState) stateMgr.getItemState(entry.getId());
+ if (!newDefs.contains(ntReg.getNodeDef(nodeState.getDefinitionId()))) {
+ // try to find new applicable definition first and
+ // redefine node if possible
+
+ NodeDefinitionImpl ndi = null;
+ try {
+ NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
+ ndi = getApplicableChildNodeDefinition(
+ entry.getName(),
+ nodeState.getNodeTypeName());
+ // redefine property
+ node.onRedefine(ndi.unwrap().getId());
+ // update collection of added definitions
+ addedDefs.remove(ndi.unwrap());
+ } catch (ConstraintViolationException cve) {
+ // no suitable definition found for this child node,
+ // remove it
removeChildNode(entry.getName(), entry.getIndex());
}
- } catch (ItemStateException ise) {
- String msg = entry.getName() + ": failed to retrieve node state";
- log.error(msg, ise);
- throw new RepositoryException(msg, ise);
}
+ } catch (ItemStateException ise) {
+ String msg = entry.getName() + ": failed to retrieve node state";
+ log.error(msg, ise);
+ throw new RepositoryException(msg, ise);
}
}
@@ -4880,11 +4941,11 @@
ItemDef def = (ItemDef) iter.next();
if (def.isAutoCreated()) {
if (def.definesNode()) {
- NodeDefinitionImpl nd = ntMgr.getNodeDefinition(((NodeDef) def).getId());
- createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
+ NodeDefinitionImpl ndi = ntMgr.getNodeDefinition(((NodeDef) def).getId());
+ createChildNode(ndi.getQName(), ndi, (NodeTypeImpl) ndi.getDefaultPrimaryType(), null);
} else {
- PropertyDefinitionImpl pd = ntMgr.getPropertyDefinition(((PropDef) def).getId());
- createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
+ PropertyDefinitionImpl pdi = ntMgr.getPropertyDefinition(((PropDef) def).getId());
+ createChildProperty(pdi.getQName(), pdi.getRequiredType(), pdi);
}
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java?rev=652800&r1=652799&r2=652800&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java Fri May 2 09:24:09 2008
@@ -19,8 +19,11 @@
import org.apache.jackrabbit.core.state.ItemState;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.value.BLOBFileValue;
import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.nodetype.PropDefId;
+import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.value.ValueHelper;
@@ -61,10 +64,7 @@
*
* @param itemMgr the <code>ItemManager</code> that created this <code>Property</code>
* @param session the <code>Session</code> through which this <code>Property</code> is acquired
- * @param id id of this <code>Property</code>
- * @param state state associated with this <code>Property</code>
- * @param definition definition of <i>this</i> <code>Property</code>
- * @param listeners listeners on life cylce changes of this <code>PropertyImpl</code>
+ * @param data the property data
*/
PropertyImpl(ItemManager itemMgr, SessionImpl session, PropertyData data) {
super(itemMgr, session, data);
@@ -162,6 +162,16 @@
thisState.setValues(transientState.getValues());
}
+ protected void onRedefine(PropDefId defId) throws RepositoryException {
+ PropertyDefinitionImpl newDef =
+ session.getNodeTypeManager().getPropertyDefinition(defId);
+ // modify the state of 'this', i.e. the target property
+ PropertyState thisState = (PropertyState) getOrCreateTransientItemState();
+ // set id of new definition
+ thisState.setDefinitionId(defId);
+ data.setDefinition(newDef);
+ }
+
/**
* Determines the length of the given value.
*