The internal model can be type-safe or not.
We need a way to identify an option from another.
Each option needs a uniquely identifying key object.
This will tell if an option is overridden by another context
or merely duplicated by other values.
For example a named query using different names are not overlapping
but a named query with the same name is replaced by a more specific context.
/**
* Interface required to be returned by the generator classes
* It represents a tuple of the option and the value associated
*
* Option can be of any type, in particular it could be represented as
*
* - an enum value
* - a Class object in particular an annotation class object
* - a String
*
* What is important is that the Option is unique according to
* the `equals()` operation amongst the realm of possible options.
*
* Likewise, Value can be of any type.
*/
publicinterface OptionValueTuple<Option,Value> {
Option getOption();
Value getValue();
}
// most likely an anonymous class in a generator implementation
public class QuorumOptionValueTuple implements OptionValueTuple<OptionEnum,Quorum> {
privatefinalint read;
privatefinalint write;
public QuorumOptionValueTuple(int read, int write) { this.read = read; this.write = write; }
public OptionEnum getOption() { return OptionEnum.QUORUM; }
public Quorum getValue() { returnnew Quorum(read, write); }
}
//an example of possible Option identifier
publicenum OptionEnum {
QUORUM;
}
// the object model representing the QUORUM value
public class Quorum {
privatefinalint read;
privatefinalint write;
public Quorum(int read, int write) { this.read = read; this.write = write }
}
`OptionValueTuple` will be used by Hibernate OGM to collect a map of option / option value and expose that to
the `GridDialect`.
Problem, there is a notion of Option Type and a unique identifier made of option type and some other unique
identifier like in a named query. We uniquely define a named query by it's NamedQuery type and its actual name.
The Option object could be a subtype of `MultiOption`
/**
* Common interfacefor options that can receive multiple values
* like named queries.
* TODO: are generics useful?
*/
public class MultiOption<Type,Id> {
/**
* Class of option, this type can be any type but typically is an
* enum, a Class instance or a String.
*/
abstract Type getType();
/**
* Uniquely identify an option for a given type
*/
abstract Id getUniqueIdentifier();
publicboolean equals(Object that) {
//TODO implementation using getType and getUniqueIdentifier
}
publicint hashCode() {
//TODO implementation using getType and getUniqueIdentifier
}
}
/**
* Example of implementation
*/
public NamedQueryOption extends MultiOption<Class<?>,String> {
privatefinalString queryName;
public NamedQueryOption(String queryName) { this.queryName = queryName; }
Class<?> getType() { return NamedQuery.class; }
String getUniqueIdentifier() { return queryName; }
}
public class NamedQuery {
privateString name;
privateString hql;
...
}
// most likely an anonymous class in a generator implementation
public class NamedQueryOptionValueTuple implements OptionValueTuple<NamedQueryOption, NamedQuery> {
public NamedQueryOptionValueTuple(String name, String hsql) { ... }
public NamedQueryOption getOption() { returnnew NamedQueryOption(name); }
public NamedQuery getValue() { returnnew NamedQuery(name, hql);
}
We could offer the ability to filter options by option or option type to help navigate them.
Wrt overriding, an option is overridden by a closer scope. Same for an option type with the same
unique identifier.
Usage from a GridDialect
We could imagine the following usage
Quorum quorum = (Quorum) context.inGlobalContext().getOption( QUORUM );
List<NamedQuery> queries = (List<NamedQuery>) context.inEntityContext().getOptionByType(NamedQuery.class);
Observations
It seems the model is fairly verbose and I am willing to simplify it if we can. I am especially concerned
about the amount of concepts and classes the designer of an option needs to provide.
Paradoxically, there is not type-safe link between an option and its value besides the `OptionValueTuple`
which is not meant to be used by consumers of options. The `GridDialect` is force to downcast the data
which is not ideal.
I am also concerned about the fact that the set of options is quite dispersed due:
the ability to define the option (or option type) type freely
the fact that some options are specific to a given datastore provider
The design seems to need refinement but I have been working on it for some time now and need a fresh look at it.
Internal model
The internal model can be type-safe or not.
We need a way to identify an option from another.
Each option needs a uniquely identifying key object.
This will tell if an option is overridden by another context
or merely duplicated by other values.
For example a named query using different names are not overlapping
but a named query with the same name is replaced by a more specific context.
`OptionValueTuple` will be used by Hibernate OGM to collect a map of option / option value and expose that to
the `GridDialect`.
Problem, there is a notion of Option Type and a unique identifier made of option type and some other unique
identifier like in a named query. We uniquely define a named query by it's NamedQuery type and its actual name.
The Option object could be a subtype of `MultiOption`
We could offer the ability to filter options by option or option type to help navigate them.
Wrt overriding, an option is overridden by a closer scope. Same for an option type with the same
unique identifier.
Usage from a GridDialect
We could imagine the following usage
Observations
It seems the model is fairly verbose and I am willing to simplify it if we can. I am especially concerned
about the amount of concepts and classes the designer of an option needs to provide.
Paradoxically, there is not type-safe link between an option and its value besides the `OptionValueTuple`
which is not meant to be used by consumers of options. The `GridDialect` is force to downcast the data
which is not ideal.
I am also concerned about the fact that the set of options is quite dispersed due:
The design seems to need refinement but I have been working on it for some time now and need a fresh look at it.