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 <[email protected]> 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 < > [email protected] > > 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 < > [email protected] > > > 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 <[email protected]> > >> 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 < > >> > [email protected] > >> > > wrote: > >> > > >> > > Thanks Jeroen, seems simple enough :) > >> > > > >> > > On Wed, Jul 29, 2015 at 9:28 PM, Jeroen van der Wal < > >> [email protected] > >> > > > >> > > 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 < > >> [email protected]> > >> > >> wrote: > >> > >> > >> > >> > On Wed, Jul 29, 2015 at 6:38 PM, Dan Haywood < > >> > >> [email protected] > >> > >> > > > >> > >> > 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 < > >> > [email protected] > >> > >> > > >> > >> > > 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 < > >> > >> > > [email protected] > >> > >> > > > > > >> > >> > > > wrote: > >> > >> > > > > >> > >> > > > > On 29 July 2015 at 08:08, Stephen Cameron < > >> > >> > [email protected]> > >> > >> > >> > >> > > > > 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 > >> > >> > > > > > >> > >> > > > > >> > >> > > > >> > >> > > >> > >> > >> > > > >> > > > >> > > >> > > > > >
