Package com.onwbp.adaptation

# Class PrimaryKey

java.lang.Object
com.onwbp.adaptation.PrimaryKey

public abstract class PrimaryKey extends Object
An instance of a `PrimaryKey` uniquely identifies a record in a `table`. The composition of a primary key is defined in the data model using the element `osd:table/primaryKeys`.

A `PrimaryKey` is used to perform direct `lookups` in a table. The string that represents it internally is also used as the value of foreign keys, namely fields declared as `osd:tableRef`. However, the shortest way to look up a record from an `osd:tableRef` field is to directly invoke the method `SchemaFacetTableRef.getLinkedRecord(ValueContext)`.

External applications which access and input data containing `osd:tableRef` fields must conform to the internal syntax described below in Syntax of the internal `String` representation of primary keys.

#### Factory and conversion

Factory and conversion methods are as follows:

- to get the `PrimaryKey` of an existing record: `Adaptation.getOccurrencePrimaryKey()`;
- to create a `PrimaryKey` instance from a `ValueContext`: `AdaptationTable.computePrimaryKey(ValueContext)`;
- to create a `PrimaryKey` instance from concrete field values: `AdaptationTable.computePrimaryKey(Object[])`;
- to convert concrete field values to the internal representation string: `parseObjects(Object[], SchemaNode[])` (low-level method);
- to convert the internal representation string to a `PrimaryKey` instance: `parseString(String)`;
- to convert a `PrimaryKey` instance to the internal representation string: `format()`.
- to decompose an internal representation string to the actual primary key field(s) value(s): `SchemaNode.getTablePrimaryKeyValues(String)`.

#### Syntax of the internal `String` representation of primary keys

To simplify declaration, representation, and persistence, a primary key is handled as a `String`, even when it is composed of several fields. Note that the fields composing a primary key are returned by the method `SchemaNode.getTablePrimaryKeyNodes()`. Specifically, the string is built as follows:

1. The value of the primary key field is formatted according to the XML Schema standard, as implemented by the method `SchemaNode.formatToXsString(Object)`.
2. If the primary key is composed of several fields, field values are separated by a "|" pipe, represented by the constant `SEPARATOR_CHAR`. This may require the following "\" escapes (represented by the constant `ESCAPE_CHAR`) in a component field, in the case where its own value is not a foreign key:
   - each "|" character in the field value is escaped by a "\";
   - each "\" character in the field value is escaped by "\";

In the following examples, the first column shows a primary key value that is composed of two fields, and the second column gives its corresponding `tableRef` or `PrimaryKey` value:

Primary key field values | String representation
--- | ---
"1", "2" | "1|2"
"1", "2|3" | "1|2\|3" if the second field is not a foreign key "1|2|3" if the second field is a foreign key
"1|2", "3" | "1\|2|3" if the first field is not a foreign key "1|2|3" if the first field is a foreign key
"1\", "2" | "1\\|2"

#### Validity of the `String` representation of primary keys

If the `String` representation of a primary key is not structurally valid, an `InvalidPrimaryKeyException` is thrown. The following table gives some examples:

Key structure | String representation | Structural validity
--- | --- | ---
(xs:string) | "" (empty string) | Valid. Will look up a record with a single primary key field set to an empty string.
(xs:int) | "" (empty string) | Invalid, throws an `InvalidPrimaryKeyException`.
(xs:int) | "aa" (invalid integer) | Invalid, throws an `InvalidPrimaryKeyException`.
(xs:int | xs:string) | "aa|aaa" (invalid integer field) | Invalid, throws an `InvalidPrimaryKeyException`.
(xs:int | xs:string) | "|aaa" | Invalid, throws an `InvalidPrimaryKeyException`.
(xs:int | xs:string) | "" (empty string) | Invalid, throws an `InvalidPrimaryKeyException`.
(xs:int | xs:string) | "aaa" | Invalid, throws an `InvalidPrimaryKeyException`.

See Also:
  - `AdaptationTable.lookupAdaptationByPrimaryKey(PrimaryKey, boolean)`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final char`
  `ESCAPE_CHAR`
  Character ("\") used for escaping a pipe ("|") or backslash ("\") character if it occurs in the value of a non-foreign-key field.
  `static final String`
  `SEPARATOR`
  Single pipe character ("|") separator between two fields, when primary key is a composite of multiple fields.
  `static final char`
  `SEPARATOR_CHAR`
  Single pipe character ("|") separator between two fields, when primary key is a composite of multiple fields.
  `static final PrimaryKey`
  `VOID_KEY`
  `PrimaryKey` with an empty string as its internal representation.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final boolean`
  `equals(Object anObject)`
  Returns `true` if the specified object has the same logical content of this instance.
  `final boolean`
  `equalsToPrimaryKey(PrimaryKey aPrimaryKey)`
  Returns `true` if the specified object has the same logical content of this instance.
  `abstract String`
  `format()`
  Returns the internal `String` representation of this `PrimaryKey` instance.
  `abstract int`
  `hashCode()`
  `static PrimaryKey`
  `parseList(List aList)`
  Deprecated.
  This method does not support the use of certain characters in the elements of the specified `List`.
  `static String`
  `parseObjects(Object[] fieldsValues, SchemaNode[] fieldsNodes)`
  Returns the internal representation string that corresponds to the concrete values of a `PrimaryKey`.
  `static PrimaryKey`
  `parseString(String aTableRefValue)`
  Returns the `PrimaryKey` that corresponds to the specified internal representation `String`.
  `final String`
  `toString()`

  ### Methods inherited from class java.lang.Object

  `getClass, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### VOID_KEY

    public static final PrimaryKey VOID_KEY
    `PrimaryKey` with an empty string as its internal representation.

  - ### SEPARATOR

    public static final String SEPARATOR
    Single pipe character ("|") separator between two fields, when primary key is a composite of multiple fields.
    See Also:
      - Constant Field Values

  - ### SEPARATOR_CHAR

    public static final char SEPARATOR_CHAR
    Single pipe character ("|") separator between two fields, when primary key is a composite of multiple fields.
    See Also:
      - Constant Field Values

  - ### ESCAPE_CHAR

    public static final char ESCAPE_CHAR
    Character ("\") used for escaping a pipe ("|") or backslash ("\") character if it occurs in the value of a non-foreign-key field.
    See Also:
      - Constant Field Values

- ## Method Details

  - ### parseString

    public static PrimaryKey parseString(String aTableRefValue)
    Returns the `PrimaryKey` that corresponds to the specified internal representation `String`.

    Warning: The specified string must comply with the internal representation syntax rules. This implies that the method should generally only be used to convert the value of a "foreign key" field (a node declared as `osd:tableRef`). For a list of other available factory methods, see Factory and conversion methods.

    See Also:
      - `format()`
      - `AdaptationTable.computePrimaryKey(Object[])`
      - `AdaptationTable.computePrimaryKey(Adaptation)`
      - `AdaptationTable.computePrimaryKey(ValueContext)`

  - ### parseObjects

    public static String parseObjects(Object[] fieldsValues, SchemaNode[] fieldsNodes)
    Returns the internal representation string that corresponds to the concrete values of a `PrimaryKey`.

    Note: It is generally recommended to use one of the `AdaptationTable.computePrimaryKey` methods instead of this one.

    For more information about the internal representation syntax, see Syntax of the internal `String` representation of primary keys.

    Throws:
      `IllegalArgumentException` - if one argument is `null`, if both specified arrays do not have the same length.
      `ClassCastException` - if one value is not of the expected Java type.
    See Also:
      - `AdaptationTable.computePrimaryKey(Object[])`
      - `AdaptationTable.computePrimaryKey(Adaptation)`
      - `AdaptationTable.computePrimaryKey(ValueContext)`

  - ### parseList

    @Deprecated public static PrimaryKey parseList(List aList)
    Deprecated.
    This method does not support the use of certain characters in the elements of the specified `List`.
    See Also:
      - `AdaptationTable.computePrimaryKey(Object[])`
      - `parseObjects(Object[], SchemaNode[])`

  - ### hashCode

    public abstract int hashCode()
    Overrides:
      `hashCode` in class `Object`

  - ### equals

    public final boolean equals(Object anObject)
    Returns `true` if the specified object has the same logical content of this instance.

    Caution: this method requires that if the specified object is a `PrimaryKey`, then it has the same structure as the one of this instance.

    Overrides:
      `equals` in class `Object`

  - ### equalsToPrimaryKey

    public final boolean equalsToPrimaryKey(PrimaryKey aPrimaryKey)
    Returns `true` if the specified object has the same logical content of this instance.

    Caution: this method requires that the specified primary key has the same structure as the one of this instance.

  - ### format

    public abstract String format()
    Returns the internal `String` representation of this `PrimaryKey` instance.

    For more information about the internal representation syntax, see Syntax of the internal `String` representation of primary keys.

    From a given table node, it is possible to decompose this string to the actual primary key fields values, by invoking `SchemaNode.getTablePrimaryKeyValues(String)`.

    See Also:
      - `parseString(String)`

  - ### toString

    public final String toString()
    Overrides:
      `toString` in class `Object`