1 13 14 package mondrian.rolap; 15 16 import mondrian.olap.*; 17 18 import org.apache.log4j.Logger; 19 import java.util.*; 20 21 29 public class RolapMember extends MemberBase { 30 31 private static final Logger LOGGER = Logger.getLogger(RolapMember.class); 32 33 38 private Comparable orderKey; 39 40 54 public static Member[][] getAllMembers(SchemaReader schemaReader, 55 Hierarchy hierarchy) { 56 57 long start = System.currentTimeMillis(); 58 59 try { 60 List<Member[]> list = new ArrayList<Member[]>(500); 61 62 Level[] levels = hierarchy.getLevels(); 65 for (Level level : levels) { 66 Member[] members = schemaReader.getLevelMembers(level, true); 67 if (members != null) { 68 list.add(members); 69 } 70 } 71 return list.toArray(new Member[list.size()][]); 72 } finally { 73 if (LOGGER.isDebugEnabled()) { 74 long end = System.currentTimeMillis(); 75 LOGGER.debug("RolapMember.getAllMembers: time=" +(end-start)); 76 } 77 } 78 } 79 80 public static int getHierarchyCardinality( 81 SchemaReader schemaReader, 82 Hierarchy hierarchy) 83 { 84 int cardinality = 0; 85 Level[] levels = hierarchy.getLevels(); 86 for (Level level1 : levels) { 87 cardinality += schemaReader.getLevelCardinality(level1, true, true); 88 } 89 return cardinality; 90 } 91 92 129 public static void setOrdinals(SchemaReader schemaReader, Member seedMember) { 130 long start = System.currentTimeMillis(); 131 132 try { 133 Hierarchy hierarchy = seedMember.getHierarchy(); 134 int ordinal = hierarchy.hasAll() ? 1 : 0; 136 Member[][] membersArray = getAllMembers(schemaReader, hierarchy); 137 Member[] leafMembers = membersArray[membersArray.length-1]; 138 139 for (Member child : leafMembers) { 141 ordinal = bottomUpSetParentOrdinals(ordinal, child); 142 ordinal = setOrdinal(child, ordinal); 143 } 144 145 boolean needsFullTopDown = false; 149 for (int i = 0; i < membersArray.length-1; i++) { 150 Member[] members = membersArray[i]; 151 for (Member member : members) { 152 if (member.getOrdinal() == -1) { 153 needsFullTopDown = true; 154 break; 155 } 156 } 157 } 158 if (needsFullTopDown) { 161 for (int i = 0; i < membersArray.length-1; i++) { 162 Member[] members = membersArray[i]; 163 for (Member member : members) { 164 if (member instanceof RolapMember) { 165 ((RolapMember) member).resetOrdinal(); 166 } 167 } 168 } 169 170 setOrdinalsTopDown(schemaReader, seedMember); 172 } 173 } finally { 174 if (LOGGER.isDebugEnabled()) { 175 long end = System.currentTimeMillis(); 176 LOGGER.debug("RolapMember.setOrdinals: time=" +(end-start)); 177 } 178 } 179 } 180 private static int bottomUpSetParentOrdinals(int ordinal, Member child) { 181 Member parent = child.getParentMember(); 182 if ((parent != null) && parent.getOrdinal() == -1) { 183 ordinal = bottomUpSetParentOrdinals(ordinal, parent); 184 ordinal = setOrdinal(parent, ordinal); 185 } 186 return ordinal; 187 } 188 189 private static int setOrdinal(Member member, int ordinal) { 190 if (member instanceof RolapMember) { 191 ((RolapMember) member).setOrdinal(ordinal++); 192 } else { 193 LOGGER.warn("RolapMember.setAllChildren: NOT RolapMember "+ 195 "member.name=" +member.getName()+ 196 ", member.class=" +member.getClass().getName()+ 197 ", ordinal=" +ordinal 198 ); 199 ordinal++; 200 } 201 return ordinal; 202 } 203 204 214 public static void setOrdinalsTopDown(SchemaReader schemaReader, Member member) { 215 long start = System.currentTimeMillis(); 216 217 try { 218 Member parent = schemaReader.getMemberParent(member); 219 220 if (parent == null) { 221 int ordinal = 0; 223 224 Member[] siblings = 225 schemaReader.getHierarchyRootMembers(member.getHierarchy()); 226 227 for (Member sibling : siblings) { 228 ordinal = setAllChildren(ordinal, schemaReader, sibling); 229 } 230 231 } else { 232 setOrdinalsTopDown(schemaReader, parent); 233 } 234 } finally { 235 if (LOGGER.isDebugEnabled()) { 236 long end = System.currentTimeMillis(); 237 LOGGER.debug("RolapMember.setOrdinalsTopDown: time=" +(end-start)); 238 } 239 } 240 } 241 private static int setAllChildren( 242 int ordinal, SchemaReader schemaReader, Member member) { 243 244 ordinal = setOrdinal(member, ordinal); 245 246 Member[] children = schemaReader.getMemberChildren(member); 247 for (Member child : children) { 248 ordinal = setAllChildren(ordinal, schemaReader, child); 249 } 250 251 return ordinal; 252 } 253 254 264 private static String keyToString(Object key) { 265 String name; 266 if (key == null) { 267 name = RolapUtil.mdxNullLiteral; 268 } else { 269 name = key.toString(); 270 } 271 if ((key instanceof Number ) && name.endsWith(".0")) { 272 name = name.substring(0, name.length() - 2); 273 } 274 return name; 275 } 276 277 280 private int ordinal; 281 private final Object key; 282 289 private Map<String , Object > mapPropertyNameToValue; 290 291 300 protected RolapMember( 301 RolapMember parentMember, 302 RolapLevel level, 303 Object key, 304 String name, 305 MemberType flags) { 306 super(parentMember, level, flags); 307 308 this.key = key; 309 this.ordinal = -1; 310 this.mapPropertyNameToValue = Collections.emptyMap(); 311 312 if (name != null && 313 !(key != null && name.equals(key.toString()))) { 314 setProperty(Property.NAME.name, name); 317 } else { 318 setUniqueName(key); 319 } 320 } 321 322 RolapMember(RolapMember parentMember, RolapLevel level, Object value) { 323 this(parentMember, level, value, null, MemberType.REGULAR); 324 } 325 326 327 protected Logger getLogger() { 328 return LOGGER; 329 } 330 331 public RolapLevel getLevel() { 332 return (RolapLevel) level; 333 } 334 335 public RolapHierarchy getHierarchy() { 336 return getLevel().getHierarchy(); 337 } 338 339 public RolapMember getParentMember() { 340 return (RolapMember) super.getParentMember(); 341 } 342 343 public boolean equals(Object o) { 344 return (o == this) || 345 ((o instanceof RolapMember) && equals((RolapMember) o)); 346 } 347 348 public boolean equals(OlapElement o) { 349 return (o instanceof RolapMember) && 350 equals((RolapMember) o); 351 } 352 353 private boolean equals(RolapMember that) { 354 assert that != null; return this.getUniqueName().equalsIgnoreCase(that.getUniqueName()); 356 } 357 358 void makeUniqueName(HierarchyUsage hierarchyUsage) { 359 if (parentMember == null && key != null) { 360 String n = hierarchyUsage.getName(); 361 if (n != null) { 362 String name = keyToString(key); 363 n = Util.quoteMdxIdentifier(n); 364 this.uniqueName = Util.makeFqName(n, name); 365 if (getLogger().isDebugEnabled()) { 366 getLogger().debug("RolapMember.makeUniqueName: uniqueName=" 367 +uniqueName); 368 } 369 } 370 } 371 } 372 373 private void setUniqueName(Object key) { 374 String name = keyToString(key); 375 this.uniqueName = (parentMember == null) 376 ? Util.makeFqName(getHierarchy(), name) 377 : Util.makeFqName(parentMember, name); 378 } 379 380 381 public boolean isCalculatedInQuery() { 382 return false; 383 } 384 385 public String getName() { 386 final String name = 387 (String ) getPropertyValue(Property.NAME.name); 388 return (name != null) 389 ? name 390 : keyToString(key); 391 } 392 393 public void setName(String name) { 394 throw new Error ("unsupported"); 395 } 396 397 403 public synchronized void setProperty(String name, Object value) { 404 if (name.equals(Property.CAPTION.name)) { 405 setCaption((String )value); 406 return; 407 } 408 409 if (mapPropertyNameToValue.isEmpty()) { 410 mapPropertyNameToValue = new HashMap<String , Object >(); 412 } 413 if (name.equals(Property.NAME.name)) { 414 if (value == null) { 415 value = RolapUtil.mdxNullLiteral; 416 } 417 setUniqueName(value); 418 } 419 420 if (name.equals(Property.MEMBER_ORDINAL.name)) { 421 String ordinal = (String ) value; 422 if (ordinal.startsWith("\"") && ordinal.endsWith("\"")) { 423 ordinal = ordinal.substring(1, ordinal.length() - 1); 424 } 425 final double d = Double.parseDouble(ordinal); 426 setOrdinal((int) d); 427 } 428 429 mapPropertyNameToValue.put(name, value); 430 } 431 432 public final Object getPropertyValue(String propertyName) { 433 return getPropertyValue(propertyName, true); 434 } 435 436 public Object getPropertyValue(String propertyName, boolean matchCase) { 437 Property property = Property.lookup(propertyName, matchCase); 438 if (property != null) { 439 Schema schema; 440 Member parentMember; 441 List<RolapMember> list; 442 switch (property.ordinal) { 443 case Property.NAME_ORDINAL: 444 break; 447 448 case Property.CAPTION_ORDINAL: 449 return getCaption(); 450 451 case Property.CONTRIBUTING_CHILDREN_ORDINAL: 452 list = new ArrayList<RolapMember>(); 453 getHierarchy().getMemberReader().getMemberChildren(this, list); 454 return list; 455 456 case Property.CATALOG_NAME_ORDINAL: 457 break; 460 461 case Property.SCHEMA_NAME_ORDINAL: 462 schema = getHierarchy().getDimension().getSchema(); 463 return schema.getName(); 464 465 case Property.CUBE_NAME_ORDINAL: 466 break; 468 469 case Property.DIMENSION_UNIQUE_NAME_ORDINAL: 470 return getHierarchy().getDimension().getUniqueName(); 471 472 case Property.HIERARCHY_UNIQUE_NAME_ORDINAL: 473 return getHierarchy().getUniqueName(); 474 475 case Property.LEVEL_UNIQUE_NAME_ORDINAL: 476 return getLevel().getUniqueName(); 477 478 case Property.LEVEL_NUMBER_ORDINAL: 479 return getLevel().getDepth(); 480 481 case Property.MEMBER_UNIQUE_NAME_ORDINAL: 482 return getUniqueName(); 483 484 case Property.MEMBER_NAME_ORDINAL: 485 return getName(); 486 487 case Property.MEMBER_TYPE_ORDINAL: 488 return getMemberType().ordinal(); 489 490 case Property.MEMBER_GUID_ORDINAL: 491 return null; 492 493 case Property.MEMBER_CAPTION_ORDINAL: 494 return getCaption(); 495 496 case Property.MEMBER_ORDINAL_ORDINAL: 497 return getOrdinal(); 498 499 case Property.CHILDREN_CARDINALITY_ORDINAL: 500 Integer cardinality; 501 502 if (isAllMember() && childLevelHasApproxRowCount()) { 503 cardinality = getLevel().getChildLevel().getApproxRowCount(); 504 } else { 505 list = new ArrayList<RolapMember>(); 506 getHierarchy().getMemberReader().getMemberChildren(this, list); 507 cardinality = list.size(); 508 } 509 return cardinality; 510 511 case Property.PARENT_LEVEL_ORDINAL: 512 parentMember = getParentMember(); 513 return parentMember == null ? 0 : 514 parentMember.getLevel().getDepth(); 515 516 case Property.PARENT_UNIQUE_NAME_ORDINAL: 517 parentMember = getParentMember(); 518 return parentMember == null ? null : 519 parentMember.getUniqueName(); 520 521 case Property.PARENT_COUNT_ORDINAL: 522 parentMember = getParentMember(); 523 return parentMember == null ? 0 : 1; 524 525 case Property.DESCRIPTION_ORDINAL: 526 return getDescription(); 527 528 case Property.VISIBLE_ORDINAL: 529 break; 530 531 default: 532 break; 533 } 535 } 536 synchronized (this) { 537 if (matchCase) { 538 return mapPropertyNameToValue.get(propertyName); 539 } else { 540 for (String key : mapPropertyNameToValue.keySet()) { 541 if (key.equalsIgnoreCase(propertyName)) { 542 return mapPropertyNameToValue.get(key); 543 } 544 } 545 return null; 546 } 547 } 548 } 549 550 private boolean childLevelHasApproxRowCount() { 551 return getLevel().getChildLevel().getApproxRowCount() > Integer.MIN_VALUE; 552 } 553 554 private boolean isAllMember() { 555 return getLevel().getHierarchy().hasAll() 556 && getLevel().getDepth() == 0; 557 } 558 559 public Property[] getProperties() { 560 return level.getInheritedProperties(); 561 } 562 563 564 public int getOrdinal() { 565 return ordinal; 566 } 567 568 public Comparable getOrderKey() { 569 return orderKey; 570 } 571 572 void setOrdinal(int ordinal) { 573 if (this.ordinal == -1) { 574 this.ordinal = ordinal; 575 } 576 } 577 578 void setOrderKey(Comparable orderKey) { 579 this.orderKey = orderKey; 580 } 581 582 private void resetOrdinal() { 583 this.ordinal = -1; 584 } 585 586 public Object getKey() { 587 return this.key; 588 } 589 590 603 public int compareTo(Object o) { 604 RolapMember other = (RolapMember)o; 605 if (this.key != null && other.key == null) { 606 return 1; } 608 if (this.key == null && other.key != null) { 609 return -1; } 611 if (this.key == null && other.key == null) { 613 return this.getUniqueName().compareTo(other.getUniqueName()); 614 } 615 if (this.key == RolapUtil.sqlNullValue || 617 other.key == RolapUtil.sqlNullValue) { 618 return this.getUniqueName().compareTo(other.getUniqueName()); 619 } 620 if (this.key.getClass().equals(other.key.getClass())) { 625 if (this.key instanceof String ) { 626 return Util.compareName((String ) this.key, (String ) other.key); 627 } else { 628 return Util.compareKey(this.key, other.key); 629 } 630 } 631 return this.getUniqueName().compareTo(other.getUniqueName()); 636 } 637 638 public boolean isHidden() { 639 final RolapLevel rolapLevel = getLevel(); 640 switch (rolapLevel.getHideMemberCondition()) { 641 case Never: 642 return false; 643 644 case IfBlankName: { 645 final String name = getName(); 648 return name.equals(RolapUtil.mdxNullLiteral) || name.equals(""); 649 } 650 651 case IfParentsName: { 652 final Member parentMember = getParentMember(); 653 if (parentMember == null) { 654 return false; 655 } 656 final String parentName = parentMember.getName(); 657 final String name = getName(); 658 return (parentName == null ? "" : parentName).equals( 659 name == null ? "" : name); 660 } 661 662 default: 663 throw Util.badValue(rolapLevel.getHideMemberCondition()); 664 } 665 } 666 667 public int getDepth() { 668 return level.getDepth(); 669 } 670 671 public Object getSqlKey() { 672 return key; 673 } 674 675 679 public String getPropertyFormattedValue(String propertyName) { 680 Property[] props = getLevel().getProperties(); 682 Property prop = null; 683 for (Property prop1 : props) { 684 if (prop1.getName().equals(propertyName)) { 685 prop = prop1; 686 break; 687 } 688 } 689 PropertyFormatter pf; 690 if (prop!=null && (pf = prop.getFormatter()) != null) { 691 return pf.formatProperty(this, propertyName, 692 getPropertyValue(propertyName)); 693 } 694 695 Object val = getPropertyValue(propertyName); 696 return (val == null) 697 ? "" 698 : val.toString(); 699 } 700 701 } 702 703 | Popular Tags |