public class Collection extends Rule<Collection> implements java.io.Serializable
Api users interact with Collections and their JSON representation while Inversion abstracts the details of of the storage implementations.
Collections can remap ugly legacy column names to pretty JSON friendly camelCase names, and Collection Relationships can be used to create logical traversable foreign keys between Collections with the same underlying Db or even between Collections with different backend storage systems.
Generally it is the job of a Db to reflect on its underlying data source and automatically configure Collections and the
associated Relationships that will be accessed and manipulated by Api caller.
The Engine inspects the inbound Request path and attempts to match a Collection to the call.
The default mapping would be: /${endpointPath}/[${collection}]/[${resource}]/[${relationship}]
Querying "/${endpointPath}/${collection}" would typically result an a paginated list of resources ie. rows from your underlying Db translated into JSON speak.
Querying "/${endpointPath}/${collection}/${resource}" will fetch a single resource or row.
Querying "/${endpointPath}/${collection}/${resource}/${relationship}" will fetch all members from the relationship target Collection that are related to resource.
RestGet/Post/Put/Patch/DeleteAction are responsible for handling basic Rest semantics for interacting with Dbs via Collections.
TODO: check on test cases related to hasName and path matching TODO: need tests for resource keys with commas
Rule.RuleMatcher| Modifier and Type | Field and Description |
|---|---|
protected java.util.Set<java.lang.String> |
aliases
Additional names that should cause this Collection to match to a Request.
|
protected Db |
db
The backend storage adapter that probably generated this Collection and associated Indexes and Relationships.
|
protected boolean |
exclude
Set this to true to prevent it from being automatically exposed through your Api.
|
protected java.util.ArrayList<Index> |
indexes
Representation of underlying Db datasource indexes.
|
protected java.util.ArrayList<Property> |
properties
Properties map database column names to JSON property names.
|
protected java.util.ArrayList<Relationship> |
relationships
Relationships like resources in one collection to the resources in another collection.
|
protected java.lang.String |
tableName
The backend datasource name that this Collection operates on.
|
configMap, configStr, excludeMatchers, excludeOn, includeMatchers, includeOn, log, name, order| Constructor and Description |
|---|
Collection() |
Collection(java.lang.String defaultName) |
| Modifier and Type | Method and Description |
|---|---|
Collection |
copy()
Performs a deep clone operation via object serialization/deserialization.
|
Rows.Row |
decodeResourceKey(Index index,
java.lang.String inKey)
Decodes a resource key into its columnName / value parts.
|
Rows.Row |
decodeResourceKey(java.lang.String inKey)
Decodes a resource key into its columnName / value parts.
|
Rows |
decodeResourceKeys(Index index,
java.lang.String inKeys)
Decodes a comma separated list of encoded resource keys.
|
Rows |
decodeResourceKeys(java.lang.String inKeys) |
static java.lang.String |
decodeStr(java.lang.String string)
The reciprocal of
encodeStr(String) that replaces "\@[0-9a-f]{4}" hex sequences with the unescaped oritional unescaped character. |
static java.lang.String |
encodeResourceKey(java.util.List pieces)
Creates a "~" separated url safe concatenation of
pieces |
java.lang.String |
encodeResourceKey(java.util.Map<java.lang.String,java.lang.Object> values)
Encodes the potentially multiple values of a resources primary index into a url path safe single value.
|
static java.lang.String |
encodeResourceKey(java.util.Map values,
Index index)
Encodes the potentially multiple values of an index into a url path and query string safe single value.
|
static java.lang.String |
encodeStr(java.lang.String string)
Encodes non url safe characters into a friendly "@FOUR_DIGIT_HEX_VALUE" equivalent that itself will not be modified by URLEncoder.encode(String).
|
boolean |
equals(java.lang.Object object) |
Property |
findProperty(java.lang.String jsonOrColumnName)
Finds the property with case insensitive jsonOrColumnName.
|
java.util.Set<java.lang.String> |
getAliases() |
java.lang.String |
getColumnName(java.lang.String jsonName) |
Db |
getDb() |
protected Rule.RuleMatcher |
getDefaultIncludeMatch()
Designed to allow subclasses to provide a default match behavior
of no configuration was provided by the developer.
|
Index |
getIndex(java.lang.String indexName)
Gets an index by case insensitive name.
|
Index |
getIndexByType(java.lang.String indexType) |
java.util.ArrayList<Index> |
getIndexes() |
java.lang.String |
getName() |
Index |
getPrimaryIndex()
Finds the first unique Index with the fewest number of Properties.
|
java.util.List<Property> |
getProperties() |
Property |
getProperty(java.lang.String jsonOrColumnName)
Convenience overload of
findProperty(String). |
Property |
getPropertyByColumnName(java.lang.String columnName)
Find the property with case insensitive columnName
|
Property |
getPropertyByJsonName(java.lang.String jsonName)
Find the property with case insensitive jsonName
|
Relationship |
getRelationship(java.lang.String name) |
java.util.List<Relationship> |
getRelationships() |
java.lang.String |
getTableName() |
boolean |
hasName(java.lang.String nameOrAlias) |
boolean |
isExclude() |
boolean |
isLinkTbl()
Returns true if all columns are foreign keys.
|
static void |
main(java.lang.String[] args) |
void |
removeIndex(Index index) |
void |
removeProperty(Property prop) |
void |
removeRelationship(Relationship relationship) |
Collection |
withAliases(java.lang.String... aliases) |
Collection |
withDb(Db db) |
Collection |
withExclude(boolean exclude) |
Collection |
withIndex(java.lang.String name,
java.lang.String type,
boolean unique,
java.lang.String... propertyNames)
Fluent utility method for constructing and adding a new Index.
|
Collection |
withIndexes(Index... indexes) |
Collection |
withManyToOneRelationship(Collection parentCollection,
java.lang.String childPropertyName,
Property... childFkProps)
Fluent utility method to construct a Relationship and associated Indexes.
|
Collection |
withManyToOneRelationship(Collection parentCollection,
java.lang.String childPropertyName,
java.lang.String... childFkProps)
Fluent utility method to construct a Relationship and associated Indexes.
|
Collection |
withOneToManyRelationship(java.lang.String parentPropertyName,
Collection childCollection,
java.lang.String childPropertyName,
Property... childFkProps)
Fluent utility method to construct a Relationship and associated Indexes.
|
Collection |
withOneToManyRelationship(java.lang.String parentPropertyName,
Collection childCollection,
java.lang.String childPropertyName,
java.lang.String... childFkProps)
Fluent utility method to construct a Relationship and associated Indexes.
|
Collection |
withProperties(Property... props)
Adds the property definitions to this Collection.
|
Collection |
withProperty(java.lang.String name,
java.lang.String type)
Fluent utility method for constructing a new Property and adding it to the Collection.
|
Collection |
withProperty(java.lang.String name,
java.lang.String type,
boolean nullable)
Fluent utility method for constructing a new Property and adding it to the Collection.
|
Collection |
withRelationship(Relationship relationship)
Add a new Relationship if a Relationship with the same name does not already exist.
|
Collection |
withRelationships(Relationship... relationships) |
Collection |
withTableName(java.lang.String name) |
checkLazyConfig, compareTo, doLazyConfig, getAllExcludePaths, getAllIncludePaths, getConfig, getConfig, getConfigKeys, getExcludeMatchers, getIncludeMatchers, getOrder, match, matches, matches, toString, withConfig, withExcludeOn, withExcludeOn, withExcludeOn, withIncludeOn, withIncludeOn, withIncludeOn, withName, withOrderprotected final java.util.Set<java.lang.String> aliases
For example, in an e-commerce environment, you may overload the "orders" collection with aliases "cart", "basket", and "bag".
protected final java.util.ArrayList<Property> properties
protected final java.util.ArrayList<Index> indexes
protected final java.util.ArrayList<Relationship> relationships
protected transient Db db
protected java.lang.String tableName
The tableName might be "ORDER_DETAIL" but the Collection might be named "orderDetails".
protected boolean exclude
public Collection()
public Collection(java.lang.String defaultName)
public static java.lang.String encodeResourceKey(java.util.Map values,
Index index)
In a typical REST Api configuration where you url paths might map to something like "${endpoint}/${collection}/[${resource}][?{querystring}]", ${resource} is the primary index of the resource that has been encoded here.
That might look like "/bookstore/books/12345" or in the case of a compound primary index It might look like "/bookstore/orders/4567~abcde" where the "~" character is used to separate parts of the key.
The names of the index fields are not encoded, only the values, relying on index property order to remain consistent.
This methods is used by various actions when constructing hypermedia urls that allow you to uniquely identify individual resources (records in a Db) or to traverse Relationships.
The inverse of this method is decodeResourceKeys(Index, String) which is used to
decode inbound Url path and query params to determine which resource is being referenced.
values - column name to Property value mapping for a resourceindex - the index identifying the values that should be encodedencodeStr(String),
decodeResourceKeys(Index, String)public static java.lang.String encodeResourceKey(java.util.List pieces)
piecespieces - key parts to be encodedpieces separated by "~" charactersencodeStr(String),
encodeResourceKey(Map, Index)public static void main(java.lang.String[] args)
public static java.lang.String encodeStr(java.lang.String string)
For example, encodeing "abcd/efg" would result in "abcd@002fefg" where "@002f" is the hex encoding for "/".
While "~" characters are considered url safe, the are specifically included for encoding so that
decodeResourceKeys(Index, String) can split a value on "~" before decoding its parts.
string - the string to encodeencodeResourceKey(Map, Index),
decodeResourceKeys(Index, String),
decodeStr(String)public static java.lang.String decodeStr(java.lang.String string)
encodeStr(String) that replaces "\@[0-9a-f]{4}" hex sequences with the unescaped oritional unescaped character.string - the string to decodeencodeResourceKey(Map, Index),
decodeResourceKeys(Index, String),
encodeStr(String)protected Rule.RuleMatcher getDefaultIncludeMatch()
RulegetDefaultIncludeMatch in class Rule<Collection>Request.COLLECTION_KEY,
Request.RESOURCE_KEY,
Request.RELATIONSHIP_KEYpublic boolean isLinkTbl()
In an RDBMS system, this would indicate that the table is used to link both sides of a many-to-many relationship and it should NOT be a public REST Collection.
public Property getProperty(java.lang.String jsonOrColumnName)
findProperty(String).jsonOrColumnName - the property to getfindProperty(String)public Property findProperty(java.lang.String jsonOrColumnName)
The algo tries to find a matching json property name first before relooping over the props looking of a column name match.
jsonOrColumnName - the property to findpublic Property getPropertyByJsonName(java.lang.String jsonName)
jsonName - the name of the property to getjsonNamepublic Property getPropertyByColumnName(java.lang.String columnName)
columnName - the name of the property to getcolumnNamepublic java.lang.String getColumnName(java.lang.String jsonName)
public boolean equals(java.lang.Object object)
equals in class java.lang.Objectobject has the same Db and name as this Collectionpublic Db getDb()
public Collection withDb(Db db)
db - the db to setpublic java.lang.String getTableName()
public Collection withTableName(java.lang.String name)
name - the name to setpublic java.lang.String getName()
getName in class Rule<Collection>tableName if name is null.public java.util.List<Property> getProperties()
propertiespublic Collection withProperties(Property... props)
If there is an existing prop with a json name to json name match or a column name to column name match, the new prop will not be added as it conflicts with the existing one.
props - the properties to addpublic Collection withProperty(java.lang.String name, java.lang.String type)
name - the name of the Property to addtype - the type of the Property to addProperty.Property(String, String, boolean)public Collection withProperty(java.lang.String name, java.lang.String type, boolean nullable)
name - the name of the Property to addtype - the type of the Property to addnullable - is the Property nullableProperty.Property(String, String, boolean)public void removeProperty(Property prop)
public Index getPrimaryIndex()
Index.isUnique()public Index getIndexByType(java.lang.String indexType)
indexType - the case insensative index type identifierpublic Index getIndex(java.lang.String indexName)
indexName - the name of the Index to getpublic java.util.ArrayList<Index> getIndexes()
indexespublic Collection withIndexes(Index... indexes)
public Collection withIndex(java.lang.String name, java.lang.String type, boolean unique, java.lang.String... propertyNames)
If an Index with name exists it will be updated with the new information.
All of the Properties in propertyNames must already exist.
name - the name of the Index to create/addtype - the type of the Index to create/addunique - specifics if Index to create/add is uniquepropertyNames - the Properties that make up the indexIndex.Index(String, String, boolean, Property...)public void removeIndex(Index index)
public boolean isExclude()
public Collection withExclude(boolean exclude)
public Relationship getRelationship(java.lang.String name)
name - the name of the Relationship to getpublic java.util.List<Relationship> getRelationships()
relationships.public void removeRelationship(Relationship relationship)
public Collection withRelationships(Relationship... relationships)
relationships - the relationships to setpublic Collection withRelationship(Relationship relationship)
relationship - the Relationship to addpublic Collection withManyToOneRelationship(Collection parentCollection, java.lang.String childPropertyName, java.lang.String... childFkProps)
parentCollection - the parent collection of the relationship being createdchildPropertyName - name of the json property that will hold this relationship referencechildFkProps - names of the existing Properties that make up the foreign keywithManyToOneRelationship(Collection, String, Property...)public Collection withManyToOneRelationship(Collection parentCollection, java.lang.String childPropertyName, Property... childFkProps)
In addition to the new Relationship a new foreign key Index will be created from childFkProps
to parentCollection's primary Index.
parentCollection - the related parent CollectionchildPropertyName - what to call this relationship in the json representation of this Collection's resources.childFkProps - the Collections Properties that make up the foreign keypublic Collection withOneToManyRelationship(java.lang.String parentPropertyName, Collection childCollection, java.lang.String childPropertyName, java.lang.String... childFkProps)
This is a convenience overload of withOneToManyRelationship(String, Collection, String, Property...) to be used when code wiring Apis and you don't want to lookup references to the actual Property objects.
parentPropertyName - the name of the json property for the parent that references the childchildCollection - the target child collectionchildPropertyName - the name of hte json property for the child that references the parentchildFkProps - names of the existing Properties that make up the foreign keywithOneToManyRelationship(String, Collection, String, Property...)public Collection withOneToManyRelationship(java.lang.String parentPropertyName, Collection childCollection, java.lang.String childPropertyName, Property... childFkProps)
In addition to the new Relationship a new foreign key Index will be created from childFkProps
to this Collection's primary Index.
parentPropertyName - the name of the json property for the parent that references the childchildCollection - the target child collectionchildPropertyName - the name of hte json property for the child that references the parentchildFkProps - Properties that make up the foreign keypublic boolean hasName(java.lang.String nameOrAlias)
nameOrAlias - the name or alias to check forpublic java.util.Set<java.lang.String> getAliases()
aliasespublic Collection withAliases(java.lang.String... aliases)
public java.lang.String encodeResourceKey(java.util.Map<java.lang.String,java.lang.Object> values)
values - the key value pairs to encodeencodeResourceKey(Map, Index)public Rows.Row decodeResourceKey(java.lang.String inKey)
inKey - the resource key to decodedecodeResourceKeys(Index, String),
encodeResourceKey(Map, Index)public Rows decodeResourceKeys(java.lang.String inKeys)
public Rows.Row decodeResourceKey(Index index, java.lang.String inKey)
index - identifies the columnNames by positioninKey - the encoded string to decodedecodeResourceKeys(Index, String),
encodeResourceKey(Map, Index)public Rows decodeResourceKeys(Index index, java.lang.String inKeys)
index - identifies the columnNames to decodeinKeys - a comma separated list of encoded resource keysencodeResourceKey(Map, Index),
encodeStr(String),
decodeStr(String)public Collection copy()
It is useful when you want to manually wire up numerous copies of a collection but tweak each one a bit differently.
For example, if you were connecting to a DynamoDb or CosmosDb where a single table is overloaded to support different domain objects.
This feature requires Collection, Relationship and Index to be Serializable.
The Db reference here is transient and reconnected to the clone so that this instance and the copy reference the same Db.
Copyright © 2021 Rocket Partners, LLC. All rights reserved.