use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class ItemValidator method validate.
/**
* Checks whether the given node state satisfies the constraints specified
* by its primary and mixin node types. The following validations/checks are
* performed:
* <ul>
* <li>check if its node type satisfies the 'required node types' constraint
* specified in its definition</li>
* <li>check if all 'mandatory' child items exist</li>
* <li>for every property: check if the property value satisfies the
* value constraints specified in the property's definition</li>
* </ul>
*
* @param nodeState state of node to be validated
* @throws ConstraintViolationException if any of the validations fail
* @throws RepositoryException if another error occurs
*/
public void validate(NodeState nodeState) throws ConstraintViolationException, RepositoryException {
// effective primary node type
NodeTypeRegistry registry = context.getNodeTypeRegistry();
EffectiveNodeType entPrimary = registry.getEffectiveNodeType(nodeState.getNodeTypeName());
// effective node type (primary type incl. mixins)
EffectiveNodeType entPrimaryAndMixins = getEffectiveNodeType(nodeState);
QNodeDefinition def = context.getItemManager().getDefinition(nodeState).unwrap();
// check if primary type satisfies the 'required node types' constraint
for (Name requiredPrimaryType : def.getRequiredPrimaryTypes()) {
if (!entPrimary.includesNodeType(requiredPrimaryType)) {
String msg = safeGetJCRPath(nodeState.getNodeId()) + ": missing required primary type " + requiredPrimaryType;
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
// mandatory properties
for (QPropertyDefinition pd : entPrimaryAndMixins.getMandatoryPropDefs()) {
if (!nodeState.hasPropertyName(pd.getName())) {
String msg = safeGetJCRPath(nodeState.getNodeId()) + ": mandatory property " + pd.getName() + " does not exist";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
// mandatory child nodes
for (QItemDefinition cnd : entPrimaryAndMixins.getMandatoryNodeDefs()) {
if (!nodeState.hasChildNodeEntry(cnd.getName())) {
String msg = safeGetJCRPath(nodeState.getNodeId()) + ": mandatory child node " + cnd.getName() + " does not exist";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class NodeImpl method setPrimaryType.
/**
* {@inheritDoc}
*/
public void setPrimaryType(String nodeTypeName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
// check state of this instance
sanityCheck();
// make sure this node is checked-out, neither protected nor locked and
// the editing session has sufficient permission to change the primary type.
int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
sessionContext.getItemValidator().checkModify(this, options, Permission.NODE_TYPE_MNGMT);
final NodeState state = data.getNodeState();
if (state.getParentId() == null) {
String msg = "changing the primary type of the root node is not supported";
log.debug(msg);
throw new RepositoryException(msg);
}
Name ntName = sessionContext.getQName(nodeTypeName);
if (ntName.equals(state.getNodeTypeName())) {
log.debug("Node already has " + nodeTypeName + " as primary node type.");
return;
}
NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
NodeType nt = ntMgr.getNodeType(ntName);
if (nt.isMixin()) {
throw new ConstraintViolationException(nodeTypeName + ": not a primary node type.");
} else if (nt.isAbstract()) {
throw new ConstraintViolationException(nodeTypeName + ": is an abstract node type.");
}
// build effective node type of new primary type & existing mixin's
// in order to detect conflicts
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
EffectiveNodeType entNew, entOld, entAll;
try {
entNew = ntReg.getEffectiveNodeType(ntName);
entOld = ntReg.getEffectiveNodeType(state.getNodeTypeName());
// try to build new effective node type (will throw in case of conflicts)
entAll = ntReg.getEffectiveNodeType(ntName, state.getMixinTypeNames());
} catch (NodeTypeConflictException ntce) {
throw new ConstraintViolationException(ntce.getMessage());
}
// get applicable definition for this node using new primary type
QNodeDefinition nodeDef;
try {
NodeImpl parent = (NodeImpl) getParent();
nodeDef = parent.getApplicableChildNodeDefinition(getQName(), ntName).unwrap();
} catch (RepositoryException re) {
String msg = this + ": no applicable definition found in parent node's node type";
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
if (!nodeDef.equals(itemMgr.getDefinition(state).unwrap())) {
onRedefine(nodeDef);
}
Set<QItemDefinition> oldDefs = new HashSet<QItemDefinition>(Arrays.asList(entOld.getAllItemDefs()));
Set<QItemDefinition> newDefs = new HashSet<QItemDefinition>(Arrays.asList(entNew.getAllItemDefs()));
Set<QItemDefinition> allDefs = new HashSet<QItemDefinition>(Arrays.asList(entAll.getAllItemDefs()));
// added child item definitions
Set<QItemDefinition> addedDefs = new HashSet<QItemDefinition>(newDefs);
addedDefs.removeAll(oldDefs);
// referential integrity check
boolean referenceableOld = entOld.includesNodeType(NameConstants.MIX_REFERENCEABLE);
boolean referenceableNew = entNew.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 primary type 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");
}
}
// do the actual modifications in content as mandated by the new primary type
// modify the state of this node
NodeState thisState = (NodeState) getOrCreateTransientItemState();
thisState.setNodeTypeName(ntName);
// set jcr:primaryType property
internalSetProperty(NameConstants.JCR_PRIMARYTYPE, InternalValue.create(ntName));
// 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) {
try {
PropertyState propState = (PropertyState) stateMgr.getItemState(new PropertyId(thisState.getNodeId(), propName));
if (!allDefs.contains(itemMgr.getDefinition(propState).unwrap())) {
// redefine property if possible
try {
PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
if (prop.getDefinition().isProtected()) {
// remove 'orphaned' protected properties immediately
removeChildProperty(propName);
continue;
}
PropertyDefinitionImpl 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(), 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 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);
}
}
// 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);
try {
NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
if (!allDefs.contains(itemMgr.getDefinition(nodeState).unwrap())) {
// redefine node if possible
try {
NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
if (node.getDefinition().isProtected()) {
// remove 'orphaned' protected child node immediately
removeChildNode(entry.getId());
continue;
}
NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(entry.getName(), nodeState.getNodeTypeName());
// redefine node
node.onRedefine(ndi.unwrap());
// update collection of added definitions
addedDefs.remove(ndi.unwrap());
} catch (ConstraintViolationException cve) {
// no suitable definition found for this child node,
// remove it
removeChildNode(entry.getId());
}
}
} catch (ItemStateException ise) {
String msg = entry.getName() + ": failed to retrieve node state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// type and at the same time were not present with the old nt
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 NodeImpl method addNode.
/**
* Same as <code>{@link Node#addNode(String, String)}</code> except that
* this method takes <code>Name</code> arguments instead of
* <code>String</code>s and has an additional <code>uuid</code> argument.
* <p>
* <b>Important Notice:</b> This method is for internal use only! Passing
* already assigned uuid's might lead to unexpected results and
* data corruption in the worst case.
*
* @param nodeName name of the new node
* @param nodeTypeName name of the new node's node type or <code>null</code>
* if it should be determined automatically
* @param id id of the new node or <code>null</code> if a new
* id should be assigned
* @return the newly added node
* @throws RepositoryException if the node can not added
*/
// FIXME: This method should not be public
public synchronized NodeImpl addNode(Name nodeName, Name nodeTypeName, NodeId id) throws RepositoryException {
// check state of this instance
sanityCheck();
Path nodePath = PathFactoryImpl.getInstance().create(getPrimaryPath(), nodeName, true);
// Check the explicitly specified node type (if any)
NodeTypeImpl nt = null;
if (nodeTypeName != null) {
nt = sessionContext.getNodeTypeManager().getNodeType(nodeTypeName);
if (nt.isMixin()) {
throw new ConstraintViolationException("Unable to add a node with a mixin node type: " + sessionContext.getJCRName(nodeTypeName));
} else if (nt.isAbstract()) {
throw new ConstraintViolationException("Unable to add a node with an abstract node type: " + sessionContext.getJCRName(nodeTypeName));
} else {
// adding a node with explicit specifying the node type name
// requires the editing session to have nt_management privilege.
sessionContext.getAccessManager().checkPermission(nodePath, Permission.NODE_TYPE_MNGMT);
}
}
// Get the applicable child node definition for this node.
NodeDefinitionImpl def;
try {
def = getApplicableChildNodeDefinition(nodeName, nodeTypeName);
} catch (RepositoryException e) {
throw new ConstraintViolationException("No child node definition for " + sessionContext.getJCRName(nodeName) + " found in " + this, e);
}
// Use default node type from child node definition if needed
if (nt == null) {
nt = (NodeTypeImpl) def.getDefaultPrimaryType();
}
// check the new name
NodeNameNormalizer.check(nodeName);
// check for name collisions
NodeState thisState = data.getNodeState();
ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
if (cne != null) {
// check same-name sibling setting of new node
if (!def.allowsSameNameSiblings()) {
throw new ItemExistsException("This node already exists: " + itemMgr.safeGetJCRPath(nodePath));
}
// check same-name sibling setting of existing node
NodeImpl existing = itemMgr.getNode(cne.getId(), getNodeId());
if (!existing.getDefinition().allowsSameNameSiblings()) {
throw new ItemExistsException("Same-name siblings not allowed for " + existing);
}
}
// check protected flag of parent (i.e. this) node and retention/hold
// make sure this node is checked-out and not locked by another session.
int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
sessionContext.getItemValidator().checkModify(this, options, Permission.NONE);
// now do create the child node
return createChildNode(nodeName, nt, id);
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class VersionTest method testSetProperty.
/**
* Tests if
* <ul> <li><code>Version.setProperty(String, String[])</code></li>
* <li><code>Version.setProperty(String, String[], int)</code></li>
* <li><code>Version.setProperty(String, Value[])</code></li>
* <li><code>Version.setProperty(String, Value[], int)</code></li>
* <li><code>Version.setProperty(String, boolean)</code></li>
* <li><code>Version.setProperty(String, double)</code></li>
* <li><code>Version.setProperty(String, InputStream)</code></li>
* <li><code>Version.setProperty(String, String)</code></li>
* <li><code>Version.setProperty(String, Calendar)</code></li>
* <li><code>Version.setProperty(String, Node)</code></li>
* <li><code>Version.setProperty(String, Value)</code></li>
* <li><code>Version.setProperty(String, long)</code></li>
* </ul> all throw a
* {@link javax.jcr.nodetype.ConstraintViolationException}
*/
public void testSetProperty() throws Exception {
// create Value[] object
Value[] vArray = new Value[3];
vArray[0] = superuser.getValueFactory().createValue("abc");
vArray[1] = superuser.getValueFactory().createValue("xyz");
vArray[2] = superuser.getValueFactory().createValue("123");
// create String array
String[] s = { "abc", "xyz", "123" };
try {
version.setProperty(propertyName1, s);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,String[]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, s, PropertyType.STRING);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,String[],int) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, vArray);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,Value[]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, vArray, PropertyType.STRING);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,Value[],int]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, true);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,boolean) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, 123);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,double) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
byte[] bytes = { 73, 26, 32, -36, 40, -43, -124 };
InputStream inpStream = new ByteArrayInputStream(bytes);
version.setProperty(propertyName1, inpStream);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,InputStream) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, "abc");
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
Calendar c = new GregorianCalendar(1945, 1, 6, 16, 20, 0);
version.setProperty(propertyName1, c);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,Calendar) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, version);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,Node) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
Value v = superuser.getValueFactory().createValue("abc");
version.setProperty(propertyName1, v);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,Value) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, -2147483650L);
version.getSession().save();
fail("Version should be read-only: Version.setProperty(String,long) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
use of javax.jcr.nodetype.ConstraintViolationException in project jackrabbit by apache.
the class NodeImpl method rename.
//-------------------------------------------------------< JackrabbitNode >
/**
* {@inheritDoc}
*/
public void rename(String newName) throws RepositoryException {
// check if this is the root node
if (getDepth() == 0) {
throw new RepositoryException("Cannot rename the root node");
}
Name qName;
try {
qName = sessionContext.getQName(newName);
} catch (NameException e) {
throw new RepositoryException("invalid node name: " + newName, e);
}
NodeImpl parent = (NodeImpl) getParent();
// check for name collisions
NodeImpl existing = null;
try {
existing = parent.getNode(qName);
// check same-name sibling setting of existing node
if (!existing.getDefinition().allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings are not allowed: " + existing);
}
} catch (AccessDeniedException ade) {
// FIXME by throwing ItemExistsException we're disclosing too much information
throw new ItemExistsException();
} catch (ItemNotFoundException infe) {
// no name collision, fall through
}
// verify that parent node
// - is checked-out
// - is not protected neither by node type constraints nor by retention/hold
int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
sessionContext.getItemValidator().checkRemove(parent, options, Permission.NONE);
sessionContext.getItemValidator().checkModify(parent, options, Permission.NONE);
// check constraints
// get applicable definition of renamed target node
NodeTypeImpl nt = (NodeTypeImpl) getPrimaryNodeType();
org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl newTargetDef;
try {
newTargetDef = parent.getApplicableChildNodeDefinition(qName, nt.getQName());
} catch (RepositoryException re) {
String msg = safeGetJCRPath() + ": no definition found in parent node's node type for renamed node";
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
// necessarily have identical definitions
if (existing != null && !newTargetDef.allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings not allowed: " + existing);
}
// check permissions:
// 1. on the parent node the session must have permission to manipulate the child-entries
AccessManager acMgr = sessionContext.getAccessManager();
if (!acMgr.isGranted(parent.getPrimaryPath(), qName, Permission.MODIFY_CHILD_NODE_COLLECTION)) {
String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
log.debug(msg);
throw new AccessDeniedException(msg);
}
// the primary node type on this node itself.
if (!nt.getName().equals(newTargetDef.getName()) && !(acMgr.isGranted(getPrimaryPath(), Permission.NODE_TYPE_MNGMT))) {
String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
log.debug(msg);
throw new AccessDeniedException(msg);
}
// change definition
onRedefine(newTargetDef.unwrap());
// delegate to parent
parent.renameChildNode(getNodeId(), qName, true);
}
Aggregations