/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012-2013, 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.chain; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.sis.metadata.iso.DefaultIdentifier; import org.apache.sis.metadata.iso.citation.DefaultCitation; import org.apache.sis.metadata.iso.identification.DefaultServiceIdentification; import org.apache.sis.parameter.ParameterBuilder; import org.geotoolkit.utility.parameter.ExtendedParameterDescriptor; import org.geotoolkit.processing.AbstractProcessDescriptor; import org.geotoolkit.process.Process; import org.geotoolkit.process.ProcessFinder; import org.geotoolkit.process.ProcessingRegistry; import org.geotoolkit.processing.chain.model.Chain; import org.geotoolkit.processing.chain.model.Parameter; import org.apache.sis.util.iso.SimpleInternationalString; import org.opengis.metadata.Identifier; import org.opengis.metadata.identification.Identification; import org.opengis.parameter.GeneralParameterDescriptor; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterValueGroup; /** * * @author Johann Sorel (Geomatys) */ public class ChainProcessDescriptor extends AbstractProcessDescriptor{ /** registry name **/ public static final DefaultServiceIdentification FALLBACK_IDENTIFICATION; static { FALLBACK_IDENTIFICATION = new DefaultServiceIdentification(); final Identifier id = new DefaultIdentifier("dynamicchain"); final DefaultCitation citation = new DefaultCitation("dynamicchain"); citation.setIdentifiers(Collections.singleton(id)); FALLBACK_IDENTIFICATION.setCitation(citation); } public static final String KEY_DISTANT_CLASS = "distanClass"; private final Collection<? extends ProcessingRegistry> factories; private final Chain model; /** * Create a process descriptor with default registry. */ public ChainProcessDescriptor(final Chain model){ this(model,FALLBACK_IDENTIFICATION,null); } /** * Create a process descriptor with default registry. */ public ChainProcessDescriptor(final Chain model, final Identification registryId){ this(model,registryId,null); } /** * Create a process descriptor with given registry. */ public ChainProcessDescriptor(final Chain model, final Identification registryId, final Collection<? extends ProcessingRegistry> factories){ super(new DerivateIdentifier(model.getName(), registryId), new SimpleInternationalString(model.getName()), new SimpleInternationalString(model.getName()), createParams(model.getInputs(), "inputParameters", true), createParams(model.getOutputs(), "outputParameters", true)); this.model = model; this.factories = factories; } /** * @return Chain model used. */ public Chain getModel(){ return model; } /** * Context in which this process is executed. * * @return Collection of ProcessingRegistry. */ public Collection<? extends ProcessingRegistry> getFactories() { if(factories == null){ final Iterator<ProcessingRegistry> ite = ProcessFinder.getProcessFactories(); final Collection<ProcessingRegistry> factories = new ArrayList<ProcessingRegistry>(); while(ite.hasNext()){ factories.add(ite.next()); } return factories; } return factories; } /** * {@inheritDoc} */ @Override public Process createProcess(ParameterValueGroup input) { return new ChainProcess(this, input); } public static ParameterDescriptorGroup createParams(final List<Parameter> inputs, final String name, final boolean realType){ int parameterSize = inputs.size(); final GeneralParameterDescriptor[] paramDescs = new GeneralParameterDescriptor[parameterSize]; int index = 0; for (Parameter param : inputs) { final ParameterDescriptor desc; if (realType) { final Class type = param.getType().getRealClass(); desc = new ParameterBuilder() .addName(param.getCode()) .setRemarks(param.getRemarks()) .setRequired(param.getMinOccurs()!=0) .create(type, convertDefaultValueInClass(param.getDefaultValue(), type)); } else { final Map<String, Object> ext = new HashMap<String,Object>(); ext.put(KEY_DISTANT_CLASS, param.getType()); Class clazz = Object.class; try { clazz = Class.forName(param.getType().getName()); } catch (ClassNotFoundException ex) { clazz = Object.class; } desc = new ExtendedParameterDescriptor(param.getCode(), param.getRemarks(), clazz, convertDefaultValueInClass(param.getDefaultValue(), clazz), param.getMinOccurs()!=0, ext); } paramDescs[index] = desc; index++; } return new ParameterBuilder().addName(name).createGroup(paramDescs); } public static ParameterDescriptor convertParameterDtoToParameterDescriptor(final Parameter param, final boolean realType) { if (realType) { final Class type = param.getType().getRealClass(); return new ParameterBuilder() .addName(param.getCode()) .setRemarks(param.getRemarks()) .setRequired(param.getMinOccurs()!=0) .create(type, convertDefaultValueInClass(param.getDefaultValue(), type)); } final Map<String, Object> ext = new HashMap<String,Object>(); ext.put(KEY_DISTANT_CLASS, param.getType()); Class clazz; try { clazz = Class.forName(param.getType().getName()); } catch (ClassNotFoundException ex) { clazz = Object.class; } return new ExtendedParameterDescriptor(param.getCode(), param.getRemarks(), clazz, convertDefaultValueInClass(param.getDefaultValue(), clazz), param.getMinOccurs()!=0, ext); } /** * Converts the default value in the given class if the default value is a string, otherwise * return {@code null}. * * @param defaultValue The default value to convert. * @param clazz Class in which the default value should be converted. * @return The default value converted in the given class, or {@code null} if impossible to convert. */ public static Object convertDefaultValueInClass(final Object defaultValue, final Class clazz) { if (defaultValue == null) { return null; } if (defaultValue.getClass().isAssignableFrom(clazz)) { // don't need to convert value since it's already in the right class return defaultValue; } if (defaultValue instanceof String && !defaultValue.getClass().isAssignableFrom(clazz) && (clazz.isAssignableFrom(String.class) || clazz.isAssignableFrom(Boolean.class) || clazz.isAssignableFrom(Double.class) || clazz.isAssignableFrom(Integer.class))) { return ConstantUtilities.stringToValue(defaultValue.toString(), clazz); } return null; } }