Package org.apache.chemistry.opencmis.server.support

Source Code of org.apache.chemistry.opencmis.server.support.TypeValidator$PropertyValidatorDecimal

/*
* 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.server.support;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.data.PropertyDecimal;
import org.apache.chemistry.opencmis.commons.data.PropertyInteger;
import org.apache.chemistry.opencmis.commons.definitions.Choice;
import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDecimalDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition;
import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
import org.apache.chemistry.opencmis.commons.enums.Cardinality;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;

/**
* @author Jens
*/
public class TypeValidator {

    public static void validateRequiredSystemProperties(Properties properties) {
        if (properties == null || properties.getProperties() == null) {
            throw new RuntimeException("Cannot create object, no properties are given");
        }

        if (!properties.getProperties().containsKey(PropertyIds.OBJECT_TYPE_ID)) {
            throw new RuntimeException("Cannot create object, type id is missing");
        }

    }

    private static boolean isMandatorySystemProperty(String propertyId) {
        // TODO Auto-generated method stub
        return propertyId.equals(PropertyIds.OBJECT_TYPE_ID);
    }

    @SuppressWarnings("unchecked")
    static <T> PropertyValidator<T> createPropertyValidator(PropertyDefinition<?> propDef) {
        PropertyValidator<T> result = null;
        if (propDef instanceof PropertyIntegerDefinition) {
            result = (PropertyValidator<T>) new PropertyValidatorInteger();
        } else if (propDef instanceof PropertyDecimalDefinition) {
            result = (PropertyValidator<T>) new PropertyValidatorDecimal();
        } else if (propDef instanceof PropertyStringDefinition) {
            result = (PropertyValidator<T>) new PropertyValidatorString();
        } else {
            result = new PropertyValidator<T>();
        }
        return result;
    }

    /*
     * property validations: not readonly, all required are given, all are known
     * in type cardinality: no multi values for single value, def min max check
     * for Integer and Decimal, choices and in list Strings, max length set
     * default value for omitted properties
     */
    static class PropertyValidator<T> {

        public void validate(PropertyDefinition<T> propDef, PropertyData<T> prop) {

            // check general constraints for all property types
            if (propDef.getCardinality() == Cardinality.SINGLE && prop.getValues().size() > 1) {
                throw new CmisConstraintException("The property with id " + propDef.getId()
                        + " is single valued, but multiple values are passed " + prop.getValues());
            }

            if (propDef.getChoices() != null && propDef.getChoices().size() > 0) {
                validateChoices(propDef, prop);
            }
        }

        private void validateChoices(PropertyDefinition<T> propDef, PropertyData<T> prop) {
            boolean isAllowedValue = true;
            boolean hasMultiValueChoiceLists = false;
            for (Choice<?> allowedValue : propDef.getChoices()) {
                if (allowedValue.getValue() != null && allowedValue.getValue().size() > 1) {
                    hasMultiValueChoiceLists = true;
                }
            }

            // check if value is in list
            if (hasMultiValueChoiceLists) {
                // do a complex check if this combination of actual values is
                // allowed
                // check if value is in list
                isAllowedValue = false;
                List<?> actualValues = prop.getValues();
                for (Choice<?> allowedValue : propDef.getChoices()) {
                    if (allowedValue.getValue().size() == actualValues.size()) {
                        boolean listValuesAreEqual = true;
                        Iterator<?> it = allowedValue.getValue().iterator();
                        for (Object actualValue : actualValues) {
                            if (!actualValue.equals(it.next())) {
                                listValuesAreEqual = false;
                                break;
                            }
                        }
                        if (listValuesAreEqual) {
                            isAllowedValue = true;
                        }
                    }

                    if (isAllowedValue) {
                        break;
                    }
                }

            } else {
                List<T> allowedValues = getAllowedValues(propDef.getChoices());
                // do a simpler check if all values are choice elements

                for (Object actualValue : prop.getValues()) {
                    if (!allowedValues.contains(actualValue)) {
                        isAllowedValue = false;
                        break;
                    }
                }
            }

            if (!isAllowedValue) {
                throw new CmisConstraintException("The property with id " + propDef.getId()
                        + " has a fixed set of values. Value(s) " + prop.getValues() + " are not listed.");
            }
        }

        /**
         * Calculate the list of allowed values for this property definition by
         * recursively collecting all choice values from property definition
         *
         * @param propDef
         *            property definition
         * @return list of possible values in complete hierarchy
         */
        private List<T> getAllowedValues(List<Choice<T>> choices) {
            List<T> allowedValues = new ArrayList<T>(choices.size());
            for (Choice<T> choice : choices) {
                if (choice.getValue() != null) {
                    allowedValues.add(choice.getValue().get(0));
                }
                if (choice.getChoice() != null) {
                    List<Choice<T>> x = choice.getChoice();
                    allowedValues.addAll(getAllowedValues(x));
                }
            }
            return allowedValues;
        }
    }

    static class PropertyValidatorInteger extends PropertyValidator<BigInteger> {

        @Override
        public void validate(PropertyDefinition<BigInteger> propDef, PropertyData<BigInteger> property) {

            super.validate(propDef, property);

            BigInteger propVal = property.getFirstValue();
            BigInteger minVal = ((PropertyIntegerDefinition) propDef).getMinValue();
            BigInteger maxVal = ((PropertyIntegerDefinition) propDef).getMaxValue();

            // check min and max
            if (minVal != null && propVal != null && propVal.compareTo(minVal) == -1) {
                throw new CmisConstraintException("For property with id " + propDef.getId() + " the value " + propVal
                        + " is less than the minimum value " + minVal);
            }
            if (maxVal != null && propVal != null && propVal.compareTo(maxVal) == 1) {
                throw new CmisConstraintException("For property with id " + propDef.getId() + " the value " + propVal
                        + " is bigger than the maximum value " + maxVal);
            }
        }
    }

    static class PropertyValidatorDecimal extends PropertyValidator<BigDecimal> {

        @Override
        public void validate(PropertyDefinition<BigDecimal> propDef, PropertyData<BigDecimal> property) {

            super.validate(propDef, property);

            BigDecimal propVal = property.getFirstValue();
            BigDecimal minVal = ((PropertyDecimalDefinition) propDef).getMinValue();
            BigDecimal maxVal = ((PropertyDecimalDefinition) propDef).getMaxValue();

            // check min and max
            if (minVal != null && propVal != null && propVal.compareTo(minVal) == -1) {
                throw new CmisConstraintException("For property with id " + propDef.getId() + " the value " + propVal
                        + " is less than the minimum value " + minVal);
            }
            if (maxVal != null && propVal != null && propVal.compareTo(maxVal) == 1) {
                throw new CmisConstraintException("For property with id " + propDef.getId() + " the value " + propVal
                        + " is bigger than the maximum value " + maxVal);
            }
        }
    }

    static class PropertyValidatorString extends PropertyValidator<String> {

        @Override
        public void validate(PropertyDefinition<String> propDef, PropertyData<String> property) {

            super.validate(propDef, property);

            long maxLen = ((PropertyStringDefinition) propDef).getMaxLength() == null ? -1
                    : ((PropertyStringDefinition) propDef).getMaxLength().longValue();
            long len = property.getFirstValue() == null ? -1
                    : property.getFirstValue().length();

            // check max length
            if (maxLen >= 0 && len >= 0 && maxLen < len) {
                throw new CmisConstraintException("For property with id " + propDef.getId() + " the length of " + len
                        + "is bigger than the maximum allowed length  " + maxLen);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> void validateProperties(TypeDefinition typeDef, Properties properties, boolean checkMandatory) {

        List<String> propDefsRequired = getMandatoryPropDefs(typeDef.getPropertyDefinitions());

        for (PropertyData<?> prop : properties.getProperties().values()) {
            String propertyId = prop.getId();
            BaseTypeId baseTypeId = typeDef.getBaseTypeId();

            // check that all mandatory attributes are present
            if (checkMandatory && propDefsRequired.contains(propertyId)) {
                propDefsRequired.remove(propertyId);
            }

            if (isSystemProperty(baseTypeId, propertyId))
             {
                continue; // ignore system properties for validation
            }

            // Check if all properties are known in the type
            if (!typeContainsProperty(typeDef, propertyId)) {
                throw new CmisConstraintException("Unknown property " + propertyId + " in type " + typeDef.getId());
            }

            // check all type specific constraints:
            PropertyDefinition<T> propDef = getPropertyDefinition(typeDef, propertyId);
            PropertyValidator<T> validator = createPropertyValidator(propDef);
            validator.validate(propDef, (PropertyData<T>) prop);
        }

        if (checkMandatory && !propDefsRequired.isEmpty()) {
            throw new CmisConstraintException("The following mandatory properties are missing: " + propDefsRequired);
        }
    }

    public static void validateVersionStateForCreate(DocumentTypeDefinition typeDef, VersioningState verState) {
        if (null == verState) {
            return;
        }
        if (typeDef.isVersionable() && verState.equals(VersioningState.NONE) || !typeDef.isVersionable()
                && !verState.equals(VersioningState.NONE)) {
            throw new CmisConstraintException("The versioning state flag is imcompatible to the type definition.");
        }

    }

    public static void validateAllowedChildObjectTypes(TypeDefinition childTypeDef, List<String> allowedChildTypes) {

       validateAllowedTypes(childTypeDef, allowedChildTypes, "in this folder");
    }
   
    public static void validateAllowedRelationshipTypes (RelationshipTypeDefinition relationshipTypeDef, TypeDefinition sourceTypeDef,
        TypeDefinition targetTypeDef)
    {
      List<String> allowedSourceTypes = relationshipTypeDef.getAllowedSourceTypeIds()
      validateAllowedTypes(sourceTypeDef, allowedSourceTypes, " as source type in this relationship");
        List<String> allowedTargetTypes = relationshipTypeDef.getAllowedTargetTypeIds();
        validateAllowedTypes(targetTypeDef, allowedTargetTypes, " as target type in this relationship")
    }
   
    protected static void validateAllowedTypes(TypeDefinition typeDef, List<String> allowedTypes, String description)
    {
       if (null == allowedTypes || allowedTypes.size() == 0)
             return; // all types are allowed

         for (String allowedType : allowedTypes) {
             if (allowedType.equals(typeDef.getId()))
                 return;
         }
         throw new CmisConstraintException("The requested type " + typeDef.getId() + " is not allowed " + description);
     }
      
    public static void  validateAcl(TypeDefinition typeDef, Acl addACEs, Acl removeACEs)
    {
      if (!typeDef.isControllableAcl() && (addACEs != null || removeACEs != null))
      {
        throw new CmisConstraintException("acl set for type: " + typeDef.getDisplayName() + " that is not controllableACL");
      }
      }

    private static List<String> getMandatoryPropDefs(Map<String, PropertyDefinition<?>> propDefs) {
        List<String> res = new ArrayList<String>();
        if (null != propDefs) {
            for (PropertyDefinition<?> propDef : propDefs.values()) {
                if (propDef.isRequired() && !isMandatorySystemProperty(propDef.getId())) {
                    res.add(propDef.getId());
                }
            }
        }
        return res;
    }

    public static boolean typeContainsProperty(TypeDefinition typeDef, String propertyId) {

        Map<String, PropertyDefinition<?>> propDefs = typeDef.getPropertyDefinitions();
        if (null == propDefs) {
            return false;
        }

        PropertyDefinition<?> propDef = propDefs.get(propertyId);

        if (null == propDef) {
            return false; // unknown property id in this type
        } else {
            return true;
        }
    }

    public static boolean typeContainsPropertyWithQueryName(TypeDefinition typeDef, String propertyQueryName) {

        Map<String, PropertyDefinition<?>> propDefs = typeDef.getPropertyDefinitions();
        if (null == propDefs) {
            return false;
        }

        for (PropertyDefinition<?> propDef : propDefs.values()) {
            if (propDef.getQueryName().toLowerCase().equals(propertyQueryName.toLowerCase())) {
                return true;
            }
        }

        return false; // unknown property query name in this type
    }

    @SuppressWarnings("unchecked")
    private static <T> PropertyDefinition<T> getPropertyDefinition(TypeDefinition typeDef, String propertyId) {

        Map<String, PropertyDefinition<?>> propDefs = typeDef.getPropertyDefinitions();
        if (null == propDefs) {
            return null;
        }

        PropertyDefinition<?> propDef = propDefs.get(propertyId);

        if (null == propDef) {
            return null; // not found
        } else {
            return (PropertyDefinition<T>) propDef;
        }
    }

    private static boolean isSystemProperty(BaseTypeId baseTypeId, String propertyId) {

        if (propertyId.equals(PropertyIds.NAME)) {
            return true;
        } else if (propertyId.equals(PropertyIds.OBJECT_ID)) {
            return true;
        } else if (propertyId.equals(PropertyIds.OBJECT_TYPE_ID)) {
            return true;
        } else if (propertyId.equals(PropertyIds.BASE_TYPE_ID)) {
            return true;
        } else if (propertyId.equals(PropertyIds.CREATED_BY)) {
            return true;
        } else if (propertyId.equals(PropertyIds.CREATION_DATE)) {
            return true;
        } else if (propertyId.equals(PropertyIds.LAST_MODIFIED_BY)) {
            return true;
        } else if (propertyId.equals(PropertyIds.LAST_MODIFICATION_DATE)) {
            return true;
        } else if (propertyId.equals(PropertyIds.CHANGE_TOKEN)) {
            return true;
        }

        if (baseTypeId.equals(BaseTypeId.CMIS_DOCUMENT)) {
            if (propertyId.equals(PropertyIds.IS_IMMUTABLE)) {
                return true;
            } else if (propertyId.equals(PropertyIds.IS_LATEST_VERSION)) {
                return true;
            } else if (propertyId.equals(PropertyIds.IS_MAJOR_VERSION)) {
                return true;
            } else if (propertyId.equals(PropertyIds.VERSION_SERIES_ID)) {
                return true;
            } else if (propertyId.equals(PropertyIds.IS_LATEST_MAJOR_VERSION)) {
                return true;
            } else if (propertyId.equals(PropertyIds.VERSION_LABEL)) {
                return true;
            } else if (propertyId.equals(PropertyIds.VERSION_SERIES_ID)) {
                return true;
            } else if (propertyId.equals(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT)) {
                return true;
            } else if (propertyId.equals(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY)) {
                return true;
            } else if (propertyId.equals(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID)) {
                return true;
            } else if (propertyId.equals(PropertyIds.CHECKIN_COMMENT)) {
                return true;
            } else if (propertyId.equals(PropertyIds.CONTENT_STREAM_LENGTH)) {
                return true;
            } else if (propertyId.equals(PropertyIds.CONTENT_STREAM_MIME_TYPE)) {
                return true;
            } else if (propertyId.equals(PropertyIds.CONTENT_STREAM_FILE_NAME)) {
                return true;
            } else if (propertyId.equals(PropertyIds.CONTENT_STREAM_ID)) {
                return true;
            } else {
                return false;
            }
        } else if (baseTypeId.equals(BaseTypeId.CMIS_FOLDER)) {
            if (propertyId.equals(PropertyIds.PARENT_ID)) {
                return true;
            } else if (propertyId.equals(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS)) {
                return true;
            } else if (propertyId.equals(PropertyIds.PATH)) {
                return true;
            } else {
                return false;
            }
        } else if (baseTypeId.equals(BaseTypeId.CMIS_POLICY)) {
            if (propertyId.equals(PropertyIds.SOURCE_ID)) {
                return true;
            } else if (propertyId.equals(PropertyIds.TARGET_ID)) {
                return true;
            } else {
                return false;
            }
        } else { // relationship
            if (propertyId.equals(PropertyIds.POLICY_TEXT)) {
                return true;
            } else {
                return false;
            }
        }
    }
}
TOP

Related Classes of org.apache.chemistry.opencmis.server.support.TypeValidator$PropertyValidatorDecimal

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.