001/* 002 * (C) Copyright 2012 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 * mcedica 018 */ 019package org.nuxeo.ecm.core.api.propertiesmapping.impl; 020 021import java.util.Map; 022 023import org.apache.commons.logging.Log; 024import org.apache.commons.logging.LogFactory; 025import org.nuxeo.ecm.core.api.CoreSession; 026import org.nuxeo.ecm.core.api.DocumentModel; 027import org.nuxeo.ecm.core.api.NuxeoException; 028import org.nuxeo.ecm.core.api.model.Property; 029import org.nuxeo.ecm.core.api.model.PropertyNotFoundException; 030import org.nuxeo.ecm.core.api.propertiesmapping.PropertiesMappingContributionRegistry; 031import org.nuxeo.ecm.core.api.propertiesmapping.PropertiesMappingDescriptor; 032import org.nuxeo.ecm.core.api.propertiesmapping.PropertiesMappingService; 033import org.nuxeo.ecm.core.schema.types.ComplexType; 034import org.nuxeo.ecm.core.schema.types.Field; 035import org.nuxeo.ecm.core.schema.types.ListType; 036import org.nuxeo.ecm.core.schema.types.Type; 037import org.nuxeo.runtime.model.ComponentInstance; 038import org.nuxeo.runtime.model.DefaultComponent; 039 040/** 041 * Service that allows to copy a set of metadata from a source to a target document 042 * 043 * @since 5.6 044 */ 045public class PropertiesMappingComponent extends DefaultComponent implements PropertiesMappingService { 046 047 public static final Log log = LogFactory.getLog(PropertiesMappingComponent.class); 048 049 public static final String MAPPING_EP = "mapping"; 050 051 protected PropertiesMappingContributionRegistry mappingsRegistry = new PropertiesMappingContributionRegistry(); 052 053 @Override 054 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 055 if (MAPPING_EP.equals(extensionPoint)) { 056 PropertiesMappingDescriptor desc = (PropertiesMappingDescriptor) contribution; 057 mappingsRegistry.addContribution(desc); 058 } 059 } 060 061 @Override 062 public Map<String, String> getMapping(String mappingName) { 063 return mappingsRegistry.getMappingProperties(mappingName); 064 } 065 066 @Override 067 public void mapProperties(CoreSession session, DocumentModel sourceDoc, DocumentModel targetDoc, String mapping) 068 { 069 Map<String, String> properties = getMapping(mapping); 070 for (String keyProp : properties.keySet()) { 071 // verify that mapping can be done 072 Property sourceProperty = sourceDoc.getProperty(keyProp); 073 Property targetProperty = targetDoc.getProperty(properties.get(keyProp)); 074 075 Type sourceType = sourceProperty.getType(); 076 Type targetType = targetProperty.getType(); 077 078 if (!compatibleTypes(targetType, sourceType)) { 079 throw new NuxeoException( 080 String.format("Invalid mapping. Cannot map %s on type %s ", sourceType, targetType)); 081 } 082 083 targetDoc.setPropertyValue(targetProperty.getPath(), sourceProperty.getValue()); 084 } 085 session.saveDocument(targetDoc); 086 } 087 088 protected boolean compatibleTypes(Type targetType, Type sourceType) { 089 if (!sourceType.getName().equals(targetType.getName())) { 090 return false; 091 } 092 if (sourceType.isComplexType()) { 093 for (Field field : ((ComplexType) sourceType).getFields()) { 094 Field targetField = ((ComplexType) targetType).getField(field.getName()); 095 if (targetField == null || !field.getType().equals(targetField.getType())) { 096 return false; 097 } 098 } 099 } 100 if (sourceType.isListType()) { 101 if (!((ListType) sourceType).getFieldType().equals(((ListType) targetType).getFieldType())) { 102 return false; 103 } 104 if (((ListType) sourceType).getFieldType().isComplexType()) { 105 return compatibleTypes(((ListType) targetType).getFieldType(), ((ListType) sourceType).getFieldType()); 106 } 107 } 108 return true; 109 } 110}