/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2008, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.data; import java.util.Collections; import java.util.Map; import org.geotools.util.SimpleInternationalString; import org.opengis.util.InternationalString; /** * A Parameter defines information about a valid process parameter. * * @author gdavis * * * @source $URL$ */ public class Parameter<T> implements org.opengis.parameter.Parameter<T>{ /** * This is the key (ie machine readable text) used to represent this parameter in a * java.util.Map. * * @param key (or machine readable name) for this parameter. */ public final String key; /** * Human readable title/name of this parameter. */ public final InternationalString title; /** * Human readable description of this parameter. */ public final InternationalString description; /** * Class binding for this parameter. * <p> * When a value is supplied for this key it should be of the provided type. */ public final Class<T> type; /** Can the value be missing? Or is null allowed... *@return true if a value is required to be both present and non null **/ public final boolean required; /** What is the min and max number of this paramter there can be * ( a value of -1 for min means 0 or more, * a value of -1 for max means any number greater than or equal to the min value ) * * eg: a geometry union process can have any number of geom parameters, * so by setting the max to -1 and the min to 2 we accomplish that. */ public final int minOccurs; public final int maxOccurs; /** * A sample value; often used as a default when prompting the end-user * to fill in the details before executing a process. */ public final Object sample; /** * Hints for the user interface */ /** "featureType" FeatureType to validate a Feature value against */ public static final String FEATURE_TYPE = "featureType"; /** Boolean indicating whether the parameter shall be used as a password field, * provides a hint for UI's to mask text fields, configuration systems to encrypt content, etc */ public static final String IS_PASSWORD = "isPassword"; /** * "length" Integer used to limit the length of strings or literal geometries. */ public static final String LENGTH = "length"; /** "crs": CoordinateReferenceSystem used to restrict a Geometry literal */ public static final String CRS = "crs"; /** "element": Class to use as the Element type for List<Element>. Please restrict * your use of this facility to simple types; for most higher order data structures * multiplicity is already accounted for - example MultiGeometry. */ public static final String ELEMENT = "element"; /** * "min" and "max" may be useful for restrictions for things like int sizes, etc. */ public static final String MIN = "min"; /** * "min" and "max" may be useful for restrictions for things like int sizes, etc. */ public static final String MAX = "max"; /** * As an alternative to "min" and "max" a speciifc List<T> of options can be provided * for a user to choose between. The description should explain what the options * mean. * * Example: a compliance level of (0-low,1-medium,2-high) * * Although a List<T> is used here (so you can specifiy order) it is assumed you * will not confuse your users by placing duplicates in the list. */ public static final String OPTIONS = "options"; /** * File extension expected - "shp", "jpg", etc... */ public static final String EXT = "ext"; /** * Level or Category of the parameter - "user", "advanced", "program" * <p> * <ul> * <li>user - should be shown to all users and is used every time.<br> * example: user name and password * </li> * <li>advanced - advanced or expert parameter used in special cases<br> * example: choice between get and post requests for WFS * </li> * <li>program - intended for programs often tweaking settings for performance<br> * example: JDBC datasource for which it is hard for a user to type in * </li> * </ul> */ public static final String LEVEL = "level"; /** * Refinement of type; such as the FeatureType of a FeatureCollection, or component type of a List. * <p> * This information is supplied (along with type) to allow a process implementor communicate * additional restrictions on the allowed value beyond the strict type. * <p> * The following keys are understood at this time: LENGTH, FEATURE_TYPE, CRS, ELEMENT * .. additional keys will be documented as static final fields over time. * <p> * Any restrictions mentioned here should be mentioned as part of your * parameter description. This metadata is only used to help restrict what * the user enters; not all client application will understand and respect * these keys - please communicate with your end-user. * * @see CRS * @see ELEMENT * @see FEATURE_TYPE * @see IS_PASSWORD * @see LENGTH * @see MAX * @see MIN */ public final Map<String, Object> metadata; /** * Mandatory parameter - quickly constructed with out a properly internationalized * title and description. * * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param title Human readable title used for use in a user interface * @param description Human readable description */ public Parameter(String key, Class<T> type, String title, String description ) { this( key, type, new SimpleInternationalString(title), new SimpleInternationalString(description) ); } /** * Mandatory parameter - quickly constructed with out a properly internationalized * title and description. * * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param title Human readable title used for use in a user interface * @param description Human readable description */ public Parameter(String key, Class<T> type, String title, String description, Map<String,Object> metadata ) { this( key, type, new SimpleInternationalString(title), new SimpleInternationalString(description), metadata); } /** * Mandatory parameter * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param title Human readable title used for use in a user interface * @param description Human readable description */ public Parameter(String key, Class<T> type, InternationalString title, InternationalString description ) { this( key, type, title, description, true, 1, 1, null, null ); } /** * Mandatory parameter with metadata. * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param title Human readable title used for use in a user interface * @param description Human readable description * @param metadata Hints to the user interface (read the javadocs for each metadata key) * * @see #CRS * @see #ELEMENT * @see #FEATURE_TYPE * @see #IS_PASSWORD * @see #LENGTH * @see #MAX * @see #MIN */ public Parameter(String key, Class<T> type, InternationalString title, InternationalString description, Map<String,Object> metadata ) { this( key, type, title, description, true, 1, 1, null, metadata ); } /** * Addition of optional parameters * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param title Human readable title used for use in a user interface * @param description Human readable description * @param required true if the value is required * @param min Minimum value; or -1 if not needed * @param max Maximum value; or -1 for unbound * @param sample Sample value; may be used as a default in a user interface * @param metadata Hints to the user interface (read the javadocs for each metadata key) * * @see #CRS * @see #ELEMENT * @see #FEATURE_TYPE * @see #IS_PASSWORD * @see #LENGTH * @see #MAX * @see #MIN */ @SuppressWarnings("unchecked") public Parameter(String key, Class<T> type, InternationalString title, InternationalString description, boolean required, int min, int max, Object sample, Map<String,Object> metadata) { this.key = key; this.title = title; this.type = type; this.description = description; this.required = required; this.minOccurs = min; this.maxOccurs = max; this.sample = sample; this.metadata = metadata == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(metadata); } /** * Constructs a parameter from key and type * * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value */ public Parameter(String key, Class<T> type) { this(key, type, null, null,true, 1, 1, null, null); } /** * Constructs a parameter from key, type, and min/max occurs. * * @param key machine readable key for use in a java.util.Map * @param type Java class for the expected value * @param min Minimum value of occurrences, -1 if not needed * @param max Maximum value of occurrences, -1 for unbound */ public Parameter(String key, Class<T> type, int min, int max) { this(key, type, null, null, min > 0, min, max, null, null); } public String getName() { return key; } public InternationalString getTitle() { return title; } public InternationalString getDescription() { return description; } public Class<T> getType() { return type; } public Boolean isRequired() { return required; } public int getMinOccurs() { return minOccurs; } public int getMaxOccurs() { return maxOccurs; } public T getDefaultValue() { return (T) sample; } /** * Provides for easy access to the {@link Parameter#IS_PASSWORD} metadata * @return true if {@code metadata.get(IS_PASSWORD) == Boolean.TRUE} */ public boolean isPassword(){ return metadata != null && Boolean.TRUE.equals(metadata.get(IS_PASSWORD)); } /** * Easy access to check the {@link #LEVEL} metadata * @return provided level or "user" by default */ public String getLevel(){ if( metadata == null ){ return "user"; } String level = (String) metadata.get(LEVEL); if( level == null ){ return "user"; } return level; } public String toString() { StringBuilder build = new StringBuilder(); build.append(key); if( type != Object.class ){ build.append(":"); build.append( type.getSimpleName() ); } if( !required ){ build.append("{optional}"); } if( minOccurs != 1 || maxOccurs != 1){ build.append("{"); build.append(minOccurs); build.append(":"); build.append(maxOccurs); build.append("}"); } return build.toString(); } }