1 13 package com.tonbeller.jpivot.table.navi; 14 15 import org.w3c.dom.Element ; 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 45 public class SortRankUI extends TableComponentExtensionSupport implements ModelChangeListener { 46 47 public static final String 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 getId() { 92 return SortRank.ID; 93 } 94 95 public Model decorate(Model modelToDecorate) { 96 return modelToDecorate; 97 } 98 99 102 public void modelInitialized() { 103 } 105 106 } 107 108 public String getId() { 109 return ID; 110 } 111 112 public void initialize(RequestContext context, TableComponent table) throws Exception { 113 super.initialize(context, table); 114 table.getOlapModel().addModelChangeListener(this); 115 116 extension = getExtension(); 117 118 table.getDispatcher().addRequestListener(null, null, dispatcher); 120 121 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 138 class DomDecorator extends SpanBuilderDecorator { 139 DomDecorator(SpanBuilder delegate) { 140 super(delegate); 141 } 142 143 public Element build(SBContext sbctx, Span span, boolean even) { 144 Element parent = super.build(sbctx, span, even); 145 146 if (!isEnabled() || !renderActions) 148 return parent; 149 150 if (!triState && !extension.isSorting()) 152 return parent; 153 154 if (!span.isMember()) 156 return parent; 157 158 Member member = span.getMember(); 160 Position position = span.getPosition(); 161 if (!isCandidate(position, member)) 162 return parent; 163 164 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 Element sort = table.insert("sort", parent); 176 String 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 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 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 public void request(RequestContext context) throws Exception { 227 Scroller.enableScroller(context); 228 229 if (!extension.isSorting()) { 231 extension.setSorting(true); 232 extension.sort(axis, position); 233 return; 234 } 235 236 if (!extension.isCurrentSorting(position)) { 238 extension.sort(axis, position); 239 return; 240 } 241 242 if (isAscending() || isTopBottomCount()) { 244 flipAscending(); 245 extension.sort(axis, position); 246 return; 247 } 248 249 flipAscending(); 251 extension.setSorting(false); 252 } 253 } 254 255 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 { 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 316 317 320 public int getSortMode() { 321 return extension.getSortMode(); 322 } 323 324 327 public int getTopBottomCount() { 328 return extension.getTopBottomCount(); 329 } 330 331 334 public boolean isSorting() { 335 return extension.isSorting(); 336 } 337 338 341 public void setSorting(boolean enabled) { 342 extension.setSorting(enabled); 343 } 344 345 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 363 public void setTopBottomCount(int topBottomCount) { 364 extension.setTopBottomCount(topBottomCount); 365 } 366 367 371 public boolean isTriState() { 372 return triState; 373 } 374 375 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 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 |