blob: 83d00d6967b9fb33177fdb55171fd9a7d43a9a34 [file] [log] [blame]
/*
* 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.opencmis.inmemory.storedobj.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import org.apache.opencmis.commons.api.TypeDefinition;
import org.apache.opencmis.commons.api.TypeDefinitionContainer;
import org.apache.opencmis.commons.enums.CapabilityAcl;
import org.apache.opencmis.commons.enums.CapabilityChanges;
import org.apache.opencmis.commons.enums.CapabilityContentStreamUpdates;
import org.apache.opencmis.commons.enums.CapabilityJoin;
import org.apache.opencmis.commons.enums.CapabilityQuery;
import org.apache.opencmis.commons.enums.CapabilityRendition;
import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.opencmis.commons.impl.dataobjects.AbstractTypeDefinition;
import org.apache.opencmis.commons.impl.dataobjects.ProviderObjectFactoryImpl;
import org.apache.opencmis.commons.impl.dataobjects.RepositoryCapabilitiesDataImpl;
import org.apache.opencmis.commons.impl.dataobjects.RepositoryInfoDataImpl;
import org.apache.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
import org.apache.opencmis.commons.provider.ProviderObjectFactory;
import org.apache.opencmis.commons.provider.RepositoryInfoData;
import org.apache.opencmis.inmemory.RepositoryInfoCreator;
import org.apache.opencmis.inmemory.TypeCreator;
import org.apache.opencmis.inmemory.TypeManager;
import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
/**
* factory to create objects that are stored in the InMemory store
*
* @author Jens
*/
public class StoreManagerImpl implements StoreManager {
protected ProviderObjectFactory fObjectFactory;
protected RepositoryInfoData fRepositoryInfo;
/**
* map from repository id to a type manager
*/
private Map<String, TypeManager> fMapRepositoryToTypeManager
= new HashMap<String, TypeManager>();
/**
* map from repository id to a object store
*/
private Map<String, ObjectStore> fMapRepositoryToObjectStore
= new HashMap<String, ObjectStore>();
public ObjectStoreImpl getStore(String repositoryId) {
return (ObjectStoreImpl)fMapRepositoryToObjectStore.get(repositoryId);
}
public StoreManagerImpl() {
fObjectFactory = new ProviderObjectFactoryImpl();
}
public List<String> getAllRepositoryIds() {
Set<String> repIds = fMapRepositoryToObjectStore.keySet();
List<String> result = new ArrayList<String>();
result.addAll(repIds);
return result;
}
public void initRepository(String repositoryId) {
fMapRepositoryToObjectStore.put(repositoryId, new ObjectStoreImpl(repositoryId));
fMapRepositoryToTypeManager.put(repositoryId, new TypeManager());
}
public void createAndInitRepository(String repositoryId, String typeCreatorClassName) {
if (fMapRepositoryToObjectStore.containsKey(repositoryId)
|| fMapRepositoryToTypeManager.containsKey(repositoryId))
throw new RuntimeException("Cannot add repository, repository " + repositoryId
+ " already exists.");
fMapRepositoryToObjectStore.put(repositoryId, new ObjectStoreImpl(repositoryId));
fMapRepositoryToTypeManager.put(repositoryId, new TypeManager());
// initialize the type system:
initTypeSystem(repositoryId, typeCreatorClassName);
}
public ObjectStore getObjectStore(String repositoryId) {
return fMapRepositoryToObjectStore.get(repositoryId);
}
public ProviderObjectFactory getObjectFactory() {
return fObjectFactory;
}
public TypeDefinitionContainer getTypeById(String repositoryId, String typeId) {
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
return typeManager.getTypeById(typeId);
}
public TypeDefinitionContainer getTypeById(String repositoryId, String typeId,
boolean includePropertyDefinitions, int depth) {
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
TypeDefinitionContainer tc = typeManager.getTypeById(typeId);
List<TypeDefinitionContainer> result = null;
if (tc != null) {
if (depth == -1) {
result = tc.getChildren();
if (!includePropertyDefinitions)
cloneTypeList(depth - 1, false, result);
}
else if (depth == 0 || depth < -1)
throw new CmisInvalidArgumentException("illegal depth value: " + depth);
else {
result = tc.getChildren();
cloneTypeList(depth - 1, includePropertyDefinitions, result);
}
}
return tc;
}
public Collection<TypeDefinitionContainer> getTypeDefinitionList(String repositoryId, boolean includePropertyDefinitions) {
Collection<TypeDefinitionContainer> result;
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
Collection<TypeDefinitionContainer> typeColl = typeManager.getTypeDefinitionList();
if (includePropertyDefinitions) {
result = typeColl;
} else {
result = new ArrayList<TypeDefinitionContainer>(typeColl);
// copy list and omit properties
for (TypeDefinitionContainer c : result) {
AbstractTypeDefinition td = ((AbstractTypeDefinition) c.getTypeDefinition()).clone();
TypeDefinitionContainerImpl tdc = new TypeDefinitionContainerImpl(td);
tdc.setChildren(c.getChildren());
td.setPropertyDefinitions(null);
}
}
return result;
}
public Map<String, TypeDefinitionContainer> getTypeDefinitionMap(String repositoryId) {
return null;
}
public List<TypeDefinitionContainer> getRootTypes(String repositoryId) {
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
List<TypeDefinitionContainer> rootTypes = typeManager.getRootTypes();
return rootTypes;
}
public RepositoryInfoData getRepositoryInfo(String repositoryId) {
ObjectStore sm = fMapRepositoryToObjectStore.get(repositoryId);
if (null == sm)
return null;
RepositoryInfoData repoInfo = createDefaultRepositoryInfo(repositoryId);
return repoInfo;
}
public void clearTypeSystem(String repositoryId) {
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
typeManager.clearTypeSystem();
}
public void initRepositoryInfo(String repositoryId, String repoInfoCreatorClassName) {
RepositoryInfoCreator repoCreator = null;
if (repoInfoCreatorClassName != null) {
Object obj = null;
try {
obj = Class.forName(repoInfoCreatorClassName).newInstance();
}
catch (InstantiationException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement RepositoryInfoCreator interface.",
e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement RepositoryInfoCreator interface.",
e);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement RepositoryInfoCreator interface.",
e);
}
if (obj instanceof RepositoryInfoCreator) {
repoCreator = (RepositoryInfoCreator) obj;
fRepositoryInfo = repoCreator.createRepositoryInfo();
}
else
throw new RuntimeException(
"Illegal class to create repository info, must implement RepositoryInfoCreator interface.");
}
else {
// create a default repository info
createDefaultRepositoryInfo(repositoryId);
}
}
public List<TypeDefinition> initTypeSystem(String typeCreatorClassName) {
List<TypeDefinition> typesList = null;
if (typeCreatorClassName != null) {
Object obj = null;
TypeCreator typeCreator = null;
try {
obj = Class.forName(typeCreatorClassName).newInstance();
}
catch (InstantiationException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement TypeCreator interface.", e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement TypeCreator interface.", e);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(
"Illegal class to create type system, must implement TypeCreator interface.", e);
}
if (obj instanceof TypeCreator)
typeCreator = (TypeCreator) obj;
else
throw new RuntimeException(
"Illegal class to create type system, must implement TypeCreator interface.");
// retrieve the list of available types from the configured class.
// test
typesList = typeCreator.createTypesList();
}
return typesList;
}
private void initTypeSystem(String repositoryId, String typeCreatorClassName) {
List<TypeDefinition> typeDefs = null;
TypeManager typeManager = fMapRepositoryToTypeManager.get(repositoryId);
if (null == typeManager)
throw new RuntimeException("Unknown repository " + repositoryId);
if (null != typeCreatorClassName)
typeDefs = initTypeSystem(typeCreatorClassName);
typeManager.initTypeSystem(typeDefs);
}
private RepositoryInfoData createDefaultRepositoryInfo(String repositoryId) {
ObjectStore objStore = getObjectStore(repositoryId);
String rootFolderId = objStore.getRootFolder().getId();
// repository info
RepositoryInfoDataImpl repoInfo;
repoInfo = new RepositoryInfoDataImpl();
repoInfo.setRepositoryId(repositoryId==null ? "inMem" : repositoryId);
repoInfo.setRepositoryName("InMemory Repository");
repoInfo.setRepositoryDescription("InMemory Test Repository");
repoInfo.setCmisVersionSupported("1.0");
repoInfo.setRepositoryCapabilities(null);
repoInfo.setRootFolder(rootFolderId);
repoInfo.setPrincipalAnonymous("anonymous");
repoInfo.setPrincipalAnyone("anyone");
repoInfo.setThinClientUri(null);
repoInfo.setChangesIncomplete(Boolean.TRUE);
repoInfo.setChangesOnType(null);
repoInfo.setLatestChangeLogToken(null);
repoInfo.setVendorName("OpenCMIS");
repoInfo.setProductName("OpenCMIS InMemory-Server");
repoInfo.setProductVersion("0.1");
// set capabilities
RepositoryCapabilitiesDataImpl caps = new RepositoryCapabilitiesDataImpl();
caps.setAllVersionsSearchable(false);
caps.setCapabilityAcl(CapabilityAcl.NONE);
caps.setCapabilityChanges(CapabilityChanges.PROPERTIES); // just for testing
caps.setCapabilityContentStreamUpdates(CapabilityContentStreamUpdates.PWCONLY);
caps.setCapabilityJoin(CapabilityJoin.NONE);
caps.setCapabilityQuery(CapabilityQuery.METADATAONLY); // just for testing
caps.setCapabilityRendition(CapabilityRendition.NONE);
caps.setIsPwcSearchable(false);
caps.setIsPwcUpdatable(true);
caps.setSupportsGetDescendants(true);
caps.setSupportsGetFolderTree(true);
caps.setSupportsMultifiling(true);
caps.setSupportsUnfiling(true);
caps.setSupportsVersionSpecificFiling(false);
repoInfo.setRepositoryCapabilities(caps);
// AclCapabilitiesDataImpl aclCaps = new AclCapabilitiesDataImpl();
// aclCaps.setACLPropagation(AclPropagation.REPOSITORYDETERMINED);
// aclCaps.setPermissionDefinitionData(null);
// aclCaps.setPermissionMappingData(null);
// repoInfo.setACLCapabilities(aclCaps);
repoInfo.setAclCapabilities(null);
fRepositoryInfo = repoInfo;
return repoInfo;
}
/**
* traverse tree and replace each need node with a clone. remove properties on clone if requested,
* cut children of clone if depth is exceeded.
*
* @param depth
* @param types
*/
private void cloneTypeList(int depth, boolean includePropertyDefinitions,
List<TypeDefinitionContainer> types) {
ListIterator<TypeDefinitionContainer> it = types.listIterator();
while (it.hasNext()) {
TypeDefinitionContainer tdc = it.next();
AbstractTypeDefinition td = ((AbstractTypeDefinition) tdc.getTypeDefinition()).clone();
if (!includePropertyDefinitions)
td.setPropertyDefinitions(null);
TypeDefinitionContainerImpl tdcClone = new TypeDefinitionContainerImpl(td);
if (depth > 0) {
ArrayList<TypeDefinitionContainer> children = new ArrayList<TypeDefinitionContainer>(tdc
.getChildren().size());
children.addAll(tdc.getChildren());
tdcClone.setChildren(children);
cloneTypeList(depth - 1, includePropertyDefinitions, children);
}
it.set(tdcClone);
}
}
}