Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jac/aspects/gui/web/AbstractCollection.java


1   /*
2     Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com>
3     
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU Lesser General Public License as
6     published by the Free Software Foundation; either version 2 of the
7     License, or (at your option) any later version.
8   
9     This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU Lesser General Public License for more details.
13  
14    You should have received a copy of the GNU Lesser General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
17  
18  package jac.aspects.gui.web;
19  
20  import jac.aspects.gui.*;
21  import jac.aspects.gui.FieldView;
22  import jac.core.Collaboration;
23  import jac.core.Wrappee;
24  import jac.core.rtti.ClassItem;
25  import jac.core.rtti.ClassRepository;
26  import jac.core.rtti.CollectionItem;
27  import jac.core.rtti.FieldItem;
28  import jac.core.rtti.MetaItem;
29  import jac.core.rtti.MethodItem;
30  import jac.util.Classes;
31  import jac.util.Log;
32  import java.io.PrintWriter;
33  import java.util.Collection;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Vector;
37  import java.util.HashMap;
38  
39  
40  public abstract class AbstractCollection extends AbstractView
41     implements CollectionListener, CollectionView
42  {
43     protected CollectionItem collection;
44     protected Object substance; 
45     protected CollectionModel model;
46  
47     MethodView addButton;
48     MethodView removeButton;
49  
50     /* index of selected row (-1 if no row if selection is empty) */
51     int selected = -1;
52  
53     /* indicates which column is chosen to sort list (-1 if no column
54      * is chosen) */
55     int sortColumn = -1;
56  
57     /* number of rows to display on each page */
58     int rowsPerPage = 10;
59     /* do we split the collection in multiple pages */
60     boolean split;
61  
62     /* do we show a column with row numbers */
63     boolean showRowNumbers;
64     
65     /* current offset */
66     int startIndex = 0;
67  
68     public AbstractCollection(ViewFactory factory, DisplayContext context,
69                               CollectionItem collection, Object substance,
70                               CollectionModel model) {
71        super(factory,context);
72  
73        this.collection = collection;
74        this.substance = substance;
75        this.model = model;
76        this.rowsPerPage = GuiAC.getNumRowsPerPage(collection);
77        this.startIndex = GuiAC.getStartIndex(collection);
78        this.showRowNumbers = GuiAC.isShowRowNumbers(collection);
79        split = rowsPerPage>0;
80        sort();
81     }
82  
83     public AbstractCollection() {
84     }
85  
86     public void setSubstance(Object substance) {
87        this.substance = substance;
88     }
89  
90     public CollectionModel getCollectionModel() {
91        return model;
92     }
93  
94     /**
95      * Generate HTML code for a collection's event (add, remove, ...)
96      * @param out write HTML to this writer
97      * @param event name of the associated event
98      * @param icon name of icon resource to display
99      * @param label text to display
100     */
101    void genCollectionEvent(PrintWriter out,
102                            String event,
103                            String icon,
104                            String label) {
105 
106       JacRequest request = ((WebDisplay)context.getDisplay()).getRequest();
107       if (request.isIEUserAgent()) {
108          out.println(
109             "<table class=\"method\"><td>"+
110             iconElement(ResourceManager.getResource(icon),"")+
111             eventURL(label,event,"").toString()+
112             "</td></table>");
113       } else {
114          out.println(
115             "<span class=\"method\">"+
116             iconElement(ResourceManager.getResource(icon),"")+
117             eventURL(label,event,"").toString()+
118             "</span>");
119       }
120    }
121 
122    /**
123     * Sorts the collection with the column index stored in the context
124     * if any.
125     */
126    public abstract void sort();
127 
128    public void onView(Object object) {
129       Log.trace("gui.events",toString()+".onView("+object+")");
130       selected = model.indexOf(object);
131 
132       // used for CollectionItemView
133       CollectionPosition extra = new CollectionPosition(
134          this,
135          collection,selected,substance);
136 
137       EventHandler.get().onSelection(context,collection,object,
138                                      null,extra,true);
139    }
140 
141    // HTMLViewer interface
142 
143    /**
144     * Generate HTML for adder, remover, and prev/next buttons
145     * @param out print HTML code to this writer 
146     */
147    protected void genAdderAndRemover(PrintWriter out) {
148       boolean addable = GuiAC.isAddable(substance,collection);
149       boolean removable = GuiAC.isRemovable(substance,collection);
150       if (!(addable ||
151             (model.getRowCount()>0 && removable) ||
152             (startIndex>0) ||
153             (split && startIndex+rowsPerPage<model.getRowCount()))) {
154          return;
155       }
156       out.println("<div class=\"methods\">");
157       if (addable) {
158          if (GuiAC.isAutoCreate(collection)) {
159             genCollectionEvent(out,"onAddToCollection","new_icon",GuiAC.getLabelAdd());
160             /*
161             genCollectionEvent(out,"onAddToCollection","new_icon","add new");
162             genCollectionEvent(out,"onAddExistingToCollection","new_icon","add existing");
163             */
164          } else {
165             genCollectionEvent(out,"onAddToCollection","new_icon",GuiAC.getLabelAdd());
166          }
167       }
168       // removed this because does not work fine 
169       /*if ( model.getRowCount()>0 && GuiAC.isRemovable(collection)) {
170          genCollectionEvent(out,"onRemoveFromCollection","remove_icon","remove");
171          }*/
172       if (startIndex>0) {
173          out.println("<a href=\""+eventURL("onFirst")+"\">"+
174                      iconElement(ResourceManager.getResource("first_icon"),"first")+
175                      "</a>");
176          out.println("<a href=\""+eventURL("onPrevious")+"\">"+
177                      iconElement(ResourceManager.getResource("previous_icon"),"previous")+
178                      "</a>");
179       }
180       if (model.getRowCount()>0 && (startIndex>0 || startIndex+rowsPerPage<model.getRowCount())) {
181          out.println("["+(startIndex+1)+"-"+
182                      Math.min(startIndex+rowsPerPage,model.getRowCount())+"/"+
183                      model.getRowCount()+"]");
184       }
185       if (split && startIndex+rowsPerPage<model.getRowCount()) {
186          out.println("<a href=\""+eventURL("onNext")+"\">"+
187                      iconElement(ResourceManager.getResource("next_icon"),"next")+
188                      "</a></span>");
189          out.println("<a href=\""+eventURL("onLast")+"\">"+
190                      iconElement(ResourceManager.getResource("last_icon"),"last")+
191                      "</a></span>");
192       }
193       if (split && model.getRowCount()>rowsPerPage) {         
194          out.println("["+(startIndex/rowsPerPage+1)+"/"+
195                      (int)Math.ceil((float)model.getRowCount()/(float)rowsPerPage)+"]");
196       }
197 
198       out.println("</div>");
199    }
200 
201    // CollectionView interface
202 
203    public void setSelected(int index) {
204       selected = index;      
205    }
206 
207    public void setField(FieldItem field) {
208       collection = (CollectionItem)field;
209    }
210 
211    public FieldItem getField() {
212       return collection;
213    }
214 
215    public void setValue(Object value) {
216    }
217 
218    public void updateModel(Object substance) {
219    }
220 
221    // CollectionListener interface
222 
223    public void onView(int index) {
224       Log.trace("gui.events",toString()+".onView("+index+")");
225       selected = index;
226 
227       // used for CollectionItemView
228       CollectionPosition extra = new CollectionPosition(
229          this,
230          collection,index,substance);
231 
232       EventHandler.get().onSelection(context,collection,model.getObject(index),
233                                      null,extra,true);
234    }
235 
236    public void onRemove(int index) {
237       Log.trace("gui.events",toString()+".onRemove("+index+")");
238       Object toRemove = model.getObject(index);
239       
240       EventHandler.get()
241          .onRemoveFromCollection(context, substance, collection, toRemove);
242    }
243 
244    public void onTableInvoke(int index,String methodName) {
245       Log.trace("gui.events",toString()+".onTableInvoke("+index+")");
246       selected = index;
247       EventHandler.get().onInvoke(
248          context,model.getObject(index),
249          ClassRepository.get().getClass(model.getObject(index))
250          .getMethod(methodName));
251    }
252    
253    public void onAddToCollection() {
254       EventHandler.get().onAddToCollection(context,substance,collection,false);
255       sort();
256    }
257 
258    public void onAddExistingToCollection() {
259       EventHandler.get().onAddToCollection(context,substance,collection,true);
260       sort();
261    }
262 
263    public void onRemoveFromCollection() {
264       EventHandler.get().onRemoveFromCollection(context,substance,collection);
265       sort();
266    }
267 
268    public void onNext() {
269       if (startIndex+rowsPerPage<model.getRowCount())
270          startIndex += rowsPerPage;
271       context.getDisplay().refresh();
272    }
273 
274    public void onLast() {
275       startIndex = model.getRowCount() - model.getRowCount()%rowsPerPage;
276       if (startIndex==model.getRowCount())
277          startIndex -= rowsPerPage;
278       context.getDisplay().refresh();
279    }
280 
281    public void onPrevious() {
282       startIndex -= rowsPerPage;
283       if (startIndex<0)
284          startIndex = 0;
285       context.getDisplay().refresh();
286    }
287 
288    public void onFirst() {
289       startIndex = 0;
290       context.getDisplay().refresh();
291    }
292 
293    /**
294     * Returns an HTML link to remove the element at a given position.
295     */
296    protected String removeLink(int position) {
297       // We should use eventURL
298       return "<a href=\""+eventURL("onRemove")+
299          "&amp;index="+position+"\">"+
300          iconElement(ResourceManager.getResource("remove_icon"),"remove")+"</a>";
301    }
302 
303    protected String viewLink(int position) {
304       // We should use eventURL
305       return "<a href=\""+eventURL("onView")+
306          "&amp;index="+position+"\">"+
307          iconElement(ResourceManager.getResource("view_icon"),"view")+"</a>";
308    }
309 
310    /**
311     * Build an HTML link with an image showing if a column is used to
312     * sort the collection
313     * @param column the index of the column 
314     * @param text additional text to put in the link
315     * @return the HTML code of the link
316     */
317    protected String sortLink(int column,String text) {
318       SortCriteria criteria = ((TableSorter)model).getSortCriteria(column);
319       String iconResource;
320       if (criteria==null) {
321          iconResource = "small_down_icon";
322       } else {
323          if (criteria.isAscending()) 
324             iconResource = "small_down_icon_selected";
325          else 
326             iconResource = "small_up_icon_selected";
327       }
328       return 
329          "      <a href=\""+eventURL("onHeaderClick")+"&amp;col="+column+"\""
330          + " title=\"sort\">"
331          + iconElement(ResourceManager.getResource(iconResource),"sort")
332          + " " + text
333          + "</a>";
334    }
335 
336 }