Emmanuel Bernard commented on Bug OGM-208

Here is my next rev on options. I tried to make it more type-safe for the read API and simplify it at the same time.

Iteration number 2

By merging the notion of `Option` and `OptionValueTupple` in a single element and using the Option class
as identifier for the option, we simplify the number of classes and make it more type safe when using it.
Options would then be identified by their class and possibly their unique identifier.

Note that we end up using classes instead of interfaces for the design. Is that a bad thing?

// Provided by Hibernate OGM
    public abstract class Option<Type extends Option<Type,Identifier>, Identifier> {
        private Class<Type> type;
        public Option(Class<Type> type) { this.type = type; }
        public abstract Identifier getOptionIdentifier();
        public Class<Type> getOptionType() { return type; }
        public boolean equals(Object that) { 
            //equals based on getOptionIdentifier() and getOptionType()
        }
        public int hashCode() {
            //same as equals
        }
    }

    // Provided by Hibernate OGM
    /**
     * Specialized class used by options that defined only once.
     * Most options should subclass this class
     */
    public abstract class UniqueOption<Type extends UniqueOption<Type>>
            extends Option<Type,Object> {
        private static Object IDENTITY = new Object();
        public UniqueOption(Class<Type> type) { super(type); }
        public Object getOptionIdentifier() { return IDENTITY; }
    }
    
    // Some examples
    // Simple unique option
    public class Quorum extends UniqueOption<Quorum> {
        public Quorum(int read, int write) { 
            super(Quorum.class);
            this.read = read;
            this.write = write;
        }

        public void getRead(int read) { this.read = read; }
        private int read;
        public void getWrite(int write) { this.write = write; }
        private int write;
    }
    
    // multiple options
    public class NamedQuery extends Option<NamedQuery, String> {
        public NamedQuery(String name, String hql) {
            super(NamedQuery.class);
            this.name = name;
            this.hql = hql;
        }
        public String getOptionIdentifier() { return name; }
        public String getName() { return name; }
        private String name;
        public String getHql() { return hql; }
        private String hql;
    }

    //Usage in GridDialect
    // getOption is only for unique options
    Quorum quorum = context.inGlobalContext().getOption( Quorum );
    // for multiple options, use getOptions
    Map<String, NamedQuery> queries =
        context.inEntityContext().getOptions(NamedQuery.class);
    //The next line does not compile as NamedQuery is not a UniqueOption
    //NamedQuery query = context.inEntityContext().getOption(NamedQuery.class);

    //API of getOption(s)
    public <O extends UniqueOption<O>> O getOption(Class<O> optionType);
    public <I,O extends Option<O,I>> Map<I,O> getOptions(Class<O> optionType);
        //TODO should it be a map, or is a `Set` sufficient?

Please let me know if I'm mad

This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators.
For more information on JIRA, see: http://www.atlassian.com/software/jira