001/* 002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Bogdan Stefanescu 018 * Florent Guillaume 019 */ 020package org.nuxeo.ecm.core.api.model.impl; 021 022import static org.nuxeo.ecm.core.api.model.impl.AbstractProperty.IS_DEPRECATED; 023import static org.nuxeo.ecm.core.api.model.impl.AbstractProperty.IS_SECURED; 024 025import java.util.stream.IntStream; 026 027import org.nuxeo.ecm.core.api.model.Property; 028import org.nuxeo.ecm.core.api.model.impl.primitives.BinaryProperty; 029import org.nuxeo.ecm.core.api.model.impl.primitives.BlobProperty; 030import org.nuxeo.ecm.core.api.model.impl.primitives.BooleanProperty; 031import org.nuxeo.ecm.core.api.model.impl.primitives.DateProperty; 032import org.nuxeo.ecm.core.api.model.impl.primitives.DoubleProperty; 033import org.nuxeo.ecm.core.api.model.impl.primitives.ExternalBlobProperty; 034import org.nuxeo.ecm.core.api.model.impl.primitives.LongProperty; 035import org.nuxeo.ecm.core.api.model.impl.primitives.StringProperty; 036import org.nuxeo.ecm.core.schema.PropertyCharacteristicHandler; 037import org.nuxeo.ecm.core.schema.TypeConstants; 038import org.nuxeo.ecm.core.schema.types.Field; 039import org.nuxeo.ecm.core.schema.types.ListType; 040import org.nuxeo.ecm.core.schema.types.SimpleTypeImpl; 041import org.nuxeo.ecm.core.schema.types.Type; 042import org.nuxeo.ecm.core.schema.types.primitives.BinaryType; 043import org.nuxeo.ecm.core.schema.types.primitives.BooleanType; 044import org.nuxeo.ecm.core.schema.types.primitives.DateType; 045import org.nuxeo.ecm.core.schema.types.primitives.DoubleType; 046import org.nuxeo.ecm.core.schema.types.primitives.IntegerType; 047import org.nuxeo.ecm.core.schema.types.primitives.LongType; 048import org.nuxeo.ecm.core.schema.types.primitives.StringType; 049import org.nuxeo.runtime.api.Framework; 050 051/** 052 * The default property factory singleton. 053 */ 054public class PropertyFactory { 055 056 private PropertyFactory() { 057 // utility class 058 } 059 060 public static Property createProperty(Property parent, Field field, int flags) { 061 flags = computePropertyFlags(parent, field, flags); 062 Type type = field.getType(); 063 if (type instanceof SimpleTypeImpl) { 064 // type with constraint 065 type = type.getSuperType(); 066 } 067 switch (type.getName()) { 068 case StringType.ID: 069 return new StringProperty(parent, field, flags); 070 case IntegerType.ID: 071 case LongType.ID: 072 return new LongProperty(parent, field, flags); 073 case DoubleType.ID: 074 return new DoubleProperty(parent, field, flags); 075 case BooleanType.ID: 076 return new BooleanProperty(parent, field, flags); 077 case DateType.ID: 078 return new DateProperty(parent, field, flags); 079 case BinaryType.ID: 080 return new BinaryProperty(parent, field, flags); 081 case TypeConstants.CONTENT: 082 return new BlobProperty(parent, field, flags); 083 case TypeConstants.EXTERNAL_CONTENT: 084 return new ExternalBlobProperty(parent, field, flags); 085 } 086 if (type.isSimpleType()) { 087 return new ScalarProperty(parent, field, flags); 088 } else if (type.isComplexType()) { 089 return new MapProperty(parent, field, flags); 090 } else if (type.isListType()) { 091 if (((ListType) type).isArray()) { 092 return new ArrayProperty(parent, field, flags); 093 } else { 094 return new ListProperty(parent, field, flags); 095 } 096 } else { 097 throw new IllegalArgumentException("Unsupported field type: " + field.getType().getName()); 098 } 099 } 100 101 protected static int computePropertyFlags(Property parent, Field field, int flags) { 102 // check if property to create has flags to inherit from parent or configuration 103 if (parent instanceof AbstractProperty) { // should always be the case 104 // compute inherit flags from parent 105 flags |= IntStream.of(IS_SECURED, IS_DEPRECATED) 106 .filter(((AbstractProperty) parent)::areFlagsSet) 107 .reduce(0, (f1, f2) -> f1 | f2); 108 // if parent is not secured or deprecated, compute characteristics for current property 109 if ((flags & IS_SECURED) == 0 || (flags & IS_DEPRECATED) == 0) { 110 String schemaName = parent.getSchema().getName(); 111 StringBuilder xpathBuilder = new StringBuilder(); 112 if (parent.getParent() != null) { 113 xpathBuilder.append(parent.getXPath()).append('/'); 114 } 115 xpathBuilder.append(field.getName().getLocalName()); 116 String xpath = xpathBuilder.toString(); 117 118 PropertyCharacteristicHandler propertyHandler = Framework.getService( 119 PropertyCharacteristicHandler.class); 120 if ((flags & IS_SECURED) == 0 && propertyHandler.isSecured(schemaName, xpath)) { 121 flags |= IS_SECURED; 122 } 123 if ((flags & IS_DEPRECATED) == 0 && propertyHandler.isDeprecated(schemaName, xpath)) { 124 flags |= IS_DEPRECATED; 125 } 126 } 127 } 128 return flags; 129 } 130 131}