/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.api.writing;
import org.exoplatform.services.jcr.JcrAPIBaseTest;
import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.value.NameValue;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.GregorianCalendar;
import javax.jcr.ItemExistsException;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.OnParentVersionAction;
/**
* Created by The eXo Platform SAS.
*
* @author <a href="mailto:geaz@users.sourceforge.net">Gennady Azarenkov</a>
* @version $Id: TestSetProperty.java 14508 2008-05-20 10:07:45Z ksm $
*/
public class TestSetProperty extends JcrAPIBaseTest implements ItemsPersistenceListener
{
static protected String TEST_MULTIVALUED = "testMultivalued";
protected Node testMultivalued = null;
private TransactionChangesLog cLog;
public void setUp() throws Exception
{
super.setUp();
WorkspaceContainerFacade wsc = repository.getWorkspaceContainer(session.getWorkspace().getName());
CacheableWorkspaceDataManager dm =
(CacheableWorkspaceDataManager)wsc.getComponent(CacheableWorkspaceDataManager.class);
dm.addItemPersistenceListener(this);
}
public void initRepository() throws RepositoryException
{
Node root = session.getRootNode();
Node propDef = root.addNode("propertyDefNode", "nt:propertyDefinition");
propDef.setProperty("jcr:name", valueFactory.createValue("test", PropertyType.NAME));
propDef.setProperty("jcr:autoCreated", false);
propDef.setProperty("jcr:mandatory", false);
propDef.setProperty("jcr:onParentVersion", OnParentVersionAction.ACTIONNAME_COPY);
propDef.setProperty("jcr:protected", false);
propDef.setProperty("jcr:requiredType", PropertyType.TYPENAME_STRING.toUpperCase());
propDef.setProperty("jcr:multiple", false);
// Unknown Property Type. Should set something!
Value[] defVals = {session.getValueFactory().createValue("testString")};
propDef.setProperty("jcr:defaultValues", defVals);
Node childNodeDefNode = root.addNode("childNodeDefNode", "nt:childNodeDefinition");
childNodeDefNode.setProperty("jcr:name", valueFactory.createValue("test"), PropertyType.NAME);
childNodeDefNode.setProperty("jcr:autoCreated", false);
childNodeDefNode.setProperty("jcr:mandatory", false);
childNodeDefNode.setProperty("jcr:onParentVersion", OnParentVersionAction.ACTIONNAME_COPY);
childNodeDefNode.setProperty("jcr:protected", false);
childNodeDefNode.setProperty("jcr:requiredPrimaryTypes", new NameValue[]{(NameValue)valueFactory.createValue(
"nt:base", PropertyType.NAME)});
childNodeDefNode.setProperty("jcr:sameNameSiblings", false);
root.addNode("unstructured", "nt:unstructured");
testMultivalued = root.addNode(TEST_MULTIVALUED);
session.save();
}
public void tearDown() throws Exception
{
try
{
// testMultivalued.getSession().refresh(false);
testMultivalued.remove();
testMultivalued.getSession().save();
}
catch (RepositoryException e)
{
log.error("Error delete '" + TEST_MULTIVALUED + "' node", e);
}
session = (SessionImpl)repository.login(credentials, WORKSPACE);
Node root = session.getRootNode();
root.getNode("unstructured").remove();
// session.getItem("/propertyDefNode").remove();
root.getNode("propertyDefNode").remove();
root.getNode("childNodeDefNode").remove();
session.save();
// Unregister the listener in order to make it available to the GC
WorkspaceContainerFacade wsc = repository.getWorkspaceContainer(session.getWorkspace().getName());
CacheableWorkspaceDataManager dm =
(CacheableWorkspaceDataManager)wsc.getComponent(CacheableWorkspaceDataManager.class);
dm.removeItemPersistenceListener(this);
super.tearDown();
}
public void testSetPropertyNameValue() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("propertyDefNode");
// Node node = (Node)session.getItem("/propertyDefNode");
try
{
node.setProperty("jcr:multiple", valueFactory.createValue(20l));
fail("exception should have been thrown");
}
catch (ValueFormatException e)
{
}
session.refresh(false);
}
public void testSetPropertyNameValueType() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("propertyDefNode");
session.refresh(false);
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(10l)}); // ,
// PropertyType
// .LONG
assertEquals(PropertyType.LONG, node.getProperty("jcr:defaultValues").getValues()[0].getType());
assertEquals(10, node.getProperty("jcr:defaultValues").getValues()[0].getLong());
node.save();
session = (SessionImpl)repository.login(credentials, WORKSPACE);
node = session.getRootNode().getNode("propertyDefNode");
assertEquals(10, node.getProperty("jcr:defaultValues").getValues()[0].getLong());
}
public void testSetPropertyNameValuesType() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("childNodeDefNode");
Value[] values = {session.getValueFactory().createValue("not"), session.getValueFactory().createValue("in")};
// it converts to required !
// node.setProperty("jcr:requiredPrimaryTypes", values, PropertyType.LONG);
node.setProperty("jcr:requiredPrimaryTypes", values, PropertyType.NAME);
try
{
Property prop = node.setProperty("jcr:onParentVersion", values, PropertyType.STRING);
fail("exception should have been thrown " + prop.getString());
}
catch (ValueFormatException e)
{
}
Value[] nameValues =
{valueFactory.createValue("jcr:unstructured", PropertyType.NAME),
valueFactory.createValue("jcr:base", PropertyType.NAME)};
node.setProperty("jcr:requiredPrimaryTypes", nameValues, PropertyType.NAME);
node.save();
session = (SessionImpl)repository.login(credentials, WORKSPACE);
node = session.getRootNode().getNode("childNodeDefNode");
assertEquals(2, node.getProperty("jcr:requiredPrimaryTypes").getValues().length);
}
public void testSetPropertyNameStringValueType() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("propertyDefNode");
session.refresh(false);
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue((long)10)});
assertEquals(PropertyType.LONG, node.getProperty("jcr:defaultValues").getValues()[0].getType());
assertEquals(10, node.getProperty("jcr:defaultValues").getValues()[0].getLong());
node.save();
session = (SessionImpl)repository.login(credentials, WORKSPACE);
node = session.getRootNode().getNode("propertyDefNode");
assertEquals(10, node.getProperty("jcr:defaultValues").getValues()[0].getLong());
}
public void testSetPropertyNameStringValuesType() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("childNodeDefNode");
String[] values = {"not", "in"};
try
{
// it converts to required !
node.setProperty("jcr:requiredPrimaryTypes", values, PropertyType.LONG);
}
catch (ValueFormatException e)
{
}
try
{
node.setProperty("jcr:onParentVersion", values, PropertyType.STRING);
fail("exception should have been thrown");
}
catch (ValueFormatException e)
{
}
Value[] nameValues =
{valueFactory.createValue("jcr:unstructured", PropertyType.NAME),
valueFactory.createValue("jcr:base", PropertyType.NAME)};
node.setProperty("jcr:requiredPrimaryTypes", nameValues, PropertyType.NAME);
node.save();
session = (SessionImpl)repository.login(credentials, WORKSPACE);
node = session.getRootNode().getNode("childNodeDefNode");
assertEquals(2, node.getProperty("jcr:requiredPrimaryTypes").getValues().length);
}
public void testSetPropertyMultivaluedString() throws RepositoryException
{
String[] values = {"binary string 1", "binary string 2"};
Property mvp1 = null;
try
{
mvp1 = testMultivalued.setProperty("Multivalued Property", values, PropertyType.BINARY);
testMultivalued.save();
}
catch (ValueFormatException e)
{
fail("Can't add 'Multivalued Property'. Error: " + e.getMessage());
}
try
{
assertTrue("'Multivalued Property' must have size 2", mvp1.getLengths().length == 2);
}
catch (RepositoryException e)
{
fail("Error of 'Multivalued Property' length reading. Error: " + e.getMessage());
}
SessionImpl newSession = (SessionImpl)repository.login(credentials, WORKSPACE);
Node test = (Node)newSession.getItem(testMultivalued.getPath());
assertEquals("Node '" + TEST_MULTIVALUED + "' must have values length 2", 2, test.getProperty(
"Multivalued Property").getValues().length);
test = newSession.getRootNode().getNode(TEST_MULTIVALUED);
assertEquals("Node '" + TEST_MULTIVALUED + "' must have values length 2", 2, test.getProperty(
"Multivalued Property").getValues().length);
}
public void testSetPropertyMultivaluedBinary() throws RepositoryException
{
Value[] values =
{valueFactory.createValue(new ByteArrayInputStream("binary string 1".getBytes())),
valueFactory.createValue(new ByteArrayInputStream("binary string 2".getBytes()))};
Property mvp1 = null;
try
{
mvp1 = testMultivalued.setProperty("Multivalued Property", values, PropertyType.BINARY);
testMultivalued.save();
}
catch (ValueFormatException e)
{
fail("Can't add 'Multivalued Property'. Error: " + e.getMessage());
}
try
{
assertTrue("'Multivalued Property' must have size 2", mvp1.getValues().length == 2);
}
catch (RepositoryException e)
{
fail("Error of 'Multivalued Property' length reading. Error: " + e.getMessage());
}
SessionImpl newSession = (SessionImpl)repository.login(credentials, WORKSPACE);
Node test = (Node)newSession.getItem(testMultivalued.getPath());
assertEquals("Node '" + TEST_MULTIVALUED + "' must have values length 2", 2, test.getProperty(
"Multivalued Property").getValues().length);
test = newSession.getRootNode().getNode(TEST_MULTIVALUED);
assertEquals("Node '" + TEST_MULTIVALUED + "' must have values length 2", 2, test.getProperty(
"Multivalued Property").getValues().length);
}
public void testSetPropertyNameTypedValue() throws RepositoryException
{
Node root = session.getRootNode();
Node node = root.getNode("propertyDefNode");
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue("default")});
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(new ByteArrayInputStream(new String(
"default").getBytes()))});
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(true)});
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(new GregorianCalendar())});
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(20D)});
node.setProperty("jcr:defaultValues", new Value[]{valueFactory.createValue(20L)});
try
{
node.setProperty("jcr:multiple", 20D);
fail("exception should have been thrown");
}
catch (ValueFormatException e)
{
}
try
{
node.setProperty("jcr:versionStorage", 20D);
fail("exception should have been thrown");
}
catch (ConstraintViolationException e)
{
}
try
{
node.setProperty("jcr:versionStorage", valueFactory.createValue(20L), PropertyType.LONG);
fail("exception should have been thrown");
}
catch (ConstraintViolationException e)
{
}
try
{
node.setProperty("jcr:versionStorage", "20", PropertyType.LONG);
fail("exception should have been thrown");
}
catch (ConstraintViolationException e)
{
}
}
public void testSetPathProperty() throws RepositoryException
{
Node root = session.getRootNode();
Node node1 = root.addNode("node1", "nt:unstructured");
node1.setProperty("pathValue", valueFactory.createValue("/root-node/node_1", PropertyType.PATH));
assertNotNull(session.getItem("/node1/pathValue"));
assertEquals("/root-node/node_1", ((Property)session.getItem("/node1/pathValue")).getString());
root.save();
assertNotNull(session.getItem("/node1/pathValue"));
assertEquals("/root-node/node_1", ((Property)session.getItem("/node1/pathValue")).getString());
node1.remove();
root.save();
// node1.save();//impossible
}
public void testInvalidItemStateException() throws RepositoryException
{
Property p = session.getRootNode().setProperty("sameProperty", "test");
Session session2 = repository.login(credentials, "ws");
Property p2 = session2.getRootNode().setProperty("sameProperty", "test");
session.save();
try
{
session2.save();
fail("InvalidItemStateException should have been thrown");
}
catch (ItemExistsException e)
{
}
}
public void testSetPropertySeveralTime() throws Exception
{
Node node = root.addNode("testNode");
File tmpFile1 = createBLOBTempFile(250);
node.setProperty("testProp", new FileInputStream(tmpFile1));
File tmpFile2 = createBLOBTempFile(500);
node.setProperty("testProp", new FileInputStream(tmpFile2));
File tmpFile3 = createBLOBTempFile(1000);
node.setProperty("testProp", new FileInputStream(tmpFile3));
session.save();
File tempFiles[] = new File[3];
tempFiles[0] = tmpFile1;
tempFiles[1] = tmpFile2;
tempFiles[2] = tmpFile3;
for (int i = 2; i < cLog.getAllStates().size(); i++)
{
ItemState item = cLog.getAllStates().get(i);
// TODO doesn't pass with FileTree VS, ok with CAS if contents different
//compareStream(((PropertyData) item.getData()).getValues().get(0).getAsStream(),
// new FileInputStream(tempFiles[i - 2]));
}
}
public void testCheckNSetProperty() throws Exception
{
Node node = root.addNode("testCheckNSetProperty");
session.save();
if (!node.hasNode("foo"))
{
node.setProperty("foo", "foo");
}
if (!node.hasProperty("foo2"))
{
node.setProperty("foo2", "foo");
}
session.save();
}
public void testCheckNSetPropertyWithRefresh() throws Exception
{
Node node = root.addNode("testCheckNSetPropertyWithRefresh");
session.save();
if (!node.hasNode("foo"))
{
node.setProperty("foo", "foo");
}
if (!node.hasProperty("foo2"))
{
node.setProperty("foo2", "foo");
}
session.refresh(true);
session.save();
}
public void testEmptyReference() throws Exception
{
Node node = root.addNode("testEmptyReference", "nt:folder");
node.addMixin("exo:testEmptyReference");
session.save();
try
{
node.setProperty("exo:emptyRef", "");
fail("A ValueFormatException was expected");
}
catch (ValueFormatException e)
{
// expected
}
try
{
node.setProperty("exo:emptyRefs", new String[]{""});
fail("A ValueFormatException was expected");
}
catch (ValueFormatException e)
{
// expected
}
Node ref = root.addNode("testEmptyReferenceRefNode");
ref.addMixin("mix:referenceable");
session.save();
node.setProperty("exo:emptyRef", ref);
node.setProperty("exo:emptyRefs", new String[]{ref.getUUID()});
session.save();
node.setProperty("exo:emptyRef", ref.getUUID());
session.save();
try
{
node.setProperty("exo:emptyRef", "");
fail("A ValueFormatException was expected");
}
catch (ValueFormatException e)
{
// expected
node.setProperty("exo:emptyRef", (String)null);
}
try
{
node.setProperty("exo:emptyRefs", new String[]{""});
fail("A ValueFormatException was expected");
}
catch (ValueFormatException e)
{
// expected
node.setProperty("exo:emptyRef", (String[])null);
}
session.save();
}
public void onSaveItems(ItemStateChangesLog itemStates)
{
cLog = (TransactionChangesLog)itemStates;
}
/**
* {@inheritDoc}
*/
public boolean isTXAware()
{
return true;
}
}