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.metadata; 033 034import java.util.Date; 035import org.opengis.metadata.*; 036import org.opengis.metadata.citation.*; 037import org.opengis.util.InternationalString; 038import org.opengis.test.ValidatorContainer; 039 040import static org.junit.Assert.*; 041 042 043/** 044 * Validates {@link Citation} and related objects from the 045 * {@code org.opengis.metadata.citation} package. 046 * 047 * <p>This class is provided for users wanting to override the validation methods. When the default 048 * behavior is sufficient, the {@link org.opengis.test.Validators} static methods provide a more 049 * convenient way to validate various kinds of objects.</p> 050 * 051 * @author Martin Desruisseaux (Geomatys) 052 * @version 3.1 053 * @since 2.2 054 */ 055public class CitationValidator extends MetadataValidator { 056 /** 057 * Creates a new validator instance. 058 * 059 * @param container the set of validators to use for validating other kinds of objects 060 * (see {@linkplain #container field javadoc}). 061 */ 062 public CitationValidator(final ValidatorContainer container) { 063 super(container, "org.opengis.metadata.citation"); 064 } 065 066 /** 067 * Validates the given citation. 068 * 069 * @param object the object to validate, or {@code null}. 070 */ 071 public void validate(final Citation object) { 072 if (object == null) { 073 return; 074 } 075 validateMandatory(object.getTitle()); 076 validateOptional (object.getEdition()); 077 for (final InternationalString e : toArray(InternationalString.class, object.getAlternateTitles())) { 078 container.validate(e); 079 } 080 for (final Identifier e : toArray(Identifier.class, object.getIdentifiers())) { 081 container.validate(e); 082 } 083 container.validate(object.getOtherCitationDetails()); 084 validate(toArray(CitationDate.class, object.getDates())); 085 for (final Responsibility e : toArray(Responsibility.class, object.getCitedResponsibleParties())) { 086 validate(e); 087 } 088 } 089 090 /** 091 * Validates citation dates. If more than one dates is given, then this method will check 092 * for the following constraints: 093 * 094 * <ul> 095 * <li>{@link DateType#CREATION} shall be before or equals to all other type of dates, ignoring user-defined codes.</li> 096 * <li>{@link DateType#LAST_UPDATE} shall be before or equals to {@link DateType#NEXT_UPDATE}.</li> 097 * <li>{@link DateType#VALIDITY_BEGINS} shall be before or equals to {@link DateType#VALIDITY_EXPIRES}.</li> 098 * </ul> 099 * 100 * Those constraints are verified in their iteration order. It is possible for example to have more than one 101 * (<var>validity begins</var>, <var>validity expires</var>) pair. 102 * 103 * @param dates the citation dates to validate. 104 * 105 * @since 3.1 106 */ 107 public void validate(final CitationDate... dates) { 108 if (dates == null) { 109 return; 110 } 111 Date creation = null; 112 Date lastUpdate = null; 113 Date validityBegins = null; 114 final int lastOrdinal = DateType.DISTRIBUTION.ordinal(); 115 for (final CitationDate date : dates) { 116 if (date != null) { 117 final DateType type = date.getDateType(); 118 final Date time = date.getDate(); 119 mandatory("CitationDate: shall have a date type.", type); 120 mandatory("CitationDate: shall have a timestamp.", time); 121 if (type != null && time != null) { 122 if (type.equals(DateType.CREATION)) { 123 creation = time; 124 } else if (type.equals(DateType.LAST_UPDATE)) { 125 lastUpdate = time; 126 } else if (type.equals(DateType.NEXT_UPDATE)) { 127 assertOrdered(DateType.LAST_UPDATE, lastUpdate, DateType.NEXT_UPDATE, time); 128 } else if (type.equals(DateType.VALIDITY_BEGINS)) { 129 validityBegins = time; 130 } else if (type.equals(DateType.VALIDITY_EXPIRES)) { 131 assertOrdered(DateType.VALIDITY_BEGINS, validityBegins, DateType.VALIDITY_EXPIRES, time); 132 } 133 if (type.ordinal() <= lastOrdinal) { 134 assertOrdered(DateType.CREATION, creation, type, time); 135 } 136 } 137 } 138 } 139 } 140 141 /** 142 * Asserts that the date {@code d2} is equals or after {@code d1}. 143 */ 144 private static void assertOrdered(final DateType t1, final Date d1, final DateType t2, final Date d2) { 145 if (d1 != null && d2.before(d1)) { 146 fail("The ‘" + t2.identifier() + "’ date (" + d2 + ") shall be equal or after " 147 + "the ‘" + t1.identifier() + "’ date (" + d1 + ")."); 148 } 149 } 150 151 /** 152 * Validates the given responsible party. 153 * 154 * @param object the object to validate, or {@code null}. 155 * 156 * @since 3.1 157 */ 158 public void validate(final Responsibility object) { 159 if (object == null) { 160 return; 161 } 162 mandatory("Responsibility: shall have a role.", object.getRole()); 163 for (final Party e : toArray(Party.class, object.getParties())) { 164 validate(e); 165 } 166 } 167 168 /** 169 * Validates the given party. 170 * 171 * @param object the object to validate, or {@code null}. 172 * 173 * @since 3.1 174 */ 175 public void validate(final Party object) { 176 if (object == null) { 177 return; 178 } 179 boolean isMandatory = true; 180 if (object instanceof Individual) { 181 isMandatory &= isNullOrEmpty(((Individual) object).getPositionName()); 182 } 183 if (object instanceof Organisation) { 184 isMandatory &= isNullOrEmpty(((Organisation) object).getLogo()); 185 } 186 if (isMandatory) { 187 mandatory("Party: shall have a name.", object.getName()); 188 } 189 for (final Contact e : toArray(Contact.class, object.getContactInfo())) { 190 validate(e); 191 } 192 } 193 194 /** 195 * Validates the given contact information. 196 * 197 * @param object the object to validate, or {@code null}. 198 * 199 * @since 3.1 200 */ 201 public void validate(final Contact object) { 202 if (object == null) { 203 return; 204 } 205 for (final Telephone e : toArray(Telephone.class, object.getPhones())) { 206 validate(e); 207 } 208 for (final Address e : toArray(Address.class, object.getAddresses())) { 209 validate(e); 210 } 211 for (final OnlineResource e : toArray(OnlineResource.class, object.getOnlineResources())) { 212 validate(e); 213 } 214 validateOptional(object.getHoursOfService()); 215 validateOptional(object.getContactInstructions()); 216 } 217 218 /** 219 * Validates the given telephone information. 220 * 221 * @param object the object to validate, or {@code null}. 222 * 223 * @since 3.1 224 */ 225 public void validate(final Telephone object) { 226 if (object == null) { 227 return; 228 } 229 mandatory("Telephone: shall have a number.", object.getNumber()); 230 } 231 232 /** 233 * Validates the given address. 234 * 235 * @param object the object to validate, or {@code null}. 236 * 237 * @since 3.1 238 */ 239 public void validate(final Address object) { 240 if (object == null) { 241 return; 242 } 243 validate(object.getDeliveryPoints()); 244 validateOptional(object.getCity()); 245 validateOptional(object.getAdministrativeArea()); 246 validateOptional(object.getCountry()); 247 validate(object.getElectronicMailAddresses()); 248 } 249 250 /** 251 * Validates the given online resource. 252 * 253 * @param object the object to validate, or {@code null}. 254 * 255 * @since 3.1 256 */ 257 public void validate(final OnlineResource object) { 258 if (object == null) { 259 return; 260 } 261 mandatory("OnlineResource: shall have a linkage.", object.getLinkage()); 262 validateOptional(object.getDescription()); 263 } 264}