001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2002-2005 Julian Hyde 008// Copyright (C) 2005-2010 Pentaho and others 009// Copyright (C) 2006-2007 CINCOM SYSTEMS, INC. 010// All Rights Reserved. 011*/ 012package mondrian.gui; 013 014import mondrian.gui.validate.ValidationUtils; 015import mondrian.gui.validate.impl.*; 016 017import org.eigenbase.xom.ElementDef; 018 019import java.awt.*; 020import javax.swing.*; 021import javax.swing.tree.TreePath; 022 023/** 024 * Render an entry for the tree. 025 * 026 * @author sean 027 */ 028public class SchemaTreeCellRenderer 029 extends javax.swing.tree.DefaultTreeCellRenderer 030{ 031 private final ClassLoader myClassLoader; 032 public boolean invalidFlag; 033 private JdbcMetaData jdbcMetaData; 034 private final Workbench workbench; 035 036 /** 037 * Creates a SchemaTreeCellRenderer with Workbench and metadata. 038 */ 039 public SchemaTreeCellRenderer( 040 Workbench workbench, 041 JdbcMetaData jdbcMetaData) 042 { 043 super(); 044 this.myClassLoader = this.getClass().getClassLoader(); 045 this.workbench = workbench; 046 this.jdbcMetaData = jdbcMetaData; 047 } 048 049 /** 050 * Creates a SchemaTreeCellRenderer. 051 */ 052 public SchemaTreeCellRenderer() { 053 this(null, null); 054 } 055 056 public Component getTreeCellRendererComponent( 057 JTree tree, 058 Object value, 059 boolean sel, 060 boolean expanded, 061 boolean leaf, 062 int row, 063 boolean hasFocus) 064 { 065 super.getTreeCellRendererComponent( 066 tree, value, sel, expanded, leaf, row, hasFocus); 067 068 invalidFlag = isInvalid(tree, value, row); 069 070 // Allow the layout mgr to calculate the pref size of renderer. 071 this.setPreferredSize(null); 072 if (value instanceof MondrianGuiDef.Cube) { 073 setText(invalidFlag, ((MondrianGuiDef.Cube) value).name); 074 super.setIcon( 075 new ImageIcon( 076 myClassLoader.getResource( 077 workbench 078 .getResourceConverter().getGUIReference("cube")))); 079 } else if (value instanceof MondrianGuiDef.Column) { 080 setText(invalidFlag, ((MondrianGuiDef.Column) value).name); 081 } else if (value instanceof MondrianGuiDef.Dimension) { 082 super.setIcon( 083 new ImageIcon( 084 myClassLoader.getResource( 085 workbench.getResourceConverter().getGUIReference( 086 "dimension")))); 087 setText(invalidFlag, ((MondrianGuiDef.CubeDimension) value).name); 088 // Do not remove this line. This sets the preferred width of tree 089 // cell displaying dimension name. This resolves the ambiguous 090 // problem of last char or last word truncated from dimension name 091 // in the tree cell. This problem was there with only Dimension 092 // objects, while all other objects display their names without any 093 // truncation of characters. Therefore, we have to force the setting 094 // of preferred width to desired width so that characters do not 095 // truncate from dimension name. Along with this the preferred size 096 // of other objects should be set to null, so that the layout mgr 097 // can calculate the preferred width in case of other objects. 098 this.setPreferredSize( 099 new java.awt.Dimension( 100 this.getPreferredSize().width + 1, 101 25)); 102 } else if (value instanceof MondrianGuiDef.DimensionUsage) { 103 super.setIcon( 104 new ImageIcon( 105 myClassLoader.getResource( 106 workbench.getResourceConverter().getGUIReference( 107 "dimensionUsage")))); 108 setText(invalidFlag, ((MondrianGuiDef.CubeDimension) value).name); 109 } else if (value instanceof MondrianGuiDef.KeyExpression) { 110 super.setIcon( 111 new ImageIcon( 112 myClassLoader.getResource( 113 workbench 114 .getResourceConverter().getGUIReference("key")))); 115 setText( 116 workbench.getResourceConverter().getString( 117 "common.keyExpression.title", 118 "Key Expression")); 119 } else if (value instanceof MondrianGuiDef.NameExpression) { 120 super.setIcon( 121 new ImageIcon( 122 myClassLoader.getResource( 123 workbench 124 .getResourceConverter().getGUIReference("name")))); 125 setText( 126 workbench.getResourceConverter().getString( 127 "common.nameExpression.title", 128 "Name Expression")); 129 } else if (value instanceof MondrianGuiDef.OrdinalExpression) { 130 super.setIcon( 131 new ImageIcon( 132 myClassLoader.getResource( 133 workbench.getResourceConverter().getGUIReference( 134 "ordinal")))); 135 setText( 136 workbench.getResourceConverter().getString( 137 "common.ordinalExpression.title", 138 "Ordinal Expression")); 139 } else if (value instanceof MondrianGuiDef.CaptionExpression) { 140 super.setIcon( 141 new ImageIcon( 142 myClassLoader.getResource( 143 workbench 144 .getResourceConverter().getGUIReference("name")))); 145 setText( 146 workbench.getResourceConverter().getString( 147 "common.captionExpression.title", 148 "Caption Expression")); 149 } else if (value instanceof MondrianGuiDef.ParentExpression) { 150 super.setIcon( 151 new ImageIcon( 152 myClassLoader.getResource( 153 workbench.getResourceConverter().getGUIReference( 154 "parent")))); 155 setText( 156 workbench.getResourceConverter().getString( 157 "common.parentExpression.title", 158 "Parent Expression")); 159 } else if (value instanceof MondrianGuiDef.Expression) { 160 super.setIcon( 161 new ImageIcon( 162 myClassLoader.getResource( 163 workbench.getResourceConverter().getGUIReference( 164 "expression")))); 165 setText( 166 workbench.getResourceConverter().getString( 167 "common.expression.title", 168 "Expression")); 169 } else if (value instanceof MondrianGuiDef.ExpressionView) { 170 super.setIcon( 171 new ImageIcon( 172 myClassLoader.getResource( 173 workbench.getResourceConverter().getGUIReference( 174 "expression")))); 175 setText( 176 workbench.getResourceConverter().getString( 177 "common.expressionView.title", 178 "Expression View")); 179 } else if (value instanceof MondrianGuiDef.Hierarchy) { 180 String name = ((MondrianGuiDef.Hierarchy) value).name; 181 182 if (name == null || name.trim().length() == 0) { 183 setText( 184 invalidFlag, 185 workbench.getResourceConverter().getString( 186 "common.hierarchy.default.name", 187 "default")); 188 } else { 189 setText(invalidFlag, name); 190 } 191 super.setIcon( 192 new ImageIcon( 193 myClassLoader.getResource( 194 workbench.getResourceConverter().getGUIReference( 195 "hierarchy")))); 196 this.setPreferredSize( 197 new java.awt.Dimension( 198 this.getPreferredSize().width + 1, 199 25)); 200 } else if (value instanceof MondrianGuiDef.RelationOrJoin) { 201 TreePath tpath = tree.getPathForRow(row); 202 String prefix = ""; 203 if (tpath != null) { 204 TreePath parentpath = tpath.getParentPath(); 205 if (parentpath != null) { 206 Object parent = parentpath.getLastPathComponent(); 207 if (parent instanceof MondrianGuiDef.Join) { 208 int indexOfChild = tree.getModel().getIndexOfChild( 209 parent, value); 210 switch (indexOfChild) { 211 case 0: 212 prefix = workbench.getResourceConverter().getString( 213 "common.left.title", 214 "Left") 215 + " "; 216 break; 217 case 1: 218 prefix = workbench.getResourceConverter().getString( 219 "common.right.title", 220 "Right") 221 + " "; 222 break; 223 } 224 } 225 } 226 } 227 if (value instanceof MondrianGuiDef.Join) { 228 setText( 229 workbench.getResourceConverter().getFormattedString( 230 "schemaTreeCellRenderer.join.title", 231 "{0}Join", 232 prefix)); 233 super.setIcon( 234 new ImageIcon( 235 myClassLoader.getResource( 236 workbench.getResourceConverter().getGUIReference( 237 "join")))); 238 } else if (value instanceof MondrianGuiDef.Table) { 239 // Set the table name to alias if present. 240 MondrianGuiDef.Table theTable = (MondrianGuiDef.Table) value; 241 String theName = 242 (theTable.alias != null 243 && theTable.alias.trim().length() > 0) 244 ? theTable.alias 245 : theTable.name; 246 setText( 247 workbench.getResourceConverter().getFormattedString( 248 "schemaTreeCellRenderer.table.title", 249 "{0}Table: {1}", 250 prefix.length() == 0 251 ? "" 252 : prefix + " : ", 253 theName)); 254 super.setIcon( 255 new ImageIcon( 256 myClassLoader.getResource( 257 workbench.getResourceConverter().getGUIReference( 258 "table")))); 259 } else if (value instanceof MondrianGuiDef.View) { 260 setText( 261 workbench.getResourceConverter().getFormattedString( 262 "schemaTreeCellRenderer.view.title", 263 "View")); 264 } 265 // REVIEW: Need to deal with InlineTable here 266 this.getPreferredSize(); 267 // Do not remove this 268 this.setPreferredSize( 269 new Dimension( 270 this.getPreferredSize().width + 35, 271 24)); 272 } else if (value instanceof MondrianGuiDef.Level) { 273 setText(invalidFlag, ((MondrianGuiDef.Level) value).name); 274 super.setIcon( 275 new ImageIcon( 276 myClassLoader.getResource( 277 workbench 278 .getResourceConverter().getGUIReference("level")))); 279 // See earlier comments about setPreferredSize. 280 this.setPreferredSize( 281 new java.awt.Dimension( 282 this.getPreferredSize().width + 1, 283 25)); //Do not remove this 284 } else if (value instanceof MondrianGuiDef.Measure) { 285 setText(invalidFlag, ((MondrianGuiDef.Measure) value).name); 286 super.setIcon( 287 new ImageIcon( 288 myClassLoader.getResource( 289 workbench.getResourceConverter().getGUIReference( 290 "measure")))); 291 } else if (value instanceof MondrianGuiDef.Formula) { 292 setText(invalidFlag, ((MondrianGuiDef.Formula) value).getName()); 293 super.setIcon( 294 new ImageIcon( 295 myClassLoader.getResource( 296 workbench.getResourceConverter().getGUIReference( 297 "formula")))); 298 } else if (value instanceof MondrianGuiDef.MemberReaderParameter) { 299 setText( 300 invalidFlag, 301 ((MondrianGuiDef.MemberReaderParameter) value).name); 302 } else if (value instanceof MondrianGuiDef.Property) { 303 setText(invalidFlag, ((MondrianGuiDef.Property) value).name); 304 super.setIcon( 305 new ImageIcon( 306 myClassLoader.getResource( 307 workbench.getResourceConverter().getGUIReference( 308 "property")))); 309 } else if (value instanceof MondrianGuiDef.Schema) { 310 setText( 311 invalidFlag, workbench.getResourceConverter().getString( 312 "common.schema.title", 313 "Schema")); 314 super.setIcon( 315 new ImageIcon( 316 myClassLoader.getResource( 317 workbench.getResourceConverter().getGUIReference( 318 "schema")))); 319 } else if (value instanceof MondrianGuiDef.NamedSet) { 320 setText(invalidFlag, ((MondrianGuiDef.NamedSet) value).name); 321 super.setIcon( 322 new ImageIcon( 323 myClassLoader.getResource( 324 workbench.getResourceConverter().getGUIReference( 325 "namedSet")))); 326 } else if (value instanceof MondrianGuiDef.CalculatedMember) { 327 setText( 328 invalidFlag, ((MondrianGuiDef.CalculatedMember) value).name); 329 super.setIcon( 330 new ImageIcon( 331 myClassLoader.getResource( 332 workbench.getResourceConverter().getGUIReference( 333 "calculatedMember")))); 334 } else if (value instanceof MondrianGuiDef.CalculatedMemberProperty) { 335 setText( 336 invalidFlag, 337 ((MondrianGuiDef.CalculatedMemberProperty) value).name); 338 super.setIcon( 339 new ImageIcon( 340 myClassLoader.getResource( 341 workbench 342 .getResourceConverter().getGUIReference("nopic")))); 343 } else if (value instanceof MondrianGuiDef.UserDefinedFunction) { 344 setText( 345 invalidFlag, ((MondrianGuiDef.UserDefinedFunction) value).name); 346 super.setIcon( 347 new ImageIcon( 348 myClassLoader.getResource( 349 workbench.getResourceConverter().getGUIReference( 350 "userDefinedFunction")))); 351 } else if (value instanceof MondrianGuiDef.MemberFormatter) { 352 setText( 353 invalidFlag, workbench.getResourceConverter().getString( 354 "common.memberFormatter.title", 355 "Member Formatter")); 356 super.setIcon( 357 new ImageIcon( 358 myClassLoader.getResource( 359 workbench.getResourceConverter().getGUIReference( 360 "format")))); 361 } else if (value instanceof MondrianGuiDef.CellFormatter) { 362 setText( 363 invalidFlag, workbench.getResourceConverter().getString( 364 "common.cellFormatter.title", 365 "Cell Formatter")); 366 super.setIcon( 367 new ImageIcon( 368 myClassLoader.getResource( 369 workbench.getResourceConverter().getGUIReference( 370 "format")))); 371 } else if (value instanceof MondrianGuiDef.PropertyFormatter) { 372 setText( 373 invalidFlag, workbench.getResourceConverter().getString( 374 "common.propertyFormatter.title", 375 "Property Formatter")); 376 super.setIcon( 377 new ImageIcon( 378 myClassLoader.getResource( 379 workbench.getResourceConverter().getGUIReference( 380 "format")))); 381 } else if (value instanceof MondrianGuiDef.Script) { 382 setText( 383 invalidFlag, workbench.getResourceConverter().getString( 384 "common.script.title", 385 "Script")); 386 super.setIcon( 387 new ImageIcon( 388 myClassLoader.getResource( 389 workbench.getResourceConverter().getGUIReference( 390 "script")))); 391 } else if (value instanceof MondrianGuiDef.Role) { 392 setText(invalidFlag, ((MondrianGuiDef.Role) value).name); 393 super.setIcon( 394 new ImageIcon( 395 myClassLoader.getResource( 396 workbench 397 .getResourceConverter().getGUIReference("role")))); 398 } else if (value instanceof MondrianGuiDef.Parameter) { 399 setText(invalidFlag, ((MondrianGuiDef.Parameter) value).name); 400 super.setIcon( 401 new ImageIcon( 402 myClassLoader.getResource( 403 workbench.getResourceConverter().getGUIReference( 404 "parameter")))); 405 } else if (value instanceof MondrianGuiDef.SchemaGrant) { 406 setText( 407 invalidFlag, workbench.getResourceConverter().getString( 408 "common.schemaGrant.title", 409 "Schema Grant")); 410 super.setIcon( 411 new ImageIcon( 412 myClassLoader.getResource( 413 workbench.getResourceConverter().getGUIReference( 414 "schemaGrant")))); 415 } else if (value instanceof MondrianGuiDef.CubeGrant) { 416 setText( 417 invalidFlag, workbench.getResourceConverter().getString( 418 "common.cubeGrant.title", 419 "Cube Grant")); 420 super.setIcon( 421 new ImageIcon( 422 myClassLoader.getResource( 423 workbench.getResourceConverter().getGUIReference( 424 "cubeGrant")))); 425 } else if (value instanceof MondrianGuiDef.DimensionGrant) { 426 setText( 427 invalidFlag, workbench.getResourceConverter().getString( 428 "common.dimensionGrant.title", 429 "Dimension Grant")); 430 super.setIcon( 431 new ImageIcon( 432 myClassLoader.getResource( 433 workbench.getResourceConverter().getGUIReference( 434 "dimensionGrant")))); 435 } else if (value instanceof MondrianGuiDef.HierarchyGrant) { 436 setText( 437 invalidFlag, workbench.getResourceConverter().getString( 438 "common.hierarchyGrant.title", 439 "Hierarchy Grant")); 440 super.setIcon( 441 new ImageIcon( 442 myClassLoader.getResource( 443 workbench.getResourceConverter().getGUIReference( 444 "hierarchyGrant")))); 445 } else if (value instanceof MondrianGuiDef.MemberGrant) { 446 setText( 447 invalidFlag, workbench.getResourceConverter().getString( 448 "common.memberGrant.title", 449 "Member Grant")); 450 super.setIcon( 451 new ImageIcon( 452 myClassLoader.getResource( 453 workbench.getResourceConverter().getGUIReference( 454 "memberGrant")))); 455 } else if (value instanceof MondrianGuiDef.Annotations) { 456 setText( 457 invalidFlag, workbench.getResourceConverter().getString( 458 "common.annotations.title", 459 "Annotations")); 460 super.setIcon( 461 new ImageIcon( 462 myClassLoader.getResource( 463 workbench.getResourceConverter().getGUIReference( 464 "annotations")))); 465 } else if (value instanceof MondrianGuiDef.Annotation) { 466 setText( 467 invalidFlag, ((MondrianGuiDef.Annotation)value).name); 468 super.setIcon( 469 new ImageIcon( 470 myClassLoader.getResource( 471 workbench.getResourceConverter().getGUIReference( 472 "annotation")))); 473 } else if (value instanceof MondrianGuiDef.SQL) { 474 setText(invalidFlag, ((MondrianGuiDef.SQL) value).dialect); 475 super.setIcon( 476 new ImageIcon( 477 myClassLoader.getResource( 478 workbench 479 .getResourceConverter().getGUIReference("sql")))); 480 } else if (value instanceof MondrianGuiDef.View) { 481 setText( 482 workbench.getResourceConverter().getString( 483 "common.view.title", 484 "View")); 485 } else if (value instanceof MondrianGuiDef.VirtualCube) { 486 setText(invalidFlag, ((MondrianGuiDef.VirtualCube) value).name); 487 super.setIcon( 488 new ImageIcon( 489 myClassLoader.getResource( 490 workbench.getResourceConverter().getGUIReference( 491 "virtualCube")))); 492 } else if (value instanceof MondrianGuiDef.VirtualCubeDimension) { 493 setText( 494 invalidFlag, 495 ((MondrianGuiDef.VirtualCubeDimension) value).name); 496 super.setIcon( 497 new ImageIcon( 498 myClassLoader.getResource( 499 workbench.getResourceConverter().getGUIReference( 500 "virtualCubeDimension")))); 501 } else if (value instanceof MondrianGuiDef.VirtualCubeMeasure) { 502 setText( 503 invalidFlag, ((MondrianGuiDef.VirtualCubeMeasure) value).name); 504 super.setIcon( 505 new ImageIcon( 506 myClassLoader.getResource( 507 workbench.getResourceConverter().getGUIReference( 508 "virtualCubeMeasure")))); 509 } else if (value instanceof MondrianGuiDef.AggName) { 510 setText( 511 invalidFlag, workbench.getResourceConverter().getString( 512 "common.aggName.title", 513 "Aggregate Name")); 514 super.setIcon( 515 new ImageIcon( 516 myClassLoader.getResource( 517 workbench.getResourceConverter().getGUIReference( 518 "aggTable")))); 519 } else if (value instanceof MondrianGuiDef.AggForeignKey) { 520 setText( 521 invalidFlag, workbench.getResourceConverter().getString( 522 "common.aggForeignKey.title", 523 "Aggregate Foreign Key")); 524 super.setIcon( 525 new ImageIcon( 526 myClassLoader.getResource( 527 workbench.getResourceConverter().getGUIReference( 528 "aggForeignKey")))); 529 } else if (value instanceof MondrianGuiDef.AggIgnoreColumn) { 530 setText( 531 invalidFlag, workbench.getResourceConverter().getString( 532 "common.aggIgnoreColumn.title", 533 "Aggregate Ignore Column")); 534 super.setIcon( 535 new ImageIcon( 536 myClassLoader.getResource( 537 workbench.getResourceConverter().getGUIReference( 538 "aggIgnoreColumn")))); 539 } else if (value instanceof MondrianGuiDef.AggLevel) { 540 setText( 541 invalidFlag, workbench.getResourceConverter().getString( 542 "common.aggLevel.title", "Aggregate Level")); 543 super.setIcon( 544 new ImageIcon( 545 myClassLoader.getResource( 546 workbench.getResourceConverter().getGUIReference( 547 "aggLevel")))); 548 } else if (value instanceof MondrianGuiDef.AggMeasure) { 549 setText( 550 invalidFlag, workbench.getResourceConverter().getString( 551 "common.aggMeasure.title", 552 "Aggregate Measure")); 553 super.setIcon( 554 new ImageIcon( 555 myClassLoader.getResource( 556 workbench.getResourceConverter().getGUIReference( 557 "aggMeasure")))); 558 } else if (value instanceof MondrianGuiDef.AggPattern) { 559 setText( 560 invalidFlag, workbench.getResourceConverter().getString( 561 "common.aggPattern.title", 562 "Aggregate Pattern")); 563 super.setIcon( 564 new ImageIcon( 565 myClassLoader.getResource( 566 workbench.getResourceConverter().getGUIReference( 567 "aggPattern")))); 568 } else if (value instanceof MondrianGuiDef.AggExclude) { 569 setText( 570 invalidFlag, workbench.getResourceConverter().getString( 571 "common.aggExclude.title", 572 "Aggregate Exclude")); 573 super.setIcon( 574 new ImageIcon( 575 myClassLoader.getResource( 576 workbench.getResourceConverter().getGUIReference( 577 "aggExclude")))); 578 } else if (value instanceof MondrianGuiDef.Closure) { 579 setText( 580 invalidFlag, workbench.getResourceConverter().getString( 581 "common.closure.title", 582 "Closure")); 583 super.setIcon( 584 new ImageIcon( 585 myClassLoader.getResource( 586 workbench.getResourceConverter().getGUIReference( 587 "closure")))); 588 } else if (value instanceof ElementDef) { 589 setText(((ElementDef) value).getName()); 590 } else { 591 super.setText(""); 592 } 593 594 return this; 595 } 596 597 // called from external methods 598 public String invalid(JTree tree, TreePath tpath, Object value) { 599 return this.invalid(tree, tpath, value, null, null, null, null); 600 } 601 602 public String invalid( 603 JTree tree, 604 TreePath tpath, 605 Object value, 606 MondrianGuiDef.Cube cube, 607 MondrianGuiDef.Dimension parentDimension, 608 MondrianGuiDef.Hierarchy parentHierarchy, 609 MondrianGuiDef.Level parentLevel) 610 { 611 return ValidationUtils.invalid( 612 new WorkbenchMessages(workbench.getResourceConverter()), 613 new WorkbenchJdbcValidator(jdbcMetaData), 614 new WorkbenchTreeModel((SchemaTreeModel) tree.getModel()), 615 new WorkbenchTreeModelPath(tpath), 616 value, 617 cube, 618 parentDimension, 619 parentHierarchy, 620 parentLevel, 621 jdbcMetaData.getRequireSchema()); 622 } 623 624 private boolean isInvalid(JTree tree, Object value, int row) { 625 // getPathForRow(row) returns null for new objects added to tree in the 626 // first run of rendering. Check for null before calling methods on 627 // Treepath returned. 628 return invalid(tree, tree.getPathForRow(row), value) != null; 629 } 630 631 public void setText(boolean invalidFlag, String myText) { 632 if (invalidFlag) { 633 myText = "<html><FONT COLOR=RED><b>x</b></FONT><FONT COLOR=" 634 + getForeground().hashCode() 635 + ">" 636 + myText 637 + "</FONT></html>"; 638 } 639 setText(myText); 640 } 641 642 /** 643 * Called from {@link SchemaExplorer#resetMetaData(JdbcMetaData)}. A call to 644 * {@link #updateUI} should be made on the owning SchemaFrame to reflect the 645 * use of the JdbcMetaData being set. 646 * 647 * @param jdbcMetaData Meta data 648 */ 649 public void setMetaData(JdbcMetaData jdbcMetaData) { 650 this.jdbcMetaData = jdbcMetaData; 651 } 652} 653 654// End SchemaTreeCellRenderer.java