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

Re: code-lists and administration thereof

Further to this, I've updated the kitchensink (against 1.9.0-SNAPSHOT) to
demonstrate this technique....

The code is in ReferenceObject, which you can get to from the "Data Types"
menu.  Use the fixture scripts menu to create some sample data.

The relevant code is below.

Cheers
Dan

[1]  https://github.com/isisaddons/isis-app-kitchensink


    private OtherObject someOtherObjectUsingName;

    @Property(hidden = Where.EVERYWHERE)
    @Column(allowsNull = "true")
    public OtherObject getSomeOtherObjectUsingName() {
        return someOtherObjectUsingName;
    }

    public void setSomeOtherObjectUsingName(final OtherObject
someOtherObjectUsingName) {
        this.someOtherObjectUsingName = someOtherObjectUsingName;
    }

    @NotPersistent
    public String getSomeOtherObjectUsingNameName() {
        return getSomeOtherObjectUsingName() != null?
getSomeOtherObjectUsingName().getName() : null;
    }

    public void setSomeOtherObjectUsingNameName(final String name) {
        OtherObject otherObject = name != null
                ? container.firstMatch(OtherObject.class, withName(name))
                : null;
        setSomeOtherObjectUsingName(otherObject);
    }

    public List<String> choicesSomeOtherObjectUsingNameName() {
        List<OtherObject> otherObjects =
container.allInstances(OtherObject.class);
        return Lists.newArrayList(
                Iterables.transform(otherObjects, nameOf())
        );
    }

    private static Function<OtherObject, String> nameOf() {
        return new Function<OtherObject, String>() {
            @Nullable @Override public String apply(final OtherObject input) {
                return input.getName();
            }
        };
    }

    private static Predicate<OtherObject> withName(final String name) {
        return new Predicate<OtherObject>() {
        @Override public boolean apply(final OtherObject input) {
             return Objects.equal(input.getName(), name);
            }
    };
    }





On 30 July 2015 at 13:16, Dan Haywood <da...@haywood-associates.co.uk> wrote:

> looks right to me, so I'll take a look at in this eve or tomorrow.
>
> thx
> Dan
>
>
> On 30 July 2015 at 13:12, Stephen Cameron <st...@gmail.com>
> wrote:
>
>> Still no luck with this one.
>>
>> The derived RegionName appears as a non-editable property, so not sure
>> what
>> was different before when I was getting an model validation error.
>>
>> My current code of interest is this:
>>
>>     @Column(name = "region", allowsNull = "true")
>>     //@MemberOrder(sequence = "7")
>>     @Property(hidden=Where.EVERYWHERE)
>>     public Region getRegion() {
>>         return this.region;
>>     }
>>
>>     public void setRegion(Region region) {
>>         this.region = region;
>>     }
>>
>>     public List<Region> choicesRegion() {
>>         return regions.listAllRegions();
>>     }
>>
>>     @MemberOrder(sequence = "7")
>>     public String getRegionName() {
>>         return regions.nameForRegion(getRegion());
>>     }
>>
>>     public void setRegionName(String name) {
>>         setRegion(regions.regionForName(name));
>>     }
>>
>>     public List<String> choicesRegionName(){
>>         return regions.listAllNamesExclusive(getRegion());
>>     }
>>
>> My Region class is this:
>>
>> package au.com.scds.chats.dom.modules.general.codes;
>>
>> import javax.jdo.annotations.Column;
>> import javax.jdo.annotations.IdentityType;
>> import javax.jdo.annotations.PrimaryKey;
>>
>> import org.apache.isis.applib.annotation.Action;
>> import org.apache.isis.applib.annotation.ActionLayout;
>> import org.apache.isis.applib.annotation.DomainServiceLayout;
>> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
>> import org.apache.isis.applib.annotation.MemberOrder;
>> import org.apache.isis.applib.annotation.PropertyLayout;
>>
>> @javax.jdo.annotations.PersistenceCapable(
>>          identityType=IdentityType.APPLICATION)
>> public class Region {
>>
>>     public String title(){
>>         return getName();
>>     }
>>
>>     private String name;
>>
>>     @Column(name="region", allowsNull = "false")
>>     @PrimaryKey()
>>     @PropertyLayout(named="Region")
>>     @MemberOrder(sequence="1")
>>     public String getName() {
>>         return name;
>>     }
>>
>>     public void setName(String name) {
>>         this.name = name;
>>     }
>> }
>>
>> My Regions repository class is this:
>>
>> package au.com.scds.chats.dom.modules.general.codes;
>>
>> import java.util.ArrayList;
>> import java.util.List;
>>
>> import org.apache.isis.applib.DomainObjectContainer;
>> import org.apache.isis.applib.annotation.Action;
>> import org.apache.isis.applib.annotation.ActionLayout;
>> import org.apache.isis.applib.annotation.BookmarkPolicy;
>> import org.apache.isis.applib.annotation.DomainService;
>> import org.apache.isis.applib.annotation.DomainServiceLayout;
>> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
>> import org.apache.isis.applib.annotation.MemberOrder;
>> import org.apache.isis.applib.annotation.ParameterLayout;
>> import org.apache.isis.applib.annotation.Programmatic;
>> import org.apache.isis.applib.annotation.SemanticsOf;
>> import org.apache.isis.applib.query.QueryDefault;
>>
>> import au.com.scds.chats.dom.modules.participant.Participant;
>>
>> @DomainService(repositoryFor = Region.class)
>> @DomainServiceLayout(menuBar = MenuBar.SECONDARY, named =
>> "Administration",
>> menuOrder = "100.1")
>> public class Regions {
>>
>>     // region > listAll (action)
>>     @Action(semantics = SemanticsOf.SAFE)
>>     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
>>     @MemberOrder(sequence = "1")
>>     public List<Region> listAllRegions() {
>>         return container.allInstances(Region.class);
>>     }
>>
>>     // endregion
>>
>>     // region > create (action)
>>     @MemberOrder(sequence = "2")
>>     public Region createRegion(
>>             final @ParameterLayout(named = "Region Name") String name) {
>>         final Region obj = container.newTransientInstance(Region.class);
>>         obj.setName(name);
>>         container.persistIfNotAlready(obj);
>>         return obj;
>>     }
>>
>>     // endregion
>>
>>     // region > injected services
>>
>>     @javax.inject.Inject
>>     DomainObjectContainer container;
>>
>>     // endregion
>>
>>     @Programmatic
>>     public String nameForRegion(Region region) {
>>         return (region != null) ? region.getName() : null;
>>     }
>>
>>
>>     @Programmatic
>>     public List<String> listAllNamesExclusive(Region region) {
>>         List<Region> regions = listAllRegions();
>>         List<String> names = new ArrayList<String>();
>>         for (Region r : regions) {
>>             if (region != null && r != region) {
>>                 names.add(r.getName());
>>             }
>>         }
>>         return names;
>>     }
>>
>>
>>     @Programmatic
>>     public Region regionForName(String name) {
>>         Region region = container.firstMatch(new QueryDefault<>(
>> Region.class,
>>                  "findRegion", "name", name));
>>         return region;
>>     }
>>
>> }
>>
>> Just maybe I there is something missing still?
>>
>> I added a @Property annotation to the getRegionName() method, but that
>> gave
>> me a message saying it expected @javax.jdo.persistence.Column too.
>>
>> Note I couldn't use deprecated @Hidden in Isis 1.9.0.
>>
>>
>> On Thu, Jul 30, 2015 at 8:14 PM, Stephen Cameron <
>> steve.cameron.62@gmail.com
>> > wrote:
>>
>> > Hi Dan, When I tried this I got an model validation error message
>> relating
>> > to the choices method, I will have another go and if it fails, provide
>> the
>> > test case. Thanks for the tips.
>> >
>> > On Thu, Jul 30, 2015 at 7:57 PM, Dan Haywood <
>> dan@haywood-associates.co.uk
>> > > wrote:
>> >
>> >> You should be able to add a choicesXxx() for the derived property:
>> >>
>> >>     public List<String> choicesRegionName(){
>> >>         return Lists.newArrayList(Iterables.transform(choicesRegion(),
>> x
>> >> ->
>> >> x.getName()));
>> >>     }
>> >>
>> >> If that isn't sufficient, you might also need to add a setter:
>> >>
>> >> public void setRegionName(final String name) {
>> >> setRegion(Iterables.find(choicesRegion(), x ->
>> x.getName().equals(name)));
>> >> }
>> >>
>> >> Obviously, you might need to also add some error handling.
>> >>
>> >> ~~~
>> >>
>> >> Regarding the "external URL" idea, perhaps you could raise that as a
>> >> separate ticket, with a code sketch as to how you'd like this
>> information
>> >> specified?
>> >>
>> >> Thanks
>> >> Dan
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> On 30 July 2015 at 03:17, Stephen Cameron <st...@gmail.com>
>> >> wrote:
>> >>
>> >> > Not so simple, as now the property cannot be updated.
>> >> >
>> >> > I have the following (@Hidden is deprecated)
>> >> >
>> >> >     @Column(allowsNull = "true")
>> >> >     @MemberOrder(sequence = "7")
>> >> >     @PropertyLayout(hidden=Where.EVERYWHERE)
>> >> >     public Region getRegion() {
>> >> >         return this.region;
>> >> >     }
>> >> >
>> >> >     public void setRegion(Region region) {
>> >> >         this.region = region;
>> >> >     }
>> >> >
>> >> >     public List<Region> choicesRegion(){
>> >> >         List<Region> regions = container.allInstances(Region.class);
>> >> >         return regions;
>> >> >     }
>> >> >
>> >> >     @MemberOrder(sequence = "7.1")
>> >> >     public String getRegionName(){
>> >> >         return (getRegion() != null) ? getRegion().getName() : null;
>> >> >     }
>> >> >
>> >> > Sure enough getRegion doesn't appear in the UI but getRegionName
>> does,
>> >> but
>> >> > then setRegion and choiceRegion don't mean anything to the UI, so the
>> >> > Region property is read-only.
>> >> >
>> >> > This issue is maybe more significant than it appears at first, in
>> terms
>> >> of
>> >> > domain modelling such code-lists are simple types that 'represent'
>> >> things
>> >> > on the boundary of the domain of interest. So we usually want to just
>> >> > represent them with a name. Presently it makes no sense to go to that
>> >> thing
>> >> > via a hyperlink as all we'll find is that name, our model extends no
>> >> > further.
>> >> >
>> >> > However we just might like to allow users to leave the domain model
>> and
>> >> go
>> >> > to a resource outside. So, extending the suppressLink=true idea, I
>> would
>> >> > add that each object could have an implicit link(URL),created by
>> Isis,
>> >> or
>> >> > an explicit one and if the explicit one is present it can optionally
>> be
>> >> > used as an alternative to the implicit one.
>> >> >
>> >> > For example, you might create a database to log fish details, species
>> >> is a
>> >> > boundary concept, we aren't likely to want to add a new species to
>> the
>> >> list
>> >> > of known species, but we'd like to keep such a list handy, but for
>> each
>> >> > named species in that list, to provide an explicit link to a resource
>> >> in a
>> >> > global fish database. It makes more sense to use this link than the
>> >> > implicit one, as if the implicit one is used we'd navigate to the
>> domain
>> >> > object page displaying the name and URL, both of which items of data
>> >> could
>> >> > have been in the explicit link.
>> >> >
>> >> > In the explicit case you might want to warn the user they are
>> navigating
>> >> > outside the Isis domain application.
>> >> >
>> >> > Perhaps all this could be done simply if there was a URI type in
>> Isis,
>> >> that
>> >> > would allow it to create 'smart links' automatically.
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > On Wed, Jul 29, 2015 at 9:37 PM, Stephen Cameron <
>> >> > steve.cameron.62@gmail.com
>> >> > > wrote:
>> >> >
>> >> > > Thanks Jeroen, seems simple enough :)
>> >> > >
>> >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal <
>> >> jeroen@stromboli.it
>> >> > >
>> >> > > wrote:
>> >> > >
>> >> > >> You could also hide the property and create a separate getter for
>> >> > display
>> >> > >> purposes only:
>> >> > >>
>> >> > >> private MyProperty myProperty;
>> >> > >>
>> >> > >> @Hidden
>> >> > >> public MyProperty getMyProperty() {...}
>> >> > >>
>> >> > >> public void setMyProperty(...) {...}
>> >> > >>
>> >> > >> public String getMyPropertyName() {
>> >> > >>     getMyProperty.getName();
>> >> > >> }
>> >> > >>
>> >> > >> On 29 July 2015 at 13:18, Stephen Cameron <
>> >> steve.cameron.62@gmail.com>
>> >> > >> wrote:
>> >> > >>
>> >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood <
>> >> > >> dan@haywood-associates.co.uk
>> >> > >> > >
>> >> > >> > wrote:
>> >> > >> >
>> >> > >> > > You are right, they will be displayed as links; there's no
>> way to
>> >> > >> disable
>> >> > >> > > it currently.
>> >> > >> > >
>> >> > >> > > We could add a bit of metadata perhaps for this, eg
>> >> > >> > > @DomainObjectLayout(suppressLink=true) or similar.
>> >> > >> > >
>> >> > >> > > Please raise a ticket.
>> >> > >> > >
>> >> > >> >
>> >> > >> > OK https://issues.apache.org/jira/browse/ISIS-1180
>> >> > >> >
>> >> > >> > >
>> >> > >> > > Thx
>> >> > >> > > Dan
>> >> > >> > >
>> >> > >> > > PS: these entities wouldn't be value types, rather regular
>> >> entities.
>> >> > >> But
>> >> > >> > > you are right... what we really want is full-class support for
>> >> value
>> >> > >> > types.
>> >> > >> > >   We're just not there yet...
>> >> > >> > >
>> >> > >> > >
>> >> > >> > >
>> >> > >> >
>> >> > >> > >
>> >> > >> > >
>> >> > >> > > On 29 July 2015 at 09:34, Stephen Cameron <
>> >> > steve.cameron.62@gmail.com
>> >> > >> >
>> >> > >> > > wrote:
>> >> > >> > >
>> >> > >> > > > Thanks, but surely such object properties always end up
>> being
>> >> > >> displayed
>> >> > >> > > as
>> >> > >> > > > links? Clicking on the link to go to such an object page is
>> >> > >> > meaningless,
>> >> > >> > > as
>> >> > >> > > > it only has one name property, that was displayed in the
>> link.
>> >> > Can I
>> >> > >> > > > disable that default behaviour for value types?
>> >> > >> > > >
>> >> > >> > > >
>> >> > >> > > >
>> >> > >> > > > On Wed, Jul 29, 2015 at 5:47 PM, Dan Haywood <
>> >> > >> > > dan@haywood-associates.co.uk
>> >> > >> > > > >
>> >> > >> > > > wrote:
>> >> > >> > > >
>> >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron <
>> >> > >> > steve.cameron.62@gmail.com>
>> >> > >>
>> >> > >> > > > > wrote:
>> >> > >> > > > >
>> >> > >> > > > > > Hi,
>> >> > >> > > > > >
>> >> > >> > > > > > I want to do have some properties that are essentially
>> >> String
>> >> > >> > types,
>> >> > >> > > > but
>> >> > >> > > > > > which have a limited range of values (code-lists or
>> >> restricted
>> >> > >> > > > > > vocabularies). I want to allow these lists to be
>> >> administered
>> >> > >> > > > centrally,
>> >> > >> > > > > so
>> >> > >> > > > > > to add them to a single Administration menu item for
>> admin
>> >> > >> users.
>> >> > >> > > > > >
>> >> > >> > > > > > For most users these codes should appears as lists of
>> >> strings
>> >> > >> not
>> >> > >> > as
>> >> > >> > > > > > objects, but making them objects seems to be the
>> logical OO
>> >> > way
>> >> > >> to
>> >> > >> > > deal
>> >> > >> > > > > > with them in Isis. So they are basically objects with
>> one
>> >> > 'name'
>> >> > >> > > > property
>> >> > >> > > > > > (and maybe an id added by datanucleus). All users need
>> to
>> >> see
>> >> > is
>> >> > >> > the
>> >> > >> > > > name
>> >> > >> > > > > > property, no icon is needed.
>> >> > >> > > > > >
>> >> > >> > > > > > Also, if I make them objects I also will get referencial
>> >> > >> integrity
>> >> > >> > > > > > constraints applied in the database.
>> >> > >> > > > > >
>> >> > >> > > > > >
>> >> > >> > > > > +1, do it this way.  That way they can also hold
>> behaviour in
>> >> > the
>> >> > >> > > future.
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > > > I wonder there is a simple recipe for this?
>> >> > >> > > > > >
>> >> > >> > > > >
>> >> > >> > > > > No magic recipe for the domain entities... basically
>> >> > copy-n-paste
>> >> > >> the
>> >> > >> > > > > SimpleObject that's in our archetype as many times as
>> needed,
>> >> > and
>> >> > >> > tweak
>> >> > >> > > > as
>> >> > >> > > > > required.
>> >> > >> > > > >
>> >> > >> > > > > If you want to use the code as the primary key, then use
>> DN
>> >> > >> > application
>> >> > >> > > > > identity
>> >> > >> > > > >
>> >> > >> > > > > @javax.jdo.annotations.PersistenceCapable(
>> >> > >> > > > >         identityType=IdentityType.APPLICATION,
>> >> > >> > > > >         schema = "simple",
>> >> > >> > > > >         table = "SimpleObject"
>> >> > >> > > > > )
>> >> > >> > > > >
>> >> > >> > > > > and add @PrimaryKey to the "name" property.  Also add
>> @Title
>> >> to
>> >> > >> that
>> >> > >> > > > 'name'
>> >> > >> > > > > property (it is in SimpleObject already).
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > > You would probably want to remove the version column, ie
>> >> remove:
>> >> > >> > > > >
>> >> > >> > > > > @javax.jdo.annotations.Version(
>> >> > >> > > > >         strategy=VersionStrategy.VERSION_NUMBER,
>> >> > >> > > > >         column="version")
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > > In addition, if you annotate the class as "bounded"
>> >> > >> > > > > (@DomainObject(bounded=true)) then you are telling the
>> >> framework
>> >> > >> that
>> >> > >> > > > > there's a limited - ie bounded - set of instances, and so
>> it
>> >> > will
>> >> > >> > > display
>> >> > >> > > > > all instances in a drop-down for you.
>> >> > >> > > > >
>> >> > >> > > > >
>> >> > >> > > > > HTH
>> >> > >> > > > > Dan
>> >> > >> > > > >
>> >> > >> > > >
>> >> > >> > >
>> >> > >> >
>> >> > >>
>> >> > >
>> >> > >
>> >> >
>> >>
>> >
>> >
>>
>
>

Re: code-lists and administration thereof

Posted by Dan Haywood <da...@haywood-associates.co.uk>.
On 3 August 2015 at 10:51, Stephen Cameron <st...@gmail.com>
wrote:

> On Mon, Aug 3, 2015 at 7:32 PM, Dan Haywood <da...@haywood-associates.co.uk>
> wrote:
>
> > Glad you got this working for your own app.
> >
> > Re: kitchensink, did you pull down the latest?  I fixed the issues for
> the
> > fixture script and the bad config, I believe.
> >
> Just tried to update my copy. Need to read up on that too!
>
>
Jeroen and I use SourceTree, free from Atlassian; it's a good tool that
makes this stuff easy.  I tend to do a "fetch" and the merge afterwards;
all easy from the UI.



> >
> > I'll fix that error message talking about "isis.properties" instead of
> > "persistor_datanucleus.properties", though.  (In Isis, it doesn't matter
> > which of those property files you use; it would be valid to just use
> > isis.properties for everything, in fact).
> >
>
> I am enjoying Isis, thinking of a project that I can make to sell as a
> customisable ERP type system, somewhat like Estatio. Just have to finish
> this one first, I have first demo for users on Friday, then hopefully into
> use by end of next week.
>
>
Jeroen and I plan to take factor out submodules of Estatio and make into
reusable (or semi-reusable components); our code name for this is UDO -
universal domain objects.  For example, Parties (legal entities),
communication channels, invoices, geography, are probably all quite widely
reusable.  The main entities in Estatio are illustrated at [1].

I expect we'll be getting onto that in a few months or so.  It'll all end
up on github, just in different repos (analogous to isisaddons).  If you're
interested in helping out, do say.

Cheers
Dan


[1]
https://github.com/estatio/estatio/blob/master/docs/application-tenancy-analysis/application-tenancy-analysis.pdf

Re: code-lists and administration thereof

Posted by Stephen Cameron <st...@gmail.com>.
On Mon, Aug 3, 2015 at 7:32 PM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:

> Glad you got this working for your own app.
>
> Re: kitchensink, did you pull down the latest?  I fixed the issues for the
> fixture script and the bad config, I believe.
>
Just tried to update my copy. Need to read up on that too!

>
> I'll fix that error message talking about "isis.properties" instead of
> "persistor_datanucleus.properties", though.  (In Isis, it doesn't matter
> which of those property files you use; it would be valid to just use
> isis.properties for everything, in fact).
>

I am enjoying Isis, thinking of a project that I can make to sell as a
customisable ERP type system, somewhat like Estatio. Just have to finish
this one first, I have first demo for users on Friday, then hopefully into
use by end of next week.

>
>
>
> On 2 August 2015 at 21:54, Stephen Cameron <st...@gmail.com>
> wrote:
>
> > Hi,
> >
> > Just trying this now, with current version of kitchen sink I got an error
> > message starting the webapp, saying that no persistable classes could be
> > found and to check value of
> > isis.persistor.datanucleus.RegisterEntities.packagePrefix
> > in isis.properties, but that key is in isis_datanucleus.properties.
> >
> > Also errors in running fixture script :(
> >
> >
> >    - org.apache.wicket.WicketRuntimeException
> >    - Method onRequest of interface
> >    org.apache.wicket.behavior.IBehaviorListener targeted at
> >    org.apache.wicket.ajax.markup.html.AjaxLink$1@1ac79481 on component
> >    [AjaxLink [Component id = menuLink]] threw an exception
> >    -
> >
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:268)
> >
> >    -
> >
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
> >
> >    -
> >
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
> >
> >    -
> >
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
> >
> >    -
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> > org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
> >
> >    -
> >
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
> >
> >    -
> > org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
> >
> >    -
> > org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
> >
> >    -
> org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
> >    -
> >
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
> >
> >    -
> >
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
> >
> >    -
> > org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
> >
> >    - org.mortbay.jetty.Server#handle(Server.java:326)
> >    -
> > org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
> >
> >    -
> >
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
> >
> >    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
> >    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
> >    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
> >    -
> >
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
> >
> >    -
> >
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
> >
> >    -
> >    - Caused by:
> >    -
> >    - java.lang.reflect.InvocationTargetException
> >    -
> >    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
> >    -
> >
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> >
> >    - java.lang.reflect.Method#invoke(Method.java:497)
> >    -
> >
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
> >
> >    -
> >
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
> >
> >    -
> >
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
> >
> >    -
> >
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
> >
> >    -
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> > org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
> >
> >    -
> >
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
> >
> >    -
> > org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
> >
> >    -
> > org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
> >
> >    -
> org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
> >    -
> >
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
> >
> >    -
> >
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
> >
> >    -
> > org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
> >
> >    - org.mortbay.jetty.Server#handle(Server.java:326)
> >    -
> > org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
> >
> >    -
> >
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
> >
> >    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
> >    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
> >    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
> >    -
> >
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
> >
> >    -
> >
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
> >
> >    -
> >    - Caused by:
> >    -
> >    - java.lang.IllegalArgumentException
> >    - argument type mismatch
> >    -
> >
> sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
> >
> >    -
> >
> sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
> >
> >    -
> >
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> >
> >    - java.lang.reflect.Method#invoke(Method.java:497)
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript#setParam(FixtureScript.java:689)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript#defaultParam(FixtureScript.java:631)
> >
> >    -
> >
> org.isisaddons.app.kitchensink.fixture.primitive.PrimitiveObjectsFixture#execute(PrimitiveObjectsFixture.java:133)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:528)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:498)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:487)
> >
> >    -
> >
> org.isisaddons.app.kitchensink.fixture.KitchensinkSetupFixture#execute(KitchensinkSetupFixture.java:62)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#access$200(FixtureScript.java:248)
> >
> >    -
> >
> org.apache.isis.applib.fixturescripts.FixtureScript#run(FixtureScript.java:719)
> >
> >    -
> >
> org.isisaddons.app.kitchensink.fixture.KitchensinkFixturesService#installFixturesAndReturnFirst(KitchensinkFixturesService.java:95)
> >
> >    -
> >
> sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
> >
> >    -
> >
> sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
> >
> >    -
> >
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> >
> >    - java.lang.reflect.Method#invoke(Method.java:497)
> >    -
> >
> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:356)
> >
> >    -
> >
> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invoke(ActionInvocationFacetForDomainEventAbstract.java:196)
> >
> >    -
> >
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:57)
> >
> >    -
> >
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:54)
> >
> >    -
> >
> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:205)
> >
> >    -
> >
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction#invoke(ActionInvocationFacetWrapTransaction.java:54)
> >
> >    -
> >
> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#execute(ObjectActionImpl.java:367)
> >
> >    -
> >
> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#executeWithRuleChecking(ObjectActionImpl.java:358)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.model.models.ActionModel#executeAction(ActionModel.java:467)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:447)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:80)
> >
> >    -
> >
> org.apache.wicket.model.LoadableDetachableModel#getObject(LoadableDetachableModel.java:121)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.model.models.ActionModel#executeHandlingApplicationExceptions(ActionModel.java:543)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionOnTargetAndProcessResults(ActionPanel.java:245)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionAndProcessResults(ActionPanel.java:193)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#buildGui(ActionPanel.java:104)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#<init>(ActionPanel.java:82)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory#createComponent(ActionPanelFactory.java:49)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault#createComponent(ComponentFactoryRegistryDefault.java:128)
> >
> >    -
> >
> org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel.ActionLinkFactoryAbstract$1#onClick(ActionLinkFactoryAbstract.java:74)
> >
> >    -
> > org.apache.wicket.ajax.markup.html.AjaxLink$1#onEvent(AjaxLink.java:86)
> >
> >    -
> >
> org.apache.wicket.ajax.AjaxEventBehavior#respond(AjaxEventBehavior.java:124)
> >
> >    -
> >
> org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onRequest(AbstractDefaultAjaxBehavior.java:633)
> >
> >    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
> >    -
> >
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> >
> >    - java.lang.reflect.Method#invoke(Method.java:497)
> >    -
> >
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
> >
> >    -
> >
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
> >
> >    -
> >
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
> >
> >    -
> >
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
> >
> >    -
> >
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
> >
> >    -
> >
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
> >
> >    -
> >
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
> >
> >    -
> >
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
> >
> >    -
> >
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
> >
> >    -
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
> >
> >    -
> >
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
> >
> >    -
> > org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
> >
> >    -
> >
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
> >
> >    -
> > org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
> >
> >    -
> > org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
> >
> >    -
> org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
> >    -
> >
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
> >
> >    -
> >
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
> >
> >    -
> > org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
> >
> >    - org.mortbay.jetty.Server#handle(Server.java:326)
> >    -
> > org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
> >
> >    -
> >
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
> >
> >    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
> >    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
> >    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
> >    -
> >
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
> >
> >    -
> >
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582
> >
> >
> >
> >
> > On Sun, Aug 2, 2015 at 11:23 PM, Dan Haywood <
> dan@haywood-associates.co.uk
> > >
> > wrote:
> >
> > > Further to this, I've updated the kitchensink (against 1.9.0-SNAPSHOT)
> to
> > > demonstrate this technique....
> > >
> > > The code is in ReferenceObject, which you can get to from the "Data
> > Types"
> > > menu.  Use the fixture scripts menu to create some sample data.
> > >
> > > The relevant code is below.
> > >
> > > Cheers
> > > Dan
> > >
> > > [1]  https://github.com/isisaddons/isis-app-kitchensink
> > >
> > >
> > >     private OtherObject someOtherObjectUsingName;
> > >
> > >     @Property(hidden = Where.EVERYWHERE)
> > >     @Column(allowsNull = "true")
> > >     public OtherObject getSomeOtherObjectUsingName() {
> > >         return someOtherObjectUsingName;
> > >     }
> > >
> > >     public void setSomeOtherObjectUsingName(final OtherObject
> > > someOtherObjectUsingName) {
> > >         this.someOtherObjectUsingName = someOtherObjectUsingName;
> > >     }
> > >
> > >     @NotPersistent
> > >     public String getSomeOtherObjectUsingNameName() {
> > >         return getSomeOtherObjectUsingName() != null?
> > > getSomeOtherObjectUsingName().getName() : null;
> > >     }
> > >
> > >     public void setSomeOtherObjectUsingNameName(final String name) {
> > >         OtherObject otherObject = name != null
> > >                 ? container.firstMatch(OtherObject.class,
> withName(name))
> > >                 : null;
> > >         setSomeOtherObjectUsingName(otherObject);
> > >     }
> > >
> > >     public List<String> choicesSomeOtherObjectUsingNameName() {
> > >         List<OtherObject> otherObjects =
> > > container.allInstances(OtherObject.class);
> > >         return Lists.newArrayList(
> > >                 Iterables.transform(otherObjects, nameOf())
> > >         );
> > >     }
> > >
> > >     private static Function<OtherObject, String> nameOf() {
> > >         return new Function<OtherObject, String>() {
> > >             @Nullable @Override public String apply(final OtherObject
> > > input) {
> > >                 return input.getName();
> > >             }
> > >         };
> > >     }
> > >
> > >     private static Predicate<OtherObject> withName(final String name) {
> > >         return new Predicate<OtherObject>() {
> > >         @Override public boolean apply(final OtherObject input) {
> > >              return Objects.equal(input.getName(), name);
> > >             }
> > >     };
> > >     }
> > >
> > >
> > >
> > >
> > >
> > > On 30 July 2015 at 13:16, Dan Haywood <da...@haywood-associates.co.uk>
> > > wrote:
> > >
> > > > looks right to me, so I'll take a look at in this eve or tomorrow.
> > > >
> > > > thx
> > > > Dan
> > > >
> > > >
> > > > On 30 July 2015 at 13:12, Stephen Cameron <
> steve.cameron.62@gmail.com>
> > > > wrote:
> > > >
> > > >> Still no luck with this one.
> > > >>
> > > >> The derived RegionName appears as a non-editable property, so not
> sure
> > > >> what
> > > >> was different before when I was getting an model validation error.
> > > >>
> > > >> My current code of interest is this:
> > > >>
> > > >>     @Column(name = "region", allowsNull = "true")
> > > >>     //@MemberOrder(sequence = "7")
> > > >>     @Property(hidden=Where.EVERYWHERE)
> > > >>     public Region getRegion() {
> > > >>         return this.region;
> > > >>     }
> > > >>
> > > >>     public void setRegion(Region region) {
> > > >>         this.region = region;
> > > >>     }
> > > >>
> > > >>     public List<Region> choicesRegion() {
> > > >>         return regions.listAllRegions();
> > > >>     }
> > > >>
> > > >>     @MemberOrder(sequence = "7")
> > > >>     public String getRegionName() {
> > > >>         return regions.nameForRegion(getRegion());
> > > >>     }
> > > >>
> > > >>     public void setRegionName(String name) {
> > > >>         setRegion(regions.regionForName(name));
> > > >>     }
> > > >>
> > > >>     public List<String> choicesRegionName(){
> > > >>         return regions.listAllNamesExclusive(getRegion());
> > > >>     }
> > > >>
> > > >> My Region class is this:
> > > >>
> > > >> package au.com.scds.chats.dom.modules.general.codes;
> > > >>
> > > >> import javax.jdo.annotations.Column;
> > > >> import javax.jdo.annotations.IdentityType;
> > > >> import javax.jdo.annotations.PrimaryKey;
> > > >>
> > > >> import org.apache.isis.applib.annotation.Action;
> > > >> import org.apache.isis.applib.annotation.ActionLayout;
> > > >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> > > >> import
> org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> > > >> import org.apache.isis.applib.annotation.MemberOrder;
> > > >> import org.apache.isis.applib.annotation.PropertyLayout;
> > > >>
> > > >> @javax.jdo.annotations.PersistenceCapable(
> > > >>          identityType=IdentityType.APPLICATION)
> > > >> public class Region {
> > > >>
> > > >>     public String title(){
> > > >>         return getName();
> > > >>     }
> > > >>
> > > >>     private String name;
> > > >>
> > > >>     @Column(name="region", allowsNull = "false")
> > > >>     @PrimaryKey()
> > > >>     @PropertyLayout(named="Region")
> > > >>     @MemberOrder(sequence="1")
> > > >>     public String getName() {
> > > >>         return name;
> > > >>     }
> > > >>
> > > >>     public void setName(String name) {
> > > >>         this.name = name;
> > > >>     }
> > > >> }
> > > >>
> > > >> My Regions repository class is this:
> > > >>
> > > >> package au.com.scds.chats.dom.modules.general.codes;
> > > >>
> > > >> import java.util.ArrayList;
> > > >> import java.util.List;
> > > >>
> > > >> import org.apache.isis.applib.DomainObjectContainer;
> > > >> import org.apache.isis.applib.annotation.Action;
> > > >> import org.apache.isis.applib.annotation.ActionLayout;
> > > >> import org.apache.isis.applib.annotation.BookmarkPolicy;
> > > >> import org.apache.isis.applib.annotation.DomainService;
> > > >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> > > >> import
> org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> > > >> import org.apache.isis.applib.annotation.MemberOrder;
> > > >> import org.apache.isis.applib.annotation.ParameterLayout;
> > > >> import org.apache.isis.applib.annotation.Programmatic;
> > > >> import org.apache.isis.applib.annotation.SemanticsOf;
> > > >> import org.apache.isis.applib.query.QueryDefault;
> > > >>
> > > >> import au.com.scds.chats.dom.modules.participant.Participant;
> > > >>
> > > >> @DomainService(repositoryFor = Region.class)
> > > >> @DomainServiceLayout(menuBar = MenuBar.SECONDARY, named =
> > > >> "Administration",
> > > >> menuOrder = "100.1")
> > > >> public class Regions {
> > > >>
> > > >>     // region > listAll (action)
> > > >>     @Action(semantics = SemanticsOf.SAFE)
> > > >>     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
> > > >>     @MemberOrder(sequence = "1")
> > > >>     public List<Region> listAllRegions() {
> > > >>         return container.allInstances(Region.class);
> > > >>     }
> > > >>
> > > >>     // endregion
> > > >>
> > > >>     // region > create (action)
> > > >>     @MemberOrder(sequence = "2")
> > > >>     public Region createRegion(
> > > >>             final @ParameterLayout(named = "Region Name") String
> > name) {
> > > >>         final Region obj =
> > container.newTransientInstance(Region.class);
> > > >>         obj.setName(name);
> > > >>         container.persistIfNotAlready(obj);
> > > >>         return obj;
> > > >>     }
> > > >>
> > > >>     // endregion
> > > >>
> > > >>     // region > injected services
> > > >>
> > > >>     @javax.inject.Inject
> > > >>     DomainObjectContainer container;
> > > >>
> > > >>     // endregion
> > > >>
> > > >>     @Programmatic
> > > >>     public String nameForRegion(Region region) {
> > > >>         return (region != null) ? region.getName() : null;
> > > >>     }
> > > >>
> > > >>
> > > >>     @Programmatic
> > > >>     public List<String> listAllNamesExclusive(Region region) {
> > > >>         List<Region> regions = listAllRegions();
> > > >>         List<String> names = new ArrayList<String>();
> > > >>         for (Region r : regions) {
> > > >>             if (region != null && r != region) {
> > > >>                 names.add(r.getName());
> > > >>             }
> > > >>         }
> > > >>         return names;
> > > >>     }
> > > >>
> > > >>
> > > >>     @Programmatic
> > > >>     public Region regionForName(String name) {
> > > >>         Region region = container.firstMatch(new QueryDefault<>(
> > > >> Region.class,
> > > >>                  "findRegion", "name", name));
> > > >>         return region;
> > > >>     }
> > > >>
> > > >> }
> > > >>
> > > >> Just maybe I there is something missing still?
> > > >>
> > > >> I added a @Property annotation to the getRegionName() method, but
> that
> > > >> gave
> > > >> me a message saying it expected @javax.jdo.persistence.Column too.
> > > >>
> > > >> Note I couldn't use deprecated @Hidden in Isis 1.9.0.
> > > >>
> > > >>
> > > >> On Thu, Jul 30, 2015 at 8:14 PM, Stephen Cameron <
> > > >> steve.cameron.62@gmail.com
> > > >> > wrote:
> > > >>
> > > >> > Hi Dan, When I tried this I got an model validation error message
> > > >> relating
> > > >> > to the choices method, I will have another go and if it fails,
> > provide
> > > >> the
> > > >> > test case. Thanks for the tips.
> > > >> >
> > > >> > On Thu, Jul 30, 2015 at 7:57 PM, Dan Haywood <
> > > >> dan@haywood-associates.co.uk
> > > >> > > wrote:
> > > >> >
> > > >> >> You should be able to add a choicesXxx() for the derived
> property:
> > > >> >>
> > > >> >>     public List<String> choicesRegionName(){
> > > >> >>         return
> > > Lists.newArrayList(Iterables.transform(choicesRegion(),
> > > >> x
> > > >> >> ->
> > > >> >> x.getName()));
> > > >> >>     }
> > > >> >>
> > > >> >> If that isn't sufficient, you might also need to add a setter:
> > > >> >>
> > > >> >> public void setRegionName(final String name) {
> > > >> >> setRegion(Iterables.find(choicesRegion(), x ->
> > > >> x.getName().equals(name)));
> > > >> >> }
> > > >> >>
> > > >> >> Obviously, you might need to also add some error handling.
> > > >> >>
> > > >> >> ~~~
> > > >> >>
> > > >> >> Regarding the "external URL" idea, perhaps you could raise that
> as
> > a
> > > >> >> separate ticket, with a code sketch as to how you'd like this
> > > >> information
> > > >> >> specified?
> > > >> >>
> > > >> >> Thanks
> > > >> >> Dan
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >> On 30 July 2015 at 03:17, Stephen Cameron <
> > > steve.cameron.62@gmail.com>
> > > >> >> wrote:
> > > >> >>
> > > >> >> > Not so simple, as now the property cannot be updated.
> > > >> >> >
> > > >> >> > I have the following (@Hidden is deprecated)
> > > >> >> >
> > > >> >> >     @Column(allowsNull = "true")
> > > >> >> >     @MemberOrder(sequence = "7")
> > > >> >> >     @PropertyLayout(hidden=Where.EVERYWHERE)
> > > >> >> >     public Region getRegion() {
> > > >> >> >         return this.region;
> > > >> >> >     }
> > > >> >> >
> > > >> >> >     public void setRegion(Region region) {
> > > >> >> >         this.region = region;
> > > >> >> >     }
> > > >> >> >
> > > >> >> >     public List<Region> choicesRegion(){
> > > >> >> >         List<Region> regions =
> > > container.allInstances(Region.class);
> > > >> >> >         return regions;
> > > >> >> >     }
> > > >> >> >
> > > >> >> >     @MemberOrder(sequence = "7.1")
> > > >> >> >     public String getRegionName(){
> > > >> >> >         return (getRegion() != null) ? getRegion().getName() :
> > > null;
> > > >> >> >     }
> > > >> >> >
> > > >> >> > Sure enough getRegion doesn't appear in the UI but
> getRegionName
> > > >> does,
> > > >> >> but
> > > >> >> > then setRegion and choiceRegion don't mean anything to the UI,
> so
> > > the
> > > >> >> > Region property is read-only.
> > > >> >> >
> > > >> >> > This issue is maybe more significant than it appears at first,
> in
> > > >> terms
> > > >> >> of
> > > >> >> > domain modelling such code-lists are simple types that
> > 'represent'
> > > >> >> things
> > > >> >> > on the boundary of the domain of interest. So we usually want
> to
> > > just
> > > >> >> > represent them with a name. Presently it makes no sense to go
> to
> > > that
> > > >> >> thing
> > > >> >> > via a hyperlink as all we'll find is that name, our model
> extends
> > > no
> > > >> >> > further.
> > > >> >> >
> > > >> >> > However we just might like to allow users to leave the domain
> > model
> > > >> and
> > > >> >> go
> > > >> >> > to a resource outside. So, extending the suppressLink=true
> idea,
> > I
> > > >> would
> > > >> >> > add that each object could have an implicit link(URL),created
> by
> > > >> Isis,
> > > >> >> or
> > > >> >> > an explicit one and if the explicit one is present it can
> > > optionally
> > > >> be
> > > >> >> > used as an alternative to the implicit one.
> > > >> >> >
> > > >> >> > For example, you might create a database to log fish details,
> > > species
> > > >> >> is a
> > > >> >> > boundary concept, we aren't likely to want to add a new species
> > to
> > > >> the
> > > >> >> list
> > > >> >> > of known species, but we'd like to keep such a list handy, but
> > for
> > > >> each
> > > >> >> > named species in that list, to provide an explicit link to a
> > > resource
> > > >> >> in a
> > > >> >> > global fish database. It makes more sense to use this link than
> > the
> > > >> >> > implicit one, as if the implicit one is used we'd navigate to
> the
> > > >> domain
> > > >> >> > object page displaying the name and URL, both of which items of
> > > data
> > > >> >> could
> > > >> >> > have been in the explicit link.
> > > >> >> >
> > > >> >> > In the explicit case you might want to warn the user they are
> > > >> navigating
> > > >> >> > outside the Isis domain application.
> > > >> >> >
> > > >> >> > Perhaps all this could be done simply if there was a URI type
> in
> > > >> Isis,
> > > >> >> that
> > > >> >> > would allow it to create 'smart links' automatically.
> > > >> >> >
> > > >> >> >
> > > >> >> >
> > > >> >> >
> > > >> >> >
> > > >> >> > On Wed, Jul 29, 2015 at 9:37 PM, Stephen Cameron <
> > > >> >> > steve.cameron.62@gmail.com
> > > >> >> > > wrote:
> > > >> >> >
> > > >> >> > > Thanks Jeroen, seems simple enough :)
> > > >> >> > >
> > > >> >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal <
> > > >> >> jeroen@stromboli.it
> > > >> >> > >
> > > >> >> > > wrote:
> > > >> >> > >
> > > >> >> > >> You could also hide the property and create a separate
> getter
> > > for
> > > >> >> > display
> > > >> >> > >> purposes only:
> > > >> >> > >>
> > > >> >> > >> private MyProperty myProperty;
> > > >> >> > >>
> > > >> >> > >> @Hidden
> > > >> >> > >> public MyProperty getMyProperty() {...}
> > > >> >> > >>
> > > >> >> > >> public void setMyProperty(...) {...}
> > > >> >> > >>
> > > >> >> > >> public String getMyPropertyName() {
> > > >> >> > >>     getMyProperty.getName();
> > > >> >> > >> }
> > > >> >> > >>
> > > >> >> > >> On 29 July 2015 at 13:18, Stephen Cameron <
> > > >> >> steve.cameron.62@gmail.com>
> > > >> >> > >> wrote:
> > > >> >> > >>
> > > >> >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood <
> > > >> >> > >> dan@haywood-associates.co.uk
> > > >> >> > >> > >
> > > >> >> > >> > wrote:
> > > >> >> > >> >
> > > >> >> > >> > > You are right, they will be displayed as links; there's
> no
> > > >> way to
> > > >> >> > >> disable
> > > >> >> > >> > > it currently.
> > > >> >> > >> > >
> > > >> >> > >> > > We could add a bit of metadata perhaps for this, eg
> > > >> >> > >> > > @DomainObjectLayout(suppressLink=true) or similar.
> > > >> >> > >> > >
> > > >> >> > >> > > Please raise a ticket.
> > > >> >> > >> > >
> > > >> >> > >> >
> > > >> >> > >> > OK https://issues.apache.org/jira/browse/ISIS-1180
> > > >> >> > >> >
> > > >> >> > >> > >
> > > >> >> > >> > > Thx
> > > >> >> > >> > > Dan
> > > >> >> > >> > >
> > > >> >> > >> > > PS: these entities wouldn't be value types, rather
> regular
> > > >> >> entities.
> > > >> >> > >> But
> > > >> >> > >> > > you are right... what we really want is full-class
> support
> > > for
> > > >> >> value
> > > >> >> > >> > types.
> > > >> >> > >> > >   We're just not there yet...
> > > >> >> > >> > >
> > > >> >> > >> > >
> > > >> >> > >> > >
> > > >> >> > >> >
> > > >> >> > >> > >
> > > >> >> > >> > >
> > > >> >> > >> > > On 29 July 2015 at 09:34, Stephen Cameron <
> > > >> >> > steve.cameron.62@gmail.com
> > > >> >> > >> >
> > > >> >> > >> > > wrote:
> > > >> >> > >> > >
> > > >> >> > >> > > > Thanks, but surely such object properties always end
> up
> > > >> being
> > > >> >> > >> displayed
> > > >> >> > >> > > as
> > > >> >> > >> > > > links? Clicking on the link to go to such an object
> page
> > > is
> > > >> >> > >> > meaningless,
> > > >> >> > >> > > as
> > > >> >> > >> > > > it only has one name property, that was displayed in
> the
> > > >> link.
> > > >> >> > Can I
> > > >> >> > >> > > > disable that default behaviour for value types?
> > > >> >> > >> > > >
> > > >> >> > >> > > >
> > > >> >> > >> > > >
> > > >> >> > >> > > > On Wed, Jul 29, 2015 at 5:47 PM, Dan Haywood <
> > > >> >> > >> > > dan@haywood-associates.co.uk
> > > >> >> > >> > > > >
> > > >> >> > >> > > > wrote:
> > > >> >> > >> > > >
> > > >> >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron <
> > > >> >> > >> > steve.cameron.62@gmail.com>
> > > >> >> > >>
> > > >> >> > >> > > > > wrote:
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > > Hi,
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > > > I want to do have some properties that are
> > essentially
> > > >> >> String
> > > >> >> > >> > types,
> > > >> >> > >> > > > but
> > > >> >> > >> > > > > > which have a limited range of values (code-lists
> or
> > > >> >> restricted
> > > >> >> > >> > > > > > vocabularies). I want to allow these lists to be
> > > >> >> administered
> > > >> >> > >> > > > centrally,
> > > >> >> > >> > > > > so
> > > >> >> > >> > > > > > to add them to a single Administration menu item
> for
> > > >> admin
> > > >> >> > >> users.
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > > > For most users these codes should appears as lists
> > of
> > > >> >> strings
> > > >> >> > >> not
> > > >> >> > >> > as
> > > >> >> > >> > > > > > objects, but making them objects seems to be the
> > > >> logical OO
> > > >> >> > way
> > > >> >> > >> to
> > > >> >> > >> > > deal
> > > >> >> > >> > > > > > with them in Isis. So they are basically objects
> > with
> > > >> one
> > > >> >> > 'name'
> > > >> >> > >> > > > property
> > > >> >> > >> > > > > > (and maybe an id added by datanucleus). All users
> > need
> > > >> to
> > > >> >> see
> > > >> >> > is
> > > >> >> > >> > the
> > > >> >> > >> > > > name
> > > >> >> > >> > > > > > property, no icon is needed.
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > > > Also, if I make them objects I also will get
> > > referencial
> > > >> >> > >> integrity
> > > >> >> > >> > > > > > constraints applied in the database.
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > > +1, do it this way.  That way they can also hold
> > > >> behaviour in
> > > >> >> > the
> > > >> >> > >> > > future.
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > > I wonder there is a simple recipe for this?
> > > >> >> > >> > > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > No magic recipe for the domain entities... basically
> > > >> >> > copy-n-paste
> > > >> >> > >> the
> > > >> >> > >> > > > > SimpleObject that's in our archetype as many times
> as
> > > >> needed,
> > > >> >> > and
> > > >> >> > >> > tweak
> > > >> >> > >> > > > as
> > > >> >> > >> > > > > required.
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > If you want to use the code as the primary key, then
> > use
> > > >> DN
> > > >> >> > >> > application
> > > >> >> > >> > > > > identity
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > @javax.jdo.annotations.PersistenceCapable(
> > > >> >> > >> > > > >         identityType=IdentityType.APPLICATION,
> > > >> >> > >> > > > >         schema = "simple",
> > > >> >> > >> > > > >         table = "SimpleObject"
> > > >> >> > >> > > > > )
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > and add @PrimaryKey to the "name" property.  Also
> add
> > > >> @Title
> > > >> >> to
> > > >> >> > >> that
> > > >> >> > >> > > > 'name'
> > > >> >> > >> > > > > property (it is in SimpleObject already).
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > You would probably want to remove the version
> column,
> > ie
> > > >> >> remove:
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > @javax.jdo.annotations.Version(
> > > >> >> > >> > > > >         strategy=VersionStrategy.VERSION_NUMBER,
> > > >> >> > >> > > > >         column="version")
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > In addition, if you annotate the class as "bounded"
> > > >> >> > >> > > > > (@DomainObject(bounded=true)) then you are telling
> the
> > > >> >> framework
> > > >> >> > >> that
> > > >> >> > >> > > > > there's a limited - ie bounded - set of instances,
> and
> > > so
> > > >> it
> > > >> >> > will
> > > >> >> > >> > > display
> > > >> >> > >> > > > > all instances in a drop-down for you.
> > > >> >> > >> > > > >
> > > >> >> > >> > > > >
> > > >> >> > >> > > > > HTH
> > > >> >> > >> > > > > Dan
> > > >> >> > >> > > > >
> > > >> >> > >> > > >
> > > >> >> > >> > >
> > > >> >> > >> >
> > > >> >> > >>
> > > >> >> > >
> > > >> >> > >
> > > >> >> >
> > > >> >>
> > > >> >
> > > >> >
> > > >>
> > > >
> > > >
> > >
> >
>

Re: code-lists and administration thereof

Posted by Dan Haywood <da...@haywood-associates.co.uk>.
Glad you got this working for your own app.

Re: kitchensink, did you pull down the latest?  I fixed the issues for the
fixture script and the bad config, I believe.

I'll fix that error message talking about "isis.properties" instead of
"persistor_datanucleus.properties", though.  (In Isis, it doesn't matter
which of those property files you use; it would be valid to just use
isis.properties for everything, in fact).



On 2 August 2015 at 21:54, Stephen Cameron <st...@gmail.com>
wrote:

> Hi,
>
> Just trying this now, with current version of kitchen sink I got an error
> message starting the webapp, saying that no persistable classes could be
> found and to check value of
> isis.persistor.datanucleus.RegisterEntities.packagePrefix
> in isis.properties, but that key is in isis_datanucleus.properties.
>
> Also errors in running fixture script :(
>
>
>    - org.apache.wicket.WicketRuntimeException
>    - Method onRequest of interface
>    org.apache.wicket.behavior.IBehaviorListener targeted at
>    org.apache.wicket.ajax.markup.html.AjaxLink$1@1ac79481 on component
>    [AjaxLink [Component id = menuLink]] threw an exception
>    -
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:268)
>
>    -
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    -
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    -
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    -
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    -
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    -
> org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    -
> org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>    -
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    -
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    -
> org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    -
> org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    -
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    -
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    -
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
>
>    -
>    - Caused by:
>    -
>    - java.lang.reflect.InvocationTargetException
>    -
>    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
>    -
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    -
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
>
>    -
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    -
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    -
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    -
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    -
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    -
> org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    -
> org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>    -
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    -
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    -
> org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    -
> org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    -
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    -
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    -
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
>
>    -
>    - Caused by:
>    -
>    - java.lang.IllegalArgumentException
>    - argument type mismatch
>    -
> sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
>
>    -
> sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
>
>    -
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript#setParam(FixtureScript.java:689)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript#defaultParam(FixtureScript.java:631)
>
>    -
> org.isisaddons.app.kitchensink.fixture.primitive.PrimitiveObjectsFixture#execute(PrimitiveObjectsFixture.java:133)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:528)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:498)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:487)
>
>    -
> org.isisaddons.app.kitchensink.fixture.KitchensinkSetupFixture#execute(KitchensinkSetupFixture.java:62)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#access$200(FixtureScript.java:248)
>
>    -
> org.apache.isis.applib.fixturescripts.FixtureScript#run(FixtureScript.java:719)
>
>    -
> org.isisaddons.app.kitchensink.fixture.KitchensinkFixturesService#installFixturesAndReturnFirst(KitchensinkFixturesService.java:95)
>
>    -
> sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
>
>    -
> sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
>
>    -
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    -
> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:356)
>
>    -
> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invoke(ActionInvocationFacetForDomainEventAbstract.java:196)
>
>    -
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:57)
>
>    -
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:54)
>
>    -
> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:205)
>
>    -
> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction#invoke(ActionInvocationFacetWrapTransaction.java:54)
>
>    -
> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#execute(ObjectActionImpl.java:367)
>
>    -
> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#executeWithRuleChecking(ObjectActionImpl.java:358)
>
>    -
> org.apache.isis.viewer.wicket.model.models.ActionModel#executeAction(ActionModel.java:467)
>
>    -
> org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:447)
>
>    -
> org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:80)
>
>    -
> org.apache.wicket.model.LoadableDetachableModel#getObject(LoadableDetachableModel.java:121)
>
>    -
> org.apache.isis.viewer.wicket.model.models.ActionModel#executeHandlingApplicationExceptions(ActionModel.java:543)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionOnTargetAndProcessResults(ActionPanel.java:245)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionAndProcessResults(ActionPanel.java:193)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#buildGui(ActionPanel.java:104)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#<init>(ActionPanel.java:82)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory#createComponent(ActionPanelFactory.java:49)
>
>    -
> org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault#createComponent(ComponentFactoryRegistryDefault.java:128)
>
>    -
> org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel.ActionLinkFactoryAbstract$1#onClick(ActionLinkFactoryAbstract.java:74)
>
>    -
> org.apache.wicket.ajax.markup.html.AjaxLink$1#onEvent(AjaxLink.java:86)
>
>    -
> org.apache.wicket.ajax.AjaxEventBehavior#respond(AjaxEventBehavior.java:124)
>
>    -
> org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onRequest(AbstractDefaultAjaxBehavior.java:633)
>
>    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
>    -
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    -
> org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
>
>    -
> org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    -
> org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    -
> org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    -
> org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    -
> org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    -
> org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    -
> org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    -
> org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    -
> org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    -
> org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    -
> org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    -
> org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    -
> org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>    -
> org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    -
> org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    -
> org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    -
> org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    -
> org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    -
> org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    -
> org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582
>
>
>
>
> On Sun, Aug 2, 2015 at 11:23 PM, Dan Haywood <dan@haywood-associates.co.uk
> >
> wrote:
>
> > Further to this, I've updated the kitchensink (against 1.9.0-SNAPSHOT) to
> > demonstrate this technique....
> >
> > The code is in ReferenceObject, which you can get to from the "Data
> Types"
> > menu.  Use the fixture scripts menu to create some sample data.
> >
> > The relevant code is below.
> >
> > Cheers
> > Dan
> >
> > [1]  https://github.com/isisaddons/isis-app-kitchensink
> >
> >
> >     private OtherObject someOtherObjectUsingName;
> >
> >     @Property(hidden = Where.EVERYWHERE)
> >     @Column(allowsNull = "true")
> >     public OtherObject getSomeOtherObjectUsingName() {
> >         return someOtherObjectUsingName;
> >     }
> >
> >     public void setSomeOtherObjectUsingName(final OtherObject
> > someOtherObjectUsingName) {
> >         this.someOtherObjectUsingName = someOtherObjectUsingName;
> >     }
> >
> >     @NotPersistent
> >     public String getSomeOtherObjectUsingNameName() {
> >         return getSomeOtherObjectUsingName() != null?
> > getSomeOtherObjectUsingName().getName() : null;
> >     }
> >
> >     public void setSomeOtherObjectUsingNameName(final String name) {
> >         OtherObject otherObject = name != null
> >                 ? container.firstMatch(OtherObject.class, withName(name))
> >                 : null;
> >         setSomeOtherObjectUsingName(otherObject);
> >     }
> >
> >     public List<String> choicesSomeOtherObjectUsingNameName() {
> >         List<OtherObject> otherObjects =
> > container.allInstances(OtherObject.class);
> >         return Lists.newArrayList(
> >                 Iterables.transform(otherObjects, nameOf())
> >         );
> >     }
> >
> >     private static Function<OtherObject, String> nameOf() {
> >         return new Function<OtherObject, String>() {
> >             @Nullable @Override public String apply(final OtherObject
> > input) {
> >                 return input.getName();
> >             }
> >         };
> >     }
> >
> >     private static Predicate<OtherObject> withName(final String name) {
> >         return new Predicate<OtherObject>() {
> >         @Override public boolean apply(final OtherObject input) {
> >              return Objects.equal(input.getName(), name);
> >             }
> >     };
> >     }
> >
> >
> >
> >
> >
> > On 30 July 2015 at 13:16, Dan Haywood <da...@haywood-associates.co.uk>
> > wrote:
> >
> > > looks right to me, so I'll take a look at in this eve or tomorrow.
> > >
> > > thx
> > > Dan
> > >
> > >
> > > On 30 July 2015 at 13:12, Stephen Cameron <st...@gmail.com>
> > > wrote:
> > >
> > >> Still no luck with this one.
> > >>
> > >> The derived RegionName appears as a non-editable property, so not sure
> > >> what
> > >> was different before when I was getting an model validation error.
> > >>
> > >> My current code of interest is this:
> > >>
> > >>     @Column(name = "region", allowsNull = "true")
> > >>     //@MemberOrder(sequence = "7")
> > >>     @Property(hidden=Where.EVERYWHERE)
> > >>     public Region getRegion() {
> > >>         return this.region;
> > >>     }
> > >>
> > >>     public void setRegion(Region region) {
> > >>         this.region = region;
> > >>     }
> > >>
> > >>     public List<Region> choicesRegion() {
> > >>         return regions.listAllRegions();
> > >>     }
> > >>
> > >>     @MemberOrder(sequence = "7")
> > >>     public String getRegionName() {
> > >>         return regions.nameForRegion(getRegion());
> > >>     }
> > >>
> > >>     public void setRegionName(String name) {
> > >>         setRegion(regions.regionForName(name));
> > >>     }
> > >>
> > >>     public List<String> choicesRegionName(){
> > >>         return regions.listAllNamesExclusive(getRegion());
> > >>     }
> > >>
> > >> My Region class is this:
> > >>
> > >> package au.com.scds.chats.dom.modules.general.codes;
> > >>
> > >> import javax.jdo.annotations.Column;
> > >> import javax.jdo.annotations.IdentityType;
> > >> import javax.jdo.annotations.PrimaryKey;
> > >>
> > >> import org.apache.isis.applib.annotation.Action;
> > >> import org.apache.isis.applib.annotation.ActionLayout;
> > >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> > >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> > >> import org.apache.isis.applib.annotation.MemberOrder;
> > >> import org.apache.isis.applib.annotation.PropertyLayout;
> > >>
> > >> @javax.jdo.annotations.PersistenceCapable(
> > >>          identityType=IdentityType.APPLICATION)
> > >> public class Region {
> > >>
> > >>     public String title(){
> > >>         return getName();
> > >>     }
> > >>
> > >>     private String name;
> > >>
> > >>     @Column(name="region", allowsNull = "false")
> > >>     @PrimaryKey()
> > >>     @PropertyLayout(named="Region")
> > >>     @MemberOrder(sequence="1")
> > >>     public String getName() {
> > >>         return name;
> > >>     }
> > >>
> > >>     public void setName(String name) {
> > >>         this.name = name;
> > >>     }
> > >> }
> > >>
> > >> My Regions repository class is this:
> > >>
> > >> package au.com.scds.chats.dom.modules.general.codes;
> > >>
> > >> import java.util.ArrayList;
> > >> import java.util.List;
> > >>
> > >> import org.apache.isis.applib.DomainObjectContainer;
> > >> import org.apache.isis.applib.annotation.Action;
> > >> import org.apache.isis.applib.annotation.ActionLayout;
> > >> import org.apache.isis.applib.annotation.BookmarkPolicy;
> > >> import org.apache.isis.applib.annotation.DomainService;
> > >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> > >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> > >> import org.apache.isis.applib.annotation.MemberOrder;
> > >> import org.apache.isis.applib.annotation.ParameterLayout;
> > >> import org.apache.isis.applib.annotation.Programmatic;
> > >> import org.apache.isis.applib.annotation.SemanticsOf;
> > >> import org.apache.isis.applib.query.QueryDefault;
> > >>
> > >> import au.com.scds.chats.dom.modules.participant.Participant;
> > >>
> > >> @DomainService(repositoryFor = Region.class)
> > >> @DomainServiceLayout(menuBar = MenuBar.SECONDARY, named =
> > >> "Administration",
> > >> menuOrder = "100.1")
> > >> public class Regions {
> > >>
> > >>     // region > listAll (action)
> > >>     @Action(semantics = SemanticsOf.SAFE)
> > >>     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
> > >>     @MemberOrder(sequence = "1")
> > >>     public List<Region> listAllRegions() {
> > >>         return container.allInstances(Region.class);
> > >>     }
> > >>
> > >>     // endregion
> > >>
> > >>     // region > create (action)
> > >>     @MemberOrder(sequence = "2")
> > >>     public Region createRegion(
> > >>             final @ParameterLayout(named = "Region Name") String
> name) {
> > >>         final Region obj =
> container.newTransientInstance(Region.class);
> > >>         obj.setName(name);
> > >>         container.persistIfNotAlready(obj);
> > >>         return obj;
> > >>     }
> > >>
> > >>     // endregion
> > >>
> > >>     // region > injected services
> > >>
> > >>     @javax.inject.Inject
> > >>     DomainObjectContainer container;
> > >>
> > >>     // endregion
> > >>
> > >>     @Programmatic
> > >>     public String nameForRegion(Region region) {
> > >>         return (region != null) ? region.getName() : null;
> > >>     }
> > >>
> > >>
> > >>     @Programmatic
> > >>     public List<String> listAllNamesExclusive(Region region) {
> > >>         List<Region> regions = listAllRegions();
> > >>         List<String> names = new ArrayList<String>();
> > >>         for (Region r : regions) {
> > >>             if (region != null && r != region) {
> > >>                 names.add(r.getName());
> > >>             }
> > >>         }
> > >>         return names;
> > >>     }
> > >>
> > >>
> > >>     @Programmatic
> > >>     public Region regionForName(String name) {
> > >>         Region region = container.firstMatch(new QueryDefault<>(
> > >> Region.class,
> > >>                  "findRegion", "name", name));
> > >>         return region;
> > >>     }
> > >>
> > >> }
> > >>
> > >> Just maybe I there is something missing still?
> > >>
> > >> I added a @Property annotation to the getRegionName() method, but that
> > >> gave
> > >> me a message saying it expected @javax.jdo.persistence.Column too.
> > >>
> > >> Note I couldn't use deprecated @Hidden in Isis 1.9.0.
> > >>
> > >>
> > >> On Thu, Jul 30, 2015 at 8:14 PM, Stephen Cameron <
> > >> steve.cameron.62@gmail.com
> > >> > wrote:
> > >>
> > >> > Hi Dan, When I tried this I got an model validation error message
> > >> relating
> > >> > to the choices method, I will have another go and if it fails,
> provide
> > >> the
> > >> > test case. Thanks for the tips.
> > >> >
> > >> > On Thu, Jul 30, 2015 at 7:57 PM, Dan Haywood <
> > >> dan@haywood-associates.co.uk
> > >> > > wrote:
> > >> >
> > >> >> You should be able to add a choicesXxx() for the derived property:
> > >> >>
> > >> >>     public List<String> choicesRegionName(){
> > >> >>         return
> > Lists.newArrayList(Iterables.transform(choicesRegion(),
> > >> x
> > >> >> ->
> > >> >> x.getName()));
> > >> >>     }
> > >> >>
> > >> >> If that isn't sufficient, you might also need to add a setter:
> > >> >>
> > >> >> public void setRegionName(final String name) {
> > >> >> setRegion(Iterables.find(choicesRegion(), x ->
> > >> x.getName().equals(name)));
> > >> >> }
> > >> >>
> > >> >> Obviously, you might need to also add some error handling.
> > >> >>
> > >> >> ~~~
> > >> >>
> > >> >> Regarding the "external URL" idea, perhaps you could raise that as
> a
> > >> >> separate ticket, with a code sketch as to how you'd like this
> > >> information
> > >> >> specified?
> > >> >>
> > >> >> Thanks
> > >> >> Dan
> > >> >>
> > >> >>
> > >> >>
> > >> >>
> > >> >>
> > >> >> On 30 July 2015 at 03:17, Stephen Cameron <
> > steve.cameron.62@gmail.com>
> > >> >> wrote:
> > >> >>
> > >> >> > Not so simple, as now the property cannot be updated.
> > >> >> >
> > >> >> > I have the following (@Hidden is deprecated)
> > >> >> >
> > >> >> >     @Column(allowsNull = "true")
> > >> >> >     @MemberOrder(sequence = "7")
> > >> >> >     @PropertyLayout(hidden=Where.EVERYWHERE)
> > >> >> >     public Region getRegion() {
> > >> >> >         return this.region;
> > >> >> >     }
> > >> >> >
> > >> >> >     public void setRegion(Region region) {
> > >> >> >         this.region = region;
> > >> >> >     }
> > >> >> >
> > >> >> >     public List<Region> choicesRegion(){
> > >> >> >         List<Region> regions =
> > container.allInstances(Region.class);
> > >> >> >         return regions;
> > >> >> >     }
> > >> >> >
> > >> >> >     @MemberOrder(sequence = "7.1")
> > >> >> >     public String getRegionName(){
> > >> >> >         return (getRegion() != null) ? getRegion().getName() :
> > null;
> > >> >> >     }
> > >> >> >
> > >> >> > Sure enough getRegion doesn't appear in the UI but getRegionName
> > >> does,
> > >> >> but
> > >> >> > then setRegion and choiceRegion don't mean anything to the UI, so
> > the
> > >> >> > Region property is read-only.
> > >> >> >
> > >> >> > This issue is maybe more significant than it appears at first, in
> > >> terms
> > >> >> of
> > >> >> > domain modelling such code-lists are simple types that
> 'represent'
> > >> >> things
> > >> >> > on the boundary of the domain of interest. So we usually want to
> > just
> > >> >> > represent them with a name. Presently it makes no sense to go to
> > that
> > >> >> thing
> > >> >> > via a hyperlink as all we'll find is that name, our model extends
> > no
> > >> >> > further.
> > >> >> >
> > >> >> > However we just might like to allow users to leave the domain
> model
> > >> and
> > >> >> go
> > >> >> > to a resource outside. So, extending the suppressLink=true idea,
> I
> > >> would
> > >> >> > add that each object could have an implicit link(URL),created by
> > >> Isis,
> > >> >> or
> > >> >> > an explicit one and if the explicit one is present it can
> > optionally
> > >> be
> > >> >> > used as an alternative to the implicit one.
> > >> >> >
> > >> >> > For example, you might create a database to log fish details,
> > species
> > >> >> is a
> > >> >> > boundary concept, we aren't likely to want to add a new species
> to
> > >> the
> > >> >> list
> > >> >> > of known species, but we'd like to keep such a list handy, but
> for
> > >> each
> > >> >> > named species in that list, to provide an explicit link to a
> > resource
> > >> >> in a
> > >> >> > global fish database. It makes more sense to use this link than
> the
> > >> >> > implicit one, as if the implicit one is used we'd navigate to the
> > >> domain
> > >> >> > object page displaying the name and URL, both of which items of
> > data
> > >> >> could
> > >> >> > have been in the explicit link.
> > >> >> >
> > >> >> > In the explicit case you might want to warn the user they are
> > >> navigating
> > >> >> > outside the Isis domain application.
> > >> >> >
> > >> >> > Perhaps all this could be done simply if there was a URI type in
> > >> Isis,
> > >> >> that
> > >> >> > would allow it to create 'smart links' automatically.
> > >> >> >
> > >> >> >
> > >> >> >
> > >> >> >
> > >> >> >
> > >> >> > On Wed, Jul 29, 2015 at 9:37 PM, Stephen Cameron <
> > >> >> > steve.cameron.62@gmail.com
> > >> >> > > wrote:
> > >> >> >
> > >> >> > > Thanks Jeroen, seems simple enough :)
> > >> >> > >
> > >> >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal <
> > >> >> jeroen@stromboli.it
> > >> >> > >
> > >> >> > > wrote:
> > >> >> > >
> > >> >> > >> You could also hide the property and create a separate getter
> > for
> > >> >> > display
> > >> >> > >> purposes only:
> > >> >> > >>
> > >> >> > >> private MyProperty myProperty;
> > >> >> > >>
> > >> >> > >> @Hidden
> > >> >> > >> public MyProperty getMyProperty() {...}
> > >> >> > >>
> > >> >> > >> public void setMyProperty(...) {...}
> > >> >> > >>
> > >> >> > >> public String getMyPropertyName() {
> > >> >> > >>     getMyProperty.getName();
> > >> >> > >> }
> > >> >> > >>
> > >> >> > >> On 29 July 2015 at 13:18, Stephen Cameron <
> > >> >> steve.cameron.62@gmail.com>
> > >> >> > >> wrote:
> > >> >> > >>
> > >> >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood <
> > >> >> > >> dan@haywood-associates.co.uk
> > >> >> > >> > >
> > >> >> > >> > wrote:
> > >> >> > >> >
> > >> >> > >> > > You are right, they will be displayed as links; there's no
> > >> way to
> > >> >> > >> disable
> > >> >> > >> > > it currently.
> > >> >> > >> > >
> > >> >> > >> > > We could add a bit of metadata perhaps for this, eg
> > >> >> > >> > > @DomainObjectLayout(suppressLink=true) or similar.
> > >> >> > >> > >
> > >> >> > >> > > Please raise a ticket.
> > >> >> > >> > >
> > >> >> > >> >
> > >> >> > >> > OK https://issues.apache.org/jira/browse/ISIS-1180
> > >> >> > >> >
> > >> >> > >> > >
> > >> >> > >> > > Thx
> > >> >> > >> > > Dan
> > >> >> > >> > >
> > >> >> > >> > > PS: these entities wouldn't be value types, rather regular
> > >> >> entities.
> > >> >> > >> But
> > >> >> > >> > > you are right... what we really want is full-class support
> > for
> > >> >> value
> > >> >> > >> > types.
> > >> >> > >> > >   We're just not there yet...
> > >> >> > >> > >
> > >> >> > >> > >
> > >> >> > >> > >
> > >> >> > >> >
> > >> >> > >> > >
> > >> >> > >> > >
> > >> >> > >> > > On 29 July 2015 at 09:34, Stephen Cameron <
> > >> >> > steve.cameron.62@gmail.com
> > >> >> > >> >
> > >> >> > >> > > wrote:
> > >> >> > >> > >
> > >> >> > >> > > > Thanks, but surely such object properties always end up
> > >> being
> > >> >> > >> displayed
> > >> >> > >> > > as
> > >> >> > >> > > > links? Clicking on the link to go to such an object page
> > is
> > >> >> > >> > meaningless,
> > >> >> > >> > > as
> > >> >> > >> > > > it only has one name property, that was displayed in the
> > >> link.
> > >> >> > Can I
> > >> >> > >> > > > disable that default behaviour for value types?
> > >> >> > >> > > >
> > >> >> > >> > > >
> > >> >> > >> > > >
> > >> >> > >> > > > On Wed, Jul 29, 2015 at 5:47 PM, Dan Haywood <
> > >> >> > >> > > dan@haywood-associates.co.uk
> > >> >> > >> > > > >
> > >> >> > >> > > > wrote:
> > >> >> > >> > > >
> > >> >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron <
> > >> >> > >> > steve.cameron.62@gmail.com>
> > >> >> > >>
> > >> >> > >> > > > > wrote:
> > >> >> > >> > > > >
> > >> >> > >> > > > > > Hi,
> > >> >> > >> > > > > >
> > >> >> > >> > > > > > I want to do have some properties that are
> essentially
> > >> >> String
> > >> >> > >> > types,
> > >> >> > >> > > > but
> > >> >> > >> > > > > > which have a limited range of values (code-lists or
> > >> >> restricted
> > >> >> > >> > > > > > vocabularies). I want to allow these lists to be
> > >> >> administered
> > >> >> > >> > > > centrally,
> > >> >> > >> > > > > so
> > >> >> > >> > > > > > to add them to a single Administration menu item for
> > >> admin
> > >> >> > >> users.
> > >> >> > >> > > > > >
> > >> >> > >> > > > > > For most users these codes should appears as lists
> of
> > >> >> strings
> > >> >> > >> not
> > >> >> > >> > as
> > >> >> > >> > > > > > objects, but making them objects seems to be the
> > >> logical OO
> > >> >> > way
> > >> >> > >> to
> > >> >> > >> > > deal
> > >> >> > >> > > > > > with them in Isis. So they are basically objects
> with
> > >> one
> > >> >> > 'name'
> > >> >> > >> > > > property
> > >> >> > >> > > > > > (and maybe an id added by datanucleus). All users
> need
> > >> to
> > >> >> see
> > >> >> > is
> > >> >> > >> > the
> > >> >> > >> > > > name
> > >> >> > >> > > > > > property, no icon is needed.
> > >> >> > >> > > > > >
> > >> >> > >> > > > > > Also, if I make them objects I also will get
> > referencial
> > >> >> > >> integrity
> > >> >> > >> > > > > > constraints applied in the database.
> > >> >> > >> > > > > >
> > >> >> > >> > > > > >
> > >> >> > >> > > > > +1, do it this way.  That way they can also hold
> > >> behaviour in
> > >> >> > the
> > >> >> > >> > > future.
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > > > I wonder there is a simple recipe for this?
> > >> >> > >> > > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > > No magic recipe for the domain entities... basically
> > >> >> > copy-n-paste
> > >> >> > >> the
> > >> >> > >> > > > > SimpleObject that's in our archetype as many times as
> > >> needed,
> > >> >> > and
> > >> >> > >> > tweak
> > >> >> > >> > > > as
> > >> >> > >> > > > > required.
> > >> >> > >> > > > >
> > >> >> > >> > > > > If you want to use the code as the primary key, then
> use
> > >> DN
> > >> >> > >> > application
> > >> >> > >> > > > > identity
> > >> >> > >> > > > >
> > >> >> > >> > > > > @javax.jdo.annotations.PersistenceCapable(
> > >> >> > >> > > > >         identityType=IdentityType.APPLICATION,
> > >> >> > >> > > > >         schema = "simple",
> > >> >> > >> > > > >         table = "SimpleObject"
> > >> >> > >> > > > > )
> > >> >> > >> > > > >
> > >> >> > >> > > > > and add @PrimaryKey to the "name" property.  Also add
> > >> @Title
> > >> >> to
> > >> >> > >> that
> > >> >> > >> > > > 'name'
> > >> >> > >> > > > > property (it is in SimpleObject already).
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > > You would probably want to remove the version column,
> ie
> > >> >> remove:
> > >> >> > >> > > > >
> > >> >> > >> > > > > @javax.jdo.annotations.Version(
> > >> >> > >> > > > >         strategy=VersionStrategy.VERSION_NUMBER,
> > >> >> > >> > > > >         column="version")
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > > In addition, if you annotate the class as "bounded"
> > >> >> > >> > > > > (@DomainObject(bounded=true)) then you are telling the
> > >> >> framework
> > >> >> > >> that
> > >> >> > >> > > > > there's a limited - ie bounded - set of instances, and
> > so
> > >> it
> > >> >> > will
> > >> >> > >> > > display
> > >> >> > >> > > > > all instances in a drop-down for you.
> > >> >> > >> > > > >
> > >> >> > >> > > > >
> > >> >> > >> > > > > HTH
> > >> >> > >> > > > > Dan
> > >> >> > >> > > > >
> > >> >> > >> > > >
> > >> >> > >> > >
> > >> >> > >> >
> > >> >> > >>
> > >> >> > >
> > >> >> > >
> > >> >> >
> > >> >>
> > >> >
> > >> >
> > >>
> > >
> > >
> >
>

Re: code-lists and administration thereof

Posted by Stephen Cameron <st...@gmail.com>.
This works nicely in my application.

Thanks Dan

On Mon, Aug 3, 2015 at 6:54 AM, Stephen Cameron <st...@gmail.com>
wrote:

> Hi,
>
> Just trying this now, with current version of kitchen sink I got an error
> message starting the webapp, saying that no persistable classes could be
> found and to check value of
> isis.persistor.datanucleus.RegisterEntities.packagePrefix
> in isis.properties, but that key is in isis_datanucleus.properties.
>
> Also errors in running fixture script :(
>
>
>    - org.apache.wicket.WicketRuntimeException
>    - Method onRequest of interface
>    org.apache.wicket.behavior.IBehaviorListener targeted at
>    org.apache.wicket.ajax.markup.html.AjaxLink$1@1ac79481 on component
>    [AjaxLink [Component id = menuLink]] threw an exception
>    - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:268)
>
>    - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>
>    - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
>
>    -
>    - Caused by:
>    -
>    - java.lang.reflect.InvocationTargetException
>    -
>    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
>    - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
>
>    - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>
>    - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)
>
>    -
>    - Caused by:
>    -
>    - java.lang.IllegalArgumentException
>    - argument type mismatch
>    - sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
>
>    - sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
>
>    - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    - org.apache.isis.applib.fixturescripts.FixtureScript#setParam(FixtureScript.java:689)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript#defaultParam(FixtureScript.java:631)
>
>    - org.isisaddons.app.kitchensink.fixture.primitive.PrimitiveObjectsFixture#execute(PrimitiveObjectsFixture.java:133)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:528)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:498)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:487)
>
>    - org.isisaddons.app.kitchensink.fixture.KitchensinkSetupFixture#execute(KitchensinkSetupFixture.java:62)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#access$200(FixtureScript.java:248)
>
>    - org.apache.isis.applib.fixturescripts.FixtureScript#run(FixtureScript.java:719)
>
>    - org.isisaddons.app.kitchensink.fixture.KitchensinkFixturesService#installFixturesAndReturnFirst(KitchensinkFixturesService.java:95)
>
>    - sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
>
>    - sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
>
>    - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    - org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:356)
>
>    - org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invoke(ActionInvocationFacetForDomainEventAbstract.java:196)
>
>    - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:57)
>
>    - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:54)
>
>    - org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:205)
>
>    - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction#invoke(ActionInvocationFacetWrapTransaction.java:54)
>
>    - org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#execute(ObjectActionImpl.java:367)
>
>    - org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#executeWithRuleChecking(ObjectActionImpl.java:358)
>
>    - org.apache.isis.viewer.wicket.model.models.ActionModel#executeAction(ActionModel.java:467)
>
>    - org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:447)
>
>    - org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:80)
>
>    - org.apache.wicket.model.LoadableDetachableModel#getObject(LoadableDetachableModel.java:121)
>
>    - org.apache.isis.viewer.wicket.model.models.ActionModel#executeHandlingApplicationExceptions(ActionModel.java:543)
>
>    - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionOnTargetAndProcessResults(ActionPanel.java:245)
>
>    - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionAndProcessResults(ActionPanel.java:193)
>
>    - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#buildGui(ActionPanel.java:104)
>
>    - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#<init>(ActionPanel.java:82)
>
>    - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory#createComponent(ActionPanelFactory.java:49)
>
>    - org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault#createComponent(ComponentFactoryRegistryDefault.java:128)
>
>    - org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel.ActionLinkFactoryAbstract$1#onClick(ActionLinkFactoryAbstract.java:74)
>
>    - org.apache.wicket.ajax.markup.html.AjaxLink$1#onEvent(AjaxLink.java:86)
>
>    - org.apache.wicket.ajax.AjaxEventBehavior#respond(AjaxEventBehavior.java:124)
>
>    - org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onRequest(AbstractDefaultAjaxBehavior.java:633)
>
>    - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
>    - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
>
>    - java.lang.reflect.Method#invoke(Method.java:497)
>    - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
>
>    - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)
>
>    - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)
>
>    - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)
>
>    - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
>
>    - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)
>
>    - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)
>
>    - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)
>
>    - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
>
>    - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
>
>    - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
>
>    - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
>
>    - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
>
>    - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
>
>    - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)
>
>    - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)
>
>    - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)
>
>    - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)
>
>    - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)
>
>    - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
>
>    - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)
>
>    - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)
>
>    - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)
>
>    - org.mortbay.jetty.Server#handle(Server.java:326)
>    - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)
>
>    - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)
>
>    - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
>    - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
>    - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
>    - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)
>
>    - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582
>
>
>
>
> On Sun, Aug 2, 2015 at 11:23 PM, Dan Haywood <dan@haywood-associates.co.uk
> > wrote:
>
>> Further to this, I've updated the kitchensink (against 1.9.0-SNAPSHOT) to
>> demonstrate this technique....
>>
>> The code is in ReferenceObject, which you can get to from the "Data Types"
>> menu.  Use the fixture scripts menu to create some sample data.
>>
>> The relevant code is below.
>>
>> Cheers
>> Dan
>>
>> [1]  https://github.com/isisaddons/isis-app-kitchensink
>>
>>
>>     private OtherObject someOtherObjectUsingName;
>>
>>     @Property(hidden = Where.EVERYWHERE)
>>     @Column(allowsNull = "true")
>>     public OtherObject getSomeOtherObjectUsingName() {
>>         return someOtherObjectUsingName;
>>     }
>>
>>     public void setSomeOtherObjectUsingName(final OtherObject
>> someOtherObjectUsingName) {
>>         this.someOtherObjectUsingName = someOtherObjectUsingName;
>>     }
>>
>>     @NotPersistent
>>     public String getSomeOtherObjectUsingNameName() {
>>         return getSomeOtherObjectUsingName() != null?
>> getSomeOtherObjectUsingName().getName() : null;
>>     }
>>
>>     public void setSomeOtherObjectUsingNameName(final String name) {
>>         OtherObject otherObject = name != null
>>                 ? container.firstMatch(OtherObject.class, withName(name))
>>                 : null;
>>         setSomeOtherObjectUsingName(otherObject);
>>     }
>>
>>     public List<String> choicesSomeOtherObjectUsingNameName() {
>>         List<OtherObject> otherObjects =
>> container.allInstances(OtherObject.class);
>>         return Lists.newArrayList(
>>                 Iterables.transform(otherObjects, nameOf())
>>         );
>>     }
>>
>>     private static Function<OtherObject, String> nameOf() {
>>         return new Function<OtherObject, String>() {
>>             @Nullable @Override public String apply(final OtherObject
>> input) {
>>                 return input.getName();
>>             }
>>         };
>>     }
>>
>>     private static Predicate<OtherObject> withName(final String name) {
>>         return new Predicate<OtherObject>() {
>>         @Override public boolean apply(final OtherObject input) {
>>              return Objects.equal(input.getName(), name);
>>             }
>>     };
>>     }
>>
>>
>>
>>
>>
>> On 30 July 2015 at 13:16, Dan Haywood <da...@haywood-associates.co.uk>
>> wrote:
>>
>> > looks right to me, so I'll take a look at in this eve or tomorrow.
>> >
>> > thx
>> > Dan
>> >
>> >
>> > On 30 July 2015 at 13:12, Stephen Cameron <st...@gmail.com>
>> > wrote:
>> >
>> >> Still no luck with this one.
>> >>
>> >> The derived RegionName appears as a non-editable property, so not sure
>> >> what
>> >> was different before when I was getting an model validation error.
>> >>
>> >> My current code of interest is this:
>> >>
>> >>     @Column(name = "region", allowsNull = "true")
>> >>     //@MemberOrder(sequence = "7")
>> >>     @Property(hidden=Where.EVERYWHERE)
>> >>     public Region getRegion() {
>> >>         return this.region;
>> >>     }
>> >>
>> >>     public void setRegion(Region region) {
>> >>         this.region = region;
>> >>     }
>> >>
>> >>     public List<Region> choicesRegion() {
>> >>         return regions.listAllRegions();
>> >>     }
>> >>
>> >>     @MemberOrder(sequence = "7")
>> >>     public String getRegionName() {
>> >>         return regions.nameForRegion(getRegion());
>> >>     }
>> >>
>> >>     public void setRegionName(String name) {
>> >>         setRegion(regions.regionForName(name));
>> >>     }
>> >>
>> >>     public List<String> choicesRegionName(){
>> >>         return regions.listAllNamesExclusive(getRegion());
>> >>     }
>> >>
>> >> My Region class is this:
>> >>
>> >> package au.com.scds.chats.dom.modules.general.codes;
>> >>
>> >> import javax.jdo.annotations.Column;
>> >> import javax.jdo.annotations.IdentityType;
>> >> import javax.jdo.annotations.PrimaryKey;
>> >>
>> >> import org.apache.isis.applib.annotation.Action;
>> >> import org.apache.isis.applib.annotation.ActionLayout;
>> >> import org.apache.isis.applib.annotation.DomainServiceLayout;
>> >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
>> >> import org.apache.isis.applib.annotation.MemberOrder;
>> >> import org.apache.isis.applib.annotation.PropertyLayout;
>> >>
>> >> @javax.jdo.annotations.PersistenceCapable(
>> >>          identityType=IdentityType.APPLICATION)
>> >> public class Region {
>> >>
>> >>     public String title(){
>> >>         return getName();
>> >>     }
>> >>
>> >>     private String name;
>> >>
>> >>     @Column(name="region", allowsNull = "false")
>> >>     @PrimaryKey()
>> >>     @PropertyLayout(named="Region")
>> >>     @MemberOrder(sequence="1")
>> >>     public String getName() {
>> >>         return name;
>> >>     }
>> >>
>> >>     public void setName(String name) {
>> >>         this.name = name;
>> >>     }
>> >> }
>> >>
>> >> My Regions repository class is this:
>> >>
>> >> package au.com.scds.chats.dom.modules.general.codes;
>> >>
>> >> import java.util.ArrayList;
>> >> import java.util.List;
>> >>
>> >> import org.apache.isis.applib.DomainObjectContainer;
>> >> import org.apache.isis.applib.annotation.Action;
>> >> import org.apache.isis.applib.annotation.ActionLayout;
>> >> import org.apache.isis.applib.annotation.BookmarkPolicy;
>> >> import org.apache.isis.applib.annotation.DomainService;
>> >> import org.apache.isis.applib.annotation.DomainServiceLayout;
>> >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
>> >> import org.apache.isis.applib.annotation.MemberOrder;
>> >> import org.apache.isis.applib.annotation.ParameterLayout;
>> >> import org.apache.isis.applib.annotation.Programmatic;
>> >> import org.apache.isis.applib.annotation.SemanticsOf;
>> >> import org.apache.isis.applib.query.QueryDefault;
>> >>
>> >> import au.com.scds.chats.dom.modules.participant.Participant;
>> >>
>> >> @DomainService(repositoryFor = Region.class)
>> >> @DomainServiceLayout(menuBar = MenuBar.SECONDARY, named =
>> >> "Administration",
>> >> menuOrder = "100.1")
>> >> public class Regions {
>> >>
>> >>     // region > listAll (action)
>> >>     @Action(semantics = SemanticsOf.SAFE)
>> >>     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
>> >>     @MemberOrder(sequence = "1")
>> >>     public List<Region> listAllRegions() {
>> >>         return container.allInstances(Region.class);
>> >>     }
>> >>
>> >>     // endregion
>> >>
>> >>     // region > create (action)
>> >>     @MemberOrder(sequence = "2")
>> >>     public Region createRegion(
>> >>             final @ParameterLayout(named = "Region Name") String name)
>> {
>> >>         final Region obj =
>> container.newTransientInstance(Region.class);
>> >>         obj.setName(name);
>> >>         container.persistIfNotAlready(obj);
>> >>         return obj;
>> >>     }
>> >>
>> >>     // endregion
>> >>
>> >>     // region > injected services
>> >>
>> >>     @javax.inject.Inject
>> >>     DomainObjectContainer container;
>> >>
>> >>     // endregion
>> >>
>> >>     @Programmatic
>> >>     public String nameForRegion(Region region) {
>> >>         return (region != null) ? region.getName() : null;
>> >>     }
>> >>
>> >>
>> >>     @Programmatic
>> >>     public List<String> listAllNamesExclusive(Region region) {
>> >>         List<Region> regions = listAllRegions();
>> >>         List<String> names = new ArrayList<String>();
>> >>         for (Region r : regions) {
>> >>             if (region != null && r != region) {
>> >>                 names.add(r.getName());
>> >>             }
>> >>         }
>> >>         return names;
>> >>     }
>> >>
>> >>
>> >>     @Programmatic
>> >>     public Region regionForName(String name) {
>> >>         Region region = container.firstMatch(new QueryDefault<>(
>> >> Region.class,
>> >>                  "findRegion", "name", name));
>> >>         return region;
>> >>     }
>> >>
>> >> }
>> >>
>> >> Just maybe I there is something missing still?
>> >>
>> >> I added a @Property annotation to the getRegionName() method, but that
>> >> gave
>> >> me a message saying it expected @javax.jdo.persistence.Column too.
>> >>
>> >> Note I couldn't use deprecated @Hidden in Isis 1.9.0.
>> >>
>> >>
>> >> On Thu, Jul 30, 2015 at 8:14 PM, Stephen Cameron <
>> >> steve.cameron.62@gmail.com
>> >> > wrote:
>> >>
>> >> > Hi Dan, When I tried this I got an model validation error message
>> >> relating
>> >> > to the choices method, I will have another go and if it fails,
>> provide
>> >> the
>> >> > test case. Thanks for the tips.
>> >> >
>> >> > On Thu, Jul 30, 2015 at 7:57 PM, Dan Haywood <
>> >> dan@haywood-associates.co.uk
>> >> > > wrote:
>> >> >
>> >> >> You should be able to add a choicesXxx() for the derived property:
>> >> >>
>> >> >>     public List<String> choicesRegionName(){
>> >> >>         return
>> Lists.newArrayList(Iterables.transform(choicesRegion(),
>> >> x
>> >> >> ->
>> >> >> x.getName()));
>> >> >>     }
>> >> >>
>> >> >> If that isn't sufficient, you might also need to add a setter:
>> >> >>
>> >> >> public void setRegionName(final String name) {
>> >> >> setRegion(Iterables.find(choicesRegion(), x ->
>> >> x.getName().equals(name)));
>> >> >> }
>> >> >>
>> >> >> Obviously, you might need to also add some error handling.
>> >> >>
>> >> >> ~~~
>> >> >>
>> >> >> Regarding the "external URL" idea, perhaps you could raise that as a
>> >> >> separate ticket, with a code sketch as to how you'd like this
>> >> information
>> >> >> specified?
>> >> >>
>> >> >> Thanks
>> >> >> Dan
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> On 30 July 2015 at 03:17, Stephen Cameron <
>> steve.cameron.62@gmail.com>
>> >> >> wrote:
>> >> >>
>> >> >> > Not so simple, as now the property cannot be updated.
>> >> >> >
>> >> >> > I have the following (@Hidden is deprecated)
>> >> >> >
>> >> >> >     @Column(allowsNull = "true")
>> >> >> >     @MemberOrder(sequence = "7")
>> >> >> >     @PropertyLayout(hidden=Where.EVERYWHERE)
>> >> >> >     public Region getRegion() {
>> >> >> >         return this.region;
>> >> >> >     }
>> >> >> >
>> >> >> >     public void setRegion(Region region) {
>> >> >> >         this.region = region;
>> >> >> >     }
>> >> >> >
>> >> >> >     public List<Region> choicesRegion(){
>> >> >> >         List<Region> regions =
>> container.allInstances(Region.class);
>> >> >> >         return regions;
>> >> >> >     }
>> >> >> >
>> >> >> >     @MemberOrder(sequence = "7.1")
>> >> >> >     public String getRegionName(){
>> >> >> >         return (getRegion() != null) ? getRegion().getName() :
>> null;
>> >> >> >     }
>> >> >> >
>> >> >> > Sure enough getRegion doesn't appear in the UI but getRegionName
>> >> does,
>> >> >> but
>> >> >> > then setRegion and choiceRegion don't mean anything to the UI, so
>> the
>> >> >> > Region property is read-only.
>> >> >> >
>> >> >> > This issue is maybe more significant than it appears at first, in
>> >> terms
>> >> >> of
>> >> >> > domain modelling such code-lists are simple types that 'represent'
>> >> >> things
>> >> >> > on the boundary of the domain of interest. So we usually want to
>> just
>> >> >> > represent them with a name. Presently it makes no sense to go to
>> that
>> >> >> thing
>> >> >> > via a hyperlink as all we'll find is that name, our model extends
>> no
>> >> >> > further.
>> >> >> >
>> >> >> > However we just might like to allow users to leave the domain
>> model
>> >> and
>> >> >> go
>> >> >> > to a resource outside. So, extending the suppressLink=true idea, I
>> >> would
>> >> >> > add that each object could have an implicit link(URL),created by
>> >> Isis,
>> >> >> or
>> >> >> > an explicit one and if the explicit one is present it can
>> optionally
>> >> be
>> >> >> > used as an alternative to the implicit one.
>> >> >> >
>> >> >> > For example, you might create a database to log fish details,
>> species
>> >> >> is a
>> >> >> > boundary concept, we aren't likely to want to add a new species to
>> >> the
>> >> >> list
>> >> >> > of known species, but we'd like to keep such a list handy, but for
>> >> each
>> >> >> > named species in that list, to provide an explicit link to a
>> resource
>> >> >> in a
>> >> >> > global fish database. It makes more sense to use this link than
>> the
>> >> >> > implicit one, as if the implicit one is used we'd navigate to the
>> >> domain
>> >> >> > object page displaying the name and URL, both of which items of
>> data
>> >> >> could
>> >> >> > have been in the explicit link.
>> >> >> >
>> >> >> > In the explicit case you might want to warn the user they are
>> >> navigating
>> >> >> > outside the Isis domain application.
>> >> >> >
>> >> >> > Perhaps all this could be done simply if there was a URI type in
>> >> Isis,
>> >> >> that
>> >> >> > would allow it to create 'smart links' automatically.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> > On Wed, Jul 29, 2015 at 9:37 PM, Stephen Cameron <
>> >> >> > steve.cameron.62@gmail.com
>> >> >> > > wrote:
>> >> >> >
>> >> >> > > Thanks Jeroen, seems simple enough :)
>> >> >> > >
>> >> >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal <
>> >> >> jeroen@stromboli.it
>> >> >> > >
>> >> >> > > wrote:
>> >> >> > >
>> >> >> > >> You could also hide the property and create a separate getter
>> for
>> >> >> > display
>> >> >> > >> purposes only:
>> >> >> > >>
>> >> >> > >> private MyProperty myProperty;
>> >> >> > >>
>> >> >> > >> @Hidden
>> >> >> > >> public MyProperty getMyProperty() {...}
>> >> >> > >>
>> >> >> > >> public void setMyProperty(...) {...}
>> >> >> > >>
>> >> >> > >> public String getMyPropertyName() {
>> >> >> > >>     getMyProperty.getName();
>> >> >> > >> }
>> >> >> > >>
>> >> >> > >> On 29 July 2015 at 13:18, Stephen Cameron <
>> >> >> steve.cameron.62@gmail.com>
>> >> >> > >> wrote:
>> >> >> > >>
>> >> >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood <
>> >> >> > >> dan@haywood-associates.co.uk
>> >> >> > >> > >
>> >> >> > >> > wrote:
>> >> >> > >> >
>> >> >> > >> > > You are right, they will be displayed as links; there's no
>> >> way to
>> >> >> > >> disable
>> >> >> > >> > > it currently.
>> >> >> > >> > >
>> >> >> > >> > > We could add a bit of metadata perhaps for this, eg
>> >> >> > >> > > @DomainObjectLayout(suppressLink=true) or similar.
>> >> >> > >> > >
>> >> >> > >> > > Please raise a ticket.
>> >> >> > >> > >
>> >> >> > >> >
>> >> >> > >> > OK https://issues.apache.org/jira/browse/ISIS-1180
>> >> >> > >> >
>> >> >> > >> > >
>> >> >> > >> > > Thx
>> >> >> > >> > > Dan
>> >> >> > >> > >
>> >> >> > >> > > PS: these entities wouldn't be value types, rather regular
>> >> >> entities.
>> >> >> > >> But
>> >> >> > >> > > you are right... what we really want is full-class support
>> for
>> >> >> value
>> >> >> > >> > types.
>> >> >> > >> > >   We're just not there yet...
>> >> >> > >> > >
>> >> >> > >> > >
>> >> >> > >> > >
>> >> >> > >> >
>> >> >> > >> > >
>> >> >> > >> > >
>> >> >> > >> > > On 29 July 2015 at 09:34, Stephen Cameron <
>> >> >> > steve.cameron.62@gmail.com
>> >> >> > >> >
>> >> >> > >> > > wrote:
>> >> >> > >> > >
>> >> >> > >> > > > Thanks, but surely such object properties always end up
>> >> being
>> >> >> > >> displayed
>> >> >> > >> > > as
>> >> >> > >> > > > links? Clicking on the link to go to such an object page
>> is
>> >> >> > >> > meaningless,
>> >> >> > >> > > as
>> >> >> > >> > > > it only has one name property, that was displayed in the
>> >> link.
>> >> >> > Can I
>> >> >> > >> > > > disable that default behaviour for value types?
>> >> >> > >> > > >
>> >> >> > >> > > >
>> >> >> > >> > > >
>> >> >> > >> > > > On Wed, Jul 29, 2015 at 5:47 PM, Dan Haywood <
>> >> >> > >> > > dan@haywood-associates.co.uk
>> >> >> > >> > > > >
>> >> >> > >> > > > wrote:
>> >> >> > >> > > >
>> >> >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron <
>> >> >> > >> > steve.cameron.62@gmail.com>
>> >> >> > >>
>> >> >> > >> > > > > wrote:
>> >> >> > >> > > > >
>> >> >> > >> > > > > > Hi,
>> >> >> > >> > > > > >
>> >> >> > >> > > > > > I want to do have some properties that are
>> essentially
>> >> >> String
>> >> >> > >> > types,
>> >> >> > >> > > > but
>> >> >> > >> > > > > > which have a limited range of values (code-lists or
>> >> >> restricted
>> >> >> > >> > > > > > vocabularies). I want to allow these lists to be
>> >> >> administered
>> >> >> > >> > > > centrally,
>> >> >> > >> > > > > so
>> >> >> > >> > > > > > to add them to a single Administration menu item for
>> >> admin
>> >> >> > >> users.
>> >> >> > >> > > > > >
>> >> >> > >> > > > > > For most users these codes should appears as lists of
>> >> >> strings
>> >> >> > >> not
>> >> >> > >> > as
>> >> >> > >> > > > > > objects, but making them objects seems to be the
>> >> logical OO
>> >> >> > way
>> >> >> > >> to
>> >> >> > >> > > deal
>> >> >> > >> > > > > > with them in Isis. So they are basically objects with
>> >> one
>> >> >> > 'name'
>> >> >> > >> > > > property
>> >> >> > >> > > > > > (and maybe an id added by datanucleus). All users
>> need
>> >> to
>> >> >> see
>> >> >> > is
>> >> >> > >> > the
>> >> >> > >> > > > name
>> >> >> > >> > > > > > property, no icon is needed.
>> >> >> > >> > > > > >
>> >> >> > >> > > > > > Also, if I make them objects I also will get
>> referencial
>> >> >> > >> integrity
>> >> >> > >> > > > > > constraints applied in the database.
>> >> >> > >> > > > > >
>> >> >> > >> > > > > >
>> >> >> > >> > > > > +1, do it this way.  That way they can also hold
>> >> behaviour in
>> >> >> > the
>> >> >> > >> > > future.
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > > > I wonder there is a simple recipe for this?
>> >> >> > >> > > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > > No magic recipe for the domain entities... basically
>> >> >> > copy-n-paste
>> >> >> > >> the
>> >> >> > >> > > > > SimpleObject that's in our archetype as many times as
>> >> needed,
>> >> >> > and
>> >> >> > >> > tweak
>> >> >> > >> > > > as
>> >> >> > >> > > > > required.
>> >> >> > >> > > > >
>> >> >> > >> > > > > If you want to use the code as the primary key, then
>> use
>> >> DN
>> >> >> > >> > application
>> >> >> > >> > > > > identity
>> >> >> > >> > > > >
>> >> >> > >> > > > > @javax.jdo.annotations.PersistenceCapable(
>> >> >> > >> > > > >         identityType=IdentityType.APPLICATION,
>> >> >> > >> > > > >         schema = "simple",
>> >> >> > >> > > > >         table = "SimpleObject"
>> >> >> > >> > > > > )
>> >> >> > >> > > > >
>> >> >> > >> > > > > and add @PrimaryKey to the "name" property.  Also add
>> >> @Title
>> >> >> to
>> >> >> > >> that
>> >> >> > >> > > > 'name'
>> >> >> > >> > > > > property (it is in SimpleObject already).
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > > You would probably want to remove the version column,
>> ie
>> >> >> remove:
>> >> >> > >> > > > >
>> >> >> > >> > > > > @javax.jdo.annotations.Version(
>> >> >> > >> > > > >         strategy=VersionStrategy.VERSION_NUMBER,
>> >> >> > >> > > > >         column="version")
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > > In addition, if you annotate the class as "bounded"
>> >> >> > >> > > > > (@DomainObject(bounded=true)) then you are telling the
>> >> >> framework
>> >> >> > >> that
>> >> >> > >> > > > > there's a limited - ie bounded - set of instances, and
>> so
>> >> it
>> >> >> > will
>> >> >> > >> > > display
>> >> >> > >> > > > > all instances in a drop-down for you.
>> >> >> > >> > > > >
>> >> >> > >> > > > >
>> >> >> > >> > > > > HTH
>> >> >> > >> > > > > Dan
>> >> >> > >> > > > >
>> >> >> > >> > > >
>> >> >> > >> > >
>> >> >> > >> >
>> >> >> > >>
>> >> >> > >
>> >> >> > >
>> >> >> >
>> >> >>
>> >> >
>> >> >
>> >>
>> >
>> >
>>
>
>

Re: code-lists and administration thereof

Posted by Stephen Cameron <st...@gmail.com>.
Hi,

Just trying this now, with current version of kitchen sink I got an error
message starting the webapp, saying that no persistable classes could be
found and to check value of
isis.persistor.datanucleus.RegisterEntities.packagePrefix
in isis.properties, but that key is in isis_datanucleus.properties.

Also errors in running fixture script :(


   - org.apache.wicket.WicketRuntimeException
   - Method onRequest of interface
   org.apache.wicket.behavior.IBehaviorListener targeted at
   org.apache.wicket.ajax.markup.html.AjaxLink$1@1ac79481 on component
   [AjaxLink [Component id = menuLink]] threw an exception
   - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:268)

   - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)

   - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)

   - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)

   - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)

   - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)

   - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)

   - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)

   - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)

   - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)

   - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)

   - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)

   - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)

   - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)

   - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)

   - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)

   - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)

   - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)

   - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
   - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)

   - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)

   - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)

   - org.mortbay.jetty.Server#handle(Server.java:326)
   - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)

   - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)

   - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
   - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
   - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
   - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)

   - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)

   -
   - Caused by:
   -
   - java.lang.reflect.InvocationTargetException
   -
   - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
   - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)

   - java.lang.reflect.Method#invoke(Method.java:497)
   - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)

   - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)

   - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)

   - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)

   - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)

   - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)

   - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)

   - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)

   - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)

   - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)

   - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)

   - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)

   - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)

   - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)

   - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)

   - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)

   - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)

   - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)

   - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
   - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)

   - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)

   - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)

   - org.mortbay.jetty.Server#handle(Server.java:326)
   - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)

   - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)

   - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
   - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
   - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
   - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)

   - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582)

   -
   - Caused by:
   -
   - java.lang.IllegalArgumentException
   - argument type mismatch
   - sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)

   - sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)

   - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)

   - java.lang.reflect.Method#invoke(Method.java:497)
   - org.apache.isis.applib.fixturescripts.FixtureScript#setParam(FixtureScript.java:689)

   - org.apache.isis.applib.fixturescripts.FixtureScript#defaultParam(FixtureScript.java:631)

   - org.isisaddons.app.kitchensink.fixture.primitive.PrimitiveObjectsFixture#execute(PrimitiveObjectsFixture.java:133)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:528)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:498)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:487)

   - org.isisaddons.app.kitchensink.fixture.KitchensinkSetupFixture#execute(KitchensinkSetupFixture.java:62)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:549)

   - org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#access$200(FixtureScript.java:248)

   - org.apache.isis.applib.fixturescripts.FixtureScript#run(FixtureScript.java:719)

   - org.isisaddons.app.kitchensink.fixture.KitchensinkFixturesService#installFixturesAndReturnFirst(KitchensinkFixturesService.java:95)

   - sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)

   - sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)

   - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)

   - java.lang.reflect.Method#invoke(Method.java:497)
   - org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:356)

   - org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invoke(ActionInvocationFacetForDomainEventAbstract.java:196)

   - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:57)

   - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1#execute(ActionInvocationFacetWrapTransaction.java:54)

   - org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:205)

   - org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction#invoke(ActionInvocationFacetWrapTransaction.java:54)

   - org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#execute(ObjectActionImpl.java:367)

   - org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl#executeWithRuleChecking(ObjectActionImpl.java:358)

   - org.apache.isis.viewer.wicket.model.models.ActionModel#executeAction(ActionModel.java:467)

   - org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:447)

   - org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:80)

   - org.apache.wicket.model.LoadableDetachableModel#getObject(LoadableDetachableModel.java:121)

   - org.apache.isis.viewer.wicket.model.models.ActionModel#executeHandlingApplicationExceptions(ActionModel.java:543)

   - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionOnTargetAndProcessResults(ActionPanel.java:245)

   - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#executeActionAndProcessResults(ActionPanel.java:193)

   - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#buildGui(ActionPanel.java:104)

   - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel#<init>(ActionPanel.java:82)

   - org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory#createComponent(ActionPanelFactory.java:49)

   - org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault#createComponent(ComponentFactoryRegistryDefault.java:128)

   - org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel.ActionLinkFactoryAbstract$1#onClick(ActionLinkFactoryAbstract.java:74)

   - org.apache.wicket.ajax.markup.html.AjaxLink$1#onEvent(AjaxLink.java:86)

   - org.apache.wicket.ajax.AjaxEventBehavior#respond(AjaxEventBehavior.java:124)

   - org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onRequest(AbstractDefaultAjaxBehavior.java:633)

   - sun.reflect.GeneratedMethodAccessor98#invoke(null:-1)
   - sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)

   - java.lang.reflect.Method#invoke(Method.java:497)
   - org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)

   - org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:250)

   - org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:236)

   - org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:862)

   - org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)

   - org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:261)

   - org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:218)

   - org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:289)

   - org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:259)

   - org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:201)

   - org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:282)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)

   - org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)

   - org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)

   - org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)

   - org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)

   - org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)

   - org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)

   - org.mortbay.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1212)

   - org.mortbay.jetty.servlet.ServletHandler#handle(ServletHandler.java:399)

   - org.mortbay.jetty.security.SecurityHandler#handle(SecurityHandler.java:216)

   - org.mortbay.jetty.servlet.SessionHandler#handle(SessionHandler.java:182)

   - org.mortbay.jetty.handler.ContextHandler#handle(ContextHandler.java:766)

   - org.mortbay.jetty.webapp.WebAppContext#handle(WebAppContext.java:450)
   - org.mortbay.jetty.handler.ContextHandlerCollection#handle(ContextHandlerCollection.java:230)

   - org.mortbay.jetty.handler.HandlerCollection#handle(HandlerCollection.java:114)

   - org.mortbay.jetty.handler.HandlerWrapper#handle(HandlerWrapper.java:152)

   - org.mortbay.jetty.Server#handle(Server.java:326)
   - org.mortbay.jetty.HttpConnection#handleRequest(HttpConnection.java:542)

   - org.mortbay.jetty.HttpConnection$RequestHandler#headerComplete(HttpConnection.java:928)

   - org.mortbay.jetty.HttpParser#parseNext(HttpParser.java:549)
   - org.mortbay.jetty.HttpParser#parseAvailable(HttpParser.java:212)
   - org.mortbay.jetty.HttpConnection#handle(HttpConnection.java:404)
   - org.mortbay.io.nio.SelectChannelEndPoint#run(SelectChannelEndPoint.java:410)

   - org.mortbay.thread.QueuedThreadPool$PoolThread#run(QueuedThreadPool.java:582




On Sun, Aug 2, 2015 at 11:23 PM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:

> Further to this, I've updated the kitchensink (against 1.9.0-SNAPSHOT) to
> demonstrate this technique....
>
> The code is in ReferenceObject, which you can get to from the "Data Types"
> menu.  Use the fixture scripts menu to create some sample data.
>
> The relevant code is below.
>
> Cheers
> Dan
>
> [1]  https://github.com/isisaddons/isis-app-kitchensink
>
>
>     private OtherObject someOtherObjectUsingName;
>
>     @Property(hidden = Where.EVERYWHERE)
>     @Column(allowsNull = "true")
>     public OtherObject getSomeOtherObjectUsingName() {
>         return someOtherObjectUsingName;
>     }
>
>     public void setSomeOtherObjectUsingName(final OtherObject
> someOtherObjectUsingName) {
>         this.someOtherObjectUsingName = someOtherObjectUsingName;
>     }
>
>     @NotPersistent
>     public String getSomeOtherObjectUsingNameName() {
>         return getSomeOtherObjectUsingName() != null?
> getSomeOtherObjectUsingName().getName() : null;
>     }
>
>     public void setSomeOtherObjectUsingNameName(final String name) {
>         OtherObject otherObject = name != null
>                 ? container.firstMatch(OtherObject.class, withName(name))
>                 : null;
>         setSomeOtherObjectUsingName(otherObject);
>     }
>
>     public List<String> choicesSomeOtherObjectUsingNameName() {
>         List<OtherObject> otherObjects =
> container.allInstances(OtherObject.class);
>         return Lists.newArrayList(
>                 Iterables.transform(otherObjects, nameOf())
>         );
>     }
>
>     private static Function<OtherObject, String> nameOf() {
>         return new Function<OtherObject, String>() {
>             @Nullable @Override public String apply(final OtherObject
> input) {
>                 return input.getName();
>             }
>         };
>     }
>
>     private static Predicate<OtherObject> withName(final String name) {
>         return new Predicate<OtherObject>() {
>         @Override public boolean apply(final OtherObject input) {
>              return Objects.equal(input.getName(), name);
>             }
>     };
>     }
>
>
>
>
>
> On 30 July 2015 at 13:16, Dan Haywood <da...@haywood-associates.co.uk>
> wrote:
>
> > looks right to me, so I'll take a look at in this eve or tomorrow.
> >
> > thx
> > Dan
> >
> >
> > On 30 July 2015 at 13:12, Stephen Cameron <st...@gmail.com>
> > wrote:
> >
> >> Still no luck with this one.
> >>
> >> The derived RegionName appears as a non-editable property, so not sure
> >> what
> >> was different before when I was getting an model validation error.
> >>
> >> My current code of interest is this:
> >>
> >>     @Column(name = "region", allowsNull = "true")
> >>     //@MemberOrder(sequence = "7")
> >>     @Property(hidden=Where.EVERYWHERE)
> >>     public Region getRegion() {
> >>         return this.region;
> >>     }
> >>
> >>     public void setRegion(Region region) {
> >>         this.region = region;
> >>     }
> >>
> >>     public List<Region> choicesRegion() {
> >>         return regions.listAllRegions();
> >>     }
> >>
> >>     @MemberOrder(sequence = "7")
> >>     public String getRegionName() {
> >>         return regions.nameForRegion(getRegion());
> >>     }
> >>
> >>     public void setRegionName(String name) {
> >>         setRegion(regions.regionForName(name));
> >>     }
> >>
> >>     public List<String> choicesRegionName(){
> >>         return regions.listAllNamesExclusive(getRegion());
> >>     }
> >>
> >> My Region class is this:
> >>
> >> package au.com.scds.chats.dom.modules.general.codes;
> >>
> >> import javax.jdo.annotations.Column;
> >> import javax.jdo.annotations.IdentityType;
> >> import javax.jdo.annotations.PrimaryKey;
> >>
> >> import org.apache.isis.applib.annotation.Action;
> >> import org.apache.isis.applib.annotation.ActionLayout;
> >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> >> import org.apache.isis.applib.annotation.MemberOrder;
> >> import org.apache.isis.applib.annotation.PropertyLayout;
> >>
> >> @javax.jdo.annotations.PersistenceCapable(
> >>          identityType=IdentityType.APPLICATION)
> >> public class Region {
> >>
> >>     public String title(){
> >>         return getName();
> >>     }
> >>
> >>     private String name;
> >>
> >>     @Column(name="region", allowsNull = "false")
> >>     @PrimaryKey()
> >>     @PropertyLayout(named="Region")
> >>     @MemberOrder(sequence="1")
> >>     public String getName() {
> >>         return name;
> >>     }
> >>
> >>     public void setName(String name) {
> >>         this.name = name;
> >>     }
> >> }
> >>
> >> My Regions repository class is this:
> >>
> >> package au.com.scds.chats.dom.modules.general.codes;
> >>
> >> import java.util.ArrayList;
> >> import java.util.List;
> >>
> >> import org.apache.isis.applib.DomainObjectContainer;
> >> import org.apache.isis.applib.annotation.Action;
> >> import org.apache.isis.applib.annotation.ActionLayout;
> >> import org.apache.isis.applib.annotation.BookmarkPolicy;
> >> import org.apache.isis.applib.annotation.DomainService;
> >> import org.apache.isis.applib.annotation.DomainServiceLayout;
> >> import org.apache.isis.applib.annotation.DomainServiceLayout.MenuBar;
> >> import org.apache.isis.applib.annotation.MemberOrder;
> >> import org.apache.isis.applib.annotation.ParameterLayout;
> >> import org.apache.isis.applib.annotation.Programmatic;
> >> import org.apache.isis.applib.annotation.SemanticsOf;
> >> import org.apache.isis.applib.query.QueryDefault;
> >>
> >> import au.com.scds.chats.dom.modules.participant.Participant;
> >>
> >> @DomainService(repositoryFor = Region.class)
> >> @DomainServiceLayout(menuBar = MenuBar.SECONDARY, named =
> >> "Administration",
> >> menuOrder = "100.1")
> >> public class Regions {
> >>
> >>     // region > listAll (action)
> >>     @Action(semantics = SemanticsOf.SAFE)
> >>     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
> >>     @MemberOrder(sequence = "1")
> >>     public List<Region> listAllRegions() {
> >>         return container.allInstances(Region.class);
> >>     }
> >>
> >>     // endregion
> >>
> >>     // region > create (action)
> >>     @MemberOrder(sequence = "2")
> >>     public Region createRegion(
> >>             final @ParameterLayout(named = "Region Name") String name) {
> >>         final Region obj = container.newTransientInstance(Region.class);
> >>         obj.setName(name);
> >>         container.persistIfNotAlready(obj);
> >>         return obj;
> >>     }
> >>
> >>     // endregion
> >>
> >>     // region > injected services
> >>
> >>     @javax.inject.Inject
> >>     DomainObjectContainer container;
> >>
> >>     // endregion
> >>
> >>     @Programmatic
> >>     public String nameForRegion(Region region) {
> >>         return (region != null) ? region.getName() : null;
> >>     }
> >>
> >>
> >>     @Programmatic
> >>     public List<String> listAllNamesExclusive(Region region) {
> >>         List<Region> regions = listAllRegions();
> >>         List<String> names = new ArrayList<String>();
> >>         for (Region r : regions) {
> >>             if (region != null && r != region) {
> >>                 names.add(r.getName());
> >>             }
> >>         }
> >>         return names;
> >>     }
> >>
> >>
> >>     @Programmatic
> >>     public Region regionForName(String name) {
> >>         Region region = container.firstMatch(new QueryDefault<>(
> >> Region.class,
> >>                  "findRegion", "name", name));
> >>         return region;
> >>     }
> >>
> >> }
> >>
> >> Just maybe I there is something missing still?
> >>
> >> I added a @Property annotation to the getRegionName() method, but that
> >> gave
> >> me a message saying it expected @javax.jdo.persistence.Column too.
> >>
> >> Note I couldn't use deprecated @Hidden in Isis 1.9.0.
> >>
> >>
> >> On Thu, Jul 30, 2015 at 8:14 PM, Stephen Cameron <
> >> steve.cameron.62@gmail.com
> >> > wrote:
> >>
> >> > Hi Dan, When I tried this I got an model validation error message
> >> relating
> >> > to the choices method, I will have another go and if it fails, provide
> >> the
> >> > test case. Thanks for the tips.
> >> >
> >> > On Thu, Jul 30, 2015 at 7:57 PM, Dan Haywood <
> >> dan@haywood-associates.co.uk
> >> > > wrote:
> >> >
> >> >> You should be able to add a choicesXxx() for the derived property:
> >> >>
> >> >>     public List<String> choicesRegionName(){
> >> >>         return
> Lists.newArrayList(Iterables.transform(choicesRegion(),
> >> x
> >> >> ->
> >> >> x.getName()));
> >> >>     }
> >> >>
> >> >> If that isn't sufficient, you might also need to add a setter:
> >> >>
> >> >> public void setRegionName(final String name) {
> >> >> setRegion(Iterables.find(choicesRegion(), x ->
> >> x.getName().equals(name)));
> >> >> }
> >> >>
> >> >> Obviously, you might need to also add some error handling.
> >> >>
> >> >> ~~~
> >> >>
> >> >> Regarding the "external URL" idea, perhaps you could raise that as a
> >> >> separate ticket, with a code sketch as to how you'd like this
> >> information
> >> >> specified?
> >> >>
> >> >> Thanks
> >> >> Dan
> >> >>
> >> >>
> >> >>
> >> >>
> >> >>
> >> >> On 30 July 2015 at 03:17, Stephen Cameron <
> steve.cameron.62@gmail.com>
> >> >> wrote:
> >> >>
> >> >> > Not so simple, as now the property cannot be updated.
> >> >> >
> >> >> > I have the following (@Hidden is deprecated)
> >> >> >
> >> >> >     @Column(allowsNull = "true")
> >> >> >     @MemberOrder(sequence = "7")
> >> >> >     @PropertyLayout(hidden=Where.EVERYWHERE)
> >> >> >     public Region getRegion() {
> >> >> >         return this.region;
> >> >> >     }
> >> >> >
> >> >> >     public void setRegion(Region region) {
> >> >> >         this.region = region;
> >> >> >     }
> >> >> >
> >> >> >     public List<Region> choicesRegion(){
> >> >> >         List<Region> regions =
> container.allInstances(Region.class);
> >> >> >         return regions;
> >> >> >     }
> >> >> >
> >> >> >     @MemberOrder(sequence = "7.1")
> >> >> >     public String getRegionName(){
> >> >> >         return (getRegion() != null) ? getRegion().getName() :
> null;
> >> >> >     }
> >> >> >
> >> >> > Sure enough getRegion doesn't appear in the UI but getRegionName
> >> does,
> >> >> but
> >> >> > then setRegion and choiceRegion don't mean anything to the UI, so
> the
> >> >> > Region property is read-only.
> >> >> >
> >> >> > This issue is maybe more significant than it appears at first, in
> >> terms
> >> >> of
> >> >> > domain modelling such code-lists are simple types that 'represent'
> >> >> things
> >> >> > on the boundary of the domain of interest. So we usually want to
> just
> >> >> > represent them with a name. Presently it makes no sense to go to
> that
> >> >> thing
> >> >> > via a hyperlink as all we'll find is that name, our model extends
> no
> >> >> > further.
> >> >> >
> >> >> > However we just might like to allow users to leave the domain model
> >> and
> >> >> go
> >> >> > to a resource outside. So, extending the suppressLink=true idea, I
> >> would
> >> >> > add that each object could have an implicit link(URL),created by
> >> Isis,
> >> >> or
> >> >> > an explicit one and if the explicit one is present it can
> optionally
> >> be
> >> >> > used as an alternative to the implicit one.
> >> >> >
> >> >> > For example, you might create a database to log fish details,
> species
> >> >> is a
> >> >> > boundary concept, we aren't likely to want to add a new species to
> >> the
> >> >> list
> >> >> > of known species, but we'd like to keep such a list handy, but for
> >> each
> >> >> > named species in that list, to provide an explicit link to a
> resource
> >> >> in a
> >> >> > global fish database. It makes more sense to use this link than the
> >> >> > implicit one, as if the implicit one is used we'd navigate to the
> >> domain
> >> >> > object page displaying the name and URL, both of which items of
> data
> >> >> could
> >> >> > have been in the explicit link.
> >> >> >
> >> >> > In the explicit case you might want to warn the user they are
> >> navigating
> >> >> > outside the Isis domain application.
> >> >> >
> >> >> > Perhaps all this could be done simply if there was a URI type in
> >> Isis,
> >> >> that
> >> >> > would allow it to create 'smart links' automatically.
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> > On Wed, Jul 29, 2015 at 9:37 PM, Stephen Cameron <
> >> >> > steve.cameron.62@gmail.com
> >> >> > > wrote:
> >> >> >
> >> >> > > Thanks Jeroen, seems simple enough :)
> >> >> > >
> >> >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal <
> >> >> jeroen@stromboli.it
> >> >> > >
> >> >> > > wrote:
> >> >> > >
> >> >> > >> You could also hide the property and create a separate getter
> for
> >> >> > display
> >> >> > >> purposes only:
> >> >> > >>
> >> >> > >> private MyProperty myProperty;
> >> >> > >>
> >> >> > >> @Hidden
> >> >> > >> public MyProperty getMyProperty() {...}
> >> >> > >>
> >> >> > >> public void setMyProperty(...) {...}
> >> >> > >>
> >> >> > >> public String getMyPropertyName() {
> >> >> > >>     getMyProperty.getName();
> >> >> > >> }
> >> >> > >>
> >> >> > >> On 29 July 2015 at 13:18, Stephen Cameron <
> >> >> steve.cameron.62@gmail.com>
> >> >> > >> wrote:
> >> >> > >>
> >> >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood <
> >> >> > >> dan@haywood-associates.co.uk
> >> >> > >> > >
> >> >> > >> > wrote:
> >> >> > >> >
> >> >> > >> > > You are right, they will be displayed as links; there's no
> >> way to
> >> >> > >> disable
> >> >> > >> > > it currently.
> >> >> > >> > >
> >> >> > >> > > We could add a bit of metadata perhaps for this, eg
> >> >> > >> > > @DomainObjectLayout(suppressLink=true) or similar.
> >> >> > >> > >
> >> >> > >> > > Please raise a ticket.
> >> >> > >> > >
> >> >> > >> >
> >> >> > >> > OK https://issues.apache.org/jira/browse/ISIS-1180
> >> >> > >> >
> >> >> > >> > >
> >> >> > >> > > Thx
> >> >> > >> > > Dan
> >> >> > >> > >
> >> >> > >> > > PS: these entities wouldn't be value types, rather regular
> >> >> entities.
> >> >> > >> But
> >> >> > >> > > you are right... what we really want is full-class support
> for
> >> >> value
> >> >> > >> > types.
> >> >> > >> > >   We're just not there yet...
> >> >> > >> > >
> >> >> > >> > >
> >> >> > >> > >
> >> >> > >> >
> >> >> > >> > >
> >> >> > >> > >
> >> >> > >> > > On 29 July 2015 at 09:34, Stephen Cameron <
> >> >> > steve.cameron.62@gmail.com
> >> >> > >> >
> >> >> > >> > > wrote:
> >> >> > >> > >
> >> >> > >> > > > Thanks, but surely such object properties always end up
> >> being
> >> >> > >> displayed
> >> >> > >> > > as
> >> >> > >> > > > links? Clicking on the link to go to such an object page
> is
> >> >> > >> > meaningless,
> >> >> > >> > > as
> >> >> > >> > > > it only has one name property, that was displayed in the
> >> link.
> >> >> > Can I
> >> >> > >> > > > disable that default behaviour for value types?
> >> >> > >> > > >
> >> >> > >> > > >
> >> >> > >> > > >
> >> >> > >> > > > On Wed, Jul 29, 2015 at 5:47 PM, Dan Haywood <
> >> >> > >> > > dan@haywood-associates.co.uk
> >> >> > >> > > > >
> >> >> > >> > > > wrote:
> >> >> > >> > > >
> >> >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron <
> >> >> > >> > steve.cameron.62@gmail.com>
> >> >> > >>
> >> >> > >> > > > > wrote:
> >> >> > >> > > > >
> >> >> > >> > > > > > Hi,
> >> >> > >> > > > > >
> >> >> > >> > > > > > I want to do have some properties that are essentially
> >> >> String
> >> >> > >> > types,
> >> >> > >> > > > but
> >> >> > >> > > > > > which have a limited range of values (code-lists or
> >> >> restricted
> >> >> > >> > > > > > vocabularies). I want to allow these lists to be
> >> >> administered
> >> >> > >> > > > centrally,
> >> >> > >> > > > > so
> >> >> > >> > > > > > to add them to a single Administration menu item for
> >> admin
> >> >> > >> users.
> >> >> > >> > > > > >
> >> >> > >> > > > > > For most users these codes should appears as lists of
> >> >> strings
> >> >> > >> not
> >> >> > >> > as
> >> >> > >> > > > > > objects, but making them objects seems to be the
> >> logical OO
> >> >> > way
> >> >> > >> to
> >> >> > >> > > deal
> >> >> > >> > > > > > with them in Isis. So they are basically objects with
> >> one
> >> >> > 'name'
> >> >> > >> > > > property
> >> >> > >> > > > > > (and maybe an id added by datanucleus). All users need
> >> to
> >> >> see
> >> >> > is
> >> >> > >> > the
> >> >> > >> > > > name
> >> >> > >> > > > > > property, no icon is needed.
> >> >> > >> > > > > >
> >> >> > >> > > > > > Also, if I make them objects I also will get
> referencial
> >> >> > >> integrity
> >> >> > >> > > > > > constraints applied in the database.
> >> >> > >> > > > > >
> >> >> > >> > > > > >
> >> >> > >> > > > > +1, do it this way.  That way they can also hold
> >> behaviour in
> >> >> > the
> >> >> > >> > > future.
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > > > I wonder there is a simple recipe for this?
> >> >> > >> > > > > >
> >> >> > >> > > > >
> >> >> > >> > > > > No magic recipe for the domain entities... basically
> >> >> > copy-n-paste
> >> >> > >> the
> >> >> > >> > > > > SimpleObject that's in our archetype as many times as
> >> needed,
> >> >> > and
> >> >> > >> > tweak
> >> >> > >> > > > as
> >> >> > >> > > > > required.
> >> >> > >> > > > >
> >> >> > >> > > > > If you want to use the code as the primary key, then use
> >> DN
> >> >> > >> > application
> >> >> > >> > > > > identity
> >> >> > >> > > > >
> >> >> > >> > > > > @javax.jdo.annotations.PersistenceCapable(
> >> >> > >> > > > >         identityType=IdentityType.APPLICATION,
> >> >> > >> > > > >         schema = "simple",
> >> >> > >> > > > >         table = "SimpleObject"
> >> >> > >> > > > > )
> >> >> > >> > > > >
> >> >> > >> > > > > and add @PrimaryKey to the "name" property.  Also add
> >> @Title
> >> >> to
> >> >> > >> that
> >> >> > >> > > > 'name'
> >> >> > >> > > > > property (it is in SimpleObject already).
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > > You would probably want to remove the version column, ie
> >> >> remove:
> >> >> > >> > > > >
> >> >> > >> > > > > @javax.jdo.annotations.Version(
> >> >> > >> > > > >         strategy=VersionStrategy.VERSION_NUMBER,
> >> >> > >> > > > >         column="version")
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > > In addition, if you annotate the class as "bounded"
> >> >> > >> > > > > (@DomainObject(bounded=true)) then you are telling the
> >> >> framework
> >> >> > >> that
> >> >> > >> > > > > there's a limited - ie bounded - set of instances, and
> so
> >> it
> >> >> > will
> >> >> > >> > > display
> >> >> > >> > > > > all instances in a drop-down for you.
> >> >> > >> > > > >
> >> >> > >> > > > >
> >> >> > >> > > > > HTH
> >> >> > >> > > > > Dan
> >> >> > >> > > > >
> >> >> > >> > > >
> >> >> > >> > >
> >> >> > >> >
> >> >> > >>
> >> >> > >
> >> >> > >
> >> >> >
> >> >>
> >> >
> >> >
> >>
> >
> >
>