You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@isis.apache.org by james agada <ok...@gmail.com> on 2013/11/16 20:46:40 UTC

How to use view model

I have created a view model (below). It is not clear to me how to either
get it to display.

*

 *  Copyright 2012-2013 Eurocommercial Properties NV

 *

 *

 *  Licensed under the Apache License, Version 2.0 (the

 *  "License"); you may not use this file except in compliance

 *  with the License.  You may obtain a copy of the License at

 *

 *        http://www.apache.org/licenses/LICENSE-2.0

 *

 *  Unless required by applicable law or agreed to in writing,

 *  software distributed under the License is distributed on an

 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

 *  KIND, either express or implied.  See the License for the

 *  specific language governing permissions and limitations

 *  under the License.

 */

package dom.todo;


import java.math.BigDecimal;

import java.util.List;


import javax.jdo.annotations.Extension;

import javax.jdo.annotations.IdentityType;

import javax.jdo.annotations.InheritanceStrategy;


import org.joda.time.LocalDate;


import org.apache.isis.applib.AbstractViewModel;

import org.apache.isis.applib.annotation.Bookmarkable;

import org.apache.isis.applib.annotation.DescribedAs;

import org.apache.isis.applib.annotation.Hidden;

import org.apache.isis.applib.annotation.Immutable;

import org.apache.isis.applib.annotation.Optional;

import org.apache.isis.applib.annotation.Render;

import org.apache.isis.applib.annotation.Render.Type;

import org.apache.isis.applib.annotation.Title;




/**

 * View model that provides a summary of the sales made on a given day by
each party

 */

@javax.jdo.annotations.PersistenceCapable(

    identityType = IdentityType.NONDURABLE,

    table = "DailySalesTotalForParty",

    extensions = {

        @Extension(vendorName = "datanucleus", key = "view-definition",

            value = "CREATE VIEW \"DailySalesTotalForParty\" " +

                    "( " +

                    "  {this.transactionDate}, " +

                    "  {this.fromPartyId}, " +

                    "  {this.transactiontype}, " +

                    "  {this.totalAmount} " +

                    ") AS " +

                    "SELECT " +

                    "   \"Tranaction\".\"transactiondate\" , " +

                    "   \"Transaction.\".\"fromparty_party_id_oid\", " +

                    "   \"Transaction.\".\"transactiontype\", " +


                    "   SUM(\"Transaction\".\"facevalue\") AS
\"totalAmount\", " +

                    "  FROM \"Transaction\" " +

                    "GROUP BY " +

                    " \"Transaction\".\"fromparty_party_id_oid\", " +

                    " \"Transaction\".\"transactiondate\"")

    })

@javax.jdo.annotations.Inheritance(strategy = InheritanceStrategy.NEW_TABLE)

@Bookmarkable

@Immutable

public class DailySalesTotalForParty extends AbstractViewModel {


    private static final String OID_SEPARATOR = "_AND_";


    // //////////////////////////////////////


    /**

     * {@link org.apache.isis.applib.ViewModel} implementation.

     */

    @Override

    public String viewModelMemento() {

        return getFromPartyId() + OID_SEPARATOR +
getTransactionDate().toString();

    }


    /**

     * {@link org.apache.isis.applib.ViewModel} implementation.

     */

    @Override

    public void viewModelInit(final String memento) {

        String[] split = memento.split(OID_SEPARATOR);

        setFromPartyId(split[0]);

        setTransactionDate(new LocalDate(split[1]));

    }


    // //////////////////////////////////////


    private String fromPartyId;


    /**

     * Used as the {@link #viewModelMemento() view model memento}, holds the

     * reference of the corresponding {@link #getProperty()}.

     *

     * <p>

     * This attribute is always guaranteed to be populated.

     */

    @javax.jdo.annotations.Column(allowsNull = "false")

    @DescribedAs("From Party Id")

    @Hidden

    public String getFromPartyId() {

        return fromPartyId;

    }


    public void setFromPartyId(final String reference) {

        this.fromPartyId = reference;

    }


    // //////////////////////////////////////


    /**

     * Annotated as {@link javax.jdo.annotations.NotPersistent not
persistent}

     * because not mapped in the <tt>view-definition</tt>.

     */

    @javax.jdo.annotations.NotPersistent

    private Party fromParty;


    /**

     * Lazily loaded from the {@link #getReference() reference}, provides
access

     * to the underlying {@link Property}.

     */

    @Optional

    @Title(sequence = "1")

    public Party getFromParty() {

        if (fromParty == null) {

            setFromParty(partytypes.findPartyFromOID(getFromPartyId()));

        }

        return fromParty;

    }


    public void setFromParty(final Party party) {

        this.fromParty = party;

    }


    // //////////////////////////////////////


    private LocalDate transactionDate;


    @Title(sequence = "2", prepend = " - ")

    public LocalDate getTransactionDate() {

        return transactionDate;

    }


    public void setTransactionDate(final LocalDate dueDate) {

        this.transactionDate = dueDate;

    }


    // //////////////////////////////////////


    private BigDecimal totalAmount;


    public BigDecimal getTotalAmount() {

        return totalAmount;

    }


    public void setTotalAmount(final BigDecimal total) {

        this.totalAmount = total;

    }




    // //////////////////////////////////////


    @Render(Type.EAGERLY)

    public List<Transaction> getTransactions() {

        return transactions.findTransactionsForPartyAndDate(getParty(),
getTransactionDate());

    }


    // //////////////////////////////////////


    private Partytypes partytypes;


    final public void injectPartytypes(final Partytypes partytypes) {

        this.partytypes = partytypes;

    }


    private Transactions transactions;


    final public void injectTransactions(final Transactions transactions) {

        this.transactions = transactions;

    }


}

Re: How to use view model

Posted by Okwui <ok...@gmail.com>.
Let's see.

Sent from my iPad

> On Nov 17, 2013, at 1:23 PM, Dan Haywood <da...@haywood-associates.co.uk> wrote:
> 
> OK, to summarise the stuff below, we have entities:
> 
> public class Party {
>    id;
> }
> 
> public class Transaction {
>    party;
>    transactionDate;
>    transactionType;
>    faceValue;
> }
> 
> and you've defined a class that specifies the aggregated data (I'm omitting
> the "ViewModel" suffix.
> 
> public class DailySalesTotalForParty  {
>   party;
>   transactionDate;
>   totalAmount;
> }
> 
> There are two ways to address this
> 
> 1. (as you've done) define a SQL view and use JDO @PersistenceCapable on
> DailySalesTotalForParty.  So far as Isis is concerned, this class is just
> an entity, and so you can define a domain service and query for it in the
> usual way).  In this case there's NO NEED (I think) for this class to
> implement Isis' ViewModel interface.
> 
> 2. alternatively, you can NOT use a SQL view, and instead only use an Isis
> ViewModel.   Here the view models are instantiated by a domain service, and
> JDO doesn't know anything about them.  You can see examples of this in the
> todo app [1], [2].
> 
> Put another way, in (1) the view is defined in the database layer, in (2)
> the view is done in the domain layer.
> 
> ~~~
> In your other email you said you want to show the daily sales for a given
> party.  So:
> 
> a) add a JDO Query so that you can filter the
> DailySalesTotalForPartyViewModel by partyId:
> @Query(name="dailySales", query= "select from
> DailySalesTotalForPartyViewModel  where partyId = :partyId)
> 
> b) write a domain service that exposes this:
> 
> public class DailySalesTotalForPartyService {
> 
>    @NotContributed(As.ACTION)  // ie contributed as a collection
>    public List<DailySalesTotalForParty> dailySales(Party party) {
>        return allMatches(new QueryDefault("dailySales", "party", party));
>    }
> }
> 
> This "dailySales" action should then appear as a contributed collection, ie
> as if there's a "dailySales" collection of Party itself.
> 
> ~~~
> 
> If you want to go use an Isis view model, then you don't need the
> @PersistenceCapable annotation or SQL VIEW, but you will need to replicate
> aggregation logic in a domain service.  That is, you'd still have a service:
> 
> public class DailySalesTotalForPartyService {
> 
>    @NotContributed(As.ACTION)  // ie contributed as a collection
>    public List<DailySalesTotalForParty> dailySales(Party party) {
>        ...
>    }
> }
> 
> but what does in the implementation would be similar to [1].
> 
> HTH
> Dan
> 
> 
> [1]
> https://github.com/apache/isis/blob/5e9d586a3a1dcb9e4cf23470f6cb4ef43ebae06d/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/app/ToDoItemAnalysis.java
> [1]
> https://github.com/apache/isis/blob/5e9d586a3a1dcb9e4cf23470f6cb4ef43ebae06d/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java

Re: How to use view model

Posted by Dan Haywood <da...@haywood-associates.co.uk>.
OK, to summarise the stuff below, we have entities:

public class Party {
    id;
 }

public class Transaction {
    party;
    transactionDate;
    transactionType;
    faceValue;
}

and you've defined a class that specifies the aggregated data (I'm omitting
the "ViewModel" suffix.

public class DailySalesTotalForParty  {
   party;
   transactionDate;
   totalAmount;
}

There are two ways to address this

1. (as you've done) define a SQL view and use JDO @PersistenceCapable on
DailySalesTotalForParty.  So far as Isis is concerned, this class is just
an entity, and so you can define a domain service and query for it in the
usual way).  In this case there's NO NEED (I think) for this class to
implement Isis' ViewModel interface.

2. alternatively, you can NOT use a SQL view, and instead only use an Isis
ViewModel.   Here the view models are instantiated by a domain service, and
JDO doesn't know anything about them.  You can see examples of this in the
todo app [1], [2].

Put another way, in (1) the view is defined in the database layer, in (2)
the view is done in the domain layer.

~~~
In your other email you said you want to show the daily sales for a given
party.  So:

a) add a JDO Query so that you can filter the
DailySalesTotalForPartyViewModel by partyId:
@Query(name="dailySales", query= "select from
DailySalesTotalForPartyViewModel  where partyId = :partyId)

b) write a domain service that exposes this:

public class DailySalesTotalForPartyService {

    @NotContributed(As.ACTION)  // ie contributed as a collection
    public List<DailySalesTotalForParty> dailySales(Party party) {
        return allMatches(new QueryDefault("dailySales", "party", party));
    }
}

This "dailySales" action should then appear as a contributed collection, ie
as if there's a "dailySales" collection of Party itself.

~~~

If you want to go use an Isis view model, then you don't need the
@PersistenceCapable annotation or SQL VIEW, but you will need to replicate
aggregation logic in a domain service.  That is, you'd still have a service:

public class DailySalesTotalForPartyService {

    @NotContributed(As.ACTION)  // ie contributed as a collection
    public List<DailySalesTotalForParty> dailySales(Party party) {
        ...
    }
}

but what does in the implementation would be similar to [1].

HTH
Dan


[1]
https://github.com/apache/isis/blob/5e9d586a3a1dcb9e4cf23470f6cb4ef43ebae06d/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/app/ToDoItemAnalysis.java
[1]
https://github.com/apache/isis/blob/5e9d586a3a1dcb9e4cf23470f6cb4ef43ebae06d/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java