com.sourcesense.opencmis.server.TypeManager.java Source code

Java tutorial

Introduction

Here is the source code for com.sourcesense.opencmis.server.TypeManager.java

Source

/*
  Copyright 2011 Sourcesense
    
  Licensed 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 com.sourcesense.opencmis.server;

import org.apache.chemistry.opencmis.commons.PropertyIds;
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.definitions.TypeDefinitionList;
import org.apache.chemistry.opencmis.commons.enums.*;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.impl.Converter;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.*;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Type Manager.
 *
 * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
 */
public class TypeManager {
    public final static String DOCUMENT_TYPE_ID = "cmis:document";
    public final static String FOLDER_TYPE_ID = "cmis:folder";
    public final static String RELATIONSHIP_TYPE_ID = "cmis:relationship";
    public final static String POLICY_TYPE_ID = "cmis:policy";

    private static final String NAMESPACE = "http://onehippo.com/hst";

    private static final Log log = LogFactory.getLog(TypeManager.class);

    private Map<String, TypeDefinitionContainerImpl> fTypes;
    private List<TypeDefinitionContainer> fTypesList;

    public TypeManager() {
        setup();
    }

    /**
     * Creates the base types.
     */
    private void setup() {
        fTypes = new HashMap<String, TypeDefinitionContainerImpl>();
        fTypesList = new ArrayList<TypeDefinitionContainer>();

        // folder type
        FolderTypeDefinitionImpl folderType = new FolderTypeDefinitionImpl();
        folderType.setBaseTypeId(BaseTypeId.CMIS_FOLDER);
        folderType.setIsControllableAcl(false);
        folderType.setIsControllablePolicy(false);
        folderType.setIsCreatable(true);
        folderType.setDescription("Folder");
        folderType.setDisplayName("Folder");
        folderType.setIsFileable(true);
        folderType.setIsFulltextIndexed(false);
        folderType.setIsIncludedInSupertypeQuery(true);
        folderType.setLocalName("Folder");
        folderType.setLocalNamespace(NAMESPACE);
        folderType.setIsQueryable(false);
        folderType.setQueryName("cmis:folder");
        folderType.setId(FOLDER_TYPE_ID);

        addBasePropertyDefinitions(folderType);
        addFolderPropertyDefinitions(folderType);

        addTypeInteral(folderType);

        // document type
        DocumentTypeDefinitionImpl documentType = new DocumentTypeDefinitionImpl();
        documentType.setBaseTypeId(BaseTypeId.CMIS_DOCUMENT);
        documentType.setIsControllableAcl(false);
        documentType.setIsControllablePolicy(false);
        documentType.setIsCreatable(true);
        documentType.setDescription("Document");
        documentType.setDisplayName("Document");
        documentType.setIsFileable(true);
        documentType.setIsFulltextIndexed(false);
        documentType.setIsIncludedInSupertypeQuery(true);
        documentType.setLocalName("Document");
        documentType.setLocalNamespace(NAMESPACE);
        documentType.setIsQueryable(false);
        documentType.setQueryName("cmis:document");
        documentType.setId(DOCUMENT_TYPE_ID);

        documentType.setIsVersionable(false);
        documentType.setContentStreamAllowed(ContentStreamAllowed.ALLOWED);

        addBasePropertyDefinitions(documentType);
        addDocumentPropertyDefinitions(documentType);

        addTypeInteral(documentType);

        // relationship types
        RelationshipTypeDefinitionImpl relationshipType = new RelationshipTypeDefinitionImpl();
        relationshipType.setBaseTypeId(BaseTypeId.CMIS_RELATIONSHIP);
        relationshipType.setIsControllableAcl(false);
        relationshipType.setIsControllablePolicy(false);
        relationshipType.setIsCreatable(false);
        relationshipType.setDescription("Relationship");
        relationshipType.setDisplayName("Relationship");
        relationshipType.setIsFileable(false);
        relationshipType.setIsIncludedInSupertypeQuery(true);
        relationshipType.setLocalName("Relationship");
        relationshipType.setLocalNamespace(NAMESPACE);
        relationshipType.setIsQueryable(false);
        relationshipType.setQueryName("cmis:relationship");
        relationshipType.setId(RELATIONSHIP_TYPE_ID);

        addBasePropertyDefinitions(relationshipType);

        // not supported - don't expose it
        // addTypeInteral(relationshipType);

        // policy type
        PolicyTypeDefinitionImpl policyType = new PolicyTypeDefinitionImpl();
        policyType.setBaseTypeId(BaseTypeId.CMIS_POLICY);
        policyType.setIsControllableAcl(false);
        policyType.setIsControllablePolicy(false);
        policyType.setIsCreatable(false);
        policyType.setDescription("Policy");
        policyType.setDisplayName("Policy");
        policyType.setIsFileable(false);
        policyType.setIsIncludedInSupertypeQuery(true);
        policyType.setLocalName("Policy");
        policyType.setLocalNamespace(NAMESPACE);
        policyType.setIsQueryable(false);
        policyType.setQueryName("cmis:policy");
        policyType.setId(POLICY_TYPE_ID);

        addBasePropertyDefinitions(policyType);

        // not supported - don't expose it
        // addTypeInteral(policyType);
    }

    private void addBasePropertyDefinitions(AbstractTypeDefinition type) {
        type.addPropertyDefinition(createPropDef(PropertyIds.BASE_TYPE_ID, "Base Type Id", "Base Type Id",
                PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.OBJECT_ID, "Object Id", "Object Id", PropertyType.ID,
                Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.OBJECT_TYPE_ID, "Type Id", "Type Id", PropertyType.ID,
                Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.NAME, "Name", "Name", PropertyType.STRING,
                Cardinality.SINGLE, Updatability.READWRITE, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.CREATED_BY, "Created By", "Created By",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.CREATION_DATE, "Creation Date", "Creation Date",
                PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.LAST_MODIFIED_BY, "Last Modified By",
                "Last Modified By", PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.LAST_MODIFICATION_DATE, "Last Modification Date",
                "Last Modification Date", PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false,
                true));

        type.addPropertyDefinition(createPropDef(PropertyIds.CHANGE_TOKEN, "Change Token", "Change Token",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
    }

    private void addFolderPropertyDefinitions(FolderTypeDefinitionImpl type) {
        type.addPropertyDefinition(createPropDef(PropertyIds.PARENT_ID, "Parent Id", "Parent Id", PropertyType.ID,
                Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS,
                "Allowed Child Object Type Ids", "Allowed Child Object Type Ids", PropertyType.ID,
                Cardinality.MULTI, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.PATH, "Path", "Path", PropertyType.STRING,
                Cardinality.SINGLE, Updatability.READONLY, false, false));
    }

    private void addDocumentPropertyDefinitions(DocumentTypeDefinitionImpl type) {
        type.addPropertyDefinition(createPropDef(PropertyIds.IS_IMMUTABLE, "Is Immutable", "Is Immutable",
                PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(
                createPropDef(PropertyIds.IS_LATEST_VERSION, "Is Latest Version", "Is Latest Version",
                        PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.IS_MAJOR_VERSION, "Is Major Version",
                "Is Major Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.IS_LATEST_MAJOR_VERSION, "Is Latest Major Version",
                "Is Latest Major Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false,
                false));

        type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_LABEL, "Version Label", "Version Label",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_SERIES_ID, "Version Series Id",
                "Version Series Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT,
                "Is Verison Series Checked Out", "Is Verison Series Checked Out", PropertyType.BOOLEAN,
                Cardinality.SINGLE, Updatability.READONLY, false, true));

        type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
                "Version Series Checked Out Id", "Version Series Checked Out Id", PropertyType.ID,
                Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.CHECKIN_COMMENT, "Checkin Comment", "Checkin Comment",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(
                createPropDef(PropertyIds.CONTENT_STREAM_LENGTH, "Content Stream Length", "Content Stream Length",
                        PropertyType.INTEGER, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_MIME_TYPE, "MIME Type", "MIME Type",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_FILE_NAME, "Filename", "Filename",
                PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));

        type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_ID, "Content Stream Id",
                "Content Stream Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, false));
    }

    /**
     * Creates a property definition object.
     */
    private PropertyDefinition<?> createPropDef(String id, String displayName, String description,
            PropertyType datatype, Cardinality cardinality, Updatability updateability, boolean inherited,
            boolean required) {
        AbstractPropertyDefinition<?> result = null;

        switch (datatype) {
        case BOOLEAN:
            result = new PropertyBooleanDefinitionImpl();
            break;
        case DATETIME:
            result = new PropertyDateTimeDefinitionImpl();
            break;
        case DECIMAL:
            result = new PropertyDecimalDefinitionImpl();
            break;
        case HTML:
            result = new PropertyHtmlDefinitionImpl();
            break;
        case ID:
            result = new PropertyIdDefinitionImpl();
            break;
        case INTEGER:
            result = new PropertyIntegerDefinitionImpl();
            break;
        case STRING:
            result = new PropertyStringDefinitionImpl();
            break;
        case URI:
            result = new PropertyUriDefinitionImpl();
            break;
        default:
            throw new RuntimeException("Unknown datatype! Spec change?");
        }

        result.setId(id);
        result.setLocalName(id);
        result.setDisplayName(displayName);
        result.setDescription(description);
        result.setPropertyType(datatype);
        result.setCardinality(cardinality);
        result.setUpdatability(updateability);
        result.setIsInherited(inherited);
        result.setIsRequired(required);
        result.setIsQueryable(false);
        result.setQueryName(id);

        return result;
    }

    /**
     * Adds a type to collection with inheriting base type properties.
     */
    public boolean addType(TypeDefinition type) {
        if (type == null) {
            return false;
        }

        if (type.getBaseTypeId() == null) {
            return false;
        }

        // find base type
        TypeDefinition baseType = null;
        if (type.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT) {
            baseType = copyTypeDefintion(fTypes.get(DOCUMENT_TYPE_ID).getTypeDefinition());
        } else if (type.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) {
            baseType = copyTypeDefintion(fTypes.get(FOLDER_TYPE_ID).getTypeDefinition());
        } else if (type.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) {
            baseType = copyTypeDefintion(fTypes.get(RELATIONSHIP_TYPE_ID).getTypeDefinition());
        } else if (type.getBaseTypeId() == BaseTypeId.CMIS_POLICY) {
            baseType = copyTypeDefintion(fTypes.get(POLICY_TYPE_ID).getTypeDefinition());
        } else {
            return false;
        }

        AbstractTypeDefinition newType = (AbstractTypeDefinition) copyTypeDefintion(type);

        // copy property definition
        for (PropertyDefinition<?> propDef : baseType.getPropertyDefinitions().values()) {
            ((AbstractPropertyDefinition<?>) propDef).setIsInherited(true);
            newType.addPropertyDefinition(propDef);
        }

        // add it
        addTypeInteral(newType);

        log.info("Added type '" + newType.getId() + "'.");

        return true;
    }

    /**
     * Adds a type to collection.
     */
    private void addTypeInteral(AbstractTypeDefinition type) {
        if (type == null) {
            return;
        }

        if (fTypes.containsKey(type.getId())) {
            // can't overwrite a type
            return;
        }

        TypeDefinitionContainerImpl tc = new TypeDefinitionContainerImpl();
        tc.setTypeDefinition(type);

        // add to parent
        if (type.getParentTypeId() != null) {
            TypeDefinitionContainerImpl tdc = fTypes.get(type.getParentTypeId());
            if (tdc != null) {
                if (tdc.getChildren() == null) {
                    tdc.setChildren(new ArrayList<TypeDefinitionContainer>());
                }
                tdc.getChildren().add(tc);
            }
        }

        fTypes.put(type.getId(), tc);
        fTypesList.add(tc);
    }

    /**
     * CMIS getTypesChildren.
     */
    public TypeDefinitionList getTypesChildren(CallContext context, String typeId,
            boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount) {
        TypeDefinitionListImpl result = new TypeDefinitionListImpl();
        result.setList(new ArrayList<TypeDefinition>());
        result.setHasMoreItems(false);
        result.setNumItems(BigInteger.valueOf(0));

        int skip = (skipCount == null ? 0 : skipCount.intValue());
        if (skip < 0) {
            skip = 0;
        }

        int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
        if (max < 1) {
            return result;
        }

        if (typeId == null) {
            if (skip < 1) {
                result.getList().add(copyTypeDefintion(fTypes.get(FOLDER_TYPE_ID).getTypeDefinition()));
                max--;
            }
            if ((skip < 2) && (max > 0)) {
                result.getList().add(copyTypeDefintion(fTypes.get(DOCUMENT_TYPE_ID).getTypeDefinition()));
                max--;
            }

            result.setHasMoreItems((result.getList().size() + skip) < 2);
            result.setNumItems(BigInteger.valueOf(2));
        } else {
            TypeDefinitionContainer tc = fTypes.get(typeId);
            if ((tc == null) || (tc.getChildren() == null)) {
                return result;
            }

            for (TypeDefinitionContainer child : tc.getChildren()) {
                if (skip > 0) {
                    skip--;
                    continue;
                }

                result.getList().add(copyTypeDefintion(child.getTypeDefinition()));

                max--;
                if (max == 0) {
                    break;
                }
            }

            result.setHasMoreItems((result.getList().size() + skip) < tc.getChildren().size());
            result.setNumItems(BigInteger.valueOf(tc.getChildren().size()));
        }

        if (!includePropertyDefinitions) {
            for (TypeDefinition type : result.getList()) {
                type.getPropertyDefinitions().clear();
            }
        }

        return result;
    }

    /**
     * CMIS getTypesDescendants.
     */
    public List<TypeDefinitionContainer> getTypesDescendants(CallContext context, String typeId, BigInteger depth,
            Boolean includePropertyDefinitions) {
        List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>();

        // check depth
        int d = (depth == null ? -1 : depth.intValue());
        if (d == 0) {
            throw new CmisInvalidArgumentException("Depth must not be 0!");
        }

        // set property definition flag to default value if not set
        boolean ipd = (includePropertyDefinitions == null ? false : includePropertyDefinitions.booleanValue());

        if (typeId == null) {
            result.add(getTypesDescendants(d, fTypes.get(FOLDER_TYPE_ID), ipd));
            result.add(getTypesDescendants(d, fTypes.get(DOCUMENT_TYPE_ID), ipd));
            // result.add(getTypesDescendants(depth,
            // fTypes.get(RELATIONSHIP_TYPE_ID), includePropertyDefinitions));
            // result.add(getTypesDescendants(depth, fTypes.get(POLICY_TYPE_ID),
            // includePropertyDefinitions));
        } else {
            TypeDefinitionContainer tc = fTypes.get(typeId);
            if (tc != null) {
                result.add(getTypesDescendants(d, tc, ipd));
            }
        }

        return result;
    }

    /**
     * Gathers the type descendants tree.
     */
    private TypeDefinitionContainer getTypesDescendants(int depth, TypeDefinitionContainer tc,
            boolean includePropertyDefinitions) {
        TypeDefinitionContainerImpl result = new TypeDefinitionContainerImpl();

        TypeDefinition type = copyTypeDefintion(tc.getTypeDefinition());
        if (!includePropertyDefinitions) {
            type.getPropertyDefinitions().clear();
        }

        result.setTypeDefinition(type);

        if (depth != 0) {
            if (tc.getChildren() != null) {
                result.setChildren(new ArrayList<TypeDefinitionContainer>());
                for (TypeDefinitionContainer tdc : tc.getChildren()) {
                    result.getChildren()
                            .add(getTypesDescendants(depth < 0 ? -1 : depth - 1, tdc, includePropertyDefinitions));
                }
            }
        }

        return result;
    }

    /**
     * For internal use.
     */
    public TypeDefinition getType(String typeId) {
        TypeDefinitionContainer tc = fTypes.get(typeId);
        if (tc == null) {
            return null;
        }

        return tc.getTypeDefinition();
    }

    /**
     * CMIS getTypeDefinition.
     */
    public TypeDefinition getTypeDefinition(CallContext context, String typeId) {
        TypeDefinitionContainer tc = fTypes.get(typeId);
        if (tc == null) {
            throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
        }

        return copyTypeDefintion(tc.getTypeDefinition());
    }

    private TypeDefinition copyTypeDefintion(TypeDefinition type) {
        return Converter.convert(Converter.convert(type));
    }
}