| /* |
| * 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.chemistry.opencmis.inmemory; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.chemistry.opencmis.commons.data.ContentStream; |
| import org.apache.chemistry.opencmis.commons.data.ExtensionsData; |
| import org.apache.chemistry.opencmis.commons.data.Properties; |
| import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; |
| import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; |
| import org.apache.chemistry.opencmis.commons.definitions.MutableDocumentTypeDefinition; |
| import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; |
| import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; |
| import org.apache.chemistry.opencmis.commons.enums.Updatability; |
| import org.apache.chemistry.opencmis.commons.enums.VersioningState; |
| import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; |
| import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException; |
| import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; |
| import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl; |
| import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringDefinitionImpl; |
| import org.apache.chemistry.opencmis.inmemory.server.InMemoryServiceFactoryImpl; |
| import org.apache.chemistry.opencmis.inmemory.types.DocumentTypeCreationHelper; |
| import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Temporary test class until CMIS 1.1 bindings are completed. Until then we use |
| * a special setup procedure to directly connect to the repository service |
| * implementation of InMemory. |
| */ |
| public class RepositoryServiceMutabilityTest extends AbstractServiceTest { |
| |
| private static final Logger log = LoggerFactory.getLogger(RepositoryServiceTest.class); |
| private static final String REPOSITORY_ID = "UnitTestRepository"; |
| private static final String TYPE_ID_MUTABILITY = "BookTypeAddedLater"; |
| private static final String PROPERTY_ID_TITLE = "Title"; |
| private static final String PROPERTY_ID_NUMBER = "Number"; |
| |
| @Override |
| @Before |
| public void setUp() { |
| super.setTypeCreatorClass(UnitTestTypeSystemCreator.class.getName()); |
| super.setUp(); |
| |
| Map<String, String> parameters = new HashMap<String, String>(); |
| |
| // attach repository info to the session: |
| parameters.put(ConfigConstants.TYPE_CREATOR_CLASS, getTypeCreatorClass()); |
| parameters.put(ConfigConstants.REPOSITORY_ID, REPOSITORY_ID); |
| |
| InMemoryServiceFactoryImpl factory = new InMemoryServiceFactoryImpl(); |
| factory.init(parameters); |
| } |
| |
| @Override |
| @After |
| public void tearDown() { |
| super.tearDown(); |
| } |
| |
| // This test is just added because this test class uses a different setup to |
| // connect to the |
| // server as long as the server bindings do not support the type mutability |
| // extension of |
| // CMIS 1.1. If this test fails then the setUp() fails! |
| @Test |
| public void testRepositoryInfo() { |
| log.info("starting testRepositoryInfo() ..."); |
| List<RepositoryInfo> repositories = fRepSvc.getRepositoryInfos(null); |
| assertNotNull(repositories); |
| assertFalse(repositories.isEmpty()); |
| |
| log.info("geRepositoryInfo(), found " + repositories.size() + " repository/repositories)."); |
| |
| for (RepositoryInfo repository : repositories) { |
| RepositoryInfo repository2 = fRepSvc.getRepositoryInfo(repository.getId(), null); |
| assertNotNull(repository2); |
| assertEquals(repository.getId(), repository2.getId()); |
| log.info("found repository" + repository2.getId()); |
| } |
| |
| log.info("... testRepositoryInfo() finished."); |
| } |
| |
| @Test |
| public void testTypeMutabilityCreation() throws Exception { |
| log.info(""); |
| log.info("starting testTypeMutabilityCreation() ..."); |
| TypeDefinition typeDefRef = createTypeForAddingAtRuntime(); |
| String repositoryId = getRepositoryId(); |
| // add type. |
| fRepSvc.createType(repositoryId, typeDefRef, null); |
| TypeDefinition type = fRepSvc.getTypeDefinition(repositoryId, typeDefRef.getId(), null); |
| assertEquals(typeDefRef.getId(), type.getId()); |
| assertEquals(typeDefRef.getDescription(), type.getDescription()); |
| assertEquals(typeDefRef.getDisplayName(), type.getDisplayName()); |
| assertEquals(typeDefRef.getLocalName(), type.getLocalName()); |
| assertEquals(typeDefRef.getLocalNamespace(), type.getLocalNamespace()); |
| RepositoryServiceTest.containsAllBasePropertyDefinitions(type); |
| log.info("... testTypeMutabilityCreation() finished."); |
| } |
| |
| @Test |
| public void testTypeMutabilityCreateDuplicate() throws Exception { |
| log.info(""); |
| log.info("starting testTypeMutabilityCreateDuplicate() ..."); |
| TypeDefinition typeDefRef = createTypeForAddingAtRuntime(); |
| String repositoryId = getRepositoryId(); |
| // add type. |
| fRepSvc.createType(repositoryId, typeDefRef, null); |
| // add type again should fail |
| checkAddingType(repositoryId, typeDefRef, CmisInvalidArgumentException.class); |
| // type should still exist then |
| TypeDefinition type = fRepSvc.getTypeDefinition(repositoryId, typeDefRef.getId(), null); |
| assertEquals(typeDefRef.getId(), type.getId()); |
| log.info("... testTypeMutabilityCreateDuplicate() finished."); |
| } |
| |
| @Test |
| public void testTypeMutabilityTypeNameConstraints() throws Exception { |
| log.info("starting testTypeMutabilityTypeNameConstraints() ..."); |
| |
| String repositoryId = getRepositoryId(); |
| |
| // test illegal type id |
| MutableDocumentTypeDefinition typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setId(typeDefRef.getId() + "!!!"); |
| TypeDefinition typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| assertEquals(TYPE_ID_MUTABILITY + "___", typeDefNew.getId()); |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY + "___", null); |
| |
| // test illegal parent type id |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setParentTypeId("NonExistingParentType"); |
| checkAddingType(repositoryId, typeDefRef, CmisInvalidArgumentException.class); |
| |
| // test null type id |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setId(null); |
| typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| assertTrue(null != typeDefNew.getId() && typeDefNew.getId().length() > 0); |
| fRepSvc.deleteType(repositoryId, typeDefNew.getId(), null); |
| |
| // test null query name |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setQueryName(null); |
| typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| assertEquals(TYPE_ID_MUTABILITY, typeDefNew.getQueryName()); |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| |
| // test illegal query name |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setQueryName(typeDefRef.getQueryName() + "!!!"); |
| typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| assertEquals(TYPE_ID_MUTABILITY, typeDefNew.getQueryName()); |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| |
| // test null local name |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setLocalName(null); |
| assertEquals(TYPE_ID_MUTABILITY, typeDefNew.getLocalName()); |
| typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| |
| // test illegal local name |
| typeDefRef = createTypeForAddingAtRuntime(); |
| typeDefRef.setLocalName(typeDefRef.getLocalName() + "!!!"); |
| assertEquals(TYPE_ID_MUTABILITY, typeDefNew.getLocalName()); |
| typeDefNew = fRepSvc.createType(repositoryId, typeDefRef, null); |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| |
| log.info("... testTypeMutabilityTypeNameConstraints() finished."); |
| } |
| |
| @Test |
| public void testTypeMutabilityPropertyNameConstraints() throws Exception { |
| log.info("starting testTypeMutabilityPropertyNameConstraints() ..."); |
| |
| String repositoryId = getRepositoryId(); |
| |
| // test null property id |
| DocumentTypeDefinition typeDef = createTypeForAddingAtRuntime(); |
| PropertyStringDefinitionImpl pd = getPropertyDefinitionImpl(typeDef); |
| pd.setId(null); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| // test illegal property id |
| typeDef = createTypeForAddingAtRuntime(); |
| pd = getPropertyDefinitionImpl(typeDef); |
| pd.setQueryName(pd.getQueryName() + "!*!"); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| // test null property query name |
| typeDef = createTypeForAddingAtRuntime(); |
| pd = getPropertyDefinitionImpl(typeDef); |
| pd.setQueryName(null); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| // test illegal property query name |
| typeDef = createTypeForAddingAtRuntime(); |
| pd = getPropertyDefinitionImpl(typeDef); |
| pd.setQueryName(pd.getQueryName() + "!!!"); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| // test null property local name |
| typeDef = createTypeForAddingAtRuntime(); |
| pd = getPropertyDefinitionImpl(typeDef); |
| pd.setLocalName(null); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| // test illegal property local name |
| typeDef = createTypeForAddingAtRuntime(); |
| pd = getPropertyDefinitionImpl(typeDef); |
| pd.setLocalName(typeDef.getLocalName() + "!!!"); |
| checkAddingType(repositoryId, typeDef, CmisInvalidArgumentException.class); |
| |
| log.info("... testTypeMutabilityPropertyNameConstraints() finished."); |
| } |
| |
| private void checkAddingType(String repositoryId, TypeDefinition typeDef, Class<? extends Exception> clazz) { |
| try { |
| typeDef = fRepSvc.createType(repositoryId, typeDef, null); |
| fail("Illegal type should throw a " + clazz.getName()); |
| } catch (RuntimeException e) { |
| assertTrue("Illegal type name threw wrong exception type (should be a " + clazz.getName() + ")", |
| clazz.isInstance(e)); |
| } |
| } |
| |
| @Test |
| public void testTypeMutabilityUpdate() throws Exception { |
| log.info(""); |
| log.info("starting testTypeMutabilityUpdate() ..."); |
| TypeDefinition typeDefRef = createTypeForAddingAtRuntime(); |
| String repositoryId = getRepositoryId(); |
| fRepSvc.createType(repositoryId, typeDefRef, null); |
| // update type. |
| try { |
| fRepSvc.updateType(repositoryId, typeDefRef, null); |
| fail("updating a type should throw exception."); |
| } catch (Exception e) { |
| assertTrue(e instanceof CmisNotSupportedException); |
| } |
| log.info("... testTypeMutabilityUpdate() finished."); |
| } |
| |
| @Test |
| public void testTypeMutabilityDeletion() throws Exception { |
| log.info(""); |
| log.info("starting testTypeMutabilityDeletion() ..."); |
| TypeDefinition typeDefRef = createTypeForAddingAtRuntime(); |
| String repositoryId = getRepositoryId(); |
| fRepSvc.createType(repositoryId, typeDefRef, null); |
| |
| String docId = createDoc("Book1", getRootFolderId(REPOSITORY_ID), TYPE_ID_MUTABILITY); |
| |
| // try deleting type, should fail, because in use. |
| try { |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| fail("deleting a type which is in use should throw exception."); |
| } catch (Exception e) { |
| assertTrue(e instanceof CmisInvalidArgumentException); |
| } |
| |
| fObjSvc.deleteObject(fRepositoryId, docId, true, null); |
| |
| try { |
| fRepSvc.deleteType(repositoryId, TYPE_ID_MUTABILITY, null); |
| } catch (Exception e) { |
| fail("deleting a type which is in not in use should not throw exception! Exception is: " + e); |
| } |
| |
| try { |
| fRepSvc.getTypeDefinition(repositoryId, TYPE_ID_MUTABILITY, null); |
| fail("getting a type after it was deleted should fail."); |
| } catch (Exception e) { |
| } |
| |
| try { |
| fRepSvc.deleteType(repositoryId, BaseTypeId.CMIS_DOCUMENT.value(), null); |
| fail("deleting a CMIS base type throw exception."); |
| } catch (Exception e) { |
| assertTrue (e instanceof CmisInvalidArgumentException); |
| } |
| try { |
| fRepSvc.deleteType(repositoryId, BaseTypeId.CMIS_FOLDER.value(), null); |
| fail("deleting a CMIS base type throw exception."); |
| } catch (Exception e) { |
| assertTrue (e instanceof CmisInvalidArgumentException); |
| } |
| |
| log.info("... testTypeMutabilityDeletion() finished."); |
| } |
| |
| private String getRepositoryId() { |
| List<RepositoryInfo> repositories = fRepSvc.getRepositoryInfos(null); |
| RepositoryInfo repository = repositories.get(0); |
| assertNotNull(repository); |
| return repository.getId(); |
| } |
| |
| private String getRootFolderId(String repositoryId) { |
| RepositoryInfo repository = fRepSvc.getRepositoryInfo(repositoryId, null); |
| assertNotNull(repository); |
| return repository.getRootFolderId(); |
| } |
| |
| private PropertyStringDefinitionImpl getPropertyDefinitionImpl(TypeDefinition typeDef) { |
| PropertyStringDefinitionImpl pd = (PropertyStringDefinitionImpl) typeDef.getPropertyDefinitions().get( |
| PROPERTY_ID_TITLE); |
| return pd; |
| } |
| |
| private MutableDocumentTypeDefinition createTypeForAddingAtRuntime() { |
| try { |
| MutableDocumentTypeDefinition cmisLaterType; |
| cmisLaterType = DocumentTypeCreationHelper |
| .createDocumentTypeDefinitionWithoutBaseProperties(DocumentTypeCreationHelper.getCmisDocumentType()); |
| cmisLaterType.setId(TYPE_ID_MUTABILITY); |
| cmisLaterType.setDisplayName("Type with two properties"); |
| cmisLaterType.setDescription("Builtin InMemory type definition " + TYPE_ID_MUTABILITY); |
| cmisLaterType.setIsIncludedInSupertypeQuery(false); |
| |
| PropertyIntegerDefinitionImpl prop1 = PropertyCreationHelper.createIntegerDefinition(PROPERTY_ID_NUMBER, |
| "Sample Int Property", Updatability.READWRITE); |
| cmisLaterType.addPropertyDefinition(prop1); |
| |
| PropertyStringDefinitionImpl prop2 = PropertyCreationHelper.createStringDefinition(PROPERTY_ID_TITLE, |
| "Sample String Property", Updatability.READWRITE); |
| cmisLaterType.addPropertyDefinition(prop2); |
| |
| return cmisLaterType; |
| } catch (Exception e) { |
| throw new CmisRuntimeException("Error when creating built-in InMemory types.", e); |
| } |
| } |
| |
| String createDoc(String name, String folderId, String typeId) { |
| ContentStream contentStream = null; |
| List<String> policies = null; |
| ExtensionsData extension = null; |
| |
| Properties props = createDocumentProperties(name, typeId); |
| |
| String id = fObjSvc.createDocument(fRepositoryId, props, folderId, contentStream, VersioningState.NONE, |
| policies, null, null, extension); |
| return id; |
| } |
| } |