blob: 3ce8a247bef677ccb802ae7acce3d85e8fbe6200 [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.chemistry.opencmis.inmemory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyDefinition;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
import org.apache.chemistry.opencmis.inmemory.types.DocumentTypeCreationHelper;
import org.apache.chemistry.opencmis.inmemory.types.TypeUtil;
import org.apache.chemistry.opencmis.server.support.TypeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class that manages a type system for a repository types can be added, the
* inheritance can be managed and type can be retrieved for a given type id.
*/
public class TypeManagerImpl implements TypeManager {
private static final Logger LOG = LoggerFactory.getLogger(TypeManagerImpl.class.getName());
/**
* map from repository id to a types map.
*/
private final Map<String, TypeDefinitionContainer> fTypesMap = new HashMap<String, TypeDefinitionContainer>();
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.TypeManager#getTypeById(java.lang
* .String)
*/
@Override
public TypeDefinitionContainer getTypeById(String typeId) {
return fTypesMap.get(typeId);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.TypeManager#getTypeByQueryName
* (java.lang.String)
*/
@Override
public TypeDefinition getTypeByQueryName(String typeQueryName) {
for (Entry<String, TypeDefinitionContainer> entry : fTypesMap.entrySet()) {
if (entry.getValue().getTypeDefinition().getQueryName().equals(typeQueryName)) {
return entry.getValue().getTypeDefinition();
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.TypeManager#getTypeDefinitionList
* ()
*/
@Override
public Collection<TypeDefinitionContainer> getTypeDefinitionList() {
return Collections.unmodifiableCollection(fTypesMap.values());
}
/*
* (non-Javadoc)
*
* @see org.apache.chemistry.opencmis.inmemory.TypeManager#getRootTypes()
*/
@Override
public List<TypeDefinitionContainer> getRootTypes() {
// just take first repository
List<TypeDefinitionContainer> rootTypes = new ArrayList<TypeDefinitionContainer>();
for (TypeDefinitionContainer type : fTypesMap.values()) {
if (isRootType(type)) {
rootTypes.add(type);
}
}
return rootTypes;
}
/**
* Initialize the type system with the given types. This list must not
* contain the CMIS default types. The default type are always contained by
* default.
*
* @param typesList
* list of types to add to the repository
*
* @param createCmisDefaultTypes
* indicates if CMIS base types should be added to list
*/
public void initTypeSystem(List<TypeDefinition> typesList, boolean createCmisDefaultTypes) {
if (createCmisDefaultTypes) {
createCmisDefaultTypes();
}
// merge all types from the list and build the correct hierachy with
// children and property lists
if (null != typesList) {
for (TypeDefinition typeDef : typesList) {
addTypeDefinition(typeDef, true);
}
}
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.storedobj.api.TypeManagerCreatable
* #addTypeDefinition(org.apache.chemistry.opencmis.commons.definitions.
* TypeDefinition, boolean)
*/
@Override
public void addTypeDefinition(TypeDefinition cmisType, boolean addInheritedProperties) {
LOG.info("Adding type definition with name " + cmisType.getLocalName() + " and id " + cmisType.getId()
+ " to repository.");
TypeDefinitionContainerImpl typeContainer = new TypeDefinitionContainerImpl(cmisType);
if (null != cmisType.getParentTypeId()) {
// add new type to children of parent types
TypeDefinitionContainer parentTypeContainer = fTypesMap.get(cmisType.getParentTypeId());
parentTypeContainer.getChildren().add(typeContainer);
if (addInheritedProperties) {
// recursively add inherited properties
Map<String, PropertyDefinition<?>> propDefs = typeContainer.getTypeDefinition()
.getPropertyDefinitions();
addInheritedProperties(propDefs, parentTypeContainer.getTypeDefinition());
}
}
// add type to type map
fTypesMap.put(cmisType.getId(), typeContainer);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.storedobj.api.TypeManagerCreatable
* #updateTypeDefinition(org.apache.chemistry.opencmis.commons.definitions.
* TypeDefinition)
*/
@Override
public void updateTypeDefinition(TypeDefinition typeDefinition) {
throw new CmisNotSupportedException("updating a type definition is not supported.");
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.storedobj.api.TypeManagerCreatable
* #deleteTypeDefinition(java.lang.String)
*/
@Override
public void deleteTypeDefinition(String typeId) {
TypeDefinitionContainer typeDef = fTypesMap.remove(typeId);
// remove type from children of parent types
TypeDefinitionContainer parentTypeContainer = fTypesMap.get(typeDef.getTypeDefinition().getParentTypeId());
parentTypeContainer.getChildren().remove(typeDef);
fTypesMap.remove(typeId);
}
/**
* Remove all types from the type system. After this call only the default
* CMIS types are present in the type system. Use this method with care, its
* mainly intended for unit tests
*
* @param repositoryId
*/
public void clearTypeSystem() {
fTypesMap.clear();
createCmisDefaultTypes();
}
/*
* (non-Javadoc)
*
* @see
* org.apache.chemistry.opencmis.inmemory.TypeManager#getPropertyIdForQueryName
* (org.apache.chemistry.opencmis.commons.definitions.TypeDefinition,
* java.lang.String)
*/
@Override
public String getPropertyIdForQueryName(TypeDefinition typeDefinition, String propQueryName) {
for (PropertyDefinition<?> pd : typeDefinition.getPropertyDefinitions().values()) {
if (pd.getQueryName().equals(propQueryName)) {
return pd.getId();
}
}
return null;
}
private void addInheritedProperties(Map<String, PropertyDefinition<?>> propDefs, TypeDefinition typeDefinition) {
if (null == typeDefinition) {
return;
}
if (null != typeDefinition.getPropertyDefinitions()) {
addInheritedPropertyDefinitions(propDefs, typeDefinition.getPropertyDefinitions());
}
TypeDefinitionContainer parentTypeContainer = fTypesMap.get(typeDefinition.getParentTypeId());
TypeDefinition parentType = (null == parentTypeContainer ? null : parentTypeContainer.getTypeDefinition());
addInheritedProperties(propDefs, parentType);
}
private static void addInheritedPropertyDefinitions(Map<String, PropertyDefinition<?>> propDefs,
Map<String, PropertyDefinition<?>> superPropDefs) {
for (Entry<String, PropertyDefinition<?>> superProp : superPropDefs.entrySet()) {
PropertyDefinition<?> superPropDef = superProp.getValue();
PropertyDefinition<?> clone = clonePropertyDefinition(superPropDef);
((AbstractPropertyDefinition<?>) clone).setIsInherited(true);
propDefs.put(superProp.getKey(), clone);
}
}
private void createCmisDefaultTypes() {
List<TypeDefinition> typesList = DocumentTypeCreationHelper.createDefaultTypes();
for (TypeDefinition typeDef : typesList) {
TypeDefinitionContainerImpl typeContainer = new TypeDefinitionContainerImpl(typeDef);
fTypesMap.put(typeDef.getId(), typeContainer);
}
}
private static boolean isRootType(TypeDefinitionContainer c) {
return (c.getTypeDefinition().getId().equals(c.getTypeDefinition().getBaseTypeId().value()));
}
private static PropertyDefinition<?> clonePropertyDefinition(PropertyDefinition<?> src) {
PropertyDefinition<?> clone = TypeUtil.clonePropertyDefinition(src);
return clone;
}
}