/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.apache.jackrabbit.test.api;
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.apache.jackrabbit.test.NotExecutableException;
import org.apache.jackrabbit.test.ISO8601;
import org.apache.jackrabbit.test.api.nodetype.NodeTypeUtil;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.Node;
import javax.jcr.Value;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Property;
import javax.jcr.ValueFormatException;
import java.util.Calendar;
import java.util.Date;
/**
* <code>SetPropertyAssumeTypeTest</code> tests if when setting a property
* of type <code>PropertyType.UNDEFINED</code> the type is assumed correctly.
* The signatures <code>Node.setProperty(String, Value, int)</code>,
* <code>Node.setProperty(String, String, int)</code>,
* <code>Node.setProperty(String, Value[], int)</code> and
* <code>Node.setProperty(String, Node)</code> are tested.
*
*/
public class SetPropertyAssumeTypeTest extends AbstractJCRTest {
private Node testNode;
private String testPropName;
private Value binaryValue;
private Value booleanValue;
private Value dateValue;
private Value doubleValue;
private Value longValue;
private Value nameValue;
private Value pathValue;
private Value stringValue;
private Value binaryValues[];
private Value booleanValues[];
private Value dateValues[];
private Value doubleValues[];
private Value longValues[];
private Value nameValues[];
private Value pathValues[];
private Value stringValues[];
public void setUp() throws Exception {
super.setUp();
testNode = testRootNode.addNode(nodeName1, testNodeType);
binaryValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.BINARY);
booleanValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.BOOLEAN);
dateValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.DATE);
doubleValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.DOUBLE);
longValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.LONG);
nameValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.NAME);
pathValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.PATH);
stringValue = NodeTypeUtil.getValueOfType(superuser, PropertyType.STRING);
binaryValues = new Value[] {binaryValue};
booleanValues = new Value[] {booleanValue};
dateValues = new Value[] {dateValue};
doubleValues = new Value[] {doubleValue};
longValues = new Value[] {longValue};
nameValues = new Value[] {nameValue};
pathValues = new Value[] {pathValue};
stringValues = new Value[] {stringValue};
}
protected void tearDown() throws Exception {
testNode = null;
testPropName = null;
binaryValue = null;
booleanValue = null;
dateValue = null;
doubleValue = null;
longValue = null;
nameValue = null;
pathValue = null;
stringValue = null;
binaryValues = null;
booleanValues = null;
dateValues = null;
doubleValues = null;
longValues = null;
nameValues = null;
pathValues = null;
stringValues = null;
super.tearDown();
}
/**
* Tests if <code>Node.setProperty(String, Value, int)</code> if the node
* type of this node does not indicate a specific property type, then the
* type parameter is used.
*/
public void testValue() throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(false);
Property prop;
prop = testNode.setProperty(testPropName, binaryValue, PropertyType.BINARY);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BINARY,
prop.getType());
prop = testNode.setProperty(testPropName, stringValue, PropertyType.BOOLEAN);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BOOLEAN,
prop.getType());
prop = testNode.setProperty(testPropName, doubleValue, PropertyType.DATE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DATE,
prop.getType());
prop = testNode.setProperty(testPropName, dateValue, PropertyType.DOUBLE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DOUBLE,
prop.getType());
prop = testNode.setProperty(testPropName, dateValue, PropertyType.LONG);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.LONG,
prop.getType());
// create a PathValue that is convertible to the value of name property
Value valueConvertibleToName = superuser.getValueFactory().createValue(nameValue.getString(), PropertyType.PATH);
prop = testNode.setProperty(testPropName, valueConvertibleToName, PropertyType.NAME);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.NAME,
prop.getType());
prop = testNode.setProperty(testPropName, nameValue, PropertyType.PATH);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.PATH,
prop.getType());
prop = testNode.setProperty(testPropName, dateValue, PropertyType.STRING);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.STRING,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, Value[], int)</code> if the node
* type of this node does not indicate a specific property type, then the
* type parameter is used.
*/
public void testValues() throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(true);
Property prop;
prop = testNode.setProperty(testPropName, binaryValues, PropertyType.BINARY);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BINARY,
prop.getType());
prop = testNode.setProperty(testPropName, stringValues, PropertyType.BOOLEAN);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BOOLEAN,
prop.getType());
prop = testNode.setProperty(testPropName, doubleValues, PropertyType.DATE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DATE,
prop.getType());
prop = testNode.setProperty(testPropName, dateValues, PropertyType.DOUBLE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DOUBLE,
prop.getType());
prop = testNode.setProperty(testPropName, dateValues, PropertyType.LONG);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.LONG,
prop.getType());
// create a PathValue that is convertible to the value of name property
Value valuesConvertibleToName[] =
new Value[] {superuser.getValueFactory().createValue(nameValue.getString(), PropertyType.PATH)};
prop = testNode.setProperty(testPropName, valuesConvertibleToName, PropertyType.NAME);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.NAME,
prop.getType());
prop = testNode.setProperty(testPropName, nameValues, PropertyType.PATH);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.PATH,
prop.getType());
prop = testNode.setProperty(testPropName, dateValues, PropertyType.STRING);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.STRING,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, String, int)</code> if the node
* type of this node does not indicate a specific property type, then the
* type parameter is used.
*/
public void testString() throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(false);
Property prop;
prop = testNode.setProperty(testPropName, binaryValue.getString(), PropertyType.BINARY);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BINARY,
prop.getType());
prop = testNode.setProperty(testPropName, booleanValue.getString(), PropertyType.BOOLEAN);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.BOOLEAN,
prop.getType());
prop = testNode.setProperty(testPropName, dateValue.getString(), PropertyType.DATE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DATE,
prop.getType());
prop = testNode.setProperty(testPropName, doubleValue.getString(), PropertyType.DOUBLE);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.DOUBLE,
prop.getType());
prop = testNode.setProperty(testPropName, longValue.getString(), PropertyType.LONG);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.LONG,
prop.getType());
prop = testNode.setProperty(testPropName, nameValue.getString(), PropertyType.NAME);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.NAME,
prop.getType());
prop = testNode.setProperty(testPropName, pathValue.getString(), PropertyType.PATH);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.PATH,
prop.getType());
prop = testNode.setProperty(testPropName, stringValue.getString(), PropertyType.STRING);
assertEquals("setProperty(String, Value, int) of a property of type undefined " +
"must assume the property type of the type parameter.",
PropertyType.STRING,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, Value)</code> if the node type of
* this node does not indicate a specific property type, then the property
* type of the supplied Value object is used and if the property already
* exists (has previously been set) it assumes the new property type.
*/
public void testValueAssumeTypeOfValue() throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(false);
Property prop;
prop = testNode.setProperty(testPropName, binaryValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.BINARY,
prop.getType());
prop = testNode.setProperty(testPropName, booleanValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.BOOLEAN,
prop.getType());
prop = testNode.setProperty(testPropName, dateValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.DATE,
prop.getType());
prop = testNode.setProperty(testPropName, doubleValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.DOUBLE,
prop.getType());
prop = testNode.setProperty(testPropName, longValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.LONG,
prop.getType());
prop = testNode.setProperty(testPropName, nameValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.NAME,
prop.getType());
prop = testNode.setProperty(testPropName, pathValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.PATH,
prop.getType());
prop = testNode.setProperty(testPropName, stringValue);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.STRING,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, Node)</code> if the node type of
* this node does not indicate a specific property type, then the property
* type of the supplied Value object is used and if the property already
* exists (has previously been set) it assumes the new property type.
*/
public void testNodeAssumeTypeOfValue()
throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(false);
Node referenceableNode = testRootNode.addNode(nodeName2);
ensureMixinType(referenceableNode, mixReferenceable);
// some implementations may require a save after addMixin()
testRootNode.getSession().save();
Property prop = testNode.setProperty(testPropName, referenceableNode);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.REFERENCE,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, Value[])</code> if the node type of
* this node does not indicate a specific property type, then the property
* type of the supplied Value object is used and if the property already
* exists (has previously been set) it assumes the new property type.
*/
public void testValuesAssumeTypeOfValue() throws NotExecutableException, RepositoryException {
setUpNodeWithUndefinedProperty(true);
Property prop;
prop = testNode.setProperty(testPropName, binaryValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.BINARY,
prop.getType());
prop = testNode.setProperty(testPropName, booleanValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.BOOLEAN,
prop.getType());
prop = testNode.setProperty(testPropName, dateValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.DATE,
prop.getType());
prop = testNode.setProperty(testPropName, doubleValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.DOUBLE,
prop.getType());
prop = testNode.setProperty(testPropName, longValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.LONG,
prop.getType());
prop = testNode.setProperty(testPropName, nameValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.NAME,
prop.getType());
prop = testNode.setProperty(testPropName, pathValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.PATH,
prop.getType());
prop = testNode.setProperty(testPropName, stringValues);
assertEquals("setProperty(String, Value) of a property of type undefined " +
"must assume the property type of the supplied value object.",
PropertyType.STRING,
prop.getType());
}
/**
* Tests if <code>Node.setProperty(String, Value, int)</code> throws a
* ConstraintViolationException if the type parameter and the type of the
* property do not match. The exception has to be thrown either immediately
* (by this method) or on save.
*/
public void testValueConstraintViolationExceptionBecauseOfInvalidTypeParameter()
throws NotExecutableException, RepositoryException {
try {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(0));
Value v = superuser.getValueFactory().createValue(ISO8601.format(cal));
testNode.setProperty(propertyName1, v, PropertyType.DATE);
testRootNode.getSession().save();
fail("Node.setProperty(String, Value, int) must throw a " +
"ConstraintViolationExcpetion if the type parameter and the " +
"type of the property do not match." );
}
catch (ConstraintViolationException e) {
// success
}
}
/**
* Tests if <code>Node.setProperty(String, String, int)</code> throws a
* ConstraintViolationException if the type parameter and the type of the
* property do not match. The exception has to be thrown either immediately
* (by this method) or on save.
*/
public void testStringConstraintViolationExceptionBecauseOfInvalidTypeParameter()
throws NotExecutableException, RepositoryException {
try {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(0));
testNode.setProperty(propertyName1, ISO8601.format(cal), PropertyType.DATE);
testRootNode.getSession().save();
fail("Node.setProperty(String, Value, int) must throw a " +
"ConstraintViolationExcpetion if the type parameter and the " +
"type of the property do not match." );
}
catch (ConstraintViolationException e) {
// success
}
}
/**
* Tests if <code>Node.setProperty(String, Value[], int)</code> throws a
* ConstraintViolationException or ValueFormatException if the type
* parameter and the type of the property do not match. The exception has to
* be thrown either immediately (by this method) or on save.
*/
public void testValuesConstraintViolationExceptionBecauseOfInvalidTypeParameter()
throws NotExecutableException, RepositoryException {
try {
testNode.setProperty(propertyName1, stringValues, PropertyType.DATE);
testRootNode.getSession().save();
fail("Node.setProperty(String, Value, int) must throw a " +
"ConstraintViolationExcpetion or a ValueFormatException if " +
"the type parameter and the type of the property do not match.");
} catch (ConstraintViolationException e) {
// success
} catch (ValueFormatException e) {
// success
}
}
//--------------------------< internal >------------------------------------
private void setUpNodeWithUndefinedProperty(boolean multiple)
throws NotExecutableException {
try {
// locate a property definition of type undefined
PropertyDefinition propDef =
NodeTypeUtil.locatePropertyDef(superuser, PropertyType.UNDEFINED, multiple, false, false, false);
if (propDef == null) {
throw new NotExecutableException("No testable property of type " +
"UNDEFINED has been found.");
}
// create a node of type propDef.getDeclaringNodeType()
String nodeType = propDef.getDeclaringNodeType().getName();
testNode = testRootNode.addNode(nodeName1, nodeType);
testPropName = propDef.getName();
}
catch (RepositoryException e) {
throw new NotExecutableException("Not able to set up test items.");
}
}
}