You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@isis.apache.org by Dan Haywood <da...@haywood-associates.co.uk> on 2013/08/23 19:40:26 UTC

Conditional choices and defaults

Folks,
just to let you know of a new (rather overdue) feature that I've just
committed [1], which is the ability to set up conditional choices and also
defaults.

Examples are:
- category/subcategory... where the subcategory depends on the parent
category, or
- country/state ... where the state depends on the country.

You can see an example of the first in Isis ToDo app [2], eg:

public ToDoItem updateCategory(
            final ToDoItem item,
            final @Named("Category") Category category,
            final @Named("Subcategory") Subcategory subcategory) {
        item.setCategory(category);
        item.setSubcategory(subcategory);
        return item;
    }

    public Category default1UpdateCategory(
            final ToDoItem item) {
        return item.getCategory();
    }
    public Subcategory default2UpdateCategory(
            final ToDoItem item) {
        return item.getSubcategory();
    }

    public List<Subcategory> choices2UpdateCategory(
            final ToDoItem item, final Category category) {
        return Subcategory.listFor(category);
    }


Note how the choices method now takes parameters; it can therefore see the
current value of the category.

Similarly, you can see an example fo the second in Estatio [3], eg:

    public CommunicationChannelOwner newPostal(
            final @Named("Owner") CommunicationChannelOwner owner,
            final @Named("Type") CommunicationChannelType type,
            final Country country,
            final State state,
            final @Named("Address Line 1") String address1,
            final @Named("Address Line 2") @Optional String address2,
            final @Named("Postal Code") String postalCode,
            final @Named("City") String city) {
        communicationChannels.newPostal(owner, type, address1, address2,
postalCode, city, state, country);
        return owner;
    }
    ...
    public CommunicationChannelType default1NewPostal() {
        return choices1NewPostal().get(0);
    }
    public Country default2NewPostal() {
        return countries.allCountries().get(0);
    }
    public List<State> choices3NewPostal(
            final CommunicationChannelOwner owner,
            final CommunicationChannelType type,
            final Country country) {
        return states.findStatesByCountry(country);
    }
    public State default3NewPostal() {
        return states.findStatesByCountry(default2NewPostal()).get(0);
    }

Here the type is an entity.

~~~
When I was doing the checkin, I realized that I haven't implemented
validation checking.  So I've descoped it.  It isn't actually an issue if
you have choices, because it isn't possible to enter any other value
anyway.  But in the more general case I can see this might be needed.  If
anyone discovers a need, raise a new ticket.

Cheers
Dan


[1] https://issues.apache.org/jira/browse/ISIS-478
[2]
https://github.com/apache/isis/blob/52bc369a0906a900fbbddf3cd7ae610d75b987a3/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItemContributions.java#L166
[3]
https://github.com/estatio/estatio/blob/3bb6e8d1a80b512a5fadf6a0f6268405a81cbbe8/dom/src/main/java/org/estatio/dom/communicationchannel/CommunicationChannelContributedActions.java#L71

Re: Conditional choices and defaults

Posted by GESCONSULTOR - Óscar Bou <o....@gesconsultor.com>.
Sure.

I have the following class definition, including an action:

public class ConsequencesByDimensionAndCriteria extends AbstractMatrix {

   ...
    // {{ AssignVulnerabilityMatrixElement (action)
    @MemberOrder(sequence = "1")
    public ConsequencesByDimensionAndCriteriaElement assignImpact_Qualitative(@Named("Valuation Dimension") final ValuationDimension valuationDimension, @Named("Impact Criterion") final ImpactCriterion impactCriterion, @Named("Impact Level") final ImpactLevel impactLevel,
            @Named("Description - Justification") @Optional final String description) {
   ...
  }

   public Collection<ValuationDimension> choices0AssignImpact_Qualitative() {
        return this.getValuationDimensionsSet().getValuationDimensions();
    }

   ... 

}


If I invoke the action over a wrapped instance of the previous class, i.e. from a BDD Glue:

wrap(consequencesByDimensionAndCriteria). assignImpact_Qualitative(valuationDimension, impactCriterion,  impactLevel, description);


I could pass an invalid "valuationDimension" (i.e., one that is not returned by the "choices0AssignImpact_Qualitative" method) and it would be accepted.

So the behavior of a "wrapped" object does not respect the business roles, and also does not correspond to the one in the Wicket viewer. The wrapped object does not validate the input value.


I consider that as a "bug", as it's not the expected behavior.


But the point is that if we always "force" that validation for each "wrapped" invocation, perhaps each time the "choices0AssignImpact_Qualitative" should be executed and that can be a costly operation (perhaps cannot be "cached" by DN). In order to avoid that cost,  I was thinking about a new  "@ValidationScope({ALWAYS, VIEWER,OBJECTSTORE})", which allows to specify when that validation is performed:
- ALWAYS: Default value. Each time the action is invoked, the validation must be performed.
- VIEWER - or INBOUND: When "passing" the object from an adapter to the Domain (i.e., when serializing from the Viewer, before executing the action).
- OBJECTSTORE - or OUTBOUND: When "passing" the object from the Domain to an adapter (i.e., before persisting to the ObjectStore).


I'm not sure if that's clear enough...

Thanks,

Oscar



El 24/08/2013, a las 18:17, Dan Haywood <da...@haywood-associates.co.uk> escribió:

> Could you spell out the idea with a code example, perhaps?
> 
> Dan
> 
> Sorry to be brief, sent from my phone
> On 24 Aug 2013 14:47, "GESCONSULTOR - Óscar Bou" <o....@gesconsultor.com>
> wrote:
> 
>> Really nice feature, Dan.
>> 
>> There are a lot of use cases out there (including in our domain) that will
>> benefit from it.
>> 
>> While executing a BDD tests, I noticed that the "business rule" that
>> requires to only being able to select one of the possible choices was not
>> forced for "wrapped" objects, so I understand that it's only currently
>> forced by viewers.
>> 
>> So it's possible to assign to a wrapped action a param value that is not
>> on the choices. I only achieved to force that by means of a "validateXXX"
>> method, whose implementation included to verify that the param's value was
>> on the Collection returned by the "choicesXXX" method.
>> 
>> As the choices and auto-complete param validations can be "computationally
>> expensive" (requires querying the database and validating that the value is
>> included on the returned resultset), and the same can happen to other
>> business rules validations, it could be considered to create a new
>> annotation named similar to "@ValidationScope({DOMAIN, VIEWER,
>> OBJECTSTORE})".
>> 
>> What do you think?
>> 
>> Thanks,
>> 
>> Oscar
>> 
>> 
>> 
>> 
>> 
>> El 23/08/2013, a las 19:40, Dan Haywood <da...@haywood-associates.co.uk>
>> escribió:
>> 
>>> Folks,
>>> just to let you know of a new (rather overdue) feature that I've just
>>> committed [1], which is the ability to set up conditional choices and
>> also
>>> defaults.
>>> 
>>> Examples are:
>>> - category/subcategory... where the subcategory depends on the parent
>>> category, or
>>> - country/state ... where the state depends on the country.
>>> 
>>> You can see an example of the first in Isis ToDo app [2], eg:
>>> 
>>> public ToDoItem updateCategory(
>>>           final ToDoItem item,
>>>           final @Named("Category") Category category,
>>>           final @Named("Subcategory") Subcategory subcategory) {
>>>       item.setCategory(category);
>>>       item.setSubcategory(subcategory);
>>>       return item;
>>>   }
>>> 
>>>   public Category default1UpdateCategory(
>>>           final ToDoItem item) {
>>>       return item.getCategory();
>>>   }
>>>   public Subcategory default2UpdateCategory(
>>>           final ToDoItem item) {
>>>       return item.getSubcategory();
>>>   }
>>> 
>>>   public List<Subcategory> choices2UpdateCategory(
>>>           final ToDoItem item, final Category category) {
>>>       return Subcategory.listFor(category);
>>>   }
>>> 
>>> 
>>> Note how the choices method now takes parameters; it can therefore see
>> the
>>> current value of the category.
>>> 
>>> Similarly, you can see an example fo the second in Estatio [3], eg:
>>> 
>>>   public CommunicationChannelOwner newPostal(
>>>           final @Named("Owner") CommunicationChannelOwner owner,
>>>           final @Named("Type") CommunicationChannelType type,
>>>           final Country country,
>>>           final State state,
>>>           final @Named("Address Line 1") String address1,
>>>           final @Named("Address Line 2") @Optional String address2,
>>>           final @Named("Postal Code") String postalCode,
>>>           final @Named("City") String city) {
>>>       communicationChannels.newPostal(owner, type, address1, address2,
>>> postalCode, city, state, country);
>>>       return owner;
>>>   }
>>>   ...
>>>   public CommunicationChannelType default1NewPostal() {
>>>       return choices1NewPostal().get(0);
>>>   }
>>>   public Country default2NewPostal() {
>>>       return countries.allCountries().get(0);
>>>   }
>>>   public List<State> choices3NewPostal(
>>>           final CommunicationChannelOwner owner,
>>>           final CommunicationChannelType type,
>>>           final Country country) {
>>>       return states.findStatesByCountry(country);
>>>   }
>>>   public State default3NewPostal() {
>>>       return states.findStatesByCountry(default2NewPostal()).get(0);
>>>   }
>>> 
>>> Here the type is an entity.
>>> 
>>> ~~~
>>> When I was doing the checkin, I realized that I haven't implemented
>>> validation checking.  So I've descoped it.  It isn't actually an issue if
>>> you have choices, because it isn't possible to enter any other value
>>> anyway.  But in the more general case I can see this might be needed.  If
>>> anyone discovers a need, raise a new ticket.
>>> 
>>> Cheers
>>> Dan
>>> 
>>> 
>>> [1] https://issues.apache.org/jira/browse/ISIS-478
>>> [2]
>>> 
>> https://github.com/apache/isis/blob/52bc369a0906a900fbbddf3cd7ae610d75b987a3/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItemContributions.java#L166
>>> [3]
>>> 
>> https://github.com/estatio/estatio/blob/3bb6e8d1a80b512a5fadf6a0f6268405a81cbbe8/dom/src/main/java/org/estatio/dom/communicationchannel/CommunicationChannelContributedActions.java#L71
>> 
>> 


Re: Conditional choices and defaults

Posted by Dan Haywood <da...@haywood-associates.co.uk>.
Could you spell out the idea with a code example, perhaps?

Dan

Sorry to be brief, sent from my phone
On 24 Aug 2013 14:47, "GESCONSULTOR - Óscar Bou" <o....@gesconsultor.com>
wrote:

> Really nice feature, Dan.
>
> There are a lot of use cases out there (including in our domain) that will
> benefit from it.
>
> While executing a BDD tests, I noticed that the "business rule" that
> requires to only being able to select one of the possible choices was not
> forced for "wrapped" objects, so I understand that it's only currently
> forced by viewers.
>
> So it's possible to assign to a wrapped action a param value that is not
> on the choices. I only achieved to force that by means of a "validateXXX"
> method, whose implementation included to verify that the param's value was
> on the Collection returned by the "choicesXXX" method.
>
> As the choices and auto-complete param validations can be "computationally
> expensive" (requires querying the database and validating that the value is
> included on the returned resultset), and the same can happen to other
> business rules validations, it could be considered to create a new
> annotation named similar to "@ValidationScope({DOMAIN, VIEWER,
> OBJECTSTORE})".
>
> What do you think?
>
> Thanks,
>
> Oscar
>
>
>
>
>
> El 23/08/2013, a las 19:40, Dan Haywood <da...@haywood-associates.co.uk>
> escribió:
>
> > Folks,
> > just to let you know of a new (rather overdue) feature that I've just
> > committed [1], which is the ability to set up conditional choices and
> also
> > defaults.
> >
> > Examples are:
> > - category/subcategory... where the subcategory depends on the parent
> > category, or
> > - country/state ... where the state depends on the country.
> >
> > You can see an example of the first in Isis ToDo app [2], eg:
> >
> > public ToDoItem updateCategory(
> >            final ToDoItem item,
> >            final @Named("Category") Category category,
> >            final @Named("Subcategory") Subcategory subcategory) {
> >        item.setCategory(category);
> >        item.setSubcategory(subcategory);
> >        return item;
> >    }
> >
> >    public Category default1UpdateCategory(
> >            final ToDoItem item) {
> >        return item.getCategory();
> >    }
> >    public Subcategory default2UpdateCategory(
> >            final ToDoItem item) {
> >        return item.getSubcategory();
> >    }
> >
> >    public List<Subcategory> choices2UpdateCategory(
> >            final ToDoItem item, final Category category) {
> >        return Subcategory.listFor(category);
> >    }
> >
> >
> > Note how the choices method now takes parameters; it can therefore see
> the
> > current value of the category.
> >
> > Similarly, you can see an example fo the second in Estatio [3], eg:
> >
> >    public CommunicationChannelOwner newPostal(
> >            final @Named("Owner") CommunicationChannelOwner owner,
> >            final @Named("Type") CommunicationChannelType type,
> >            final Country country,
> >            final State state,
> >            final @Named("Address Line 1") String address1,
> >            final @Named("Address Line 2") @Optional String address2,
> >            final @Named("Postal Code") String postalCode,
> >            final @Named("City") String city) {
> >        communicationChannels.newPostal(owner, type, address1, address2,
> > postalCode, city, state, country);
> >        return owner;
> >    }
> >    ...
> >    public CommunicationChannelType default1NewPostal() {
> >        return choices1NewPostal().get(0);
> >    }
> >    public Country default2NewPostal() {
> >        return countries.allCountries().get(0);
> >    }
> >    public List<State> choices3NewPostal(
> >            final CommunicationChannelOwner owner,
> >            final CommunicationChannelType type,
> >            final Country country) {
> >        return states.findStatesByCountry(country);
> >    }
> >    public State default3NewPostal() {
> >        return states.findStatesByCountry(default2NewPostal()).get(0);
> >    }
> >
> > Here the type is an entity.
> >
> > ~~~
> > When I was doing the checkin, I realized that I haven't implemented
> > validation checking.  So I've descoped it.  It isn't actually an issue if
> > you have choices, because it isn't possible to enter any other value
> > anyway.  But in the more general case I can see this might be needed.  If
> > anyone discovers a need, raise a new ticket.
> >
> > Cheers
> > Dan
> >
> >
> > [1] https://issues.apache.org/jira/browse/ISIS-478
> > [2]
> >
> https://github.com/apache/isis/blob/52bc369a0906a900fbbddf3cd7ae610d75b987a3/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItemContributions.java#L166
> > [3]
> >
> https://github.com/estatio/estatio/blob/3bb6e8d1a80b512a5fadf6a0f6268405a81cbbe8/dom/src/main/java/org/estatio/dom/communicationchannel/CommunicationChannelContributedActions.java#L71
>
>

Re: Conditional choices and defaults

Posted by GESCONSULTOR - Óscar Bou <o....@gesconsultor.com>.
Really nice feature, Dan.

There are a lot of use cases out there (including in our domain) that will benefit from it.

While executing a BDD tests, I noticed that the "business rule" that requires to only being able to select one of the possible choices was not forced for "wrapped" objects, so I understand that it's only currently forced by viewers.

So it's possible to assign to a wrapped action a param value that is not on the choices. I only achieved to force that by means of a "validateXXX" method, whose implementation included to verify that the param's value was on the Collection returned by the "choicesXXX" method.

As the choices and auto-complete param validations can be "computationally expensive" (requires querying the database and validating that the value is included on the returned resultset), and the same can happen to other business rules validations, it could be considered to create a new annotation named similar to "@ValidationScope({DOMAIN, VIEWER, OBJECTSTORE})".

What do you think?

Thanks,

Oscar





El 23/08/2013, a las 19:40, Dan Haywood <da...@haywood-associates.co.uk> escribió:

> Folks,
> just to let you know of a new (rather overdue) feature that I've just
> committed [1], which is the ability to set up conditional choices and also
> defaults.
> 
> Examples are:
> - category/subcategory... where the subcategory depends on the parent
> category, or
> - country/state ... where the state depends on the country.
> 
> You can see an example of the first in Isis ToDo app [2], eg:
> 
> public ToDoItem updateCategory(
>            final ToDoItem item,
>            final @Named("Category") Category category,
>            final @Named("Subcategory") Subcategory subcategory) {
>        item.setCategory(category);
>        item.setSubcategory(subcategory);
>        return item;
>    }
> 
>    public Category default1UpdateCategory(
>            final ToDoItem item) {
>        return item.getCategory();
>    }
>    public Subcategory default2UpdateCategory(
>            final ToDoItem item) {
>        return item.getSubcategory();
>    }
> 
>    public List<Subcategory> choices2UpdateCategory(
>            final ToDoItem item, final Category category) {
>        return Subcategory.listFor(category);
>    }
> 
> 
> Note how the choices method now takes parameters; it can therefore see the
> current value of the category.
> 
> Similarly, you can see an example fo the second in Estatio [3], eg:
> 
>    public CommunicationChannelOwner newPostal(
>            final @Named("Owner") CommunicationChannelOwner owner,
>            final @Named("Type") CommunicationChannelType type,
>            final Country country,
>            final State state,
>            final @Named("Address Line 1") String address1,
>            final @Named("Address Line 2") @Optional String address2,
>            final @Named("Postal Code") String postalCode,
>            final @Named("City") String city) {
>        communicationChannels.newPostal(owner, type, address1, address2,
> postalCode, city, state, country);
>        return owner;
>    }
>    ...
>    public CommunicationChannelType default1NewPostal() {
>        return choices1NewPostal().get(0);
>    }
>    public Country default2NewPostal() {
>        return countries.allCountries().get(0);
>    }
>    public List<State> choices3NewPostal(
>            final CommunicationChannelOwner owner,
>            final CommunicationChannelType type,
>            final Country country) {
>        return states.findStatesByCountry(country);
>    }
>    public State default3NewPostal() {
>        return states.findStatesByCountry(default2NewPostal()).get(0);
>    }
> 
> Here the type is an entity.
> 
> ~~~
> When I was doing the checkin, I realized that I haven't implemented
> validation checking.  So I've descoped it.  It isn't actually an issue if
> you have choices, because it isn't possible to enter any other value
> anyway.  But in the more general case I can see this might be needed.  If
> anyone discovers a need, raise a new ticket.
> 
> Cheers
> Dan
> 
> 
> [1] https://issues.apache.org/jira/browse/ISIS-478
> [2]
> https://github.com/apache/isis/blob/52bc369a0906a900fbbddf3cd7ae610d75b987a3/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItemContributions.java#L166
> [3]
> https://github.com/estatio/estatio/blob/3bb6e8d1a80b512a5fadf6a0f6268405a81cbbe8/dom/src/main/java/org/estatio/dom/communicationchannel/CommunicationChannelContributedActions.java#L71


Re: Conditional choices and defaults

Posted by GESCONSULTOR - Óscar Bou <o....@gesconsultor.com>.
Really nice feature, Dan.

There are a lot of use cases out there (including in our domain) that will benefit from it.

While executing a BDD tests, I noticed that the "business rule" that requires to only being able to select one of the possible choices was not forced for "wrapped" objects, so I understand that it's only currently forced by viewers.

So it's possible to assign to a wrapped action a param value that is not on the choices. I only achieved to force that by means of a "validateXXX" method, whose implementation included to verify that the param's value was on the Collection returned by the "choicesXXX" method.

As the choices and auto-complete param validations can be "computationally expensive" (requires querying the database and validating that the value is included on the returned resultset), and the same can happen to other business rules validations, it could be considered to create a new annotation named similar to "@ValidationScope({DOMAIN, VIEWER, OBJECTSTORE})".

What do you think?

Thanks,

Oscar





El 23/08/2013, a las 19:40, Dan Haywood <da...@haywood-associates.co.uk> escribió:

> Folks,
> just to let you know of a new (rather overdue) feature that I've just
> committed [1], which is the ability to set up conditional choices and also
> defaults.
> 
> Examples are:
> - category/subcategory... where the subcategory depends on the parent
> category, or
> - country/state ... where the state depends on the country.
> 
> You can see an example of the first in Isis ToDo app [2], eg:
> 
> public ToDoItem updateCategory(
>            final ToDoItem item,
>            final @Named("Category") Category category,
>            final @Named("Subcategory") Subcategory subcategory) {
>        item.setCategory(category);
>        item.setSubcategory(subcategory);
>        return item;
>    }
> 
>    public Category default1UpdateCategory(
>            final ToDoItem item) {
>        return item.getCategory();
>    }
>    public Subcategory default2UpdateCategory(
>            final ToDoItem item) {
>        return item.getSubcategory();
>    }
> 
>    public List<Subcategory> choices2UpdateCategory(
>            final ToDoItem item, final Category category) {
>        return Subcategory.listFor(category);
>    }
> 
> 
> Note how the choices method now takes parameters; it can therefore see the
> current value of the category.
> 
> Similarly, you can see an example fo the second in Estatio [3], eg:
> 
>    public CommunicationChannelOwner newPostal(
>            final @Named("Owner") CommunicationChannelOwner owner,
>            final @Named("Type") CommunicationChannelType type,
>            final Country country,
>            final State state,
>            final @Named("Address Line 1") String address1,
>            final @Named("Address Line 2") @Optional String address2,
>            final @Named("Postal Code") String postalCode,
>            final @Named("City") String city) {
>        communicationChannels.newPostal(owner, type, address1, address2,
> postalCode, city, state, country);
>        return owner;
>    }
>    ...
>    public CommunicationChannelType default1NewPostal() {
>        return choices1NewPostal().get(0);
>    }
>    public Country default2NewPostal() {
>        return countries.allCountries().get(0);
>    }
>    public List<State> choices3NewPostal(
>            final CommunicationChannelOwner owner,
>            final CommunicationChannelType type,
>            final Country country) {
>        return states.findStatesByCountry(country);
>    }
>    public State default3NewPostal() {
>        return states.findStatesByCountry(default2NewPostal()).get(0);
>    }
> 
> Here the type is an entity.
> 
> ~~~
> When I was doing the checkin, I realized that I haven't implemented
> validation checking.  So I've descoped it.  It isn't actually an issue if
> you have choices, because it isn't possible to enter any other value
> anyway.  But in the more general case I can see this might be needed.  If
> anyone discovers a need, raise a new ticket.
> 
> Cheers
> Dan
> 
> 
> [1] https://issues.apache.org/jira/browse/ISIS-478
> [2]
> https://github.com/apache/isis/blob/52bc369a0906a900fbbddf3cd7ae610d75b987a3/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItemContributions.java#L166
> [3]
> https://github.com/estatio/estatio/blob/3bb6e8d1a80b512a5fadf6a0f6268405a81cbbe8/dom/src/main/java/org/estatio/dom/communicationchannel/CommunicationChannelContributedActions.java#L71