001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * http://www.geoapi.org 004 * 005 * Copyright (C) 2008-2019 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 */ 032package org.opengis.test.referencing; 033 034import java.util.Set; 035import java.util.List; 036 037import org.opengis.parameter.*; 038import org.opengis.test.ValidatorContainer; 039import 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 */ 054public 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: shall 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: shall 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}