/* * Geotools 2 - OpenSource mapping toolkit * (C) 2003, Geotools Project Management Committee (PMC) * (C) 2003, Institut de Recherche pour le Développement * * 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; either * version 2.1 of the License, or (at your option) any later version. * * 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.geotools.gp; // J2SE dependencies import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.media.jai.EnumeratedParameter; import javax.media.jai.ParameterList; import javax.media.jai.ParameterListDescriptor; import javax.media.jai.ParameterListImpl; import javax.media.jai.util.Range; import org.geotools.gc.GridCoverage; /** * A JAI operation which accepts an arbitrary number of sources. * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux */ class PolyadicOperation extends OperationJAI { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = 8936249190166828917L; /** * Construct an operation from a JAI operation name. * * @param operationName JAI operation name. */ public PolyadicOperation(final String operationName) { super(operationName); } /** * Returns the number of source grid coverages required for the operation. * Since this operation accepts an arbitrary amount of sources, this method * returns the minimal number of source grid coverages required. */ public int getNumSources() { return super.getNumSources(); } /** * Returns source name for the specified parameters. */ String[] getSourceNames(final ParameterList parameters) { if (parameters instanceof DynamicParameterList) { return ((DynamicParameterList) parameters).getSourceNames(); } return super.getSourceNames(parameters); } /** * Returns a default parameter list for this operation. This method returns a special * instance of {@link ParameterList} which accept an arbitrary number of sources. */ public ParameterList getParameterList() { return new DynamicParameterList(getParameterListDescriptor()); } /** * A {@link ParameterList} which accepts an arbitrary number of sources. * This parameter list is also its own descriptor. * * @version $Id$ * @author Martin Desruisseaux */ private static final class DynamicParameterList extends ParameterListImpl implements ParameterListDescriptor { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = 1110818299138716246L; /** * The prefix for "Source" argument name. */ private static final String SOURCE = "Source"; /** * The sources. */ private final List sources = new ArrayList(); /** * Constructs a parameter list. */ public DynamicParameterList(final ParameterListDescriptor descriptor) { super(descriptor); } /** * Returns the source indice for the specified source name, or -1 if the specified * name is not a source name. */ private static int getSourceIndex(final String name) { if (name.regionMatches(true, 0, SOURCE, 0, SOURCE.length())) try { return Integer.parseInt(name.substring(SOURCE.length())); } catch (NumberFormatException exception) { /* * The source number can't be parsed. Ignore the exception; we will * assume that the parameter name is not a source. If this is not * true, an IllegalArgumentException will be throws later, which is * a more correct exception type. */ } return -1; } /** * Returns the associated parameter list descriptor. This method returns a special * instance with a variable number of sources, defined as the number of sources * actually added to this {@link ParameterList}. */ public ParameterListDescriptor getParameterListDescriptor() { return this; } /** * Sets a named parameter to the given value. If the parameter name starts with * "Source" followed by a number, then it is assumed to be a source and will be * set only if the previous source were added. For example "Source3" is valid * only if "Source2" was previously set. */ public ParameterList setParameter(final String name, final Object value) { final int index = getSourceIndex(name); if (index >= 0) { final int length = sources.size(); if (value == null) { /* * A null value remove the source. We allow the removal of the last source * only, because removing previous sources would shift the next sources by * one index (i.e. change some source name, which is probably not the expected * behavior for most users). */ if (index == length-1) { sources.remove(index); return this; } } else if (index <= length) { if (index == length) { sources.add(value); } else { sources.set(index, value); } return this; } } return super.setParameter(name, value); } /** * Gets a named parameter as an object. */ public Object getObjectParameter(final String name) { final int index = getSourceIndex(name); if (index>=0 && index= 0) { return ParameterListDescriptor.NO_PARAMETER_DEFAULT; } return super.getParameterListDescriptor().getParamDefaultValue(name); } /** * Returns the Range that represents the range of valid values for the specified parameter. */ public Range getParamValueRange(final String name) { if (getSourceIndex(name) >= 0) { return null; } return super.getParameterListDescriptor().getParamValueRange(name); } /** * {@link inheritDoc} */ public String[] getEnumeratedParameterNames() { return super.getParameterListDescriptor().getEnumeratedParameterNames(); } /** * {@link inheritDoc} */ public EnumeratedParameter[] getEnumeratedParameterValues(final String name) { if (getSourceIndex(name) >= 0) { return null; } return super.getParameterListDescriptor().getEnumeratedParameterValues(name); } /** * Checks to see if the specified parameter can take on the specified value. */ public boolean isParameterValueValid(final String name, final Object value) { if (getSourceIndex(name) >= 0) { return value instanceof GridCoverage; } return super.getParameterListDescriptor().isParameterValueValid(name, value); } } }