1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.google.gwt.sample.dynatable.client;
17 
18 import com.google.gwt.core.client.GWT;
19 import com.google.gwt.user.client.Command;
20 import com.google.gwt.user.client.DeferredCommand;
21 import com.google.gwt.user.client.rpc.AsyncCallback;
22 import com.google.gwt.user.client.rpc.ServiceDefTarget;
23 import com.google.gwt.user.client.ui.Composite;
24 
25 /**
26  * A Composite widget that abstracts a DynaTableWidget and a data provider tied
27  * to the <@link SchoolCalendarService> RPC endpoint.
28  */
29 public class SchoolCalendarWidget extends Composite {
30 
31   /**
32    * A data provider that bridges the provides row level updates from the data
33    * available through a <@link SchoolCalendarService>.
34    */
35   public class CalendarProvider implements DynaTableDataProvider {
36 
37     private final SchoolCalendarServiceAsync calService;
38 
39     private int lastMaxRows = -1;
40 
41     private Person[] lastPeople;
42 
43     private int lastStartRow = -1;
44 
CalendarProvider()45     public CalendarProvider() {
46       // Initialize the service.
47       //
48       calService = (SchoolCalendarServiceAsync) GWT.create(SchoolCalendarService.class);
49 
50       // By default, we assume we'll make RPCs to a servlet, but see
51       // updateRowData(). There is special support for canned RPC responses.
52       // (Which is a totally demo hack, by the way :-)
53       //
54       ServiceDefTarget target = (ServiceDefTarget) calService;
55 
56       // Use a module-relative URLs to ensure that this client code can find
57       // its way home, even when the URL changes (as might happen when you
58       // deploy this as a webapp under an external servlet container).
59       String moduleRelativeURL = GWT.getModuleBaseURL() + "calendar";
60       target.setServiceEntryPoint(moduleRelativeURL);
61     }
62 
updateRowData(final int startRow, final int maxRows, final RowDataAcceptor acceptor)63     public void updateRowData(final int startRow, final int maxRows,
64         final RowDataAcceptor acceptor) {
65       // Check the simple cache first.
66       //
67       if (startRow == lastStartRow) {
68         if (maxRows == lastMaxRows) {
69           // Use the cached batch.
70           //
71           pushResults(acceptor, startRow, lastPeople);
72           return;
73         }
74       }
75 
76       // Fetch the data remotely.
77       //
78       calService.getPeople(startRow, maxRows, new AsyncCallback<Person[]>() {
79         public void onFailure(Throwable caught) {
80           acceptor.failed(caught);
81         }
82 
83         public void onSuccess(Person[] result) {
84           lastStartRow = startRow;
85           lastMaxRows = maxRows;
86           lastPeople = result;
87           pushResults(acceptor, startRow, result);
88         }
89 
90       });
91     }
92 
pushResults(RowDataAcceptor acceptor, int startRow, Person[] people)93     private void pushResults(RowDataAcceptor acceptor, int startRow,
94         Person[] people) {
95       String[][] rows = new String[people.length][];
96       for (int i = 0, n = rows.length; i < n; i++) {
97         Person person = people[i];
98         rows[i] = new String[3];
99         rows[i][0] = person.getName();
100         rows[i][1] = person.getDescription();
101         rows[i][2] = person.getSchedule(daysFilter);
102       }
103       acceptor.accept(startRow, rows);
104     }
105   }
106 
107   private final CalendarProvider calProvider = new CalendarProvider();
108 
109   private final boolean[] daysFilter = new boolean[] {
110       true, true, true, true, true, true, true};
111 
112   private final DynaTableWidget dynaTable;
113 
114   private Command pendingRefresh;
115 
SchoolCalendarWidget(int visibleRows)116   public SchoolCalendarWidget(int visibleRows) {
117     String[] columns = new String[] {"Name", "Description", "Schedule"};
118     String[] styles = new String[] {"name", "desc", "sched"};
119     dynaTable = new DynaTableWidget(calProvider, columns, styles, visibleRows);
120     initWidget(dynaTable);
121   }
122 
getDayIncluded(int day)123   protected boolean getDayIncluded(int day) {
124     return daysFilter[day];
125   }
126 
127   @Override
onLoad()128   protected void onLoad() {
129     dynaTable.refresh();
130   }
131 
setDayIncluded(int day, boolean included)132   protected void setDayIncluded(int day, boolean included) {
133     if (daysFilter[day] == included) {
134       // No change.
135       //
136       return;
137     }
138 
139     daysFilter[day] = included;
140     if (pendingRefresh == null) {
141       pendingRefresh = new Command() {
142         public void execute() {
143           pendingRefresh = null;
144           dynaTable.refresh();
145         }
146       };
147       DeferredCommand.addCommand(pendingRefresh);
148     }
149   }
150 }
151