1 13 package com.tonbeller.jpivot.olap.query; 14 15 import java.io.BufferedWriter ; 16 import java.io.FileWriter ; 17 import java.io.IOException ; 18 import java.io.PrintWriter ; 19 import java.util.ArrayList ; 20 import java.util.Collections ; 21 import java.util.Comparator ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.ListIterator ; 26 import java.util.Map ; 27 28 import com.tonbeller.jpivot.core.Model; 29 import com.tonbeller.jpivot.olap.model.Axis; 30 import com.tonbeller.jpivot.olap.model.Cell; 31 import com.tonbeller.jpivot.olap.model.Member; 32 import com.tonbeller.jpivot.olap.model.Position; 33 import com.tonbeller.jpivot.olap.model.Result; 34 import com.tonbeller.jpivot.olap.model.Visitor; 35 import com.tonbeller.jpivot.util.CubeIndexIterator; 36 37 40 public abstract class ResultBase implements Result { 41 42 private static String [] specialProps = { "arrow"}; 43 44 protected List axesList; 45 46 protected List aCells; 47 48 protected Axis slicer; 49 50 protected Model model; 51 52 boolean overflow = false; 53 54 public ResultBase(Model model) { 56 aCells = new ArrayList (); 57 axesList = new ArrayList (); 58 this.model = model; 59 } 60 61 67 void processSpecialProps() { 68 } 69 70 73 public abstract Axis[] getAxes(); 74 75 81 public Axis getSlicer() { 82 return slicer; 83 } 84 85 91 public List getCells() { 92 return aCells; 93 } 94 95 104 public void hierarchize(int iAxis) { 105 List posList = ((Axis) axesList.get(iAxis)).getPositions(); 106 int nDim = axesList.size(); 107 int indexForAxis = nDim - 1 - iAxis; 108 int[] ni = new int[nDim]; 109 int[] iFull = new int[nDim]; 110 for (int i = 0; i < nDim; i++) { 111 ni[i] = ((Axis) axesList.get(i)).getPositions().size() - 1; 112 } 113 int[] iSlice = new int[nDim - 1]; 114 CubeIndexIterator cubit = null; 115 if (nDim > 1) { 116 full2slice(ni, iSlice, iAxis); 117 cubit = new CubeIndexIterator(iSlice, false); 118 } 119 120 133 136 int iPos = 0; 137 int nDimension = 0; 138 for (Iterator iter = posList.iterator(); iter.hasNext(); iPos++) { 139 PositionBase pos = (PositionBase) iter.next(); 140 if (nDimension == 0) 141 nDimension = pos.getMembers().length; 142 pos.number = iPos; 143 if (pos.cellList == null) 144 pos.cellList = new ArrayList (); 145 else 146 pos.cellList.clear(); 147 if (nDim > 1) { 148 cubit.reset(); 149 while (true) { 150 int[] iCurrent = cubit.next(); 151 if (iCurrent == null) 152 break; 153 slice2full(iCurrent, iFull, indexForAxis, iPos); 154 int ii = lindex(iFull, ni); 155 pos.cellList.add(aCells.get(ii)); 156 } 157 } else { 158 pos.cellList.add(aCells.get(iPos)); 160 } 161 } 162 163 posList = sortPosList(posList, 0, nDim); 165 166 int nc = aCells.size(); 168 aCells.clear(); 169 for (int i = 0; i < nc; i++) 170 aCells.add(null); 171 iPos = 0; 172 for (Iterator iter = posList.iterator(); iter.hasNext(); iPos++) { 173 PositionBase posBase = (PositionBase) iter.next(); 174 if (nDim > 1) { 175 cubit.reset(); 176 for (Iterator iterator = posBase.cellList.iterator(); iterator.hasNext();) { 177 Object cellObj = iterator.next(); 178 int[] iCurrent = cubit.next(); 179 if (iCurrent == null) 180 break; 181 slice2full(iCurrent, iFull, indexForAxis, iPos); 182 int ii = lindex(iFull, ni); 183 aCells.set(ii, cellObj); 184 } 185 } else { 186 Object cellObj = posBase.cellList.get(0); 188 aCells.set(iPos, cellObj); 189 } 190 posBase.cellList.clear(); 191 } 192 193 } 194 195 202 private List sortPosList(List posList, final int iDim, int nDim) { 203 204 printPosList(posList, new PrintWriter (System.out), "Start sortPosList " + iDim); 205 206 if (posList.size() < 2) 207 return posList; 208 209 final Map firstOcc = new HashMap (); 211 int k = 0; 212 for (Iterator iter = posList.iterator(); iter.hasNext(); k++) { 213 PositionBase posb = (PositionBase) iter.next(); 214 posb.parent = null; 215 Member m = posb.getMembers()[iDim]; 216 if (!firstOcc.containsKey(m)) 217 firstOcc.put(m, new Integer (k)); 218 } 219 220 Collections.sort(posList, new Comparator () { 224 public int compare(Object o1, Object o2) { 225 Position pos1 = (Position) o1; 227 Position pos2 = (Position) o2; 228 Member a1 = pos1.getMembers()[iDim]; 229 Member a2 = pos2.getMembers()[iDim]; 230 231 int level1 = ((MDXLevel) a1.getLevel()).getDepth(); 234 int level2 = ((MDXLevel) a2.getLevel()).getDepth(); 235 if (level1 == level2) { 236 return ((PositionBase) pos1).number - ((PositionBase) pos2).number; 237 } else { 238 return level1 - level2; 239 } 240 } 241 }); 242 243 int i = 0; 246 Outerloop: for (Iterator iter = posList.iterator(); iter.hasNext(); i++) { 247 PositionBase posb = (PositionBase) iter.next(); 248 if (!iter.hasNext()) 249 break; 250 MDXMember m = (MDXMember) posb.getMembers()[iDim]; 251 int iLevel = ((MDXLevel) m.getLevel()).getDepth(); 252 ListIterator lit = posList.listIterator(i + 1); 253 InnerLoop: while (lit.hasNext()) { 254 PositionBase posb2 = (PositionBase) lit.next(); 255 if (posb2.parent != null) 256 continue; 257 MDXMember m2 = (MDXMember) posb2.getMembers()[iDim]; 258 int iLevel2 = ((MDXLevel) m2.getLevel()).getDepth(); 259 if (iLevel2 <= iLevel) 260 continue InnerLoop; 261 if (iLevel2 > iLevel + 1) 262 break InnerLoop; 263 if (m.getUniqueName().equals(m2.getParentUniqueName())) 265 posb2.parent = posb; 266 } 267 } 268 269 Collections.sort(posList, new Comparator () { 272 public int compare(Object o1, Object o2) { 273 PositionBase pos1 = (PositionBase) o1; 275 PositionBase pos2 = (PositionBase) o2; 276 Member a1 = pos1.getMembers()[iDim]; 277 Member a2 = pos2.getMembers()[iDim]; 278 if (a1.equals(a2)) { return pos1.number - pos2.number; } 279 280 int level1 = ((MDXLevel) a1.getLevel()).getDepth(); 282 int level2 = ((MDXLevel) a2.getLevel()).getDepth(); 283 PositionBase par1 = null; 284 PositionBase par2 = null; 285 PositionBase parb = null; 286 if (level1 < level2) { 287 parb = pos2; 289 for (int j = 0; j < level2 - level1; j++) { 290 if (parb != null) 291 parb = parb.parent; 292 } 293 if (parb != null) { 294 Member ab = parb.getMembers()[iDim]; 295 if (ab.equals(a1)) 296 return -1; } 298 par1 = pos1; 299 par2 = parb; 300 } else if (level1 > level2) { 301 parb = pos1; 303 for (int j = 0; j < level1 - level2; j++) { 304 if (parb != null) 305 parb = parb.parent; 306 } 307 if (parb != null) { 308 Member ab = parb.getMembers()[iDim]; 309 if (ab.equals(a2)) 310 return 1; } 312 par1 = parb; 313 par2 = pos2; 314 315 } else { 316 par1 = pos1; 318 par2 = pos2; 319 } 320 if (par1 == null || par2 == null) 322 return pos1.number - pos2.number; Member apar1 = par1.getMembers()[iDim]; 325 Member apar2 = par2.getMembers()[iDim]; 326 PositionBase p1 = par1.parent; 327 PositionBase p2 = par2.parent; 328 while (p1 != null && p2 != null) { 329 Member ap1 = p1.getMembers()[iDim]; 330 Member ap2 = p2.getMembers()[iDim]; 331 if (ap1.equals(ap2)) 332 break; 333 par1 = p1; 334 par2 = p2; 335 p1 = par1.parent; 336 p2 = par2.parent; 337 if (p1 == null || p2 == null) 338 break; 339 apar1 = ap1; 340 apar2 = ap2; 341 } 342 343 int retcode = ((Integer ) firstOcc.get(apar1)).intValue() 344 - ((Integer ) firstOcc.get(apar2)).intValue(); 345 346 return retcode; 347 } 348 }); 349 350 printPosList(posList, new PrintWriter (System.out), "Step 3 sortPosList " + iDim); 351 352 if (iDim == nDim - 1) 355 return posList; 356 List newPosList = new ArrayList (); 357 List subList = new ArrayList (); 358 Member first = null; 359 for (Iterator iter = posList.iterator(); iter.hasNext();) { 360 PositionBase pb = (PositionBase) iter.next(); 361 if (first == null) { 362 first = pb.getMembers()[iDim]; 363 subList.add(pb); 364 } else { 365 Member current = pb.getMembers()[iDim]; 366 if (current.equals(first)) { 367 subList.add(pb); 368 } else { 369 subList = sortPosList(subList, iDim + 1, nDim); 370 newPosList.addAll(subList); 371 subList.clear(); 372 first = current; 373 subList.add(pb); 374 } 375 } 376 } 377 if (subList.size() > 1) { 378 subList = sortPosList(subList, iDim + 1, nDim); 379 } 380 newPosList.addAll(subList); 381 382 printPosList(newPosList, new PrintWriter (System.out), "End sortPosList " + iDim); 383 384 return newPosList; 385 } 386 387 390 private void printPosList(List posList, PrintWriter wout, String label) { 391 wout.println(label); 392 int n = 0; 393 for (Iterator iter = posList.iterator(); iter.hasNext(); n++) { 394 PositionBase pb = (PositionBase) iter.next(); 395 Member[] members = pb.getMembers(); 396 StringBuffer sb = new StringBuffer (); 397 for (int i = 0; i < members.length; i++) { 398 if (i == 0) { 399 sb.append(n); 400 sb.append(" "); 401 sb.append(pb.number); 402 sb.append(" "); 403 } else { 404 sb.append(" * "); 405 } 406 407 sb.append(members[i].getLabel()); 408 } 409 wout.println(sb.toString()); 410 } 411 wout.flush(); 412 } 413 414 422 private void full2slice(int[] iFull, int[] iSlice, int iAxis) { 423 if (iSlice.length == 0) 424 return; int j = 0; 426 for (int i = 0; i < iFull.length; i++) { 427 if (i != iAxis) 428 iSlice[j++] = iFull[i]; 429 } 430 } 431 432 440 private void slice2full(int[] iSlice, int[] iFull, int iAxis, int iAxisVal) { 441 if (iSlice.length == 0) { 442 iFull[0] = iAxisVal; 443 return; 444 } 445 446 int j = 0; 447 for (int i = 0; i < iFull.length; i++) { 448 if (i != iAxis) 449 iFull[i] = iSlice[j++]; 450 else 451 iFull[i] = iAxisVal; 452 } 453 } 454 455 461 private int lindex(int[] iar, int[] ni) { 462 463 469 470 471 int k = iar[0]; 472 for (int j = 1; j < iar.length; j++) 473 k = k * (ni[j - 1] + 1) + iar[j]; 474 475 return k; 476 } 477 478 481 public Object getRootDecoree() { 482 return this; 483 } 484 485 488 489 public void accept(Visitor visitor) { 490 visitor.visitResult(this); 491 } 492 493 496 public static void renderHtml(Result result, String mdx, String outfile) throws IOException { 497 int i; 498 499 PrintWriter wout = new PrintWriter (new BufferedWriter (new FileWriter (outfile))); 500 501 Axis[] axes = result.getAxes(); 502 503 wout.println("<HTML>"); 504 wout.println("<HEAD>"); 505 wout.println("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">"); 506 wout.println("<TITLE>Result from MDX Query</TITLE>"); 507 wout.println("</HEAD>"); 508 wout.println("<BODY>"); 509 510 wout.println("<h1>MDX Query Result</h1>"); 511 512 if (mdx != null ) { 514 wout.println("<p>"); 515 wout.println(mdx); 516 wout.println("</p>"); 517 } 518 wout.println("<table border=\"3\">"); 519 wout.println("<thead><tr>"); 520 521 if (axes.length == 0) { 522 wout.println("<th>Slicer</th><th>Result</th>"); 524 wout.println("</thead><tbody><tr>"); 525 526 renderSlicerRowHeader(result.getSlicer(), wout); 528 529 Cell cell = (Cell) result.getCells().get(0); 530 String value = cell.getFormattedValue(); 531 wout.println("<td>" + value + "</td>"); 532 wout.println("</tr>"); 533 } else if (axes.length == 1) { 534 renderColHeaders(wout, axes[0]); 537 wout.println("</tr></thead>"); 538 539 wout.println("<tbody><tr>"); 540 renderSlicerRowHeader(result.getSlicer(), wout); 542 543 int n = 0; 544 for (i = 0; i < axes[0].getPositions().size(); i++) { 545 Cell cell = (Cell) result.getCells().get(n++); 546 String value = cell.getFormattedValue(); 547 wout.println("<td>" + value + "</td>"); 548 } 549 wout.println("</tr>"); 550 } else if( axes.length == 2 ) { 551 renderColHeaders(wout, axes[0]); 554 555 wout.println("</tr></thead>"); 556 557 wout.println("<tbody>"); 559 Position[] positions = (Position[]) axes[1].getPositions().toArray(new Position[0]); 560 int n = 0; 561 for (i = 0; i < positions.length; i++) { 562 wout.println("<tr>"); 563 Member[] members = positions[i].getMembers(); 564 565 String caption = ""; 566 for (int j = 0; j < members.length; j++) { 567 if (j > 0) 568 caption = caption + "<br>" + members[j].getLabel(); 569 else 570 caption = members[j].getLabel(); 571 } 572 wout.println("<th>" + caption + "</th>"); 573 for (int j = 0; j < axes[0].getPositions().size(); j++) { 574 Cell cell = (Cell) result.getCells().get(n++); 575 String value = cell.getFormattedValue(); 576 wout.println("<td>" + value + "</td>"); 577 } 578 wout.println("</tr>"); 579 } 580 } else { 581 throw new IllegalArgumentException ("ResultBase.renderHtml cannot handle more than 2 axes"); 583 } 584 585 wout.println("</tbody>"); 586 587 wout.println("</BODY></HTML>"); 588 wout.close(); 589 } 590 591 594 private static void renderColHeaders(PrintWriter wout, Axis axis) { 595 wout.println("<th></th>"); 597 Position[] positions = (Position[]) axis.getPositions().toArray(new Position[0]); 598 for (int i = 0; i < positions.length; i++) { 599 Member[] members = positions[i].getMembers(); 600 601 String caption = ""; 602 for (int j = 0; j < members.length; j++) { 603 if (j > 0) 604 caption = caption + "<br>" + members[j].getLabel(); 605 else 606 caption = members[j].getLabel(); 607 } 608 wout.println("<th>" + caption + "</th>"); 609 } 610 } 611 612 615 private static void renderSlicerRowHeader(Axis slicerax, PrintWriter wout) { 616 Position[] positions = (Position[]) slicerax.getPositions().toArray(new Position[0]); 617 String caption = ""; 618 for (int i = 0; i < positions.length; i++) { 619 Member[] members = positions[i].getMembers(); 620 for (int j = 0; j < members.length; j++) { 621 if (j == 0 && i == 0) 622 caption = members[j].getLabel(); 623 else 624 caption = caption + "<br>" + members[j].getLabel(); 625 } 626 } 627 wout.println("<th>" + caption + "</th>"); 628 } 629 630 636 public void printOut(java.io.PrintStream ps) { 637 Axis[] axes = this.getAxes(); 638 for (int i = 0; i < axes.length; i++) { 639 Axis a = axes[i]; 640 ps.println("Axis " + i); 641 printAxis(ps, a); 642 } 643 644 Axis slicer = this.getSlicer(); 645 ps.println("Slicer Axis "); 646 printAxis(ps, slicer); 647 648 Iterator it = aCells.iterator(); 649 int ic = 0; 650 while (it.hasNext()) { 651 Cell c = (Cell) it.next(); 652 String val = c.getFormattedValue(); 653 ps.println("Cell " + ic++ + " Value=" + val); 654 } 655 } 656 657 660 private void printAxis(java.io.PrintStream ps, Axis a) { 661 List positions = a.getPositions(); 662 Iterator it = positions.iterator(); 663 664 int ip = 0; 665 while (it.hasNext()) { 666 Position p = (Position) it.next(); 667 ps.println("Position " + ip++); 668 Member[] members = p.getMembers(); 669 for (int j = 0; j < members.length; j++) { 670 Member m = members[j]; 671 String mcap = m.getLabel(); 672 int idep = m.getRootDistance(); 673 ps.println("Member " + mcap + " depth=" + idep); 674 } 675 } 676 } 677 678 681 public boolean isOverflowOccured() { 682 return overflow; 683 } 684 685 688 public void setOverflowOccured(boolean overflow) { 689 this.overflow = overflow; 690 } 691 692 } | Popular Tags |