Module org.apache.sis.feature
Package org.apache.sis.feature.builder

# Class FeatureTypeBuilder

Object
TypeBuilder
FeatureTypeBuilder

All Implemented Interfaces:
  `Localized`

public class FeatureTypeBuilder extends TypeBuilder
Helper class for the creation of `FeatureType` instances. This builder can create the arguments to be given to the feature type constructor from simpler parameters given to this builder. The main methods provided in this class are:

- Various `setName(...)` methods for specifying the feature type name (mandatory).
- Methods for optionally setting designation, definition or description texts, or the deprecation status.
- Methods for optionally specifying the feature type hierarchy: its super types and whether the feature type is abstract.
- Convenience methods for setting the name space and the default multiplicity of properties to be added to the feature type.
- Methods for adding an attribute, an association or an operation.
- Method for listing the previously added properties.
- A `build()` method for creating the `FeatureType` instance from all previous information.

The following example creates a city named "Utopia" by default:

    FeatureTypeBuilder builder;

    // Create a feature type for a city, which contains a name and a population.
    builder = new FeatureTypeBuilder() .setName("City");
    builder.addAttribute(String.class) .setName("name").setDefaultValue("Utopia");
    builder.addAttribute(Integer.class).setName("population");
    FeatureType city = builder.build();

A call to `System​.out​.println(city)` prints the following table:

       City
       ┌────────────┬─────────┬──────────────┬───────────────┐
       │ Name       │ Type    │ Multiplicity │ Default value │
       ├────────────┼─────────┼──────────────┼───────────────┤
       │ name       │ String  │   [1 … 1]    │ Utopia        │
       │ population │ Integer │   [1 … 1]    │               │
       └────────────┴─────────┴──────────────┴───────────────┘

`FeatureTypeBuilder` instances should be short lived. After the `FeatureType` has been created, the builder should be discarded.

Since:
  0.8
See Also:
  - `ParameterBuilder`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `FeatureTypeBuilder()`
  Creates a new builder instance using the default name factory.
  `FeatureTypeBuilder(DefaultFeatureType template)`
  Creates a new builder instance using the given feature type as a template.
  `FeatureTypeBuilder(NameFactory factory, GeometryLibrary library, Locale locale)`
  Creates a new builder instance using the given name factory, geometry library and locale for formatting error messages.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `AssociationRoleBuilder`
  `addAssociation(DefaultAssociationRole template)`
  Creates a new `FeatureAssociationRole` builder initialized to the same characteristics than the given template.
  `AssociationRoleBuilder`
  `addAssociation(DefaultFeatureType type)`
  Creates a new `FeatureAssociationRole` builder for features of the given type.
  `AssociationRoleBuilder`
  `addAssociation(GenericName type)`
  Creates a new `FeatureAssociationRole` builder for features of a type of the given name.
  `<V> AttributeTypeBuilder<V>`
  `addAttribute(Class<V> valueClass)`
  Creates a new `AttributeType` builder for values of the given class.
  `<V> AttributeTypeBuilder<V>`
  `addAttribute(DefaultAttributeType<V> template)`
  Creates a new `AttributeType` builder initialized to the same characteristics than the given template.
  `AttributeTypeBuilder<?>`
  `addAttribute(GeometryType type)`
  Creates a new attribute for geometries of the given type.
  `PropertyTypeBuilder`
  `addProperty(AbstractIdentifiedType template)`
  Adds the given property in the feature type properties.
  `DefaultFeatureType`
  `build()`
  Builds the feature type from the information and properties specified to this builder.
  `FeatureTypeBuilder`
  `clear()`
  Clears all setting in this builder.
  `CharSequence`
  `getNameSpace()`
  Returns the namespace of the names created by `setName(CharSequence...)` method calls.
  `PropertyTypeBuilder`
  `getProperty(String name)`
  Returns the builder for the property of the given name.
  `DefaultFeatureType[]`
  `getSuperTypes()`
  Returns the direct parents of the feature type to create.
  `boolean`
  `isAbstract()`
  Returns `true` if the feature type to create will act as an abstract super-type.
  `boolean`
  `isNameUsed(String name)`
  Returns `true` if a property of the given name is defined or if the given name is ambiguous.
  `List<PropertyTypeBuilder>`
  `properties()`
  Returns a view of all attributes and associations added to the `FeatureType` to build.
  `FeatureTypeBuilder`
  `setAbstract(boolean isAbstract)`
  Sets whether the feature type to create will be abstract.
  `FeatureTypeBuilder`
  `setAll(DefaultFeatureType template)`
  Sets all properties of this builder to the values of the given feature type.
  `FeatureTypeBuilder`
  `setDefaultMultiplicity(int minimumOccurs, int maximumOccurs)`
  Sets the default minimum and maximum number of next attributes and associations to add.
  `FeatureTypeBuilder`
  `setDefinition(CharSequence definition)`
  Sets a concise definition of the element.
  `FeatureTypeBuilder`
  `setDeprecated(boolean deprecated)`
  Sets whether the type is deprecated.
  `FeatureTypeBuilder`
  `setDescription(CharSequence description)`
  Sets optional information beyond that required for concise definition of the element.
  `FeatureTypeBuilder`
  `setDesignation(CharSequence designation)`
  Sets a natural language designator for the element.
  `FeatureTypeBuilder`
  `setIdentifierDelimiters(String delimiter, String prefix, String suffix)`
  Sets the prefix, suffix and delimiter to use when formatting a compound identifier made of two or more attributes.
  `FeatureTypeBuilder`
  `setName(CharSequence localPart)`
  Sets the `FeatureType` name as a simple string.
  `FeatureTypeBuilder`
  `setName(CharSequence... components)`
  Sets the `FeatureType` name as a string in the given scope.
  `FeatureTypeBuilder`
  `setName(GenericName name)`
  Sets the `FeatureType` name as a generic name.
  `FeatureTypeBuilder`
  `setNameSpace(CharSequence ns)`
  Sets the namespace of the next names to be created by `setName(CharSequence...)` method calls.
  `FeatureTypeBuilder`
  `setSuperTypes(DefaultFeatureType... parents)`
  Sets the parent types (or super-type) from which to inherit properties.

  ### Methods inherited from class TypeBuilder

  `getDefinition, getDescription, getDesignation, getLocale, getName, isDeprecated, toString`

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### FeatureTypeBuilder

    public FeatureTypeBuilder()
    Creates a new builder instance using the default name factory.

  - ### FeatureTypeBuilder

    public FeatureTypeBuilder(DefaultFeatureType template)
    Creates a new builder instance using the given feature type as a template. This constructor initializes the list of properties, the super types and `isAbstract` flag to values inferred from the given template. The properties list will contain properties declared explicitly in the given template, not including properties inherited from super types.
    Warning: The `template` argument type will be changed to `FeatureType` if and when such interface will be defined in GeoAPI.
    Parameters:
      `template` - an existing feature type to use as a template, or `null` if none.

  - ### FeatureTypeBuilder

    public FeatureTypeBuilder(NameFactory factory, GeometryLibrary library, Locale locale)
    Creates a new builder instance using the given name factory, geometry library and locale for formatting error messages.
    Parameters:
      `factory` - the factory to use for creating names, or `null` for the default factory.
      `library` - the library to use for creating geometric objects, or `null` for the default.
      `locale` - the locale to use for formatting error messages, or `null` for the default locale.

- ## Method Details

  - ### clear

    public FeatureTypeBuilder clear()
    Clears all setting in this builder. After invoking this method, this `FeatureTypeBuilder` is in same state that after it has been constructed. This method can be invoked for reusing the same builder for creating other `FeatureType` instances after `build()` invocation.
    Returns:
      `this` for allowing method calls chaining.

  - ### setAll

    public FeatureTypeBuilder setAll(DefaultFeatureType template)
    Sets all properties of this builder to the values of the given feature type. This builder is cleared before the properties of the given type are copied. The copy is performed as documented in the constructor.
    Warning: The `template` argument type will be changed to `FeatureType` if and when such interface will be defined in GeoAPI.
    Parameters:
      `template` - an existing feature type to use as a template, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.

  - ### isAbstract

    public boolean isAbstract()
    Returns `true` if the feature type to create will act as an abstract super-type. Abstract types cannot be instantiated.
    Returns:
      `true` if the feature type to create will act as an abstract super-type.
    See Also:
      - `DefaultFeatureType​.isAbstract()`

  - ### setAbstract

    public FeatureTypeBuilder setAbstract(boolean isAbstract)
    Sets whether the feature type to create will be abstract. If this method is not invoked, then the default value is `false`.
    Parameters:
      `isAbstract` - whether the feature type will be abstract.
    Returns:
      `this` for allowing method calls chaining.

  - ### getSuperTypes

    public DefaultFeatureType[] getSuperTypes()
    Returns the direct parents of the feature type to create.
    Warning: The return type will be changed to `FeatureType[]` if and when such interface will be defined in GeoAPI.
    Returns:
      the parents of the feature type to create, or an empty array if none.
    See Also:
      - `DefaultFeatureType​.getSuperTypes()`

  - ### setSuperTypes

    public FeatureTypeBuilder setSuperTypes(DefaultFeatureType... parents)
    Sets the parent types (or super-type) from which to inherit properties. If this method is not invoked, then the default value is no parent.
    Warning: The `parents` argument type will be changed to `FeatureType...` if and when such interface will be defined in GeoAPI.
    Parameters:
      `parents` - the parent types from which to inherit properties, or an empty array if none. Null elements are ignored.
    Returns:
      `this` for allowing method calls chaining.

  - ### getNameSpace

    public CharSequence getNameSpace()
    Returns the namespace of the names created by `setName(CharSequence...)` method calls. A `null` value means that the names are in the global namespace.
    Returns:
      the namespace to use when `setName(CharSequence)` is invoked, or `null` if none.

  - ### setNameSpace

    public FeatureTypeBuilder setNameSpace(CharSequence ns)
    Sets the namespace of the next names to be created by `setName(CharSequence...)` method calls. This method applies only to the next calls to `setName(CharSequence)` or `setName(CharSequence...)` methods; the result of all previous calls stay unmodified. Example:

        FeatureTypeBuilder builder = new FeatureTypeBuilder().setNameSpace("MyNameSpace").setName("City");
        FeatureType city = builder.build();

        System.out.println(city.getName());                              // Prints "City"
        System.out.println(city.getName().toFullyQualifiedName());       // Prints "MyNameSpace:City"

    There is different conventions about the use of name spaces. ISO 19109 suggests that the namespace of all `AttributeType` names is the name of the enclosing `FeatureType`, but this is not mandatory. Users who want to apply this convention can invoke `setNameSpace(featureName)` after `FeatureTypeBuilder​.setName(featureName)` but before `AttributeTypeBuilder​.setName(attributeName)`.
    Parameters:
      `ns` - the new namespace, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.

  - ### setName

    public FeatureTypeBuilder setName(GenericName name)
    Sets the `FeatureType` name as a generic name. If another name was defined before this method call, that previous value will be discarded.

    #### Note for subclasses

    All `setName(…)` convenience methods in this builder delegate to this method. Consequently, this method can be used as a central place where to control the creation of all names.
    Overrides:
      `setName` in class `TypeBuilder`
    Parameters:
      `name` - the generic name (cannot be `null`).
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getName()`
      - `TypeBuilder​.setName(CharSequence)`
      - `AbstractIdentifiedType​.NAME_KEY`

  - ### setName

    public FeatureTypeBuilder setName(CharSequence localPart)
    Sets the `FeatureType` name as a simple string. The namespace will be the value specified by the last call to `setNameSpace(CharSequence)`, but that namespace will not be visible in the string representation unless the fully qualified name is requested.

    This convenience method creates a `LocalName` instance from the given `CharSequence`, then delegates to `setName(GenericName)`.

    Overrides:
      `setName` in class `TypeBuilder`
    Parameters:
      `localPart` - the local part of the generic name as a `String` or `InternationalString`.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getName()`
      - `TypeBuilder​.setName(CharSequence...)`
      - `getNameSpace()`

  - ### setName

    public FeatureTypeBuilder setName(CharSequence... components)
    Sets the `FeatureType` name as a string in the given scope. The `components` array must contain at least one element. In addition to the path specified by the `components` array, the name may also contain a namespace specified by the last call to `setNameSpace(CharSequence)`. But contrarily to the specified components, the namespace will not be visible in the name string representation unless the fully qualified name is requested.

    This convenience method creates a `LocalName` or `ScopedName` instance depending on whether the `names` array contains exactly 1 element or more than 1 element, then delegates to `setName(GenericName)`.

    Overrides:
      `setName` in class `TypeBuilder`
    Parameters:
      `components` - the name components as an array of `String` or `InternationalString` instances.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getName()`
      - `TypeBuilder​.setName(CharSequence)`
      - `getNameSpace()`

  - ### setDefaultMultiplicity

    public FeatureTypeBuilder setDefaultMultiplicity(int minimumOccurs, int maximumOccurs)
    Sets the default minimum and maximum number of next attributes and associations to add. Those defaults will applied to newly created attributes or associations, for example in next calls to `addAttribute(Class)`. Attributes and associations added before this method call are not modified.

    If this method is not invoked, then the default multiplicity is [1 … 1].

    Parameters:
      `minimumOccurs` - new default minimum number of property values.
      `maximumOccurs` - new default maximum number of property values.
    Returns:
      `this` for allowing method calls chaining.
    Since:
      1.0
    See Also:
      - `PropertyTypeBuilder​.setMinimumOccurs(int)`
      - `PropertyTypeBuilder​.setMaximumOccurs(int)`

  - ### setIdentifierDelimiters

    public FeatureTypeBuilder setIdentifierDelimiters(String delimiter, String prefix, String suffix)
    Sets the prefix, suffix and delimiter to use when formatting a compound identifier made of two or more attributes. The delimiter will be used only if at least two attributes have the identifier component role.

    If this method is not invoked, then the default values are the `":"` delimiter and no prefix or suffix.

    Parameters:
      `delimiter` - the characters to use as delimiter between each single property value.
      `prefix` - characters to use at the beginning of the concatenated string, or `null` if none.
      `suffix` - characters to use at the end of the concatenated string, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `AttributeRole​.IDENTIFIER_COMPONENT`

  - ### properties

    public List<PropertyTypeBuilder> properties()
    Returns a view of all attributes and associations added to the `FeatureType` to build. This list contains only properties declared explicitly to this builder; it does not include properties inherited from super-types. The returned list is live: changes in this builder are reflected in that list and conversely. However, the returned list allows only remove operations; new attributes or associations can be added only by calls to one of the `addAttribute(…)` or `addAssociation(…)` methods. Removal operations never affect the super-types.
    Returns:
      a live list over the properties declared to this builder.
    See Also:
      - `getProperty(String)`
      - `addAttribute(Class)`
      - `addAttribute(DefaultAttributeType)`
      - `addAssociation(DefaultFeatureType)`
      - `addAssociation(GenericName)`
      - `addAssociation(DefaultAssociationRole)`

  - ### isNameUsed

    public boolean isNameUsed(String name)
    Returns `true` if a property of the given name is defined or if the given name is ambiguous. Invoking this method is equivalent to testing if `getProperty(name) != null` except that this method does not throw exception if the given name is ambiguous.
    Parameters:
      `name` - the name to test.
    Returns:
      `true` if the given name is used by another property or is ambiguous.
    Since:
      1.0

  - ### getProperty

    public PropertyTypeBuilder getProperty(String name)
    Returns the builder for the property of the given name. The given name does not need to contains all elements of a `ScopedName`; it is okay to specify only the tip (for example `"myName"` instead of `"myScope:myName"`) provided that ignoring the name head does not create ambiguity.
    Parameters:
      `name` - name of the property to search.
    Returns:
      property of the given name, or `null` if none.
    Throws:
      `IllegalArgumentException` - if the given name is ambiguous.

  - ### addAttribute

    public <V> AttributeTypeBuilder<V> addAttribute(Class<V> valueClass)
    Creates a new `AttributeType` builder for values of the given class. The default attribute name is the name of the given type, but callers should invoke one of the `AttributeTypeBuilder​.setName(…)` methods on the returned instance with a better name.

    #### Usage example

        builder.addAttribute(String.class).setName("City").setDefaultValue("Metropolis");

    The value class cannot be `Feature​.class` since features shall be handled as associations instead of attributes.
    Type Parameters:
      `V` - the compile-time value of `valueClass` argument.
    Parameters:
      `valueClass` - the class of attribute values (cannot be `Feature​.class`).
    Returns:
      a builder for an `AttributeType`.
    See Also:
      - `properties()`

  - ### addAttribute

    public <V> AttributeTypeBuilder<V> addAttribute(DefaultAttributeType<V> template)
    Creates a new `AttributeType` builder initialized to the same characteristics than the given template. If the new attribute duplicates an existing one (for example if the same template is used many times), caller should use the returned builder for modifying some attributes.
    Warning: The `template` argument type will be changed to `AttributeType` if and when such interface will be defined in GeoAPI.
    Type Parameters:
      `V` - the compile-time type of values in the `template` argument.
    Parameters:
      `template` - an existing attribute type to use as a template.
    Returns:
      a builder for an `AttributeType`, initialized with the values of the given template.
    See Also:
      - `properties()`

  - ### addAttribute

    public AttributeTypeBuilder<?> addAttribute(GeometryType type)
    Creates a new attribute for geometries of the given type. This method delegates to `addAttribute(Class)` with a `valueClass` argument inferred from the combination of the `GeometryType` argument given to this method with the `GeometryLibrary` argument given at builder creation time. The geometry type can be:
    - `GeometryType​.POINT` for `Point` or `Point2D` type.
    - `GeometryType​.LINEAR` for `Polyline` or `LineString` type.
    - `GeometryType​.AREAL` for `Polygon` type.
    Geometric objects outside the above list can still be used by declaring their type explicitly. However, in this case there is no isolation level between the geometry types and the library that implement them.

    #### Example

    The following code creates an attribute named "MyPoint" with values of class `Point2D` if the library in use is Java2D. The Coordinate Reference System (CRS) uses (longitude, latitude) axes on the WGS 84 datum. Finally that new attribute is declared the feature default geometry:

        builder.addAttribute(GeometryType.POINT).setName("MyPoint")
               .setCRS(CommonCRS.WGS84.normalizedGeographic())
               .addRole(AttributeRole.DEFAULT_GEOMETRY);

    If the library in use is JTS or ESRI instead of Java2D, then the `Point` class of those libraries will be used instead of `Point2D`. The fully-qualified class names are given in the `GeometryLibrary` javadoc.
    Parameters:
      `type` - kind of geometric object (point, polyline or polygon).
    Returns:
      a builder for an `AttributeType`.

  - ### addAssociation

    public AssociationRoleBuilder addAssociation(DefaultFeatureType type)
    Creates a new `FeatureAssociationRole` builder for features of the given type. The default association name is the name of the given type, but callers should invoke one of the `AssociationRoleBuilder​.setName(…)` methods on the returned instance with a better name.
    Warning: The `type` argument type will be changed to `FeatureType` if and when such interface will be defined in GeoAPI.
    Parameters:
      `type` - the type of feature values.
    Returns:
      a builder for a `FeatureAssociationRole`.
    See Also:
      - `properties()`

  - ### addAssociation

    public AssociationRoleBuilder addAssociation(GenericName type)
    Creates a new `FeatureAssociationRole` builder for features of a type of the given name. This method can be invoked as an alternative to `addAssociation(FeatureType)` when the `FeatureType` instance is not yet available because of cyclic dependency.
    Parameters:
      `type` - the name of the type of feature values.
    Returns:
      a builder for a `FeatureAssociationRole`.
    See Also:
      - `properties()`

  - ### addAssociation

    public AssociationRoleBuilder addAssociation(DefaultAssociationRole template)
    Creates a new `FeatureAssociationRole` builder initialized to the same characteristics than the given template. If the new association duplicates an existing one (for example if the same template is used many times), caller should use the returned builder for modifying some associations.
    Warning: The `template` argument type will be changed to `FeatureAssociationRole` if and when such interface will be defined in GeoAPI.
    Parameters:
      `template` - an existing feature association to use as a template.
    Returns:
      a builder for an `FeatureAssociationRole`, initialized with the values of the given template.
    See Also:
      - `properties()`

  - ### addProperty

    public PropertyTypeBuilder addProperty(AbstractIdentifiedType template)
    Adds the given property in the feature type properties. The given property shall be an instance of one of the following types:
    - `AttributeType`, in which case this method delegate to `addAttribute(AttributeType)`.
    - `FeatureAssociationRole`, in which case this method delegate to `addAssociation(FeatureAssociationRole)`.
    - `Operation`, in which case the given operation object will be added verbatim in the `FeatureType`; this builder does not create new operations.
    This method does not verify if the given property duplicates an existing property. If the same template is used many times, then the caller should use the returned builder for modifying some properties.
    Warning: In a future SIS version, the argument type may be changed to the `org​.opengis​.feature​.PropertyType` interface. This change is pending GeoAPI revision.
    Parameters:
      `template` - the property to add to the feature type.
    Returns:
      a builder initialized to the given template. In the `Operation` case, the builder is a read-only accessor on the operation properties.
    See Also:
      - `properties()`
      - `getProperty(String)`

  - ### setDefinition

    public FeatureTypeBuilder setDefinition(CharSequence definition)
    Sets a concise definition of the element.
    Overrides:
      `setDefinition` in class `TypeBuilder`
    Parameters:
      `definition` - a concise definition of the element, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getDefinition()`
      - `AbstractIdentifiedType​.DEFINITION_KEY`

  - ### setDesignation

    public FeatureTypeBuilder setDesignation(CharSequence designation)
    Sets a natural language designator for the element. This can be used as an alternative to the name in user interfaces.
    Overrides:
      `setDesignation` in class `TypeBuilder`
    Parameters:
      `designation` - a natural language designator for the element, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getDesignation()`
      - `AbstractIdentifiedType​.DESIGNATION_KEY`

  - ### setDescription

    public FeatureTypeBuilder setDescription(CharSequence description)
    Sets optional information beyond that required for concise definition of the element. The description may assist in understanding the feature scope and application. If the type is deprecated, then the description should give indication about the replacement (e.g. "superceded by …").
    Overrides:
      `setDescription` in class `TypeBuilder`
    Parameters:
      `description` - information beyond that required for concise definition of the element, or `null` if none.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.getDescription()`
      - `AbstractIdentifiedType​.DESCRIPTION_KEY`

  - ### setDeprecated

    public FeatureTypeBuilder setDeprecated(boolean deprecated)
    Sets whether the type is deprecated. If the type is deprecated, then the description should be set to an indication about the replacement (e.g. "superceded by …").
    Overrides:
      `setDeprecated` in class `TypeBuilder`
    Parameters:
      `deprecated` - whether this type is deprecated.
    Returns:
      `this` for allowing method calls chaining.
    See Also:
      - `TypeBuilder​.isDeprecated()`
      - `AbstractIdentifiedType​.DEPRECATED_KEY`

  - ### build

    public DefaultFeatureType build() throws IllegalStateException
    Builds the feature type from the information and properties specified to this builder. One of the `setName(…)` methods must have been invoked before this `build()` method (mandatory). All other methods are optional, but some calls to a `add` method are usually needed.
    Warning: In a future SIS version, the return type may be changed to the `org​.opengis​.feature​.FeatureType` interface. This change is pending GeoAPI revision.

    If a feature type has already been built and this builder state has not changed since the feature type creation, then the previously created `FeatureType` instance is returned.

    Specified by:
      `build` in class `TypeBuilder`
    Returns:
      the feature type.
    Throws:
      `IllegalStateException` - if the builder contains inconsistent information.
    See Also:
      - `clear()`