/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.processing.metadata.merge; import org.apache.sis.metadata.KeyNamePolicy; import org.apache.sis.metadata.MetadataStandard; import org.apache.sis.metadata.ValueExistencePolicy; import org.apache.sis.metadata.iso.DefaultMetadata; import org.geotoolkit.processing.AbstractProcess; import org.geotoolkit.process.ProcessException; import org.opengis.metadata.Metadata; import org.opengis.parameter.ParameterValueGroup; import java.util.Collection; import java.util.Map; import static org.geotoolkit.parameter.Parameters.getOrCreate; import static org.geotoolkit.processing.metadata.merge.MergeDescriptor.FIRST_IN; import static org.geotoolkit.processing.metadata.merge.MergeDescriptor.INSTANCE; import static org.geotoolkit.processing.metadata.merge.MergeDescriptor.RESULT_OUT; import static org.geotoolkit.processing.metadata.merge.MergeDescriptor.SECOND_IN; /** * Merge two metadata objects. * * @author Johann Sorel (Geomatys) * @author Benjamin Garcia (Geomatys) * @module */ public class Merge extends AbstractProcess { public Merge(final ParameterValueGroup input) { super(INSTANCE, input); } /** * {@inheritDoc } */ @Override protected void execute() throws ProcessException { fireProcessStarted("Start merge"); final Metadata first = (Metadata) getOrCreate(FIRST_IN, inputParameters).getValue(); final Metadata second = (Metadata) getOrCreate(SECOND_IN, inputParameters).getValue(); final DefaultMetadata merged = new DefaultMetadata(first); final MetadataStandard standard = merged.getStandard(); merge(standard, second, merged); getOrCreate(RESULT_OUT, outputParameters).setValue(merged); fireProcessCompleted("Merge done."); } /** * Merger recursively metadata. * @param standard {@link MetadataStandard} object used to find Metadata tree object. * @param sourceMetadata a metadata object which need to be insert on the other metadata. * @param targetMetadata a metadata object which receive merged metadata */ private void merge(final MetadataStandard standard, final Object sourceMetadata, final Object targetMetadata) { //transfomr metadatas to maps final Map<String, Object> source = standard.asValueMap(sourceMetadata, KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.NON_EMPTY); final Map<String, Object> target = standard.asValueMap(targetMetadata, KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.ALL); //Iterate on sources to found object which need to be merged for (final Map.Entry<String, Object> entry : source.entrySet()) { // final String propertyName = entry.getKey(); final Object sourceValue = entry.getValue(); final Object targetValue = target.get(propertyName); //directly put if value is null on targer (they don't need merge) if (targetValue == null) { target.put(propertyName, sourceValue); } else { //if it's metadata object (DefaultMetadata, Extent, ...) if (standard.isMetadata(targetValue.getClass())) { merge(standard, sourceValue, targetValue); } else { //targetValue is a Collection if(targetValue instanceof Collection){ Collection targetList = ((Collection) targetValue); Collection sourceList = ((Collection) sourceValue); //recursively merge if (targetList.size() > 0) { for (Object mergeElement : targetList) { for (Object sourceElement : sourceList) { if (mergeElement.getClass().equals(sourceElement.getClass()) && standard.isMetadata(mergeElement.getClass())) { merge(standard, sourceElement, mergeElement); } } } } else { //list is empty on target : we add all other collection without merge ((Collection) targetValue).addAll((Collection) sourceValue); } } } } } } }