Hi Gabriel,
as Vladimir says, that validatePrice(...) is only fired when the property
itself is edited.
And, as he also says, one solution is to add a validateXxx method for the
action, eg:
public String validate1NewCategory() {
return price >= 0? null : "The price must not be negative!";
}
But that does violate DRY principle, which is a shame.
The ideal would be for "Price" to be a proper value type and enforce the
rule everywhere. However, Isis doesn't support this (we used to, sort of,
prior to JDO/DataNucleus, but have not resurrected it).
A half-way house, which *does* work and I think is still quite elegant, is
to create an implementation of o.a.i.applib.spec.Specification, and enforce
using #mustSatisfy():
public static class PriceSpecification extends
AbstractSpecification<Double> {
public String satisfiesSafely(Double price) {
return price >= 0? null : "The price must not be negative!";
}
}
for the action, use:
public Category newCategory(
String name,
@Parameter(mustSatisfy=PriceSpecification.class)
Double price) { ... }
and for the property (if also modifiable), use:
@Property(mustSatisfy=PriceSpecification.class)
public Double getPrice() {
return this.price;
}
One minor limitation I've just realized is that the Specification interface
doesn't support i18n; I've just raised a ticket [1] for that, should be
easy enough to implement.
HTH
Dan
[1] https://issues.apache.org/jira/browse/ISIS-1158
On 30 May 2015 at 20:41, Vladimir Nišević <[email protected]> wrote:
> Hi Gabriel, just tried your code with DomainService Categories
>
> package dom.simple;
>
> import org.apache.isis.applib.DomainObjectContainer;
> import org.apache.isis.applib.annotation.DomainService;
>
> @DomainService
> public class Categories {
>
> public Category newCategory(
> String name,
> Double price) {
> Category aCategory =
> container.newTransientInstance(Category.class);
> aCategory.setName(name);
> aCategory.setPrice(price);
> container.persist(aCategory);
> container.flush();
> return aCategory;
> }
>
> @javax.inject.Inject
> private DomainObjectContainer container;
>
> }
>
>
> You can create negative price, since there is no validation in newCategory,
> but when you open the object view, edit object and try to type negative
> value, validation will work.
>
> BR,Vladimir
>
>
> 2015-05-30 18:36 GMT+02:00 Gabriel Malimpensa <[email protected]>:
>
> > Vladimir,
> >
> > Price is a property of a domain object.
> > The whole code:
> >
> > package dom.simple;
> >
> > import javax.jdo.annotations.Column;
> > import javax.jdo.annotations.IdGeneratorStrategy;
> > import javax.jdo.annotations.IdentityType;
> > import javax.jdo.annotations.PersistenceCapable;
> > import javax.jdo.annotations.Persistent;
> > import javax.jdo.annotations.PrimaryKey;
> > import javax.jdo.identity.LongIdentity;
> >
> > import org.apache.isis.applib.annotation.Bounded;
> > import org.apache.isis.applib.annotation.MemberOrder;
> > import org.apache.isis.applib.annotation.Title;
> > import org.apache.isis.applib.util.ObjectContracts;
> >
> > @PersistenceCapable(identityType=IdentityType.APPLICATION,
> > objectIdClass=LongIdentity.class)
> > @Bounded
> > public class Category implements Comparable<Category> {
> >
> > private Long id;
> > private String name;
> > private Double price;
> >
> > @PrimaryKey
> > @Persistent(valueStrategy=IdGeneratorStrategy.NATIVE)
> > @Column(allowsNull="false")
> > @MemberOrder(sequence="1")
> > public Long getId() {
> > return this.id;
> > }
> >
> > public void setId(Long id) {
> > this.id = id;
> > }
> >
> > @Column(allowsNull="false")
> > @MemberOrder(sequence="2")
> > @Title(sequence="1")
> > public String getName() {
> > return this.name;
> > }
> >
> > public void setName(String name) {
> > this.name = name;
> > }
> >
> > @Column(allowsNull="false")
> > @MemberOrder(sequence="3")
> > public Double getPrice() {
> > return this.price;
> > }
> >
> > public void setPrice(Double price) {
> > this.price = price;
> > }
> >
> > public String validatePrice(Double price) {
> > if (price >= 0) {
> > return null;
> > } else {
> > return "The price must not be negative!";
> > }
> > }
> >
> > @Override
> > public int compareTo(Category category) {
> > return ObjectContracts.compare(this, category, "id");
> > }
> >
> > @Override
> > public int hashCode() {
> > final int prime = 31;
> > int result = 1;
> > result = prime * result + ((id == null) ? 0 : id.hashCode());
> > return result;
> > }
> >
> > @Override
> > public boolean equals(Object obj) {
> > if (this == obj)
> > return true;
> > if (obj == null)
> > return false;
> > if (getClass() != obj.getClass())
> > return false;
> > Category other = (Category) obj;
> > if (id == null) {
> > if (other.id != null)
> > return false;
> > } else if (!id.equals(other.id))
> > return false;
> > return true;
> > }
> >
> > @Override
> > public String toString() {
> > return ObjectContracts.toString(this, "id,name,price");
> > }
> > }
> >
> > Thank you.
> > Gabriel Malimpensa.
> >
> >
> > 2015-05-30 11:41 GMT-03:00 Vladimir Nišević <[email protected]>:
> >
> > > Hi ,Gabriel, is the price a property of domain object or action? Show
> us
> > a
> > > whole class.
> > >
> > > Check
> > >
> >
> http://isis.apache.org/how-tos/how-to-02-100-How-to-validate-user-input-for-a-property.html
> > > or
> > >
> >
> http://isis.apache.org/how-tos/how-to-02-120-How-to-validate-an-action-parameter-argument.html
> > >
> > > lG,Vladimir
> > >
> > >
> > > > Am 30.05.2015 um 16:00 schrieb Gabriel Malimpensa <
> > > [email protected]>:
> > > >
> > > > Sorry for insist in this question, but I have tried many things and I
> > > can't
> > > > resolve. I have used the validate method for attributes in other
> > systems
> > > I
> > > > have made, but this one I really don't know what is happening. Maybe
> > > > (propably) it's something stupid... =D
> > > >
> > > > Thank you for support.
> > > >
> > > > Gabriel Malimpensa.
> > > > São Carlos, São Paulo, Brazil.
> > > >
> > > > 2015-05-27 21:43 GMT-03:00 Gabriel Malimpensa <
> [email protected]
> > >:
> > > >
> > > >> Hi.
> > > >>
> > > >> I've created a validate method for an attribute but when I insert
> the
> > > >> entity that contains such attribute, the validate is not called by
> the
> > > >> interface. I don't know what is wrong. Someone can help?
> > > >>
> > > >> Code:
> > > >> public String validatePrice(Double price) {
> > > >> if (price >= 0) {
> > > >> return null;
> > > >> } else {
> > > >> return "The price must not be negative!";
> > > >> }
> > > >> }
> > > >>
> > > >> Thanks.
> > > >>
> > > >> Gabriel Malimpensa.
> > > >> São Carlos, São Paulo, Brazil.
> > > >>
> > > >>
> > >
> >
>