Putting a Custom UI on Naked Objects: Part 4, Business Rules

In the previous post in this series we saw how the Naked Objects metamodel uses Facets to allow arbitrary metadata to be associated to the classes, properties, collections or actions. We’ve already explored the well-defined facets that are used to capture presentation semantics and to enable interactions, but we still need to see how facets enable business rules to be captured.

As I’ve previously blogged about, Naked Objects allows three different types of business rules to be implemented. In the metamodel API there is a corresponding interface for each of these rule types, implemented by Facets:

Business rule Description API Facet implementation examples
Visibility can this user see the class member? HidingInteractionAdvisor @Hidden annotation, hideXxx() supporting methods
Usability if so, can this user use (edit, modify or invoke) the class member? DisablingInteractionAdvisor @Disabled annotation, disableXxx() supporting methods
Validity if so, can this user use (edit, modify or invoke) the class member? ValidatingInteractionAdvisor @RegEx annotation, validateXxx() supporting methods

For example, the following will install a disabling facet for the disableXxx() method, and validation facets for the (lack of an) @Optional annotation and for the @RegEx annotation:

private String name;
@MemberOrder(sequence="1")
@RegEx(validation = "[A-Z][a-z].* [A-Z][a-z].*")
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String disableName() {
    return isLocked()? "Locked": null;  // isLocked() not shown
}

When we query the metamodel for visibility or usability etc, each of the facets are checked to see if they implement the appropriate advisor interface. If they do, then they get the opportunity to veto the interaction.

It’s also possible to implement additional FacetFactorys that install Facets that implement the InteractionAdvisor interface. In an earlier post I showed an example of writing a FacetFactory. It’s worth noting is that there’s nothing in the Naked Objects Framework that assumes that these facet implementations wrap blocks of code; they could veto the interaction based on any criteria you can think of.

Ok, supposing we want to write a custom viewer and want to honour these business rules; how do we actually query the metamodel? Here’s how:

Business rule Member type(s) Description API
Visibility property, collection, action can this user see the class member? NakedObjectMember#isVisible(AuthenticationSession, NakedObject)
Usability property, collection, action can this user use the class member (or is it disabled/greyed out)? NakedObjectMember#isUsable(AuthenticationSession, NakedObject)
Validity property is the proposed value valid? OneToOneAssociation#isAssociationValid(NakedObject, NakedObject)
collection is the proposed object valid to add? OneToManyAssociation#isValidToAdd(NakedObject, NakedObject)
is the proposed object valid to remove? OneToManyAssociation#isValidToRemove(NakedObject, NakedObject)
action params is the proposed argument valid? NakedObjectActionParameter#isValid(NakedObject, Object)
action are all the proposed arguments valid? NakedObjectAction#isProposedArgumentSetValid(NakedObject, NakedObject[])

So, given a NakedObject adapter, the viewer:

  • looks up the corresponding NakedObjectSpecification
  • for each of the specification’s NakedObjectMembers:
    • check if it is visible; if not then don’t render it, otherwise (for a property or collection) obtain the current value
    • check if it is usable; if not then render the value as disabled/greyed out, otherwise render in an editable field

When an property/collection is edited or action invoked, the viewer then:

  • obtain the proposed value/argument
  • for properties/collections, check the value is valid
  • for actions, check if all arguments are valid individually, then check if the arguments are valid as a set
  • if so, perform the interaction (as described in the previous post)

That’s it for now. In the next blog post we’ll look in a little more detail on how to render the class member values.

Advertisement

Posted on December 8, 2009, in apache isis. Bookmark the permalink. 4 Comments.

  1. Hello Dan, sorry for the off-topic.

    I have bought you previous book “Better software faster”. Is it possible to get an application developed for this book – CarServe. The last time I checked, the book web site – bettersoftwarefaster.com was dead.

    Thank you,
    Danylo

    • Hi Danylo,
      Nice to hear you bought my last book. But yes, bettersoftwarefaster.com is indeed dead, as, of course, is TogetherJ (the topic of that book), in spirit if not in name.

      In fact, I use CarServ as the case study again in this book. This was born out of piece of work I did many years back with Richard Pawson (the inventor of the Naked Objects pattern) when I redid the CarServ application in a very early version of Naked Objects. He used the results of that work for his thesis, which you can view here. So it seemed like an obvious candidate to use when I wrote my own Naked Objects book.

      The scope of CarServ in the DDD/NO book isn’t quite the same as the BSF book; I only take the case study as far as is needed to explain the points I want to put across. But I hope there’s enough for everyone reading the book to see how Naked Objects can be put to work building their own applications.

      Feel free to mail me offline if you want to take the discussion further – my email is floating around the web, but dan @ this domain name will also get to me.

      Cheers
      Dan

  1. Pingback: Tweets that mention Putting a Custom UI on Naked Objects: Part 4, Business Rules | Domain Driven Design using Naked Objects -- Topsy.com

  2. Pingback: Putting a Custom UI on Naked Objects: Part 3, The MetaModel API | Domain Driven Design, Quickly

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 109 other followers