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 2004/09/20 18:53:40 UTC
svn commit: rev 46941 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core: . nodetype xml
Author: stefan
Date: Mon Sep 20 09:53:38 2004
New Revision: 46941
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/NodeImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/Test.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/EffectiveNodeType.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeDefId.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeTypeImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/PropDefId.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/builtin_nodetypes.xml
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/DocViewImportHandler.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/SysViewImportHandler.java
Log:
differentiated handling of single vs. multi-valued properties:
multi-valued property can only be set with value array and vice versa
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/NodeImpl.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/NodeImpl.java Mon Sep 20 09:53:38 2004
@@ -15,7 +15,6 @@
*/
package org.apache.jackrabbit.jcr.core;
-import org.apache.log4j.Logger;
import org.apache.jackrabbit.jcr.core.nodetype.*;
import org.apache.jackrabbit.jcr.core.state.*;
import org.apache.jackrabbit.jcr.core.version.FrozenNode;
@@ -25,6 +24,7 @@
import org.apache.jackrabbit.jcr.util.ChildrenCollector;
import org.apache.jackrabbit.jcr.util.IteratorHelper;
import org.apache.jackrabbit.jcr.util.uuid.UUID;
+import org.apache.log4j.Logger;
import javax.jcr.*;
import javax.jcr.access.AccessDeniedException;
@@ -173,7 +173,7 @@
return genValues;
}
- protected PropertyImpl getOrCreateProperty(String name, int type)
+ protected PropertyImpl getOrCreateProperty(String name, int type, boolean multiValued)
throws RepositoryException {
try {
return (PropertyImpl) getProperty(name);
@@ -190,18 +190,18 @@
throw new RepositoryException("invalid property name: " + name, upe);
}
// find definition for the specified property and create property
- PropertyDefImpl def = getApplicablePropertyDef(qName, type);
+ PropertyDefImpl def = getApplicablePropertyDef(qName, type, multiValued);
return createChildProperty(qName, type, def);
}
- protected PropertyImpl getOrCreateProperty(QName name, int type)
+ protected PropertyImpl getOrCreateProperty(QName name, int type, boolean multiValued)
throws RepositoryException {
try {
return (PropertyImpl) getProperty(name);
} catch (ItemNotFoundException e) {
// does not exist yet:
// find definition for the specified property and create property
- PropertyDefImpl def = getApplicablePropertyDef(name, type);
+ PropertyDefImpl def = getApplicablePropertyDef(name, type, multiValued);
return createChildProperty(name, type, def);
}
}
@@ -533,7 +533,7 @@
prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), PROPNAME_MIXINTYPES));
} else {
// find definition for the jcr:mixinTypes property and create property
- PropertyDefImpl def = getApplicablePropertyDef(PROPNAME_MIXINTYPES, PropertyType.NAME);
+ PropertyDefImpl def = getApplicablePropertyDef(PROPNAME_MIXINTYPES, PropertyType.NAME, true);
prop = createChildProperty(PROPNAME_MIXINTYPES, PropertyType.NAME, def);
}
@@ -599,13 +599,15 @@
*
* @param propertyName
* @param type
+ * @param multiValued
* @return
* @throws RepositoryException if no applicable property definition
* could be found
*/
- protected PropertyDefImpl getApplicablePropertyDef(QName propertyName, int type)
+ protected PropertyDefImpl getApplicablePropertyDef(QName propertyName,
+ int type, boolean multiValued)
throws RepositoryException {
- PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(propertyName, type);
+ PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(propertyName, type, multiValued);
return session.getNodeTypeManager().getPropDef(new PropDefId(pd));
}
@@ -656,6 +658,7 @@
/**
* Checks if this node is the root node.
* todo: is this the root node of this workspace?
+ *
* @return
*/
protected boolean isRepositoryRoot() {
@@ -677,11 +680,22 @@
*/
public Property internalSetProperty(QName name, InternalValue value)
throws ValueFormatException, RepositoryException {
+ // check state of this instance
+ checkItemState();
+
+ int type;
+ if (value == null) {
+ type = PropertyType.STRING;
+ } else {
+ type = value.getType();
+ }
+ PropertyImpl prop = getOrCreateProperty(name, type, false);
if (value == null) {
- return internalSetProperty(name, (InternalValue[]) null);
+ prop.internalSetValue((InternalValue[]) null, type);
} else {
- return internalSetProperty(name, new InternalValue[]{value});
+ prop.internalSetValue(new InternalValue[]{value}, type);
}
+ return prop;
}
/**
@@ -708,7 +722,7 @@
} else {
type = values[0].getType();
}
- PropertyImpl prop = getOrCreateProperty(name, type);
+ PropertyImpl prop = getOrCreateProperty(name, type, true);
prop.internalSetValue(values, type);
return prop;
}
@@ -885,7 +899,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.NAME);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.NAME, false);
prop.setValue(value);
return prop;
}
@@ -905,7 +919,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.NAME);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.NAME, true);
prop.setValue(values);
return prop;
}
@@ -932,12 +946,34 @@
} else {
type = values[0].getType();
}
- PropertyImpl prop = getOrCreateProperty(name, type);
+ PropertyImpl prop = getOrCreateProperty(name, type, true);
prop.setValue(values);
return prop;
}
/**
+ * Same as <code>{@link Node#setProperty(String, Value)}</code> except that
+ * this method takes a <code>QName</code> name argument instead of a
+ * <code>String</code>.
+ *
+ * @param name
+ * @param value
+ * @return
+ * @throws ValueFormatException
+ * @throws RepositoryException
+ */
+ public PropertyImpl setProperty(QName name, Value value)
+ throws ValueFormatException, RepositoryException {
+ // check state of this instance
+ checkItemState();
+
+ int type = (value == null) ? PropertyType.STRING : value.getType();
+ PropertyImpl prop = getOrCreateProperty(name, type, false);
+ prop.setValue(value);
+ return prop;
+ }
+
+ /**
* @see ItemImpl#getQName()
*/
public QName getQName() throws RepositoryException {
@@ -1254,7 +1290,7 @@
} else {
type = values[0].getType();
}
- PropertyImpl prop = getOrCreateProperty(name, type);
+ PropertyImpl prop = getOrCreateProperty(name, type, true);
prop.setValue(values);
return prop;
}
@@ -1267,7 +1303,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING, true);
prop.setValue(values);
return prop;
}
@@ -1279,7 +1315,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING, false);
prop.setValue(value);
return prop;
}
@@ -1293,7 +1329,7 @@
checkItemState();
int type = (value == null) ? PropertyType.STRING : value.getType();
- PropertyImpl prop = getOrCreateProperty(name, type);
+ PropertyImpl prop = getOrCreateProperty(name, type, false);
prop.setValue(value);
return prop;
}
@@ -1306,7 +1342,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.BINARY);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.BINARY, false);
prop.setValue(value);
return prop;
}
@@ -1319,7 +1355,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.BOOLEAN);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.BOOLEAN, false);
prop.setValue(value);
return prop;
}
@@ -1332,7 +1368,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.DOUBLE);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.DOUBLE, false);
prop.setValue(value);
return prop;
}
@@ -1345,7 +1381,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.LONG);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.LONG, false);
prop.setValue(value);
return prop;
}
@@ -1358,7 +1394,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.DATE);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.DATE, false);
prop.setValue(value);
return prop;
}
@@ -1371,7 +1407,7 @@
// check state of this instance
checkItemState();
- PropertyImpl prop = getOrCreateProperty(name, PropertyType.REFERENCE);
+ PropertyImpl prop = getOrCreateProperty(name, PropertyType.REFERENCE, false);
prop.setValue(value);
return prop;
}
@@ -2163,7 +2199,7 @@
RepositoryException {
NodeImpl srcNode = getCorrespondingNode(srcWorkspaceName);
- if (srcNode==null) {
+ if (srcNode == null) {
throw new ItemNotFoundException("No corresponding node for " + safeGetJCRPath());
}
// not sure, if clone overrides 'this' node.
@@ -2173,25 +2209,26 @@
/**
* Returns the corresponding node in the <code>scrWorkspaceName</code> of
* this node.
- * <p>
+ * <p/>
* Given a node N1 in workspace W1, its corresponding node N2 in workspace
* W2 is defined as follows:
* <ul>
* <li>If N1 is the root node of W1 then N2 is the root node of W2.
* <li>If N1 is referenceable (has a UUID) then N2 is the node in W2 with
- * the same UUID.
+ * the same UUID.
* <li>If N1 is not referenceable (does not have a UUID) then there is some
- * node M1 which is either the nearest ancestor of N1 that is
- * referenceable, or is the root node of W1. If the corresponding node
- * of M1 is M2 in W2, then N2 is the node with the same relative path
- * from M2 as N1 has from M1.
+ * node M1 which is either the nearest ancestor of N1 that is
+ * referenceable, or is the root node of W1. If the corresponding node
+ * of M1 is M2 in W2, then N2 is the node with the same relative path
+ * from M2 as N1 has from M1.
* </ul>
+ *
* @param srcWorkspaceName
* @return the corresponding node or <code>null</code> if no corresponding
* node exists.
* @throws NoSuchWorkspaceException If <code>srcWorkspace</code> does not exist.
- * @throws AccessDeniedException If the current session does not have sufficient rights to perform the operation.
- * @throws RepositoryException If another error occurs.
+ * @throws AccessDeniedException If the current session does not have sufficient rights to perform the operation.
+ * @throws RepositoryException If another error occurs.
*/
private NodeImpl getCorrespondingNode(String srcWorkspaceName)
throws NoSuchWorkspaceException, AccessDeniedException,
@@ -2229,7 +2266,7 @@
// n1.getPath() = /foo/bar/something[1]
// m1.getPath() = /foo
// relpath = bar/something[1]
- String relPath = getPath().substring(m1.getPath().length()+1);
+ String relPath = getPath().substring(m1.getPath().length() + 1);
try {
return (NodeImpl) srcSession.getNodeByUUID(m1.getUUID()).getNode(relPath);
} catch (ItemNotFoundException e) {
@@ -2245,7 +2282,7 @@
AccessDeniedException, MergeException, RepositoryException {
NodeImpl srcNode = doMergeTest(srcWorkspace, bestEffort);
- if (srcNode!=null) {
+ if (srcNode != null) {
// remove properties
PropertyIterator pi = getProperties();
while (pi.hasNext()) {
@@ -2315,7 +2352,7 @@
// If N does not have a corresponding node then the merge result for N is leave.
NodeImpl srcNode = getCorrespondingNode(srcWorkspace);
- if (srcNode==null) {
+ if (srcNode == null) {
return null;
}
@@ -2350,7 +2387,7 @@
// add 'offending' version to jcr:mergeFailed property
if (hasProperty(ItemImpl.PROPNAME_MERGE_FAILED)) {
Value[] values = getProperty(ItemImpl.PROPNAME_MERGE_FAILED).getValues();
- Value[] newValues = new Value[values.length+1];
+ Value[] newValues = new Value[values.length + 1];
System.arraycopy(values, 0, newValues, 0, values.length);
newValues[values.length] = new ReferenceValue(vp);
setProperty(ItemImpl.PROPNAME_MERGE_FAILED, newValues);
@@ -2554,11 +2591,14 @@
* Little helper to retrieve the opv value for a property. depends on the
* implementaion. if nt:frozen is used, need to lookup prop def.
*
- * @param prop
+ * @param name
+ * @param type
+ * @param multiValued
* @return
+ * @throws RepositoryException
*/
- private int getOPV(PropertyImpl prop) throws RepositoryException {
- PropertyDefImpl def = getApplicablePropertyDef(prop.getQName(), PropertyType.UNDEFINED);
+ private int guessOPV(QName name, int type, boolean multiValued) throws RepositoryException {
+ PropertyDefImpl def = getApplicablePropertyDef(name, type, multiValued);
return def.getOnParentVersion();
}
@@ -2629,7 +2669,16 @@
// ignore
} else {
// normal property
- int opv = getOPV(prop);
+ int type = PropertyType.UNDEFINED;
+ if (prop.getDefinition().isMultiple()) {
+ Value[] values = prop.getValues();
+ if (values.length != 0) {
+ type = values[0].getType();
+ }
+ } else {
+ type = prop.getValue().getType();
+ }
+ int opv = guessOPV(prop.getQName(), type, prop.getDefinition().isMultiple());
switch (opv) {
case OnParentVersionAction.ABORT:
throw new RepositoryException("Checkin aborted due to OPV in " + prop.safeGetJCRPath());
@@ -2652,7 +2701,7 @@
if (child.isNodeType(NodeTypeRegistry.NT_FROZEN)) {
FrozenNode f = (FrozenNode) child;
// if frozen node exist, replace
- // todo: make work for samename siblings
+ // todo: make work for same name siblings
if (hasNode(child.getName())) {
remove(child.getName());
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/Test.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/Test.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/Test.java Mon Sep 20 09:53:38 2004
@@ -99,9 +99,12 @@
//root.setProperty("blob", new FileInputStream(new File("d:/temp/jckrabbit.zip")));
- //root.setProperty("blah", 1);
- //root.setProperty("blah", 1.4);
- //root.setProperty("blah", "blahblah");
+ if (root.hasProperty("blah")) {
+ root.remove("blah");
+ }
+ root.setProperty("blah", 1);
+ root.setProperty("blah", 1.4);
+ root.setProperty("blah", "blahblah");
Node file = root.addNode("blu", "nt:file");
file.addNode("jcr:content", "nt:unstructured");
root.addNode("blu", "nt:folder");
@@ -123,8 +126,8 @@
root.save();
- if (root.hasProperty("bla")) {
- root.setProperty("bla", (String) null);
+ if (root.hasProperty("blah")) {
+ root.setProperty("blah", (String) null);
}
if (!root.hasProperty("blah")) {
String[] strings = new String[]{"huey", "louie", null, "dewey"};
@@ -160,18 +163,17 @@
Node misc = root.addNode("misc", "nt:unstructured");
misc.addMixin("mix:referenceable");
- Property link = misc.setProperty("link", new Value[]{PathValue.valueOf("../blu[2]")});
+ Property link = misc.setProperty("link", PathValue.valueOf("../blu[2]"));
root.save();
- Node linkTarget = link.getParent().getNode(link.getValues()[0].getString());
+ Node linkTarget = link.getParent().getNode(link.getValue().getString());
System.out.println(link.getPath() + " refers to " + linkTarget.getPath());
- root.setProperty("ref", new Value[]{new ReferenceValue(misc)});
+ root.setProperty("ref", new ReferenceValue(misc));
root.save();
PropertyIterator pi = misc.getReferences();
while (pi.hasNext()) {
Property prop = pi.nextProperty();
- String uuid = prop.getValues()[0].getString();
- Node target = session.getNodeByUUID(uuid);
+ Node target = prop.getNode();
System.out.println(prop.getPath() + " is a reference to " + target.getPath());
}
/*
@@ -184,9 +186,9 @@
}
*/
String date1 = "2003-07-28T06:18:57.848+01:00";
- root.setProperty("date", new Value[]{new DateValue(new StringValue(date1).getDate())});
+ root.setProperty("date", new DateValue(new StringValue(date1).getDate()));
Property p = root.getProperty("date");
- Value val = p.getValues()[0];
+ Value val = p.getValue();
Calendar d = val.getDate();
Node imported = null;
@@ -196,7 +198,7 @@
imported = root.getNode("imported");
}
- importNode(new File("d:/dev/jackrabbit/src/java"), imported);
+ importNode(new File("d:/dev/jsr170/jackrabbit/src/java"), imported);
if (root.hasNode("foo")) {
root.remove("foo");
@@ -205,8 +207,8 @@
Node n = root.addNode("foo", "nt:folder");
Node n2 = n.addNode("foofile", "nt:file");
Node n3 = n2.addNode("jcr:content", "nt:unstructured");
- Property prop1 = n3.setProperty("prop1", new Value[]{new LongValue(123)});
- Property prop2 = n3.setProperty("prop2", new Value[]{new StringValue("blahblah")});
+ Property prop1 = n3.setProperty("prop1", new LongValue(123));
+ Property prop2 = n3.setProperty("prop2", new StringValue("blahblah"));
System.out.println("before save()...");
System.out.println();
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/EffectiveNodeType.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/EffectiveNodeType.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/EffectiveNodeType.java Mon Sep 20 09:53:38 2004
@@ -455,11 +455,12 @@
*
* @param name
* @param type
+ * @param multiValued
* @return
* @throws ConstraintViolationException if no applicable property definition
* could be found
*/
- public PropDef getApplicablePropertyDef(QName name, int type)
+ public PropDef getApplicablePropertyDef(QName name, int type, boolean multiValued)
throws ConstraintViolationException {
ChildItemDef def = (ChildItemDef) namedItemDefs.get(name);
if (def == null) {
@@ -473,8 +474,11 @@
if (reqType == PropertyType.UNDEFINED ||
type == PropertyType.UNDEFINED ||
reqType == type) {
- // found match
- return pd;
+ // match multiValued flag
+ if (multiValued == pd.isMultiple()) {
+ // found match
+ return pd;
+ }
}
}
} else {
@@ -486,8 +490,11 @@
if (reqType == PropertyType.UNDEFINED ||
type == PropertyType.UNDEFINED ||
reqType == type) {
- // found match
- return pd;
+ // match multiValued flag
+ if (multiValued == pd.isMultiple()) {
+ // found match
+ return pd;
+ }
}
}
}
@@ -617,13 +624,28 @@
ChildItemDef existing = (ChildItemDef) iter.next();
// compare with existing definition
if (def.definesNode() == existing.definesNode()) {
- // conflict
- String msg = "An item definition in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': ambiguos residual item definition";
- log.error(msg);
- throw new NodeTypeConflictException(msg);
+ if (!def.definesNode()) {
+ // property definition
+ PropDef pd = (PropDef) def;
+ PropDef epd = (PropDef) existing;
+ // compare type & multiValued flag
+ if (pd.getRequiredType() == epd.getRequiredType() &&
+ pd.isMultiple() == epd.isMultiple()) {
+ // conflict
+ String msg = "A property definition in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': ambiguos residual property definition";
+ log.error(msg);
+ throw new NodeTypeConflictException(msg);
+ }
+ } else {
+ // child node definition
+ // conflict
+ String msg = "A child node definition in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': ambiguos residual child node definition";
+ log.error(msg);
+ throw new NodeTypeConflictException(msg);
+ }
}
}
- // @todo check for ambiguous definitions & other conflicts
+ // @todo do further checks for ambiguous definitions & other conflicts
unnamedItemDefs.add(def);
}
// @todo implement further validations
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeDefId.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeDefId.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeDefId.java Mon Sep 20 09:53:38 2004
@@ -37,6 +37,7 @@
if (def == null) {
throw new IllegalArgumentException("ChildNodeDef argument can not be null");
}
+ // build key (format: <declaringNodeType>/<name>/<defaultPrimaryType>/<requiredPrimaryTypes>)
StringBuffer sb = new StringBuffer();
sb.append(def.getDeclaringNodeType().toString());
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeTypeImpl.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeTypeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/NodeTypeImpl.java Mon Sep 20 09:53:38 2004
@@ -104,13 +104,15 @@
*
* @param propertyName
* @param type
+ * @param multiValued
* @return
* @throws RepositoryException if no applicable property definition
* could be found
*/
- public PropertyDefImpl getApplicablePropertyDef(QName propertyName, int type)
+ public PropertyDefImpl getApplicablePropertyDef(QName propertyName, int type,
+ boolean multiValued)
throws RepositoryException {
- return new PropertyDefImpl(ent.getApplicablePropertyDef(propertyName, type),
+ return new PropertyDefImpl(ent.getApplicablePropertyDef(propertyName, type, multiValued),
ntMgr, nsResolver);
}
@@ -378,14 +380,59 @@
* @see NodeType#canSetProperty(String, Value)
*/
public boolean canSetProperty(String propertyName, Value value) {
+ if (value == null) {
+ // setting a property to null is equivalent of removing it
+ return canRemoveItem(propertyName);
+ }
try {
QName name = QName.fromJCRName(propertyName, nsResolver);
- PropertyDefImpl def = getApplicablePropertyDef(name, value == null ? PropertyType.UNDEFINED : value.getType());
+ int type = (value == null) ? PropertyType.UNDEFINED : value.getType();
+ PropertyDefImpl def = getApplicablePropertyDef(name, type, false);
if (def.isProtected()) {
return false;
}
+ if (def.isMultiple()) {
+ return false;
+ }
InternalValue internalValue = InternalValue.create(value, nsResolver);
checkSetPropertyValueConstraints(def, new InternalValue[]{internalValue});
+ return true;
+ } catch (BaseException be) {
+ // implementation specific exception, fall through
+ } catch (RepositoryException re) {
+ // fall through
+ }
+ return false;
+ }
+
+ /**
+ * @see NodeType#canSetProperty(String, Value[])
+ */
+ public boolean canSetProperty(String propertyName, Value values[]) {
+ if (values == null) {
+ // setting a property to null is equivalent of removing it
+ return canRemoveItem(propertyName);
+ }
+ try {
+ QName name = QName.fromJCRName(propertyName, nsResolver);
+ int type = (values == null || values.length == 0) ? PropertyType.UNDEFINED : values[0].getType();
+ PropertyDefImpl def = getApplicablePropertyDef(name, type, true);
+ if (def.isProtected()) {
+ return false;
+ }
+ if (!def.isMultiple()) {
+ return false;
+ }
+ ArrayList list = new ArrayList();
+ // convert values and compact array (purge null entries)
+ for (int i = 0; i < values.length; i++) {
+ if (values[i] != null) {
+ InternalValue internalValue = InternalValue.create(values[i], nsResolver);
+ list.add(internalValue);
+ }
+ }
+ InternalValue[] internalValues = (InternalValue[]) list.toArray(new InternalValue[list.size()]);
+ checkSetPropertyValueConstraints(def, internalValues);
return true;
} catch (BaseException be) {
// implementation specific exception, fall through
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/PropDefId.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/PropDefId.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/PropDefId.java Mon Sep 20 09:53:38 2004
@@ -34,7 +34,7 @@
if (def == null) {
throw new IllegalArgumentException("PropDef argument can not be null");
}
- // build key (format: <declaring node type>/<name>/<type>/<multiple flag>)
+ // build key (format: <declaringNodeType>/<name>/<requiredType>/<multiple>)
StringBuffer sb = new StringBuffer();
sb.append(def.getDeclaringNodeType().toString());
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/builtin_nodetypes.xml
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/builtin_nodetypes.xml (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/nodetype/builtin_nodetypes.xml Mon Sep 20 09:53:38 2004
@@ -64,6 +64,7 @@
<nodeType name="nt:unstructured" mixin="false" orderableChildNodes="true" supertypes="nt:base">
<childNodeDef name="" requiredPrimaryTypes="nt:base" defaultPrimaryType="nt:unstructured" autoCreate="false" mandatory="false" onParentVersion="COPY" protected="false" primaryItem="false" sameNameSibs="true"/>
<propertyDef name="" type="undefined" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="COPY" protected="false" primaryItem="false" multiple="true"/>
+ <propertyDef name="" type="undefined" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="COPY" protected="false" primaryItem="false" multiple="false"/>
</nodeType>
<nodeType name="nt:hierarchyNode" mixin="false" orderableChildNodes="false" supertypes="nt:base">
<propertyDef name="jcr:created" type="Date" valueConstraint="" defaultValues="" autoCreate="true" mandatory="true" onParentVersion="INITIALIZE" protected="true" primaryItem="false" multiple="false"/>
@@ -124,6 +125,7 @@
<propertyDef name="jcr:frozenMixinTypes" type="Name" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="ABORT" protected="true" primaryItem="false" multiple="true"/>
<propertyDef name="jcr:frozenUUID" type="String" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="ABORT" protected="true" primaryItem="false" multiple="false"/>
<propertyDef name="" type="undefined" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="ABORT" protected="true" primaryItem="false" multiple="true"/>
+ <propertyDef name="" type="undefined" valueConstraint="" defaultValues="" autoCreate="false" mandatory="false" onParentVersion="ABORT" protected="true" primaryItem="false" multiple="false"/>
<childNodeDef name="" requiredPrimaryTypes="nt:base" defaultPrimaryType="nt:frozen" autoCreate="false" mandatory="false" onParentVersion="ABORT" protected="true" primaryItem="false" sameNameSibs="true"/>
</nodeType>
<nodeType name="nt:version" mixin="false" orderableChildNodes="false" supertypes="nt:frozen,mix:referenceable">
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/DocViewImportHandler.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/DocViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/DocViewImportHandler.java Mon Sep 20 09:53:38 2004
@@ -15,9 +15,9 @@
*/
package org.apache.jackrabbit.jcr.core.xml;
-import org.apache.log4j.Logger;
import org.apache.jackrabbit.jcr.core.*;
import org.apache.jackrabbit.jcr.core.nodetype.NodeTypeRegistry;
+import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -25,7 +25,6 @@
import javax.jcr.RepositoryException;
import javax.jcr.StringValue;
-import javax.jcr.Value;
import java.util.Stack;
/**
@@ -87,7 +86,7 @@
}
}
StringValue val = new StringValue(atts.getValue(i));
- currentParent.setProperty(propName, new Value[]{val});
+ currentParent.setProperty(propName, val);
}
} catch (RepositoryException re) {
throw new SAXException(re);
@@ -105,8 +104,7 @@
NodeImpl currentParent = (NodeImpl) parents.peek();
NodeImpl txtNode = (NodeImpl) currentParent.addNode(DocViewSAXEventGenerator.NODENAME_XMLTEXT);
StringValue val = new StringValue(new String(ch, start, length));
- txtNode.setProperty(DocViewSAXEventGenerator.PROPNAME_XMLCHARACTERS,
- new Value[]{val});
+ txtNode.setProperty(DocViewSAXEventGenerator.PROPNAME_XMLCHARACTERS, val);
} catch (RepositoryException re) {
throw new SAXException(re);
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/SysViewImportHandler.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/SysViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/jcr/core/xml/SysViewImportHandler.java Mon Sep 20 09:53:38 2004
@@ -28,6 +28,7 @@
import javax.jcr.*;
import javax.jcr.nodetype.NodeDef;
import javax.jcr.nodetype.PropertyDef;
+import javax.jcr.nodetype.ConstraintViolationException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -272,10 +273,25 @@
}
if (current.node.hasProperty(currentPropName)) {
PropertyDef def = current.node.getProperty(currentPropName).getDefinition();
- if (!def.isProtected()) {
+ if (def.isProtected()) {
+ // ignore protected property
+ // reset temp fields and get outta here
+ currentPropValues = null;
+ return;
+ }
+ }
+ // multi- or single-valued property?
+ if (vals.length == 1) {
+ // could be single- or multi-valued (n == 1)
+ try {
+ // try setting single-value
+ current.node.setProperty(currentPropName, vals[0]);
+ } catch (ConstraintViolationException cve) {
+ // try setting value array
current.node.setProperty(currentPropName, vals);
}
} else {
+ // can only be multi-valued (n == 0 || n > 1)
current.node.setProperty(currentPropName, vals);
}
}