/**
* Copyright (C) 2010 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.xcmis.spi.tck;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xcmis.spi.ChangeTokenHolder;
import org.xcmis.spi.CmisConstants;
import org.xcmis.spi.ConstraintException;
import org.xcmis.spi.ItemsList;
import org.xcmis.spi.NotSupportedException;
import org.xcmis.spi.RenditionFilter;
import org.xcmis.spi.model.CmisObject;
import org.xcmis.spi.model.IncludeRelationships;
import org.xcmis.spi.model.ObjectParent;
import org.xcmis.spi.model.Property;
import org.xcmis.spi.model.PropertyDefinition;
import org.xcmis.spi.model.TypeDefinition;
import org.xcmis.spi.model.Updatability;
import org.xcmis.spi.model.impl.IdProperty;
import org.xcmis.spi.model.impl.StringProperty;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 2.2.5 The Multi-filing services (addObjectToFolder, removeObjectFromFolder)
* are supported only if the repository supports the multifiling or unfiling
* optional capabilities. The Multi-filing Services are used to file/un-file
* objects into/from folders.
*
* @author <a href="mailto:alexey.zavizionov@exoplatform.com">Alexey
* Zavizionov</a>
* @version $Id$
*
*/
public class MultifilingTest extends BaseTest
{
private static String testRootFolderId;
@BeforeClass
public static void start() throws Exception
{
testRootFolderId = createFolder(rootFolderID, CmisConstants.FOLDER, "acl_testroot", null, null, null);
System.out.println("Running Multifiling Service tests");
}
@AfterClass
public static void stop() throws Exception
{
if (testRootFolderId != null)
{
clear(testRootFolderId);
}
}
/**
* 2.2.5.1 addObjectToFolder Adds an existing fileable non-folder object to a
* folder.
*
* @throws Exception
*/
@Test
public void testAddObjectToFolder() throws Exception
{
if (!capabilities.isCapabilityMultifiling())
{
return;
}
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
TypeDefinition folderType = connection.getTypeDefinition(CmisConstants.FOLDER);
String folder0 =
createFolder(testRootFolderId, folderType.getId(), generateName(folderType, null), null, null, null);
String document0 =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
connection.addObjectToFolder(document0, folder0, true);
List<ObjectParent> parents =
connection.getObjectParents(document0, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE);
Set<String> parentIDs = new HashSet<String>(parents.size());
for (ObjectParent item : parents)
{
CmisObject o = item.getObject();
parentIDs.add(o.getObjectInfo().getId());
}
assertEquals(2, parentIDs.size());
assertTrue("Expected parent not found. ", parentIDs.contains(folder0));
assertTrue("Expected parent not found. ", parentIDs.contains(testRootFolderId));
ItemsList<CmisObject> children =
connection.getChildren(folder0, false, IncludeRelationships.NONE, true, true, null, RenditionFilter.NONE,
null, -1, 0);
Set<String> childrenIDs = new HashSet<String>(children.getItems().size());
for (CmisObject child : children.getItems())
{
childrenIDs.add(child.getObjectInfo().getId());
}
assertEquals(1, childrenIDs.size());
assertTrue("Expected child not found. ", childrenIDs.contains(document0));
}
/**
* 2.2.5.1 addObjectToFolder Adds an existing fileable non-folder object to a
* folder.
*
* The Repository MUST throw this exception if the cmis:objectTypeId property
* value of the given object is NOT in the list of AllowedChildObjectTypeIds
* of the parent-folder specified by folderId.
*
* cmis:allowedChildObjectTypeIds IDs of the set of Object-types that can be
* created, moved or filed into this folder.
*
* @throws Exception
*/
@Test
public void testAddObjectToFolder_ConstraintException() throws Exception
{
if (!capabilities.isCapabilityMultifiling())
{
return;
}
TypeDefinition folderType = connection.getTypeDefinition(CmisConstants.FOLDER);
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
String folder0 =
createFolder(testRootFolderId, folderType.getId(), generateName(folderType, null), null, null, null);
StringBuilder filter = new StringBuilder();
filter.append(CmisConstants.ALLOWED_CHILD_OBJECT_TYPE_IDS) //
.append(',') //
.append(CmisConstants.CHANGE_TOKEN);
Map<String, Property<?>> folderProperties =
connection.getProperties(folder0, true, filter.toString()).getProperties();
StringProperty changeTokenProperty = (StringProperty)folderProperties.get(CmisConstants.CHANGE_TOKEN);
TypeDefinition fileableTypeDefinition = null;
// Check if we able set property 'cmis:allowedChildObjectTypeIds'
PropertyDefinition<?> childIdPropertyDefinition =
folderType.getPropertyDefinition(CmisConstants.ALLOWED_CHILD_OBJECT_TYPE_IDS);
Updatability updatability = childIdPropertyDefinition.getUpdatability();
if (updatability == Updatability.READWRITE)
{
// Update property if possible (cmis:document as not allowed child type)
ChangeTokenHolder holder = new ChangeTokenHolder();
if (changeTokenProperty != null && changeTokenProperty.getValues().size() > 0)
{
holder.setValue(changeTokenProperty.getValues().get(0));
}
Map<String, Property<?>> properties = new HashMap<String, Property<?>>();
properties.put(childIdPropertyDefinition.getId(), new IdProperty(childIdPropertyDefinition.getId(),
childIdPropertyDefinition.getQueryName(), childIdPropertyDefinition.getLocalName(),
childIdPropertyDefinition.getDisplayName(), folderType.getId()));
connection.updateProperties(folder0, holder, properties);
// Only folders allowed as child from now.
fileableTypeDefinition = documentType;
}
if (fileableTypeDefinition == null)
{
// If there is no fileable type which is disable for cmis:folder do nothing in this test.
return;
}
String documentO =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
try
{
connection.addObjectToFolder(documentO, folder0, true);
fail("ConstraintException must be thrown since type 'cmis:document' is not allowed as child.");
}
catch (ConstraintException e)
{
}
}
/**
* 2.2.5.1 addObjectToFolder Adds an existing fileable non-folder object to a
* folder. If multiling is not supported then {@link NotSupportedException}
* must be thrown.
*
* @throws Exception
*/
@Test
public void testAddObjectToFolder_NotSupported() throws Exception
{
if (capabilities.isCapabilityMultifiling())
{
// If multi-filing feature is supported skip this test
return;
}
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
TypeDefinition folderType = connection.getTypeDefinition(CmisConstants.FOLDER);
String folder0 =
createFolder(testRootFolderId, folderType.getId(), generateName(folderType, null), null, null, null);
String documentO =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
try
{
connection.addObjectToFolder(documentO, folder0, true);
}
catch (NotSupportedException e)
{
}
}
/**
* 2.2.5.2 removeObjectFromFolder Removes an existing fileable non-folder
* object from a folder. Try to remove object (document) from latest folder
* where it is filled. This test will be skiped if unfiling capability is not
* supported.
*
* @throws Exception
*/
@Test
public void testRemoveObjectFromFolder() throws Exception
{
if (!capabilities.isCapabilityUnfiling())
{
return;
}
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
String document0 =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
// Document filled only in one folder. Try remove from this folder.
connection.removeObjectFromFolder(document0, testRootFolderId);
List<ObjectParent> parents =
connection.getObjectParents(document0, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE);
assertTrue("Parents list must be empty. ", parents.isEmpty());
ItemsList<CmisObject> children =
connection.getChildren(testRootFolderId, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE, null, -1, 0);
Set<String> childrenIDs = new HashSet<String>(children.getItems().size());
for (CmisObject child : children.getItems())
{
childrenIDs.add(child.getObjectInfo().getId());
}
assertTrue("Object must be removed from folder. ", !childrenIDs.contains(document0));
}
/**
* 2.2.5.2 removeObjectFromFolder Removes an existing fileable non-folder
* object from a folder.
*
* @throws Exception
*/
@Test
public void testRemoveObjectFromFolder2() throws Exception
{
if (!capabilities.isCapabilityMultifiling())
{
return;
}
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
TypeDefinition folderType = connection.getTypeDefinition(CmisConstants.FOLDER);
String folder0 =
createFolder(testRootFolderId, folderType.getId(), generateName(folderType, null), null, null, null);
String document0 =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
connection.addObjectToFolder(document0, folder0, true);
List<ObjectParent> parents =
connection.getObjectParents(document0, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE);
assertEquals(2, parents.size());
ItemsList<CmisObject> children =
connection.getChildren(folder0, false, IncludeRelationships.NONE, true, true, null, RenditionFilter.NONE,
null, -1, 0);
assertEquals(1, children.getItems().size());
// Document filled in two folders.
connection.removeObjectFromFolder(document0, folder0);
parents =
connection.getObjectParents(document0, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE);
assertEquals(1, parents.size());
children =
connection.getChildren(folder0, false, IncludeRelationships.NONE, true, true, null, RenditionFilter.NONE,
null, -1, 0);
assertTrue("Object must be removed from folder. ", children.getItems().isEmpty());
}
/**
* 2.2.5.2 removeObjectFromFolder Removes an existing fileable non-folder
* object from a folder. If folder id from which object should be removed is
* not set then object removed from all folders in which it is currently
* filled.
*
* @throws Exception
*/
@Test
public void testUnfile() throws Exception
{
if (!capabilities.isCapabilityUnfiling())
{
return;
}
TypeDefinition documentType = connection.getTypeDefinition(CmisConstants.DOCUMENT);
String document0 =
createDocument(testRootFolderId, documentType.getId(), generateName(documentType, null), null, null, null,
null, null);
String folder0 = null;
if (capabilities.isCapabilityMultifiling())
{
// If multifiling supported add document in one more folder.
TypeDefinition folderType = connection.getTypeDefinition(CmisConstants.FOLDER);
folder0 = createFolder(testRootFolderId, folderType.getId(), generateName(folderType, null), null, null, null);
connection.addObjectToFolder(document0, folder0, true);
}
connection.removeObjectFromFolder(document0, null);
// Check parents
List<ObjectParent> parents =
connection.getObjectParents(document0, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE);
assertTrue("Parents list must be empty. ", parents.isEmpty());
ItemsList<CmisObject> children =
connection.getChildren(testRootFolderId, false, IncludeRelationships.NONE, true, true, null,
RenditionFilter.NONE, null, -1, 0);
Set<String> childrenIDs = new HashSet<String>(children.getItems().size());
for (CmisObject child : children.getItems())
{
childrenIDs.add(child.getObjectInfo().getId());
}
assertTrue("Object must be removed from folder. ", !childrenIDs.contains(document0));
if (folder0 != null)
{
// If add in two folders.
children =
connection.getChildren(folder0, false, IncludeRelationships.NONE, true, true, null, RenditionFilter.NONE,
null, -1, 0);
assertTrue("Object must be removed from folder. ", children.getItems().isEmpty());
}
}
}