KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > table > navi > SortRankUI


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.jpivot.table.navi;
14
15 import org.w3c.dom.Element JavaDoc;
16
17 import com.tonbeller.jpivot.core.Model;
18 import com.tonbeller.jpivot.core.ModelChangeEvent;
19 import com.tonbeller.jpivot.core.ModelChangeListener;
20 import com.tonbeller.jpivot.olap.model.Axis;
21 import com.tonbeller.jpivot.olap.model.Member;
22 import com.tonbeller.jpivot.olap.model.OlapException;
23 import com.tonbeller.jpivot.olap.model.Position;
24 import com.tonbeller.jpivot.olap.navi.SortRank;
25 import com.tonbeller.jpivot.table.AxisBuilder;
26 import com.tonbeller.jpivot.table.SpanBuilder;
27 import com.tonbeller.jpivot.table.SpanBuilderDecorator;
28 import com.tonbeller.jpivot.table.TableComponent;
29 import com.tonbeller.jpivot.table.TableComponentExtensionSupport;
30 import com.tonbeller.jpivot.table.span.Span;
31 import com.tonbeller.tbutils.res.Resources;
32 import com.tonbeller.wcf.component.RendererParameters;
33 import com.tonbeller.wcf.controller.Dispatcher;
34 import com.tonbeller.wcf.controller.DispatcherSupport;
35 import com.tonbeller.wcf.controller.RequestContext;
36 import com.tonbeller.wcf.controller.RequestListener;
37 import com.tonbeller.wcf.scroller.Scroller;
38 import com.tonbeller.wcf.utils.DomUtils;
39
40 /**
41  * Sort Buttons
42  *
43  * @author av
44  */

45 public class SortRankUI extends TableComponentExtensionSupport implements ModelChangeListener {
46
47   public static final String JavaDoc ID = "sortRank";
48
49   Dispatcher dispatcher = new DispatcherSupport();
50   private boolean triState = true;
51   Resources resources;
52   SortRank extension;
53   boolean renderActions;
54
55   class DummySortRank implements SortRank {
56     public boolean isSorting() {
57       return false;
58     }
59
60     public void setSorting(boolean enabled) {
61     }
62
63     public boolean isSortable(Position position) {
64       return false;
65     }
66
67     public boolean isCurrentSorting(Position position) {
68       return false;
69     }
70
71     public int getSortMode() {
72       return SortRank.ASC;
73     }
74
75     public void setSortMode(int mode) {
76     }
77
78     public int getTopBottomCount() {
79       return 10;
80     }
81
82     public void setTopBottomCount(int topBottomCount) {
83     }
84
85     public void sort(Axis membersToSort, Position position) throws OlapException {
86     }
87
88     public void setModel(Model model) {
89     }
90
91     public String JavaDoc getId() {
92       return SortRank.ID;
93     }
94
95     public Model decorate(Model modelToDecorate) {
96       return modelToDecorate;
97     }
98
99     /**
100      * Notification after model initialization is complete
101      */

102     public void modelInitialized() {
103       // no action
104
}
105
106   }
107
108   public String JavaDoc getId() {
109     return ID;
110   }
111
112   public void initialize(RequestContext context, TableComponent table) throws Exception JavaDoc {
113     super.initialize(context, table);
114     table.getOlapModel().addModelChangeListener(this);
115
116     extension = getExtension();
117
118     // extend the controller
119
table.getDispatcher().addRequestListener(null, null, dispatcher);
120
121     // add some decorators
122
AxisBuilder cab = table.getColumnAxisBuilder();
123     DomDecorator chr = new DomDecorator(cab.getSpanBuilder());
124     cab.setSpanBuilder(chr);
125     resources = context.getResources(SortRankUI.class);
126   }
127
128   public void startBuild(RequestContext context) {
129     super.startBuild(context);
130     renderActions = RendererParameters.isRenderActions(context);
131     if (renderActions)
132       dispatcher.clear();
133   }
134
135   /**
136    * adds the sort button elements to the dom tree
137    */

138   class DomDecorator extends SpanBuilderDecorator {
139     DomDecorator(SpanBuilder delegate) {
140       super(delegate);
141     }
142
143     public Element JavaDoc build(SBContext sbctx, Span span, boolean even) {
144       Element JavaDoc parent = super.build(sbctx, span, even);
145
146       // this extension is disabled
147
if (!isEnabled() || !renderActions)
148         return parent;
149
150       // natural sorting is shown w/o buttons
151
if (!triState && !extension.isSorting())
152         return parent;
153
154       // only member can be sorted
155
if (!span.isMember())
156         return parent;
157
158       // test if member is the on the innermost hierarchy
159
Member member = span.getMember();
160       Position position = span.getPosition();
161       if (!isCandidate(position, member))
162         return parent;
163
164       // find the axis to sort by. its "the other" axis
165
Axis axis = span.getAxis();
166       Axis[] axes = table.getResult().getAxes();
167       if (axes.length < 2)
168         return parent;
169       if (axes[0].getRootDecoree().equals(axis.getRootDecoree()))
170         axis = axes[1];
171       else
172         axis = axes[0];
173
174       // this node is sortable!
175
Element JavaDoc sort = table.insert("sort", parent);
176       String JavaDoc id = DomUtils.randomId();
177       sort.setAttribute("id", id);
178       if (triState)
179         dispatcher.addRequestListener(id, null, new SortHandler3(position, axis));
180       else
181         dispatcher.addRequestListener(id, null, new SortHandler2(position, axis));
182
183       sort.setAttribute("title", resources.getString("sort.mode." + extension.getSortMode()));
184       if (!extension.isSorting()) {
185         sort.setAttribute("mode", "sort-natural");
186         sort.setAttribute("title", resources.getString("sort.mode.natural"));
187       } else if (extension.isCurrentSorting((Position) position.getRootDecoree())) {
188         if (isAscending())
189           sort.setAttribute("mode", "sort-current-up");
190         else
191           sort.setAttribute("mode", "sort-current-down");
192       } else {
193         if (isAscending())
194           sort.setAttribute("mode", "sort-other-up");
195         else
196           sort.setAttribute("mode", "sort-other-down");
197       }
198
199       return parent;
200     }
201
202     /**
203      * true if member is at the innermost position and accepted by the extension
204      */

205     boolean isCandidate(Position position, Member member) {
206       Member[] members = position.getMembers();
207       if (!member.equals(members[members.length - 1]))
208         return false;
209       return extension.isSortable((Position) position.getRootDecoree());
210     }
211   }
212
213   /*
214    * tristate sort handler: ascending -&gt; descending -&gt; disabled
215    */

216   private class SortHandler3 implements RequestListener {
217     Position position;
218     Axis axis;
219
220     SortHandler3(Position position, Axis axis) {
221       this.position = (Position) position.getRootDecoree();
222       this.axis = (Axis) axis.getRootDecoree();
223     }
224
225     // tristate: asc -> desc -> disabled
226
public void request(RequestContext context) throws Exception JavaDoc {
227       Scroller.enableScroller(context);
228
229       // disabled -> asc
230
if (!extension.isSorting()) {
231         extension.setSorting(true);
232         extension.sort(axis, position);
233         return;
234       }
235
236       // clicked on another measure -> activate that measure
237
if (!extension.isCurrentSorting(position)) {
238         extension.sort(axis, position);
239         return;
240       }
241
242       // asc -> desc
243
if (isAscending() || isTopBottomCount()) {
244         flipAscending();
245         extension.sort(axis, position);
246         return;
247       }
248
249       // desc -> disabled
250
flipAscending();
251       extension.setSorting(false);
252     }
253   }
254
255   /**
256    * two state sort handler: asc &gt; desc
257    */

258   private class SortHandler2 implements RequestListener {
259     Position position;
260     Axis axis;
261
262     SortHandler2(Position position, Axis axis) {
263       this.position = (Position) position.getRootDecoree();
264       this.axis = (Axis) axis.getRootDecoree();
265     }
266
267     public void request(RequestContext context) throws Exception JavaDoc {
268       Scroller.enableScroller(context);
269       if (extension.isCurrentSorting(position))
270         flipAscending();
271       extension.sort(axis, position);
272     }
273   }
274
275   public boolean isAvailable() {
276     SortRank ext = getExtension();
277     return ext != null && !(ext instanceof DummySortRank);
278   }
279
280   boolean isTopBottomCount() {
281     int mode = extension.getSortMode();
282     return mode == SortRank.TOPCOUNT || mode == SortRank.BOTTOMCOUNT;
283   }
284   
285   boolean isAscending() {
286     int mode = extension.getSortMode();
287     return mode == SortRank.ASC || mode == SortRank.BASC || mode == SortRank.BOTTOMCOUNT;
288   }
289
290   void flipAscending() {
291     int mode = extension.getSortMode();
292     switch (mode) {
293     case SortRank.ASC:
294       mode = SortRank.DESC;
295       break;
296     case SortRank.DESC:
297       mode = SortRank.ASC;
298       break;
299     case SortRank.BASC:
300       mode = SortRank.BDESC;
301       break;
302     case SortRank.BDESC:
303       mode = SortRank.BASC;
304       break;
305     case SortRank.TOPCOUNT:
306       mode = SortRank.BOTTOMCOUNT;
307       break;
308     case SortRank.BOTTOMCOUNT:
309       mode = SortRank.TOPCOUNT;
310       break;
311     }
312     extension.setSortMode(mode);
313   }
314
315   /* ------------------------ properties for settings form -------------------- */
316
317   /**
318    * @see com.tonbeller.jpivot.olap.navi.SortRank
319    */

320   public int getSortMode() {
321     return extension.getSortMode();
322   }
323
324   /**
325    * @see com.tonbeller.jpivot.olap.navi.SortRank
326    */

327   public int getTopBottomCount() {
328     return extension.getTopBottomCount();
329   }
330
331   /**
332    * @see com.tonbeller.jpivot.olap.navi.SortRank
333    */

334   public boolean isSorting() {
335     return extension.isSorting();
336   }
337
338   /**
339    * @see com.tonbeller.jpivot.olap.navi.SortRank
340    */

341   public void setSorting(boolean enabled) {
342     extension.setSorting(enabled);
343   }
344
345   /**
346    * sets the sort mode and the level style
347    * @see com.tonbeller.jpivot.olap.navi.SortRank
348    */

349   public void setSortMode(int mode) {
350     extension.setSortMode(mode);
351     AxisStyleUI asu = (AxisStyleUI) table.getExtensions().get(AxisStyleUI.ID);
352     if (asu == null)
353       return;
354     if (mode == SortRank.ASC || mode == SortRank.DESC)
355       asu.setLevelStyle(false);
356     else
357       asu.setLevelStyle(true);
358   }
359
360   /**
361    * @see com.tonbeller.jpivot.olap.navi.SortRank
362    */

363   public void setTopBottomCount(int topBottomCount) {
364     extension.setTopBottomCount(topBottomCount);
365   }
366
367   /**
368    * Returns the triState.
369    * @return boolean
370    */

371   public boolean isTriState() {
372     return triState;
373   }
374
375   /**
376    * Sets the triState.
377    * @param triState The triState to set
378    */

379   public void setTriState(boolean triState) {
380     this.triState = triState;
381   }
382
383   private SortRank getExtension() {
384     SortRank ext = (SortRank) table.getOlapModel().getExtension(SortRank.ID);
385     if (ext == null)
386       ext = new DummySortRank();
387     return ext;
388   }
389
390   public void modelChanged(ModelChangeEvent e) {
391   }
392
393   public void structureChanged(ModelChangeEvent e) {
394     extension = getExtension();
395     dispatcher.clear();
396   }
397
398   /* ----------------------------------------------------------------- */
399
400   /**
401    * for easier GUI, user chooses a radio button out of "Keep Hierarchy",
402    * "Break Hierarchy" and "Topcount"
403    */

404   public boolean isBreakHierarchy() {
405     switch (extension.getSortMode()) {
406     case SortRank.BASC:
407     case SortRank.BDESC:
408       return true;
409     default:
410       return false;
411     }
412   }
413
414   public void setBreakHierarchy(boolean b) {
415     if (b)
416       setSortMode(SortRank.BDESC);
417   }
418
419   public boolean isKeepHierarchy() {
420     switch (extension.getSortMode()) {
421     case SortRank.ASC:
422     case SortRank.DESC:
423       return true;
424     default:
425       return false;
426     }
427   }
428
429   public void setKeepHierarchy(boolean b) {
430     if (b)
431       setSortMode(SortRank.DESC);
432   }
433
434   public boolean isRanking() {
435     switch (extension.getSortMode()) {
436     case SortRank.TOPCOUNT:
437     case SortRank.BOTTOMCOUNT:
438       return true;
439     default:
440       return false;
441     }
442   }
443
444   public void setRanking(boolean b) {
445     if (b)
446       setSortMode(SortRank.TOPCOUNT);
447   }
448
449 }
450
Popular Tags