001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    http://www.geoapi.org
004 *
005 *    Copyright (C) 2011-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.geoapi;
033
034import java.lang.reflect.Type;
035import java.lang.reflect.Field;
036import java.lang.reflect.Method;
037import java.lang.reflect.ParameterizedType;
038import java.lang.reflect.WildcardType;
039
040
041/**
042 * All interfaces, code lists, enumerations and exceptions declared in GeoAPI.
043 * The array of types that are members of a category is given by {@link #types()}.
044 *
045 * @author  Martin Desruisseaux (Geomatys)
046 * @version 3.1
047 * @since   3.1
048 */
049public enum Content {
050    /**
051     * All GeoAPI interfaces, in approximate dependency order.
052     * It is not possible to list the interfaces in strict dependency order because of circular dependencies.
053     * But this list nevertheless tries to provide such order in a "best effort" basis.
054     */
055    @SuppressWarnings("deprecation")
056    INTERFACES(org.opengis.util                    .InternationalString                 .class,
057               org.opengis.util                    .ControlledVocabulary                .class,
058               org.opengis.util                    .NameSpace                           .class,
059               org.opengis.util                    .GenericName                         .class,
060               org.opengis.util                    .LocalName                           .class,
061               org.opengis.util                    .ScopedName                          .class,
062               org.opengis.util                    .TypeName                            .class,
063               org.opengis.util                    .Type                                .class,
064               org.opengis.util                    .MemberName                          .class,
065               org.opengis.util                    .RecordSchema                        .class,
066               org.opengis.util                    .RecordType                          .class,
067               org.opengis.util                    .Record                              .class,
068               org.opengis.metadata.citation       .Series                              .class,
069               org.opengis.metadata.citation       .Address                             .class,
070               org.opengis.metadata.citation       .Telephone                           .class,
071               org.opengis.metadata.citation       .OnlineResource                      .class,
072               org.opengis.metadata.citation       .Contact                             .class,
073               org.opengis.metadata.citation       .Party                               .class,
074               org.opengis.metadata.citation       .Responsibility                      .class,
075               org.opengis.metadata.citation       .ResponsibleParty                    .class,
076               org.opengis.metadata.citation       .Individual                          .class,
077               org.opengis.metadata.citation       .Organisation                        .class,
078               org.opengis.metadata.citation       .CitationDate                        .class,
079               org.opengis.metadata.citation       .Citation                            .class,
080               org.opengis.metadata                .Identifier                          .class,     // Depends on Citation
081               org.opengis.referencing             .ReferenceIdentifier                 .class,
082               org.opengis.referencing             .IdentifiedObject                    .class,     // A parameter dependency.
083               org.opengis.parameter               .GeneralParameterDescriptor          .class,
084               org.opengis.parameter               .GeneralParameterValue               .class,
085               org.opengis.parameter               .ParameterDescriptor                 .class,
086               org.opengis.parameter               .ParameterValue                      .class,
087               org.opengis.parameter               .ParameterDescriptorGroup            .class,
088               org.opengis.parameter               .ParameterValueGroup                 .class,
089               org.opengis.temporal                .TemporalPrimitive                   .class,
090               org.opengis.temporal                .TemporalPosition                    .class,
091               org.opengis.temporal                .Duration                            .class,
092               org.opengis.temporal                .PeriodDuration                      .class,
093               org.opengis.metadata.extent         .GeographicExtent                    .class,
094               org.opengis.metadata.extent         .GeographicBoundingBox               .class,
095               org.opengis.metadata.extent         .GeographicDescription               .class,
096               org.opengis.metadata.extent         .BoundingPolygon                     .class,
097               org.opengis.metadata.extent         .VerticalExtent                      .class,
098               org.opengis.metadata.extent         .TemporalExtent                      .class,
099               org.opengis.metadata.extent         .SpatialTemporalExtent               .class,
100               org.opengis.metadata.extent         .Extent                              .class,
101               org.opengis.metadata.maintenance    .ScopeDescription                    .class,
102               org.opengis.metadata.maintenance    .Scope                               .class,
103               org.opengis.metadata.maintenance    .MaintenanceInformation              .class,
104               org.opengis.metadata.distribution   .Medium                              .class,
105               org.opengis.metadata.distribution   .Format                              .class,
106               org.opengis.metadata.distribution   .DataFile                            .class,
107               org.opengis.metadata.distribution   .DigitalTransferOptions              .class,
108               org.opengis.metadata.distribution   .StandardOrderProcess                .class,
109               org.opengis.metadata.distribution   .Distributor                         .class,
110               org.opengis.metadata.distribution   .Distribution                        .class,
111               org.opengis.metadata.constraint     .Releasability                       .class,
112               org.opengis.metadata.constraint     .Constraints                         .class,
113               org.opengis.metadata.constraint     .LegalConstraints                    .class,
114               org.opengis.metadata.constraint     .SecurityConstraints                 .class,
115               org.opengis.metadata.identification .BrowseGraphic                       .class,
116               org.opengis.metadata.identification .KeywordClass                        .class,
117               org.opengis.metadata.identification .Keywords                            .class,
118               org.opengis.metadata.identification .Usage                               .class,
119               org.opengis.metadata.identification .RepresentativeFraction              .class,
120               org.opengis.metadata.identification .Resolution                          .class,
121               org.opengis.metadata.identification .AssociatedResource                  .class,
122               org.opengis.metadata.identification .AggregateInformation                .class,
123               org.opengis.metadata.identification .Identification                      .class,
124               org.opengis.metadata.identification .DataIdentification                  .class,
125               org.opengis.metadata.identification .OperationMetadata                   .class,
126               org.opengis.metadata.identification .OperationChainMetadata              .class,
127               org.opengis.metadata.identification .CoupledResource                     .class,
128               org.opengis.metadata.identification .ServiceIdentification               .class,
129               org.opengis.referencing             .ReferenceSystem                     .class,     // Depends on Extent.
130               org.opengis.referencing.datum       .Datum                               .class,
131               org.opengis.referencing.cs          .CoordinateSystemAxis                .class,
132               org.opengis.referencing.cs          .CoordinateSystem                    .class,
133               org.opengis.referencing.crs         .CoordinateReferenceSystem           .class,
134               org.opengis.geometry.coordinate     .Position                            .class,
135               org.opengis.geometry                .DirectPosition                      .class,
136               org.opengis.geometry                .Envelope                            .class,
137               org.opengis.geometry                .Geometry                            .class,
138               org.opengis.geometry.primitive      .Point                               .class,
139               org.opengis.metadata.acquisition    .Instrument                          .class,
140               org.opengis.metadata.acquisition    .Platform                            .class,
141               org.opengis.metadata.acquisition    .PlatformPass                        .class,
142               org.opengis.metadata.acquisition    .Event                               .class,
143               org.opengis.metadata.acquisition    .EnvironmentalRecord                 .class,
144               org.opengis.metadata.acquisition    .Objective                           .class,
145               org.opengis.metadata.acquisition    .Operation                           .class,
146               org.opengis.metadata.acquisition    .RequestedDate                       .class,
147               org.opengis.metadata.acquisition    .Requirement                         .class,
148               org.opengis.metadata.acquisition    .Plan                                .class,
149               org.opengis.metadata.acquisition    .AcquisitionInformation              .class,
150               org.opengis.metadata.content        .RangeDimension                      .class,
151               org.opengis.metadata.content        .AttributeGroup                      .class,
152               org.opengis.metadata.content        .SampleDimension                     .class,
153               org.opengis.metadata.content        .Band                                .class,
154               org.opengis.metadata.content        .ContentInformation                  .class,
155               org.opengis.metadata.content        .RangeElementDescription             .class,
156               org.opengis.metadata.content        .CoverageDescription                 .class,
157               org.opengis.metadata.content        .ImageDescription                    .class,
158               org.opengis.metadata.content        .FeatureTypeInfo                     .class,
159               org.opengis.metadata.content        .FeatureCatalogueDescription         .class,
160               org.opengis.metadata.lineage        .NominalResolution                   .class,
161               org.opengis.metadata.lineage        .Source                              .class,
162               org.opengis.metadata.lineage        .Algorithm                           .class,
163               org.opengis.metadata.lineage        .Processing                          .class,
164               org.opengis.metadata.lineage        .ProcessStepReport                   .class,
165               org.opengis.metadata.lineage        .ProcessStep                         .class,
166               org.opengis.metadata.lineage        .Lineage                             .class,
167               org.opengis.metadata.quality        .Scope                               .class,
168               org.opengis.metadata.quality        .Result                              .class,
169               org.opengis.metadata.quality        .Element                             .class,
170               org.opengis.metadata.quality        .Usability                           .class,
171               org.opengis.metadata.quality        .PositionalAccuracy                  .class,
172               org.opengis.metadata.quality        .AbsoluteExternalPositionalAccuracy  .class,
173               org.opengis.metadata.quality        .GriddedDataPositionalAccuracy       .class,
174               org.opengis.metadata.quality        .RelativeInternalPositionalAccuracy  .class,
175               org.opengis.metadata.quality        .TemporalAccuracy                    .class,
176               org.opengis.metadata.quality        .TemporalConsistency                 .class,
177               org.opengis.metadata.quality        .TemporalValidity                    .class,
178               org.opengis.metadata.quality        .AccuracyOfATimeMeasurement          .class,
179               org.opengis.metadata.quality        .ThematicAccuracy                    .class,
180               org.opengis.metadata.quality        .ThematicClassificationCorrectness   .class,
181               org.opengis.metadata.quality        .QuantitativeAttributeAccuracy       .class,
182               org.opengis.metadata.quality        .NonQuantitativeAttributeAccuracy    .class,
183               org.opengis.metadata.quality        .LogicalConsistency                  .class,
184               org.opengis.metadata.quality        .ConceptualConsistency               .class,
185               org.opengis.metadata.quality        .DomainConsistency                   .class,
186               org.opengis.metadata.quality        .FormatConsistency                   .class,
187               org.opengis.metadata.quality        .TopologicalConsistency              .class,
188               org.opengis.metadata.quality        .Completeness                        .class,
189               org.opengis.metadata.quality        .CompletenessCommission              .class,
190               org.opengis.metadata.quality        .CompletenessOmission                .class,
191               org.opengis.metadata.quality        .ConformanceResult                   .class,
192               org.opengis.metadata.quality        .CoverageResult                      .class,
193               org.opengis.metadata.quality        .QuantitativeResult                  .class,
194               org.opengis.metadata.quality        .DataQuality                         .class,
195               org.opengis.metadata.spatial        .Dimension                           .class,
196               org.opengis.metadata.spatial        .GeolocationInformation              .class,
197               org.opengis.metadata.spatial        .GCP                                 .class,
198               org.opengis.metadata.spatial        .GCPCollection                       .class,
199               org.opengis.metadata.spatial        .GeometricObjects                    .class,
200               org.opengis.metadata.spatial        .SpatialRepresentation               .class,
201               org.opengis.metadata.spatial        .GridSpatialRepresentation           .class,
202               org.opengis.metadata.spatial        .VectorSpatialRepresentation         .class,
203               org.opengis.metadata.spatial        .Georectified                        .class,
204               org.opengis.metadata.spatial        .Georeferenceable                    .class,
205               org.opengis.metadata                .FeatureTypeList                     .class,
206               org.opengis.metadata                .ApplicationSchemaInformation        .class,
207               org.opengis.metadata                .ExtendedElementInformation          .class,
208               org.opengis.metadata                .MetadataExtensionInformation        .class,
209               org.opengis.metadata                .PortrayalCatalogueReference         .class,
210               org.opengis.metadata                .MetadataScope                       .class,
211               org.opengis.metadata                .Metadata                            .class,
212               org.opengis.referencing.datum       .Ellipsoid                           .class,
213               org.opengis.referencing.datum       .PrimeMeridian                       .class,
214               org.opengis.referencing.datum       .GeodeticDatum                       .class,
215               org.opengis.referencing.datum       .EngineeringDatum                    .class,
216               org.opengis.referencing.datum       .ImageDatum                          .class,
217               org.opengis.referencing.datum       .ParametricDatum                     .class,
218               org.opengis.referencing.datum       .TemporalDatum                       .class,
219               org.opengis.referencing.datum       .VerticalDatum                       .class,
220               org.opengis.referencing.cs          .AffineCS                            .class,
221               org.opengis.referencing.cs          .CartesianCS                         .class,
222               org.opengis.referencing.cs          .CylindricalCS                       .class,
223               org.opengis.referencing.cs          .EllipsoidalCS                       .class,
224               org.opengis.referencing.cs          .LinearCS                            .class,
225               org.opengis.referencing.cs          .ParametricCS                        .class,
226               org.opengis.referencing.cs          .PolarCS                             .class,
227               org.opengis.referencing.cs          .SphericalCS                         .class,
228               org.opengis.referencing.cs          .TimeCS                              .class,
229               org.opengis.referencing.cs          .UserDefinedCS                       .class,
230               org.opengis.referencing.cs          .VerticalCS                          .class,
231               org.opengis.referencing.crs         .SingleCRS                           .class,
232               org.opengis.referencing.crs         .CompoundCRS                         .class,
233               org.opengis.referencing.crs         .EngineeringCRS                      .class,
234               org.opengis.referencing.crs         .GeodeticCRS                         .class,
235               org.opengis.referencing.crs         .GeographicCRS                       .class,
236               org.opengis.referencing.crs         .GeocentricCRS                       .class,
237               org.opengis.referencing.crs         .ImageCRS                            .class,
238               org.opengis.referencing.crs         .ParametricCRS                       .class,
239               org.opengis.referencing.crs         .TemporalCRS                         .class,
240               org.opengis.referencing.crs         .VerticalCRS                         .class,
241               org.opengis.referencing.operation   .Formula                             .class,
242               org.opengis.referencing.operation   .OperationMethod                     .class,
243               org.opengis.referencing.operation   .Matrix                              .class,
244               org.opengis.referencing.operation   .MathTransform                       .class,
245               org.opengis.referencing.operation   .MathTransform1D                     .class,
246               org.opengis.referencing.operation   .MathTransform2D                     .class,
247               org.opengis.referencing.operation   .CoordinateOperation                 .class,
248               org.opengis.referencing.operation   .SingleOperation                     .class,
249               org.opengis.referencing.operation   .ConcatenatedOperation               .class,
250               org.opengis.referencing.operation   .Conversion                          .class,
251               org.opengis.referencing.operation   .Projection                          .class,
252               org.opengis.referencing.operation   .Transformation                      .class,
253               org.opengis.referencing.operation   .PassThroughOperation                .class,
254               org.opengis.referencing.crs         .GeneralDerivedCRS                   .class,
255               org.opengis.referencing.crs         .DerivedCRS                          .class,
256               org.opengis.referencing.crs         .ProjectedCRS                        .class,
257               org.opengis.referencing.operation   .ConicProjection                     .class,
258               org.opengis.referencing.operation   .CylindricalProjection               .class,
259               org.opengis.referencing.operation   .PlanarProjection                    .class,
260               org.opengis.feature                 .IdentifiedType                      .class,
261               org.opengis.feature                 .PropertyType                        .class,
262               org.opengis.feature                 .Property                            .class,
263               org.opengis.feature                 .AttributeType                       .class,
264               org.opengis.feature                 .Attribute                           .class,
265               org.opengis.feature                 .DynamicAttributeType                .class,
266               org.opengis.feature                 .DynamicAttribute                    .class,
267               org.opengis.feature                 .FeatureType                         .class,
268               org.opengis.feature                 .Feature                             .class,
269               org.opengis.feature                 .FeatureAssociation                  .class,
270               org.opengis.feature                 .FeatureAssociationRole              .class,
271               org.opengis.feature                 .Operation                           .class,
272               org.opengis.util                    .Factory                             .class,
273               org.opengis.util                    .NameFactory                         .class,
274               org.opengis.referencing             .ObjectFactory                       .class,
275               org.opengis.referencing             .AuthorityFactory                    .class,
276               org.opengis.referencing.datum       .DatumFactory                        .class,
277               org.opengis.referencing.datum       .DatumAuthorityFactory               .class,
278               org.opengis.referencing.cs          .CSFactory                           .class,
279               org.opengis.referencing.cs          .CSAuthorityFactory                  .class,
280               org.opengis.referencing.crs         .CRSFactory                          .class,
281               org.opengis.referencing.crs         .CRSAuthorityFactory                 .class,
282               org.opengis.referencing.operation   .MathTransformFactory                .class,
283               org.opengis.referencing.operation   .CoordinateOperationFactory          .class,
284               org.opengis.referencing.operation   .CoordinateOperationAuthorityFactory .class
285    ),
286
287    /**
288     * All code list classes.
289     */
290    @SuppressWarnings("deprecation")
291    CODE_LISTS(
292            org.opengis.metadata                .Datatype                     .class,
293            org.opengis.metadata                .Obligation                   .class,
294            org.opengis.metadata.acquisition    .Context                      .class,
295            org.opengis.metadata.acquisition    .GeometryType                 .class,
296            org.opengis.metadata.acquisition    .ObjectiveType                .class,
297            org.opengis.metadata.acquisition    .OperationType                .class,
298            org.opengis.metadata.acquisition    .Priority                     .class,
299            org.opengis.metadata.acquisition    .Sequence                     .class,
300            org.opengis.metadata.acquisition    .Trigger                      .class,
301            org.opengis.metadata.citation       .DateType                     .class,
302            org.opengis.metadata.citation       .OnLineFunction               .class,
303            org.opengis.metadata.citation       .PresentationForm             .class,
304            org.opengis.metadata.citation       .Role                         .class,
305            org.opengis.metadata.citation       .TelephoneType                .class,
306            org.opengis.metadata.constraint     .Classification               .class,
307            org.opengis.metadata.constraint     .Restriction                  .class,
308            org.opengis.metadata.content        .BandDefinition               .class,
309            org.opengis.metadata.content        .CoverageContentType          .class,
310            org.opengis.metadata.content        .ImagingCondition             .class,
311            org.opengis.metadata.content        .PolarizationOrientation      .class,
312            org.opengis.metadata.content        .TransferFunctionType         .class,
313            org.opengis.metadata.distribution   .MediumFormat                 .class,
314            org.opengis.metadata.distribution   .MediumName                   .class,
315            org.opengis.metadata.identification .AssociationType              .class,
316            org.opengis.metadata.identification .CharacterSet                 .class,
317            org.opengis.metadata.identification .CouplingType                 .class,
318            org.opengis.metadata.identification .DistributedComputingPlatform .class,
319            org.opengis.metadata.identification .InitiativeType               .class,
320            org.opengis.metadata.identification .KeywordType                  .class,
321            org.opengis.metadata.identification .Progress                     .class,
322            org.opengis.metadata.maintenance    .MaintenanceFrequency         .class,
323            org.opengis.metadata.maintenance    .ScopeCode                    .class,
324            org.opengis.metadata.quality        .EvaluationMethodType         .class,
325            org.opengis.metadata.spatial        .CellGeometry                 .class,
326            org.opengis.metadata.spatial        .DimensionNameType            .class,
327            org.opengis.metadata.spatial        .GeometricObjectType          .class,
328            org.opengis.metadata.spatial        .SpatialRepresentationType    .class,
329            org.opengis.metadata.spatial        .TopologyLevel                .class,
330            org.opengis.referencing             .ReferenceSystemType          .class,
331            org.opengis.referencing.cs          .AxisDirection                .class,
332            org.opengis.referencing.cs          .RangeMeaning                 .class,
333            org.opengis.referencing.datum       .PixelInCell                  .class,
334            org.opengis.referencing.datum       .VerticalDatumType            .class),
335
336    /**
337     * All enumeration classes.
338     */
339    ENUMERATIONS(org.opengis.metadata.identification .TopicCategory      .class,
340                 org.opengis.metadata.spatial        .PixelOrientation   .class,
341                 org.opengis.parameter               .ParameterDirection .class),
342
343    /**
344     * The union of code lists and enumerations.
345     */
346    CONTROLLED_VOCABULARY(CODE_LISTS, ENUMERATIONS),
347
348    /**
349     * All exceptions.
350     */
351    EXCEPTIONS(org.opengis.util                  .FactoryException                     .class,
352               org.opengis.util                  .NoSuchIdentifierException            .class,
353               org.opengis.referencing           .NoSuchAuthorityCodeException         .class,
354               org.opengis.referencing.operation .OperationNotFoundException           .class,
355               org.opengis.referencing.operation .TransformException                   .class,
356               org.opengis.referencing.operation .NoninvertibleTransformException      .class,
357               org.opengis.parameter             .ParameterNotFoundException           .class,
358               org.opengis.parameter             .InvalidParameterNameException        .class,
359               org.opengis.parameter             .InvalidParameterTypeException        .class,
360               org.opengis.parameter             .InvalidParameterValueException       .class,
361               org.opengis.parameter             .InvalidParameterCardinalityException .class,
362               org.opengis.geometry              .MismatchedDimensionException         .class,
363               org.opengis.feature               .MismatchedFeatureException           .class,
364               org.opengis.feature               .FeatureInstantiationException        .class,
365               org.opengis.feature               .FeatureOperationException            .class,
366               org.opengis.feature               .PropertyNotFoundException            .class,
367               org.opengis.feature               .OutOfTemporalDomainException         .class,
368               org.opengis.feature               .InvalidPropertyValueException        .class,
369               org.opengis.feature               .MultiValuedPropertyException         .class),
370
371    /**
372     * All interfaces, code lists, enumerations and exceptions.
373     */
374    ALL(CONTROLLED_VOCABULARY, INTERFACES, EXCEPTIONS);
375
376    /**
377     * All types in that are members of the category identified by this enumeration value.
378     */
379    private final Class<?>[] types;
380
381    /**
382     * Creates a new enumeration with the given members.
383     */
384    private Content(final Class<?>... types) {
385        this.types = types;
386    }
387
388    /**
389     * Creates a new enumeration as the union of existing enumerations.
390     */
391    private Content(final Content... others) {
392        int length = 0;
393        for (final Content other : others) {
394            length += other.types.length;
395        }
396        types = new Class<?>[length];
397        length = 0;
398        for (final Content other : others) {
399            final int n = other.types.length;
400            System.arraycopy(other.types, 0, types, length, n);
401            length += n;
402        }
403    }
404
405    /**
406     * Returns {@code true} if this enumeration is for enumerations, code lists, or combination of both.
407     *
408     * @return {@code true} if {@link #ENUMERATIONS}, {@link #CODE_LISTS} or {@link #CONTROLLED_VOCABULARY}.
409     */
410    public boolean isControlledVocabulary() {
411        switch (this) {
412            case ENUMERATIONS:
413            case CODE_LISTS:
414            case CONTROLLED_VOCABULARY: return true;
415            default: return false;
416        }
417    }
418
419    /**
420     * Returns all types in that are members of the category identified by this enumeration value.
421     *
422     * @return types that are members of this category.
423     */
424    public Class<?>[] types() {
425        return types.clone();
426    }
427
428    /**
429     * Returns the element type of the given field. If the field type is parameterized, then
430     * this method returns the upper bound. Otherwise this method returns the value type.
431     *
432     * @param  field  the field for which to obtain the (eventually parameterized) type.
433     * @return the property element type.
434     */
435    public static Class<?> typeOf(final Field field) {
436        Class<?> c = getActualTypeArgument(field.getGenericType());
437        if (c == null) {
438            c = field.getType();
439        }
440        return c;
441    }
442
443    /**
444     * Returns the element type of the return value or single parameter type of the given method.
445     * If the return type or the single parameter is a parameterized type, then this method returns
446     * the upper bound. Otherwise this method returns the type directly.
447     *
448     * @param  method  the method for which to obtain the (eventually parameterized) return type.
449     * @return the return element type (may be {@link Void#TYPE}).
450     */
451    public static Class<?> typeOf(final Method method) {
452        Class<?> c = getActualTypeArgument(method.getGenericReturnType());
453        if (c == null) {
454            final Type[] parameters = method.getGenericParameterTypes();
455            if (parameters != null && parameters.length == 1) {
456                c = getActualTypeArgument(parameters[0]);
457            }
458        }
459        if (c == null) {
460            c = method.getReturnType();
461        }
462        return c;
463    }
464
465    /**
466     * Returns {@link ParameterizedType#getActualTypeArguments()} as a {@link Class} or {@code null}.
467     */
468    private static Class<?> getActualTypeArgument(Type type) {
469        if (type instanceof ParameterizedType) {
470            Type[] p = ((ParameterizedType) type).getActualTypeArguments();
471            while (p.length == 1) {
472                type = p[0];
473                if (type instanceof WildcardType) {
474                    p = ((WildcardType) type).getUpperBounds();
475                } else {
476                    if (type instanceof ParameterizedType) {
477                        type = ((ParameterizedType) type).getRawType();
478                    }
479                    if (type instanceof Class<?>) {
480                        return (Class<?>) type;
481                    }
482                    break;                                      // Unknown type.
483                }
484            }
485        }
486        return null;
487    }
488}