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.
> > > >>
> > > >>
> > >
> >
>

Reply via email to