use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class NodeImpl method setMixins.
/**
* {@inheritDoc}
*/
public void setMixins(String[] mixinNames) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
// check state of this instance
sanityCheck();
NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
Set<Name> newMixins = new HashSet<Name>();
for (String name : mixinNames) {
Name qName = sessionContext.getQName(name);
if (!ntMgr.getNodeType(qName).isMixin()) {
throw new RepositoryException(sessionContext.getJCRName(qName) + " is not a mixin node type");
}
newMixins.add(qName);
}
// make sure this node is checked-out, neither protected nor locked and
// the editing session has sufficient permission to change the mixin types.
// special handling of mix:(simple)versionable. since adding the
// mixin alters the version storage jcr:versionManagement privilege
// is required in addition.
int permissions = Permission.NODE_TYPE_MNGMT;
if (newMixins.contains(MIX_VERSIONABLE) || newMixins.contains(MIX_SIMPLE_VERSIONABLE)) {
permissions |= Permission.VERSION_MNGMT;
}
int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
sessionContext.getItemValidator().checkModify(this, options, permissions);
final NodeState state = data.getNodeState();
// build effective node type of primary type & new mixin's
// in order to detect conflicts
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
EffectiveNodeType entNew, entOld, entAll;
try {
entNew = ntReg.getEffectiveNodeType(newMixins);
entOld = ntReg.getEffectiveNodeType(state.getMixinTypeNames());
// try to build new effective node type (will throw in case of conflicts)
entAll = ntReg.getEffectiveNodeType(state.getNodeTypeName(), newMixins);
} catch (NodeTypeConflictException ntce) {
throw new ConstraintViolationException(ntce.getMessage());
}
// added child item definitions
Set<QItemDefinition> addedDefs = new HashSet<QItemDefinition>(Arrays.asList(entNew.getAllItemDefs()));
addedDefs.removeAll(Arrays.asList(entOld.getAllItemDefs()));
// referential integrity check
boolean referenceableOld = getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE);
boolean referenceableNew = entAll.includesNodeType(NameConstants.MIX_REFERENCEABLE);
if (referenceableOld && !referenceableNew) {
// node would become non-referenceable;
// make sure no references exist
PropertyIterator iter = getReferences();
if (iter.hasNext()) {
throw new ConstraintViolationException("the new mixin types cannot be set as it would render " + "this node 'non-referenceable' while it is still being " + "referenced through at least one property of type REFERENCE");
}
}
// gather currently assigned definitions *before* doing actual modifications
Map<ItemId, ItemDefinition> oldDefs = new HashMap<ItemId, ItemDefinition>();
for (Name name : getNodeState().getPropertyNames()) {
PropertyId id = new PropertyId(getNodeId(), name);
try {
PropertyState propState = (PropertyState) stateMgr.getItemState(id);
oldDefs.put(id, itemMgr.getDefinition(propState));
} catch (ItemStateException ise) {
String msg = name + ": failed to retrieve property state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
for (ChildNodeEntry cne : getNodeState().getChildNodeEntries()) {
try {
NodeState nodeState = (NodeState) stateMgr.getItemState(cne.getId());
oldDefs.put(cne.getId(), itemMgr.getDefinition(nodeState));
} catch (ItemStateException ise) {
String msg = cne + ": failed to retrieve node state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// now do the actual modifications in content as mandated by the new mixins
// modify the state of this node
NodeState thisState = (NodeState) getOrCreateTransientItemState();
thisState.setMixinTypeNames(newMixins);
// set jcr:mixinTypes property
setMixinTypesProperty(newMixins);
// walk through properties and child nodes and change definition as necessary
// use temp set to avoid ConcurrentModificationException
HashSet<Name> set = new HashSet<Name>(thisState.getPropertyNames());
for (Name propName : set) {
PropertyState propState = null;
try {
propState = (PropertyState) stateMgr.getItemState(new PropertyId(thisState.getNodeId(), propName));
// the following call triggers ConstraintViolationException
// if there isn't any suitable definition anymore
itemMgr.getDefinition(propState);
} catch (ConstraintViolationException cve) {
// redefine property if possible
try {
if (oldDefs.get(propState.getId()).isProtected()) {
// remove 'orphaned' protected properties immediately
removeChildProperty(propName);
continue;
}
PropertyDefinitionImpl pdi = getApplicablePropertyDefinition(propName, propState.getType(), propState.isMultiValued(), false);
PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
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(), getSession().getValueFactory());
// redefine property
prop.onRedefine(pdi.unwrap());
// set converted values
prop.setValue(values);
} else {
// convert value
Value value = ValueHelper.convert(prop.getValue(), pdi.getRequiredType(), getSession().getValueFactory());
// redefine property
prop.onRedefine(pdi.unwrap());
// set converted values
prop.setValue(value);
}
} else {
// redefine property
prop.onRedefine(pdi.unwrap());
}
// update collection of added definitions
addedDefs.remove(pdi.unwrap());
} catch (ValueFormatException vfe) {
// value conversion failed, remove it
removeChildProperty(propName);
} catch (ConstraintViolationException cve1) {
// 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);
}
}
// use temp array to avoid ConcurrentModificationException
ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(thisState.getChildNodeEntries());
// start from tail to avoid problems with same-name siblings
for (int i = list.size() - 1; i >= 0; i--) {
ChildNodeEntry entry = list.get(i);
NodeState nodeState = null;
try {
nodeState = (NodeState) stateMgr.getItemState(entry.getId());
// the following call triggers ConstraintViolationException
// if there isn't any suitable definition anymore
itemMgr.getDefinition(nodeState);
} catch (ConstraintViolationException cve) {
// redefine node if possible
try {
if (oldDefs.get(nodeState.getId()).isProtected()) {
// remove 'orphaned' protected child node immediately
removeChildNode(entry.getId());
continue;
}
NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(entry.getName(), nodeState.getNodeTypeName());
NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
// redefine node
node.onRedefine(ndi.unwrap());
// update collection of added definitions
addedDefs.remove(ndi.unwrap());
} catch (ConstraintViolationException cve1) {
// no suitable definition found for this child node,
// remove it
removeChildNode(entry.getId());
}
} catch (ItemStateException ise) {
String msg = entry + ": failed to retrieve node state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// and at the same time were not present with the old mixins
for (QItemDefinition def : addedDefs) {
if (def.isAutoCreated()) {
if (def.definesNode()) {
NodeDefinitionImpl ndi = ntMgr.getNodeDefinition((QNodeDefinition) def);
createChildNode(def.getName(), (NodeTypeImpl) ndi.getDefaultPrimaryType(), null);
} else {
PropertyDefinitionImpl pdi = ntMgr.getPropertyDefinition((QPropertyDefinition) def);
createChildProperty(pdi.unwrap().getName(), pdi.getRequiredType(), pdi);
}
}
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class SetPropertyConstraintViolationExceptionTest method testBinaryProperty.
/**
* Tests if setProperty(String name, InputStream value) and
* setProperty(String name, Value value) where value is a BinaryValue throw
* a ConstraintViolationException either immediately (by setProperty()), or
* on save, if the change would violate a node type constraint
*/
public void testBinaryProperty() throws NotExecutableException, RepositoryException {
// locate a PropertyDefinition with ValueConstraints
PropertyDefinition propDef = NodeTypeUtil.locatePropertyDef(superuser, PropertyType.BINARY, false, false, true, false);
if (propDef == null) {
throw new NotExecutableException("No binary property def with " + "testable value constraints has been found");
}
// find a Value that does not satisfy the ValueConstraints of propDef
Value valueNotSatisfied1 = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, false);
Value valueNotSatisfied2 = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, false);
if (valueNotSatisfied1 == null || valueNotSatisfied2 == null) {
throw new NotExecutableException("No binary property def with " + "testable value constraints has been found");
}
// create a sub node of testRootNode of type propDef.getDeclaringNodeType()
Node node;
try {
String nodeType = propDef.getDeclaringNodeType().getName();
node = testRootNode.addNode(nodeName2, nodeType);
testRootNode.getSession().save();
} catch (ConstraintViolationException e) {
// implementation specific constraints do not allow to set up test environment
throw new NotExecutableException("Not able to create required test items.");
}
// test of signature setProperty(String name, InputStream value)
InputStream in = valueNotSatisfied1.getStream();
try {
node.setProperty(propDef.getName(), in);
node.save();
fail("setProperty(String name, InputStream value) must throw a " + "ConstraintViolationException if the change would violate a " + "node type constraint either immediately or on save");
} catch (ConstraintViolationException e) {
// success
} finally {
try {
in.close();
} catch (IOException ignore) {
}
}
// test of signature setProperty(String name, Value value)
try {
node.setProperty(propDef.getName(), valueNotSatisfied2);
node.save();
fail("setProperty(String name, Value value) must throw a " + "ConstraintViolationException if the change would violate a " + "node type constraint either immediately or on save");
} catch (ConstraintViolationException e) {
// success
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class SetValueConstraintViolationExceptionTest method testBinaryProperty.
/**
* Tests if setValue(InputStream value) and setValue(Value value) where
* value is a BinaryValue throw a ConstraintViolationException if the change
* would violate a value constraint
*/
public void testBinaryProperty() throws NotExecutableException, RepositoryException {
// locate a PropertyDefinition with ValueConstraints
PropertyDefinition propDef = NodeTypeUtil.locatePropertyDef(superuser, PropertyType.BINARY, false, false, true, false);
if (propDef == null) {
throw new NotExecutableException("No binary property def with " + "testable value constraints has been found");
}
// find a Value that does not satisfy the ValueConstraints of propDef
Value valueNotSatisfied1 = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, false);
Value valueNotSatisfied2 = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, false);
if (valueNotSatisfied1 == null || valueNotSatisfied2 == null) {
throw new NotExecutableException("No binary property def with " + "testable value constraints has been found");
}
// find a Value that does satisfy the ValueConstraints of propDef
Value valueSatisfied = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, true);
if (valueSatisfied == null) {
throw new NotExecutableException("The value constraints do not allow any value.");
}
// create a sub node of testRootNode of type propDef.getDeclaringNodeType()
// and add a property with constraints to this node
Node node;
Property prop;
try {
String nodeType = propDef.getDeclaringNodeType().getName();
node = testRootNode.addNode(nodeName2, nodeType);
prop = node.setProperty(propDef.getName(), valueSatisfied);
testRootNode.getSession().save();
} catch (ConstraintViolationException e) {
// implementation specific constraints do not allow to set up test environment
throw new NotExecutableException("Not able to create required test items.");
}
// test of signature setValue(InputStream value)
InputStream in = valueNotSatisfied1.getStream();
try {
prop.setValue(in);
node.save();
fail("setValue(InputStream value) must throw a ConstraintViolationException " + "if the change would violate a node type constraint " + "either immediately or on save");
} catch (ConstraintViolationException e) {
// success
} finally {
try {
in.close();
} catch (IOException ignore) {
}
}
// test of signature setValue(Value value)
try {
prop.setValue(valueNotSatisfied2);
node.save();
fail("setValue(Value value) must throw a ConstraintViolationException " + "if the change would violate a node type constraint " + "either immediately or on save");
} catch (ConstraintViolationException e) {
// success
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class SetValueConstraintViolationExceptionTest method testDateProperty.
/**
* Tests if setValue(Calendar value) and setValue(Value value) where value
* is a DateValue throw a ConstraintViolationException if the change would
* violate a value constraint
*/
public void testDateProperty() throws NotExecutableException, RepositoryException {
// locate a PropertyDefinition with ValueConstraints
PropertyDefinition propDef = NodeTypeUtil.locatePropertyDef(superuser, PropertyType.DATE, false, false, true, false);
if (propDef == null) {
throw new NotExecutableException("No date property def with " + "testable value constraints has been found");
}
// find a Value that does not satisfy the ValueConstraints of propDef
Value valueNotSatisfied = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, false);
if (valueNotSatisfied == null) {
throw new NotExecutableException("No date property def with " + "testable value constraints has been found");
}
// find a Value that does satisfy the ValueConstraints of propDef
Value valueSatisfied = NodeTypeUtil.getValueAccordingToValueConstraints(superuser, propDef, true);
if (valueSatisfied == null) {
throw new NotExecutableException("The value constraints do not allow any value.");
}
// create a sub node of testRootNode of type propDef.getDeclaringNodeType()
// and add a property with constraints to this node
Node node;
Property prop;
try {
String nodeType = propDef.getDeclaringNodeType().getName();
node = testRootNode.addNode(nodeName2, nodeType);
prop = node.setProperty(propDef.getName(), valueSatisfied);
testRootNode.getSession().save();
} catch (ConstraintViolationException e) {
// implementation specific constraints do not allow to set up test environment
throw new NotExecutableException("Not able to create required test items.");
}
// test of signature setValue(Calendar value)
try {
prop.setValue(valueNotSatisfied.getDate());
node.save();
fail("setValue(Date value) must throw a ConstraintViolationException " + "if the change would violate a node type constraint " + "either immediately or on save");
} catch (ConstraintViolationException e) {
// success
}
// test of signature setValue(Value value)
try {
prop.setValue(valueNotSatisfied);
node.save();
fail("setValue(Value value) must throw a ConstraintViolationException " + "if the change would violate a node type constraint " + "either immediately or on save");
} catch (ConstraintViolationException e) {
// success
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class SetValueConstraintViolationExceptionTest method testMultipleReferenceProperty.
/**
* Tests if setValue(Value[] values) where values are of type ReferenceValue
* throw a ConstraintViolationException if the change would violate a value
* constraint
*/
public void testMultipleReferenceProperty() throws NotExecutableException, RepositoryException {
// locate a PropertyDefinition with ValueConstraints
PropertyDefinition propDef = NodeTypeUtil.locatePropertyDef(superuser, PropertyType.REFERENCE, true, false, true, false);
if (propDef == null) {
throw new NotExecutableException("No multiple reference property def with " + "testable value constraints has been found");
}
String[] valueConstraints = propDef.getValueConstraints();
if (valueConstraints == null || valueConstraints.length == 0) {
throw new NotExecutableException("No reference property def with " + "testable value constraints has been found");
}
List<String> constraints = Arrays.asList(valueConstraints);
String nodeTypeSatisfied = constraints.get(0);
String nodeTypeNotSatisfied = null;
NodeTypeManager manager = superuser.getWorkspace().getNodeTypeManager();
NodeTypeIterator types = manager.getAllNodeTypes();
// find a NodeType which is not satisfying the constraints
while (types.hasNext()) {
NodeType type = types.nextNodeType();
String name = type.getName();
if (constraints.contains(name) || ntFrozenNode.equals(name)) {
continue;
}
if (type.getChildNodeDefinitions() != null && type.getChildNodeDefinitions().length > 0) {
continue;
}
nodeTypeNotSatisfied = name;
break;
}
if (nodeTypeNotSatisfied == null) {
throw new NotExecutableException("No reference property def with " + "testable value constraints has been found");
}
// create a sub node of testRootNode of type propDef.getDeclaringNodeType()
// and add a property with constraints to this node
Node node;
Property prop;
Node nodeSatisfied;
Node nodeNotSatisfied;
try {
String nodeType = propDef.getDeclaringNodeType().getName();
node = testRootNode.addNode(nodeName2, nodeType);
// create a referenceable node satisfying the constraint
nodeSatisfied = testRootNode.addNode(nodeName3, nodeTypeSatisfied);
ensureMixinType(nodeSatisfied, mixReferenceable);
// create a referenceable node not satisfying the constraint
nodeNotSatisfied = testRootNode.addNode(nodeName4, nodeTypeNotSatisfied);
ensureMixinType(nodeNotSatisfied, mixReferenceable);
// some implementations may require a save after addMixin()
testRootNode.getSession().save();
Value valueSatisfied = superuser.getValueFactory().createValue(nodeSatisfied);
prop = node.setProperty(propDef.getName(), new Value[] { valueSatisfied });
testRootNode.getSession().save();
} catch (ConstraintViolationException e) {
// implementation specific constraints do not allow to set up test environment
throw new NotExecutableException("Not able to create required test items.");
}
// test of signature setValue(Value value)
try {
Value valueNotSatisfied = superuser.getValueFactory().createValue(nodeNotSatisfied);
prop.setValue(new Value[] { valueNotSatisfied });
node.save();
fail("setValue(Value[] values) must throw a ConstraintViolationException " + "if the change would violate a node type constraint " + "either immediately or on save");
} catch (ConstraintViolationException e) {
// success
}
}
Aggregations