001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2004-2024 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.feature; 019 020import java.util.Set; 021import java.util.Collection; 022import org.opengis.annotation.UML; 023import org.opengis.annotation.Classifier; 024import org.opengis.annotation.Stereotype; 025import org.opengis.util.GenericName; 026 027import static org.opengis.annotation.Obligation.*; 028import static org.opengis.annotation.Specification.ISO_19109; 029 030 031/** 032 * Abstraction of a real-world phenomena. 033 * A {@code FeatureType} instance describes the class of all {@link Feature} instances of that type. 034 * 035 * <div class="note"><b>Analogy with Java reflection</b>: 036 * compared to the Java language, {@code FeatureType} is equivalent to {@link Class} while 037 * {@code Feature} instances are equivalent to {@link Object} instances of that class.</div> 038 * 039 * <h2>Naming</h2> 040 * The feature type {@linkplain #getName() name} is mandatory and should be unique. 041 * Names can be {@linkplain org.opengis.util.ScopedName} for avoiding name collision. 042 * 043 * <h2>Properties and inheritance</h2> 044 * Each feature type can provide descriptions for the following {@linkplain #getProperties(boolean) properties}: 045 * 046 * <ul> 047 * <li>{@linkplain AttributeType Attributes}</li> 048 * <li>{@linkplain FeatureAssociationRole Associations to other features}</li> 049 * <li>{@linkplain Operation Operations}</li> 050 * </ul> 051 * 052 * In addition, a feature type can inherit the properties of one or more other feature types. 053 * Properties defined in the sub-type can override properties of the same name defined in the 054 * {@linkplain #getSuperTypes() super-types}, provided that values of the sub-type property are 055 * assignable to the super-type property. 056 * 057 * <div class="note"><b>Analogy with Java language</b>: 058 * compared to the Java language, the above rule is similar to overriding a method with a more specific return 059 * type (a.k.a. <dfn>covariant return type</dfn>). This is also similar to Java arrays, which are implicitly 060 * <i>covariant</i> (i.e. {@code String[]} can be casted to {@code CharSequence[]}, which is safe for read 061 * operations but not for write operations — the latter may throw {@link ArrayStoreException}).</div> 062 * 063 * @author Jody Garnett (Refractions Research) 064 * @author Justin Deoliveira (The Open Planning Project) 065 * @author Martin Desruisseaux (Geomatys) 066 * @version 3.1 067 * @since 3.1 068 * 069 * @see Feature 070 */ 071@Classifier(Stereotype.METACLASS) 072@UML(identifier="FeatureType", specification=ISO_19109) 073public interface FeatureType extends IdentifiedType { 074 /** 075 * Returns the name of this feature type. 076 * For {@code FeatureType}, the name is mandatory. 077 * The feature name is often an instance of {@link org.opengis.util.TypeName}, but this is not mandatory. 078 * 079 * @return the feature type name. 080 */ 081 @Override 082 @UML(identifier="name", obligation=MANDATORY, specification=ISO_19109) 083 GenericName getName(); 084 085 /** 086 * Returns {@code true} if the feature type acts as an abstract super-type. 087 * Abstract types cannot be {@linkplain #newInstance() instantiated}. 088 * 089 * @return {@code true} if the feature type acts as an abstract super-type. 090 */ 091 @UML(identifier="isAbstract", obligation=MANDATORY, specification=ISO_19109) 092 boolean isAbstract(); 093 094 /** 095 * Returns {@code true} if this feature type contains only attributes constrained to the [1 … 1] multiplicity, 096 * or operations (no feature association). 097 * Such feature types can be handled as a {@link org.opengis.util.RecordType} instances. 098 * 099 * @return {@code true} if this feature type contains only simple attributes or operations. 100 */ 101 boolean isSimple(); 102 103 /** 104 * Returns {@code true} if and only if an attribute, operation or association role of the given name exists 105 * in this feature type or in one of its super-types. If this method returns {@code true}, then calls to 106 * <code>{@linkplain #getProperty(String) getProperty}(name)</code> will not throw 107 * {@link PropertyNotFoundException}. 108 * 109 * @param name the name of the property to search. 110 * @return whether an attribute, operation or association role exists for the given name. 111 */ 112// boolean hasProperty(String name); 113 114 /** 115 * Returns the attribute, operation or association role for the given name. 116 * 117 * @param name the name of the property to search. 118 * @return the property for the given name. 119 * @throws PropertyNotFoundException if the given argument is not a property name of this feature type. 120 * 121 * @see Feature#getProperty(String) 122 */ 123 PropertyType getProperty(String name) throws PropertyNotFoundException; 124 125 /** 126 * Returns any feature operation, any feature attribute type and any feature association role that 127 * carries characteristics of a feature type. The returned collection will include the properties 128 * inherited from the {@linkplain #getSuperTypes() super-types} only if {@code includeSuperTypes} 129 * is {@code true}. 130 * 131 * @param includeSuperTypes {@code true} for including the properties inherited from the super-types, 132 * or {@code false} for returning only the properties defined explicitly in this type. 133 * @return Feature operation, attribute type and association role that carries characteristics of this 134 * feature type (not including parent types). 135 */ 136 @UML(identifier="carrierOfCharacteristics", obligation=OPTIONAL, specification=ISO_19109) 137 Collection<? extends PropertyType> getProperties(boolean includeSuperTypes); 138 139 /** 140 * Returns the direct parents of this feature type. 141 * 142 * <div class="note"><b>Analogy with Java reflection</b>: 143 * if we compare {@code FeatureType} to {@link Class} in the Java language, then this method is equivalent 144 * to {@link Class#getSuperclass()} except that feature types allow multi-inheritance.</div> 145 * 146 * @return the parents of this feature type, or an empty set if none. 147 */ 148 @UML(identifier="superType", obligation=OPTIONAL, specification=ISO_19109) 149 Set<? extends FeatureType> getSuperTypes(); 150 151 /** 152 * Returns {@code true} if this type is same or a super-type of the given type. 153 * Implementations should ensure that the following constraints are met: 154 * 155 * <ul> 156 * <li>If <var>A</var> is assignable from <var>B</var> and <var>B</var> is assignable from <var>C</var>, 157 * then <var>A</var> is assignable from <var>C</var>.</li> 158 * </ul> 159 * 160 * <div class="note"><b>Analogy with Java reflection</b>: 161 * if we compare {@code FeatureType} to {@link Class} in the Java language, then this method is equivalent 162 * to {@link Class#isAssignableFrom(Class)}.</div> 163 * 164 * @param type the type to be checked. 165 * @return {@code true} if instances of the given type can be assigned to association of this type. 166 */ 167 boolean isAssignableFrom(FeatureType type); 168 169 /** 170 * Creates a new feature instance of this type. 171 * 172 * <div class="note"><b>Analogy with Java reflection</b>: 173 * if we compare {@code FeatureType} to {@link Class} and {@code Feature} to {@link Object} in the Java language, 174 * then this method is equivalent to {@link Class#newInstance()}.</div> 175 * 176 * @return a new feature instance. 177 * @throws FeatureInstantiationException if this feature type {@linkplain #isAbstract() is abstract} 178 * or cannot be instantiated for some other reason. 179 * @throws UnsupportedOperationException if this type does not support new instance creation. 180 */ 181 Feature newInstance() throws FeatureInstantiationException, UnsupportedOperationException; 182}