KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > gui > web > AbstractCollection


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 org.objectweb.jac.aspects.gui.web;
19
20 import java.io.PrintWriter JavaDoc;
21 import java.net.URLEncoder JavaDoc;
22 import org.apache.log4j.Logger;
23 import org.objectweb.jac.aspects.gui.*;
24 import org.objectweb.jac.core.NameRepository;
25 import org.objectweb.jac.core.rtti.ClassRepository;
26 import org.objectweb.jac.core.rtti.CollectionItem;
27 import org.objectweb.jac.core.rtti.FieldItem;
28
29 /**
30  * Base class for collection views (list, table, etc)
31  */

32 public abstract class AbstractCollection extends AbstractView
33     implements CollectionListener, CollectionView, HTMLViewer
34 {
35     static Logger loggerEvents = Logger.getLogger("gui.events");
36     static Logger loggerEditor = Logger.getLogger("gui.editor");
37
38     protected CollectionItem collection;
39     protected Object JavaDoc substance;
40     protected CollectionModel model;
41     protected TableSorter sorter;
42     protected TableFilter filter;
43
44     protected boolean autoUpdate = true;
45     protected boolean isEditor = true;
46
47     /* index of selected row (-1 if no row if selection is empty) */
48     int selected = -1;
49
50     /* number of rows to display on each page */
51     int rowsPerPage = 10;
52     protected void setRowsPerPage(int rowsPerPage) {
53         this.rowsPerPage = rowsPerPage;
54         split = rowsPerPage>0;
55     }
56
57     /* do we split the collection in multiple pages */
58     boolean split;
59
60     /* do we show a column with row numbers */
61     boolean showRowNumbers;
62    
63     /* current offset */
64     int startIndex = 0;
65
66     protected org.objectweb.jac.aspects.gui.CollectionItemView itemView;
67
68     protected boolean viewableItems; // shortcut for itemView.isViewableItems()
69

70     protected ObjectChooser rowsPerPageChooser;
71
72     public AbstractCollection(ViewFactory factory, DisplayContext context,
73                               CollectionItem collection, Object JavaDoc substance,
74                               CollectionModel model,
75                               org.objectweb.jac.aspects.gui.CollectionItemView itemView)
76     {
77         super(factory,context);
78
79         this.collection = collection;
80         this.substance = substance;
81         this.model = model;
82         setRowsPerPage(GuiAC.getNumRowsPerPage(collection));
83         this.startIndex = GuiAC.getStartIndex(collection);
84         this.showRowNumbers = GuiAC.isShowRowNumbers(collection);
85         this.itemView = itemView;
86         if (itemView!=null)
87             this.viewableItems = itemView.isViewableItems();
88         init();
89         sort();
90
91         int[] availableNumRowsPerPage = GuiAC.getAvailableNumRowsPerPage(collection);
92         if (availableNumRowsPerPage!=null) {
93             ComboBoxModel comboModel = new ComboBoxModel();
94             for (int i=0; i<availableNumRowsPerPage.length; i++) {
95                 int n = availableNumRowsPerPage[i];
96                 comboModel.addObject(new Integer JavaDoc(n), n!=0?(""+n):GuiAC.getLabelAll());
97             }
98             rowsPerPageChooser = new ObjectChooser(null,null,comboModel,false);
99             rowsPerPageChooser.setLabel(label+"_rowsPerPageChooser");
100             comboModel.setSelectedItem(""+availableNumRowsPerPage[0]);
101             setRowsPerPage(availableNumRowsPerPage[0]);
102         }
103     }
104
105     public AbstractCollection() {
106     }
107
108     public void setSubstance(Object JavaDoc substance) {
109         this.substance = substance;
110     }
111
112     public Object JavaDoc getSubstance() {
113         return substance;
114     }
115
116     public CollectionModel getCollectionModel() {
117         return model;
118     }
119
120     public boolean isEditor() {
121         return isEditor;
122     }
123
124     public void setEditor(boolean isEditor) {
125         this.isEditor = isEditor;
126     }
127
128     public void setAutoUpdate(boolean autoUpdate) {
129         this.autoUpdate = autoUpdate;
130     }
131
132     /**
133      * Generate HTML code for a collection's event (add, remove, ...)
134      * @param out write HTML to this writer
135      * @param event name of the associated event
136      * @param icon name of icon resource to display
137      * @param label text to display
138      */

139     void genCollectionEvent(PrintWriter JavaDoc out,
140                             String JavaDoc event,
141                             String JavaDoc icon,
142                             String JavaDoc label)
143     {
144         JacRequest request = WebDisplay.getRequest();
145         if (request.isIEUserAgent()) {
146             out.println(
147                 "<table class=\"method\"><td>"+
148                 iconElement(ResourceManager.getResource(icon),"")+
149                 eventURL(label,event,"").toString()+
150                 "</td></table>");
151         } else {
152             out.println(
153                 eventURL(" "+label,event,"")
154                 .add(0,iconElement(ResourceManager.getResource(icon),"").addCssClass("first"))
155                 .cssClass("method").toString());
156         }
157     }
158
159     /**
160      * Sorts the collection with the column index stored in the context
161      * if any.
162      */

163     public abstract void sort();
164
165     /**
166      * Initialization to be performed before sort()
167      */

168     protected void init() {}
169
170     public void onView(Object JavaDoc object) {
171         loggerEvents.debug(toString()+".onView("+object+")");
172         selected = model.indexOf(object);
173
174         // used for CollectionItemView
175
CollectionPosition extra = new CollectionPosition(
176             this,
177             collection,selected,substance);
178
179         EventHandler.get().onSelection(context,collection,object,
180                                        null,extra,true);
181     }
182
183     // HTMLViewer interface
184

185     protected void genHeader(PrintWriter JavaDoc out) {
186         genHeader(out, true);
187     }
188     
189     /**
190      * Generate HTML for adder, remover, prev/next buttons, ...
191      * @param out print HTML code to this writer
192      */

193     protected void genHeader(PrintWriter JavaDoc out, boolean div) {
194         if (collection.getSubstance(substance)==null)
195             return;
196
197         boolean addable = GuiAC.isAddable(substance,collection);
198         boolean removable = GuiAC.isRemovable(substance,collection);
199         boolean refreshable = showRefreshButton();
200         if (!(addable || refreshable ||
201               (model.getRowCount()>0 && removable) ||
202               (startIndex>0) ||
203               (split && startIndex+rowsPerPage<model.getRowCount()))) {
204             return;
205         }
206         if (div) {
207             out.println("<div class=\"methods\">");
208         }
209         if (addable && isEditor) {
210             if (GuiAC.isAutoCreate(collection)) {
211                 genCollectionEvent(out,"onAddToCollection","new_icon",GuiAC.getLabelAdd());
212                 /*
213                   genCollectionEvent(out,"onAddToCollection","new_icon","add new");
214                   genCollectionEvent(out,"onAddExistingToCollection","new_icon","add existing");
215                 */

216             } else {
217                 genCollectionEvent(out,"onAddToCollection","new_icon",GuiAC.getLabelAdd());
218             }
219         }
220         if (startIndex>0) {
221             out.println("<a HREF=\""+eventURL("onFirst")+"\">"+
222                         iconElement(ResourceManager.getResource("first_icon"),"first")+
223                         "</a>");
224             out.println("<a HREF=\""+eventURL("onPrevious")+"\">"+
225                         iconElement(ResourceManager.getResource("previous_icon"),"previous")+
226                         "</a>");
227         }
228         if (rowsPerPage>0 && model.getRowCount()>0 &&
229             (startIndex>0 || startIndex+rowsPerPage<model.getRowCount())) {
230             out.println("["+(startIndex+1)+"-"+
231                         Math.min(startIndex+rowsPerPage,model.getRowCount())+"/"+
232                         model.getRowCount()+"]");
233         }
234         if (split && startIndex+rowsPerPage<model.getRowCount()) {
235             out.println("<a HREF=\""+eventURL("onNext")+"\">"+
236                         iconElement(ResourceManager.getResource("next_icon"),"next")+
237                         "</a>");
238             out.println("<a HREF=\""+eventURL("onLast")+"\">"+
239                         iconElement(ResourceManager.getResource("last_icon"),"last")+
240                         "</a>");
241         }
242         if (split && model.getRowCount()>rowsPerPage) {
243             out.println("["+(startIndex/rowsPerPage+1)+"/"+
244                         (int)Math.ceil((float)model.getRowCount()/(float)rowsPerPage)+"]");
245         }
246
247         if (rowsPerPageChooser!=null) {
248             out.print("Display ");
249             rowsPerPageChooser.genHTML(out);
250             out.print(" rows");
251         }
252         if (showRefreshButton())
253             genEventAndActionButton(out,"onRefreshCollection");
254
255         if (div) {
256             out.println("</div>");
257         }
258     }
259
260     /**
261      * Tells whether a refesh button must be shown
262      */

263     protected boolean showRefreshButton() {
264         return rowsPerPageChooser!=null;
265     }
266
267     /**
268      * Gets object at a given index
269      */

270     protected Object JavaDoc getObject(int index) {
271         return model.getObject(index);
272     }
273
274     // CollectionView interface
275

276     public void setSelected(int index) {
277         selected = index;
278     }
279
280     public void setField(FieldItem field) {
281         collection = (CollectionItem)field;
282     }
283
284     public FieldItem getField() {
285         return collection;
286     }
287
288     public void setValue(Object JavaDoc value) {
289     }
290
291     public void updateModel(Object JavaDoc substance) {
292     }
293
294     // CollectionListener interface
295

296     public void onView(int index) {
297         loggerEvents.debug(toString()+".onView("+index+")");
298         selected = index;
299
300         // used for CollectionItemView
301
CollectionPosition extra = new CollectionPosition(
302             this,
303             collection,index,substance);
304
305         EventHandler.get().onSelection(context,collection,getObject(index),
306                                        null,extra,true);
307         loggerEvents.debug(" ending "+toString()+".onView("+index+"), selected="+selected);
308     }
309
310     public void onViewObject(String JavaDoc name) {
311         Object JavaDoc object = NameRepository.get().getObject(name);
312         EventHandler.get().onSelection(context,collection,object,
313                                        null,null,true);
314     }
315
316     public void onRemove(int index) {
317         loggerEvents.debug(toString()+".onRemove("+index+")");
318         Object JavaDoc toRemove = getObject(index);
319       
320         EventHandler.get()
321             .onRemoveFromCollection(
322                 context,
323                 new RemoveEvent(
324                     this,
325                     collection.getSubstance(substance),
326                     collection,
327                     toRemove),
328                 false);
329     }
330
331     public void onTableInvoke(int index,String JavaDoc methodName) {
332         loggerEvents.debug(toString()+".onTableInvoke("+index+")");
333         selected = index;
334         EventHandler.get().onInvoke(
335             context,
336             new InvokeEvent(
337                 this,
338                 getObject(index),
339                 ClassRepository.get().getClass(getObject(index)).getMethod(methodName)));
340     }
341    
342     public void onAddToCollection() {
343         EventHandler.get().onAddToCollection(
344             context,
345             new AddEvent(
346                 this,
347                 collection.getSubstance(substance),
348                 collection,
349                 null),
350             false);
351         sort();
352     }
353
354     public void onAddExistingToCollection() {
355         EventHandler.get().onAddToCollection(
356             context,
357             new AddEvent(this,collection.getSubstance(substance),collection,null),
358             true);
359         sort();
360     }
361
362     public void onRemoveFromCollection() {
363         EventHandler.get().onRemoveFromCollection(
364             context,
365             new RemoveEvent(this,collection.getSubstance(substance),collection,null),
366             true);
367         sort();
368     }
369
370     public void onNext() {
371         if (startIndex+rowsPerPage<model.getRowCount())
372             startIndex += rowsPerPage;
373         context.getDisplay().refresh();
374     }
375
376     public void onLast() {
377         startIndex = model.getRowCount() - model.getRowCount()%rowsPerPage;
378         if (startIndex==model.getRowCount())
379             startIndex -= rowsPerPage;
380         context.getDisplay().refresh();
381     }
382
383     public void onPrevious() {
384         startIndex -= rowsPerPage;
385         if (startIndex<0)
386             startIndex = 0;
387         context.getDisplay().refresh();
388     }
389
390     public void onFirst() {
391         startIndex = 0;
392         context.getDisplay().refresh();
393     }
394
395     public void onRefreshCollection() {
396         if (rowsPerPageChooser!=null) {
397             rowsPerPageChooser.readValue(
398                 ((WebDisplay)context.getDisplay())
399                     .getRequest().getParameter(rowsPerPageChooser.getLabel()));
400             setRowsPerPage(((Number JavaDoc)rowsPerPageChooser.getValue()).intValue());
401         }
402         context.getDisplay().refresh();
403     }
404     
405     /**
406      * Ensures that startIndex is not ouf of range
407      */

408     protected void checkRange() {
409         if (startIndex>=model.getRowCount()) {
410             if (split) {
411                 startIndex = model.getRowCount() - model.getRowCount()%rowsPerPage;
412                 if (startIndex==model.getRowCount())
413                     startIndex = 0;
414             } else
415                 startIndex = 0;
416         }
417     }
418
419     /**
420      * Returns an HTML link to remove the element at a given position.
421      */

422     protected String JavaDoc removeLink(int position) {
423         // We should use eventURL
424
return "<a HREF=\""+eventURL("onRemove")+
425             "&amp;index="+position+"\">"+
426             iconElement(ResourceManager.getResource("remove_icon"),"remove")+"</a>";
427     }
428
429     protected String JavaDoc viewLink(int position) {
430         // We should use eventURL
431
return "<a HREF=\""+eventURL("onView")+
432             "&amp;index="+position+"\">"+
433             iconElement(ResourceManager.getResource("view_icon"),"view")+"</a>";
434     }
435
436     /**
437      * Build an HTML link with an image showing if a column is used to
438      * sort the collection
439      * @param column the index of the column
440      * @param text additional text to put in the link
441      * @return the HTML code of the link
442      */

443     protected String JavaDoc sortLink(int column,String JavaDoc text) {
444         SortCriteria criteria = sorter.getSortCriteria(column);
445         String JavaDoc iconResource;
446         if (criteria==null) {
447             iconResource = "small_down_icon";
448         } else {
449             if (criteria.isAscending())
450                 iconResource = "small_down_icon_selected";
451             else
452                 iconResource = "small_up_icon_selected";
453         }
454         return
455             "<a HREF=\""+eventURL("onHeaderClick")+"&amp;col="+column+"\""
456             + " title=\"sort\">"
457             + iconElement(ResourceManager.getResource(iconResource),"sort")
458             + " " + text
459             + "</a>";
460     }
461
462     // When disabled == true, readValue() does nothing
463
boolean disabled = false;
464     public boolean isEnabled() {
465         return !disabled;
466     }
467     public void setEnabled(boolean enabled) {
468         loggerEditor.debug((enabled?"enable ":"disable ")+this);
469         this.disabled = !enabled;
470     }
471 }
472
Popular Tags