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