Package org.apache.chemistry.opencmis.inmemory

Source Code of org.apache.chemistry.opencmis.inmemory.TypeManagerImpl

/*
* 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.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.impl.Converter;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyDefinition;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisPropertyDefinitionType;
import org.apache.chemistry.opencmis.inmemory.types.DocumentTypeCreationHelper;
import org.apache.chemistry.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
import org.apache.chemistry.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
import org.apache.chemistry.opencmis.inmemory.types.InMemoryPolicyTypeDefinition;
import org.apache.chemistry.opencmis.inmemory.types.InMemoryRelationshipTypeDefinition;
import org.apache.chemistry.opencmis.server.support.TypeManager;

/**
* 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.
*
* @author Jens
*
*/
public class TypeManagerImpl implements TypeManager {

    /**
     * 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)
     */
    public TypeDefinitionContainer getTypeById(String typeId) {
        return fTypesMap.get(typeId);
    }

    /* (non-Javadoc)
     * @see org.apache.chemistry.opencmis.inmemory.TypeManager#getTypeByQueryName(java.lang.String)
     */
    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()
     */
    public synchronized Collection<TypeDefinitionContainer> getTypeDefinitionList() {

        List<TypeDefinitionContainer> typeRoots = new ArrayList<TypeDefinitionContainer>();
        // iterate types map and return a list collecting the root types:
        for (TypeDefinitionContainer typeDef : fTypesMap.values()) {
            if (typeDef.getTypeDefinition().getParentTypeId() == null) {
                typeRoots.add(typeDef);
            }
        }

        return typeRoots;
    }

    /* (non-Javadoc)
     * @see org.apache.chemistry.opencmis.inmemory.TypeManager#getRootTypes()
     */
    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
     *
     */
    public void initTypeSystem(List<TypeDefinition> typesList) {

        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);
            }
        }

    }

    /**
     * Add a type to the type system. Add all properties from inherited types,
     * add type to children of parent types.
     *
     * @param repositoryId
     *            repository to which the type is added
     * @param cmisType
     *            new type to add
     */
    public void addTypeDefinition(TypeDefinition cmisType) {
        if (fTypesMap.containsKey(cmisType.getId())) {
            throw new RuntimeException("You cannot add type with id " + cmisType.getId()
                    + " because it already exists.");
        }

        TypeDefinitionContainerImpl typeContainer = new TypeDefinitionContainerImpl(cmisType);

        if (!fTypesMap.containsKey(cmisType.getParentTypeId())) {
            throw new RuntimeException("Cannot add type, because parent with id " + cmisType.getParentTypeId()
                    + " does not exist.");
        }

        // add new type to children of parent types
        TypeDefinitionContainer parentTypeContainer = fTypesMap.get(cmisType.getParentTypeId());
        parentTypeContainer.getChildren().add(typeContainer);

        // 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);
    }

    /**
     * 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)
     */
    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());
        // propDefs.putAll(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) {
        if (c.getTypeDefinition().equals(InMemoryFolderTypeDefinition.getRootFolderType())
                || c.getTypeDefinition().equals(InMemoryDocumentTypeDefinition.getRootDocumentType())
                || c.getTypeDefinition().equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType())
                || c.getTypeDefinition().equals(InMemoryPolicyTypeDefinition.getRootPolicyType())) {
            return true;
        } else {
            return false;
        }
    }

    private static PropertyDefinition<?> clonePropertyDefinition(PropertyDefinition<?> src) {
        // use JAXB converter to easily clone a property definition
        CmisPropertyDefinitionType tmp = Converter.convert(src);
        PropertyDefinition<?> clone = Converter.convert(tmp);
        return clone;
    }

    // private static PropertyDefinition<?>
    // clonePropertyDefinition2(PropertyDefinition<?> src)
    // throws IOException, ClassNotFoundException {
    // ByteArrayOutputStream bout = new ByteArrayOutputStream();
    // ObjectOutputStream oout = new ObjectOutputStream(bout);
    // oout.writeObject(src);
    // byte[] bytes = bout.toByteArray();
    //
    // ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
    // ObjectInputStream oin = new ObjectInputStream(bin);
    // PropertyDefinition<?> clone = (PropertyDefinition<?>) oin.readObject();
    // return clone;
    // }

}
TOP

Related Classes of org.apache.chemistry.opencmis.inmemory.TypeManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.