001 /*
002 * GeoAPI - Java interfaces for OGC/ISO standards
003 * http://www.geoapi.org
004 *
005 * Copyright (C) 2008-2013 Open Geospatial Consortium, Inc.
006 * All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007 *
008 * Permission to use, copy, and modify this software and its documentation, with
009 * or without modification, for any purpose and without fee or royalty is hereby
010 * granted, provided that you include the following on ALL copies of the software
011 * and documentation or portions thereof, including modifications, that you make:
012 *
013 * 1. The full text of this NOTICE in a location viewable to users of the
014 * redistributed or derivative work.
015 * 2. Notice of any changes or modifications to the OGC files, including the
016 * date changes were made.
017 *
018 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019 * NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020 * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021 * THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023 *
024 * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025 * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026 *
027 * The name and trademarks of copyright holders may NOT be used in advertising or
028 * publicity pertaining to the software without specific, written prior permission.
029 * Title to copyright in this software and any associated documentation will at all
030 * times remain with copyright holders.
031 */
032 package org.opengis.test.referencing;
033
034 import java.util.Set;
035 import java.util.List;
036
037 import org.opengis.parameter.*;
038 import org.opengis.test.ValidatorContainer;
039 import static org.opengis.test.Assert.*;
040
041
042 /**
043 * Validates {@link ParameterValue} and related objects from the {@code org.opengis.parameter}
044 * package.
045 *
046 * <p>This class is provided for users wanting to override the validation methods. When the default
047 * behavior is sufficient, the {@link org.opengis.test.Validators} static methods provide a more
048 * convenient way to validate various kinds of objects.</p>
049 *
050 * @author Martin Desruisseaux (Geomatys)
051 * @version 3.1
052 * @since 2.2
053 */
054 public class ParameterValidator extends ReferencingValidator {
055 /**
056 * Creates a new validator instance.
057 *
058 * @param container The set of validators to use for validating other kinds of objects
059 * (see {@linkplain #container field javadoc}).
060 */
061 public ParameterValidator(final ValidatorContainer container) {
062 super(container, "org.opengis.parameter");
063 }
064
065 /**
066 * For each interface implemented by the given object, invokes the corresponding
067 * {@code validate(...)} method defined in this class (if any).
068 *
069 * @param object The object to dispatch to {@code validate(...)} methods, or {@code null}.
070 * @return Number of {@code validate(...)} methods invoked in this class for the given object.
071 */
072 public int dispatch(final GeneralParameterDescriptor object) {
073 int n = 0;
074 if (object != null) {
075 if (object instanceof ParameterDescriptor<?>) {validate((ParameterDescriptor<?>) object); n++;}
076 if (object instanceof ParameterDescriptorGroup) {validate((ParameterDescriptorGroup) object); n++;}
077 if (n == 0) {
078 validateIdentifiedObject(object);
079 }
080 }
081 return n;
082 }
083
084 /**
085 * For each interface implemented by the given object, invokes the corresponding
086 * {@code validate(...)} method defined in this class (if any).
087 *
088 * @param object The object to dispatch to {@code validate(...)} methods, or {@code null}.
089 * @return Number of {@code validate(...)} methods invoked in this class for the given object.
090 */
091 public int dispatch(final GeneralParameterValue object) {
092 int n = 0;
093 if (object != null) {
094 if (object instanceof ParameterValue<?>) {validate((ParameterValue<?>) object); n++;}
095 if (object instanceof ParameterValueGroup) {validate((ParameterValueGroup) object); n++;}
096 if (n == 0) {
097 dispatch(object.getDescriptor());
098 }
099 }
100 return n;
101 }
102
103 /**
104 * Validates the given descriptor.
105 *
106 * @param <T> The class of parameter values.
107 * @param object The object to validate, or {@code null}.
108 */
109 public <T> void validate(final ParameterDescriptor<T> object) {
110 if (object == null) {
111 return;
112 }
113 validateIdentifiedObject(object);
114 final Class<T> valueClass = object.getValueClass();
115 mandatory("ParameterDescriptor: getValueClass() can not return null.", valueClass);
116 Set<T> validValues = object.getValidValues();
117 if (validValues != null) {
118 validate(validValues);
119 for (final T value : validValues) {
120 if (value != null) {
121 assertInstanceOf("ParameterDescriptor: getValidValues() has unexpected element.", valueClass, value);
122 }
123 }
124 }
125 final Comparable<T> min = object.getMinimumValue();
126 if (min != null) {
127 assertInstanceOf("ParameterDescriptor: getMinimumValue() returns unexpected value.", valueClass, min);
128 }
129 final Comparable<T> max = object.getMaximumValue();
130 if (max != null) {
131 assertInstanceOf("ParameterDescriptor: getMaximumValue() returns unexpected value.", valueClass, max);
132 }
133 assertValidRange("ParameterDescriptor: inconsistent minimum and maximum values.", min, max);
134 final T def = object.getDefaultValue();
135 if (def != null) {
136 assertInstanceOf("ParameterDescriptor: getDefaultValue() returns unexpected value.", valueClass, def);
137 assertBetween("ParameterDescriptor: getDefaultValue() out of range.", min, max, def);
138 }
139 assertBetween("ParameterDescriptor: getMinimumOccurs() shall returns 0 or 1.", 0, 1, object.getMinimumOccurs());
140 assertEquals("ParameterDescriptor: getMaximumOccurs() shall returns exactly 1.", 1, object.getMaximumOccurs());
141 }
142
143 /**
144 * Validates the given descriptor.
145 *
146 * @param object The object to validate, or {@code null}.
147 */
148 public void validate(final ParameterDescriptorGroup object) {
149 if (object == null) {
150 return;
151 }
152 validateIdentifiedObject(object);
153 final List<GeneralParameterDescriptor> descriptors = object.descriptors();
154 if (requireMandatoryAttributes) {
155 // Do not invoke mandatory(...) because we allow empty collections.
156 assertNotNull("ParameterDescriptorGroup: descriptors() should not return null.", descriptors);
157 }
158 if (descriptors != null) {
159 validate(descriptors);
160 for (final GeneralParameterDescriptor descriptor : descriptors) {
161 assertNotNull("ParameterDescriptorGroup: descriptors() can not contain null element.", descriptor);
162 dispatch(descriptor);
163 final GeneralParameterDescriptor byName = object.descriptor(descriptor.getName().getCode());
164 mandatory("ParameterDescriptorGroup: descriptor(String) should returns a value.", byName);
165 if (byName != null) {
166 assertEquals("ParameterDescriptorGroup: descriptor(String) inconsistent with descriptors().",
167 descriptor, byName);
168 }
169 }
170 }
171 final int minOccurs = object.getMinimumOccurs();
172 assertPositive("ParameterDescriptor: getMinimumOccurs() can not be negative.", minOccurs);
173 assertValidRange("ParameterDescriptor: getMaximumOccurs() gives inconsistent range.",
174 minOccurs, object.getMaximumOccurs());
175 }
176
177 /**
178 * Validates the given parameter value.
179 *
180 * @param <T> The class of parameter values.
181 * @param object The object to validate, or {@code null}.
182 */
183 public <T> void validate(final ParameterValue<T> object) {
184 if (object == null) {
185 return;
186 }
187 final ParameterDescriptor<T> descriptor = object.getDescriptor();
188 mandatory("ParameterValue: must have a descriptor.", descriptor);
189 validate(descriptor);
190 final T value = object.getValue();
191 if (value != null) {
192 if (descriptor != null) {
193 final Class<T> valueClass = descriptor.getValueClass();
194 assertInstanceOf("ParameterValue: getValue() returns unexpected value.", valueClass, value);
195 final Set<T> validValues = descriptor.getValidValues();
196 if (validValues != null) {
197 validate(validValues);
198 assertContains("ParameterValue: getValue() not a member of getValidValues() set.",
199 validValues, value);
200 }
201 assertBetween("ParameterValue: getValue() is out of bounds.",
202 descriptor.getMinimumValue(), descriptor.getMaximumValue(), value);
203 }
204 }
205 }
206
207 /**
208 * Validates the given coordinate system.
209 *
210 * @param object The object to validate, or {@code null}.
211 */
212 public void validate(final ParameterValueGroup object) {
213 if (object == null) {
214 return;
215 }
216 final ParameterDescriptorGroup descriptors = object.getDescriptor();
217 mandatory("ParameterValueGroup: must have a descriptor.", descriptors);
218 validate(descriptors);
219 final List<GeneralParameterValue> values = object.values();
220 if (requireMandatoryAttributes) {
221 // Do not invoke mandatory(...) because we allow empty collections.
222 assertNotNull("ParameterValueGroup: values() should not return null.", values);
223 }
224 if (values == null) {
225 return;
226 }
227 validate(values);
228 for (final GeneralParameterValue value : values) {
229 assertNotNull("ParameterValueGroup: values() can not contain null element.", value);
230 dispatch(value);
231 final GeneralParameterDescriptor descriptor = value.getDescriptor();
232 mandatory("GeneralParameterValue: expected a descriptor.", descriptor);
233 if (descriptor == null) {
234 continue;
235 }
236 final String name = descriptor.getName().getCode();
237 mandatory("GeneralParameterDescriptor: expected a name.", name);
238 if (name == null) {
239 continue;
240 }
241 if (descriptors != null) {
242 final GeneralParameterDescriptor byName = descriptors.descriptor(name);
243 mandatory("ParameterDescriptorGroup: should never return null.", byName);
244 if (byName != null) {
245 assertEquals("ParameterValueGroup: descriptor(String) inconsistent" +
246 " with value.getDescriptor().", descriptor, byName);
247 }
248 }
249 if (value instanceof ParameterValue<?>) {
250 final ParameterValue<?> byName = object.parameter(name);
251 mandatory("ParameterValueGroup: parameter(String) should returns a value.", byName);
252 if (byName != null) {
253 assertEquals("ParameterValueGroup: value(String) inconsistent with values().", value, byName);
254 }
255 }
256 }
257 }
258 }