001 /* 002 // This java file was automatically generated 003 // from XOM model 'aggregates' 004 // on Tue Mar 06 01:13:59 PST 2007 005 // Do not edit this file by hand. 006 */ 007 008 package mondrian.rolap.aggmatcher; 009 /** 010 * This is the XML model for defining default aggregate table recognition 011 * and level/measure mapping. 012 * Revision is $Id: //open/mondrian/src/main/mondrian/rolap/aggmatcher/DefaultRulesSchema.xml#9 $ 013 * <p>This class was generated from XOM model 'aggregates' on Tue Mar 06 01:13:59 PST 2007 014 */ 015 public class DefaultDef { 016 017 public static java.lang.Class getXMLDefClass() 018 { 019 return DefaultDef.class; 020 } 021 022 public static String[] _elements = { 023 "AggRules", 024 "Base", 025 "CaseMatcher", 026 "NameMatcher", 027 "FactCountMatch", 028 "ForeignKeyMatch", 029 "TableMatch", 030 "Mapper", 031 "Regex", 032 "RegexMapper", 033 "Ref", 034 "LevelMapRef", 035 "MeasureMapRef", 036 "IgnoreMapRef", 037 "FactCountMatchRef", 038 "ForeignKeyMatchRef", 039 "TableMatchRef", 040 "LevelMap", 041 "MeasureMap", 042 "IgnoreMap", 043 "AggRule" 044 }; 045 046 /** 047 * The set of "named" rules for matching aggregate tables. 048 * Only one rule can be applied to a given connection. In 049 * addition, one rule must be set as the default - this rule 050 * is always the choice when not selecting by name. 051 * It is very important that the AggRules validate method is called 052 * prior to using any of the object. 053 */ 054 public static class AggRules extends org.eigenbase.xom.ElementDef 055 { 056 public AggRules() 057 { 058 } 059 060 public AggRules(org.eigenbase.xom.DOMWrapper _def) 061 throws org.eigenbase.xom.XOMException 062 { 063 try { 064 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 065 _parser = _parser; 066 org.eigenbase.xom.NodeDef[] _tempArray = null; 067 _tempArray = _tempArray; 068 tag = (String)_parser.getAttribute("tag", "String", null, null, true); 069 _tempArray = _parser.getArray(TableMatch.class, 0, 0); 070 tableMatches = new TableMatch[_tempArray.length]; 071 for(int _i=0; _i<tableMatches.length; _i++) 072 tableMatches[_i] = (TableMatch)_tempArray[_i]; 073 _tempArray = _parser.getArray(FactCountMatch.class, 0, 0); 074 factCountMatches = new FactCountMatch[_tempArray.length]; 075 for(int _i=0; _i<factCountMatches.length; _i++) 076 factCountMatches[_i] = (FactCountMatch)_tempArray[_i]; 077 _tempArray = _parser.getArray(ForeignKeyMatch.class, 0, 0); 078 foreignKeyMatches = new ForeignKeyMatch[_tempArray.length]; 079 for(int _i=0; _i<foreignKeyMatches.length; _i++) 080 foreignKeyMatches[_i] = (ForeignKeyMatch)_tempArray[_i]; 081 _tempArray = _parser.getArray(LevelMap.class, 0, 0); 082 levelMaps = new LevelMap[_tempArray.length]; 083 for(int _i=0; _i<levelMaps.length; _i++) 084 levelMaps[_i] = (LevelMap)_tempArray[_i]; 085 _tempArray = _parser.getArray(MeasureMap.class, 0, 0); 086 measureMaps = new MeasureMap[_tempArray.length]; 087 for(int _i=0; _i<measureMaps.length; _i++) 088 measureMaps[_i] = (MeasureMap)_tempArray[_i]; 089 _tempArray = _parser.getArray(IgnoreMap.class, 0, 0); 090 ignoreMaps = new IgnoreMap[_tempArray.length]; 091 for(int _i=0; _i<ignoreMaps.length; _i++) 092 ignoreMaps[_i] = (IgnoreMap)_tempArray[_i]; 093 _tempArray = _parser.getArray(AggRule.class, 1, 0); 094 aggRules = new AggRule[_tempArray.length]; 095 for(int _i=0; _i<aggRules.length; _i++) 096 aggRules[_i] = (AggRule)_tempArray[_i]; 097 } catch(org.eigenbase.xom.XOMException _ex) { 098 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 099 } 100 } 101 102 public String tag; // required attribute 103 104 /** 105 * All shared TableMatches. 106 */ 107 public TableMatch[] tableMatches; //optional array 108 /** 109 * All shared FactCountMatches. 110 */ 111 public FactCountMatch[] factCountMatches; //optional array 112 /** 113 * All shared ForeignKeyMatches. 114 */ 115 public ForeignKeyMatch[] foreignKeyMatches; //optional array 116 /** 117 * All shared LevelMap. 118 */ 119 public LevelMap[] levelMaps; //optional array 120 /** 121 * All shared MeasureMap. 122 */ 123 public MeasureMap[] measureMaps; //optional array 124 /** 125 * All shared IgnoreMap. 126 */ 127 public IgnoreMap[] ignoreMaps; //optional array 128 /** 129 * All AggRules (at least one). 130 * Also, one of them must be marked with default=true. 131 */ 132 public AggRule[] aggRules; //min 1 133 134 public String getName() 135 { 136 return "AggRules"; 137 } 138 139 public void display(java.io.PrintWriter _out, int _indent) 140 { 141 _out.println(getName()); 142 displayAttribute(_out, "tag", tag, _indent+1); 143 displayElementArray(_out, "tableMatches", tableMatches, _indent+1); 144 displayElementArray(_out, "factCountMatches", factCountMatches, _indent+1); 145 displayElementArray(_out, "foreignKeyMatches", foreignKeyMatches, _indent+1); 146 displayElementArray(_out, "levelMaps", levelMaps, _indent+1); 147 displayElementArray(_out, "measureMaps", measureMaps, _indent+1); 148 displayElementArray(_out, "ignoreMaps", ignoreMaps, _indent+1); 149 displayElementArray(_out, "aggRules", aggRules, _indent+1); 150 } 151 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 152 { 153 _out.beginTag("AggRules", new org.eigenbase.xom.XMLAttrVector() 154 .add("tag", tag) 155 ); 156 displayXMLElementArray(_out, tableMatches); 157 displayXMLElementArray(_out, factCountMatches); 158 displayXMLElementArray(_out, foreignKeyMatches); 159 displayXMLElementArray(_out, levelMaps); 160 displayXMLElementArray(_out, measureMaps); 161 displayXMLElementArray(_out, ignoreMaps); 162 displayXMLElementArray(_out, aggRules); 163 _out.endTag("AggRules"); 164 } 165 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 166 { 167 boolean _diff = true; 168 AggRules _cother = (AggRules)_other; 169 _diff = _diff && displayAttributeDiff("tag", tag, _cother.tag, _out, _indent+1); 170 _diff = _diff && displayElementArrayDiff("tableMatches", tableMatches, _cother.tableMatches, _out, _indent+1); 171 _diff = _diff && displayElementArrayDiff("factCountMatches", factCountMatches, _cother.factCountMatches, _out, _indent+1); 172 _diff = _diff && displayElementArrayDiff("foreignKeyMatches", foreignKeyMatches, _cother.foreignKeyMatches, _out, _indent+1); 173 _diff = _diff && displayElementArrayDiff("levelMaps", levelMaps, _cother.levelMaps, _out, _indent+1); 174 _diff = _diff && displayElementArrayDiff("measureMaps", measureMaps, _cother.measureMaps, _out, _indent+1); 175 _diff = _diff && displayElementArrayDiff("ignoreMaps", ignoreMaps, _cother.ignoreMaps, _out, _indent+1); 176 _diff = _diff && displayElementArrayDiff("aggRules", aggRules, _cother.aggRules, _out, _indent+1); 177 return _diff; 178 } 179 // BEGIN pass-through code block --- 180 private static final org.apache.log4j.Logger LOGGER = 181 org.apache.log4j.Logger.getLogger(DefaultDef.class); 182 183 protected static org.apache.log4j.Logger getLogger() { 184 return LOGGER; 185 } 186 187 public String getTag() { 188 return tag; 189 } 190 191 public AggRule getAggRule(String tag) { 192 for (int i = 0; i < aggRules.length; i++) { 193 AggRule aggRule = aggRules[i]; 194 if (aggRule.isEnabled() && aggRule.getTag().equals(tag)) { 195 return aggRule; 196 } 197 } 198 return null; 199 } 200 201 public void validate(final mondrian.recorder.MessageRecorder msgRecorder) { 202 msgRecorder.pushContextName(getName()); 203 try { 204 validate(factCountMatches, msgRecorder); 205 validate(tableMatches, msgRecorder); 206 validate(levelMaps, msgRecorder); 207 validate(measureMaps, msgRecorder); 208 validate(ignoreMaps, msgRecorder); 209 validate(aggRules, msgRecorder); 210 } finally { 211 msgRecorder.popContextName(); 212 } 213 } 214 private void validate(final Base[] bases, 215 final mondrian.recorder.MessageRecorder msgRecorder) { 216 for (int i = 0; i < bases.length; i++) { 217 Base base = bases[i]; 218 if (base.isEnabled()) { 219 base.validate(this, msgRecorder); 220 } 221 } 222 } 223 224 public boolean hasIgnoreMap(String id) { 225 return (lookupIgnoreMap(id) != null); 226 } 227 public IgnoreMap lookupIgnoreMap(String id) { 228 return (IgnoreMap) lookupBase(id, ignoreMaps); 229 } 230 231 public boolean hasFactCountMatch(String id) { 232 return (lookupFactCountMatch(id) != null); 233 } 234 public FactCountMatch lookupFactCountMatch(String id) { 235 return (FactCountMatch) lookupBase(id, factCountMatches); 236 } 237 238 public boolean hasForeignKeyMatch(String id) { 239 return (lookupForeignKeyMatch(id) != null); 240 } 241 public ForeignKeyMatch lookupForeignKeyMatch(String id) { 242 return (ForeignKeyMatch) lookupBase(id, foreignKeyMatches); 243 } 244 245 public boolean hasTableMatch(String id) { 246 return (lookupTableMatch(id) != null); 247 } 248 public TableMatch lookupTableMatch(String id) { 249 return (TableMatch) lookupBase(id, tableMatches); 250 } 251 252 public boolean hasLevelMap(String id) { 253 return (lookupLevelMap(id) != null); 254 } 255 public LevelMap lookupLevelMap(String id) { 256 return (LevelMap) lookupBase(id, levelMaps); 257 } 258 259 public boolean hasMeasureMap(String id) { 260 return (lookupMeasureMap(id) != null); 261 } 262 public MeasureMap lookupMeasureMap(String id) { 263 return (MeasureMap) lookupBase(id, measureMaps); 264 } 265 266 public boolean hasAggRule(String id) { 267 return (lookupAggRule(id) != null); 268 } 269 public AggRule lookupAggRule(String id) { 270 return (AggRule) lookupBase(id, aggRules); 271 } 272 273 private Base lookupBase(String tag, Base[] bases) { 274 for (int i = 0; i < bases.length; i++) { 275 Base base = bases[i]; 276 if (base.isEnabled() && base.getTag().equals(tag)) { 277 return base; 278 } 279 } 280 return null; 281 } 282 283 public IgnoreMap[] getIgnoreMaps() { 284 return ignoreMaps; 285 } 286 public FactCountMatch[] getFactCountMatches() { 287 return factCountMatches; 288 } 289 public ForeignKeyMatch[] getForeignKeyMatches() { 290 return foreignKeyMatches; 291 } 292 public TableMatch[] getTableMatches() { 293 return tableMatches; 294 } 295 public LevelMap[] getLevelMaps() { 296 return levelMaps; 297 } 298 public MeasureMap[] getMeasureMaps() { 299 return measureMaps; 300 } 301 public AggRule[] getAggRules() { 302 return aggRules; 303 } 304 // END pass-through code block --- 305 } 306 307 /** 308 * Base is the base class for all of the elements. 309 * All elements can be enabled or not, have a tag, and 310 * can be validated. 311 */ 312 public static abstract class Base extends org.eigenbase.xom.ElementDef 313 { 314 public Base() 315 { 316 } 317 318 public Base(org.eigenbase.xom.DOMWrapper _def) 319 throws org.eigenbase.xom.XOMException 320 { 321 try { 322 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 323 _parser = _parser; 324 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 325 } catch(org.eigenbase.xom.XOMException _ex) { 326 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 327 } 328 } 329 330 public Boolean enabled; // attribute default: true 331 332 333 public String getName() 334 { 335 return "Base"; 336 } 337 338 public void display(java.io.PrintWriter _out, int _indent) 339 { 340 _out.println(getName()); 341 displayAttribute(_out, "enabled", enabled, _indent+1); 342 } 343 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 344 { 345 _out.beginTag("(%Base;)", new org.eigenbase.xom.XMLAttrVector() 346 .add("enabled", enabled) 347 ); 348 _out.endTag("(%Base;)"); 349 } 350 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 351 { 352 boolean _diff = true; 353 Base _cother = (Base)_other; 354 _diff = _diff && displayAttributeDiff("enabled", enabled, _cother.enabled, _out, _indent+1); 355 return _diff; 356 } 357 // BEGIN pass-through code block --- 358 public boolean isEnabled() { 359 return enabled.booleanValue(); 360 } 361 protected abstract String getTag(); 362 public abstract void validate(final AggRules rules, 363 final mondrian.recorder.MessageRecorder msgRecorder); 364 // END pass-through code block --- 365 } 366 367 /** 368 * This is a base class for all elements that can match strings 369 * where the case of the string is important. In addition, 370 * it has an id which services as its tag. 371 */ 372 public static abstract class CaseMatcher extends Base 373 { 374 public CaseMatcher() 375 { 376 } 377 378 public CaseMatcher(org.eigenbase.xom.DOMWrapper _def) 379 throws org.eigenbase.xom.XOMException 380 { 381 try { 382 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 383 _parser = _parser; 384 id = (String)_parser.getAttribute("id", "String", null, null, true); 385 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 386 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 387 } catch(org.eigenbase.xom.XOMException _ex) { 388 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 389 } 390 } 391 392 public String id; // required attribute 393 /** Allowable values for {@link #charcase}. */ 394 public static final String[] _charcase_values = {"ignore", "exact", "upper", "lower"}; 395 public String charcase; // attribute default: ignore 396 397 398 public String getName() 399 { 400 return "CaseMatcher"; 401 } 402 403 public void display(java.io.PrintWriter _out, int _indent) 404 { 405 _out.println(getName()); 406 displayAttribute(_out, "id", id, _indent+1); 407 displayAttribute(_out, "charcase", charcase, _indent+1); 408 displayAttribute(_out, "enabled", enabled, _indent+1); 409 } 410 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 411 { 412 _out.beginTag("(%CaseMatcher;)", new org.eigenbase.xom.XMLAttrVector() 413 .add("id", id) 414 .add("charcase", charcase) 415 .add("enabled", enabled) 416 ); 417 _out.endTag("(%CaseMatcher;)"); 418 } 419 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 420 { 421 boolean _diff = true; 422 CaseMatcher _cother = (CaseMatcher)_other; 423 _diff = _diff && displayAttributeDiff("id", id, _cother.id, _out, _indent+1); 424 _diff = _diff && displayAttributeDiff("charcase", charcase, _cother.charcase, _out, _indent+1); 425 return _diff; 426 } 427 // BEGIN pass-through code block --- 428 public void validate(final AggRules rules, 429 final mondrian.recorder.MessageRecorder msgRecorder) { 430 // empty 431 } 432 protected String getTag() { 433 return getId(); 434 } 435 public String getId() { 436 return id; 437 } 438 public String getCharCase() { 439 return charcase; 440 } 441 // END pass-through code block --- 442 } 443 444 /** 445 * A NameMatcher is a CaseMatcher that prepends and appends 446 * regular expressions to a given string as part of creating 447 * the matching regular expression. Both the pre/post 448 * regular expression can be null in which case matches are 449 * applied simply against the name (modulo case considerations). 450 * The purpose of this class is to allow aggregate tables to 451 * be identified when their table names are formed by placing 452 * text before and/or after the base fact table name. 453 */ 454 public static abstract class NameMatcher extends CaseMatcher 455 { 456 public NameMatcher() 457 { 458 } 459 460 public NameMatcher(org.eigenbase.xom.DOMWrapper _def) 461 throws org.eigenbase.xom.XOMException 462 { 463 try { 464 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 465 _parser = _parser; 466 pretemplate = (String)_parser.getAttribute("pretemplate", "String", null, null, false); 467 posttemplate = (String)_parser.getAttribute("posttemplate", "String", null, null, false); 468 basename = (String)_parser.getAttribute("basename", "String", null, null, false); 469 id = (String)_parser.getAttribute("id", "String", null, null, true); 470 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 471 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 472 } catch(org.eigenbase.xom.XOMException _ex) { 473 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 474 } 475 } 476 477 public String pretemplate; // optional attribute 478 public String posttemplate; // optional attribute 479 public String basename; // optional attribute 480 481 482 public String getName() 483 { 484 return "NameMatcher"; 485 } 486 487 public void display(java.io.PrintWriter _out, int _indent) 488 { 489 _out.println(getName()); 490 displayAttribute(_out, "pretemplate", pretemplate, _indent+1); 491 displayAttribute(_out, "posttemplate", posttemplate, _indent+1); 492 displayAttribute(_out, "basename", basename, _indent+1); 493 displayAttribute(_out, "id", id, _indent+1); 494 displayAttribute(_out, "charcase", charcase, _indent+1); 495 displayAttribute(_out, "enabled", enabled, _indent+1); 496 } 497 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 498 { 499 _out.beginTag("(%NameMatcher;)", new org.eigenbase.xom.XMLAttrVector() 500 .add("pretemplate", pretemplate) 501 .add("posttemplate", posttemplate) 502 .add("basename", basename) 503 .add("id", id) 504 .add("charcase", charcase) 505 .add("enabled", enabled) 506 ); 507 _out.endTag("(%NameMatcher;)"); 508 } 509 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 510 { 511 boolean _diff = true; 512 NameMatcher _cother = (NameMatcher)_other; 513 _diff = _diff && displayAttributeDiff("pretemplate", pretemplate, _cother.pretemplate, _out, _indent+1); 514 _diff = _diff && displayAttributeDiff("posttemplate", posttemplate, _cother.posttemplate, _out, _indent+1); 515 _diff = _diff && displayAttributeDiff("basename", basename, _cother.basename, _out, _indent+1); 516 return _diff; 517 } 518 // BEGIN pass-through code block --- 519 java.util.regex.Pattern baseNamePattern = null; 520 public void validate(final AggRules rules, 521 final mondrian.recorder.MessageRecorder msgRecorder) { 522 msgRecorder.pushContextName(getName()); 523 try { 524 super.validate(rules, msgRecorder); 525 526 if (basename != null) { 527 baseNamePattern = 528 java.util.regex.Pattern.compile(basename); 529 } 530 } finally { 531 msgRecorder.popContextName(); 532 } 533 } 534 535 /** 536 * Generates a regular expression string by prepending and 537 * appending regular expression to the parameter tableName. 538 * 539 * @param name Table name 540 * @return regular expression 541 */ 542 public String getRegex(final String name) { 543 StringBuilder buf = new StringBuilder(); 544 if (pretemplate != null) { 545 buf.append(pretemplate); 546 } 547 if (name != null) { 548 String n = name; 549 if (baseNamePattern != null) { 550 java.util.regex.Matcher matcher = 551 baseNamePattern.matcher(name); 552 if (matcher.matches() && matcher.groupCount() > 0) { 553 n = matcher.group(1); 554 555 } else { 556 if (AggRules.getLogger().isDebugEnabled()) { 557 StringBuilder bf = new StringBuilder(64); 558 bf.append(getName()); 559 bf.append(".getRegex: for name \""); 560 bf.append(name); 561 bf.append("\" regex is null because basename \""); 562 bf.append(basename); 563 bf.append("\" is not matched."); 564 565 String msg = bf.toString(); 566 AggRules.getLogger().debug(msg); 567 } 568 // If the table name does not match the basename 569 // pattern, then return null for regex. 570 return null; 571 } 572 } 573 buf.append(n); 574 } 575 if (posttemplate != null) { 576 buf.append(posttemplate); 577 } 578 579 String regex = buf.toString(); 580 581 if (AggRules.getLogger().isDebugEnabled()) { 582 StringBuilder bf = new StringBuilder(64); 583 bf.append(getName()); 584 bf.append(".getRegex: for name \""); 585 bf.append(name); 586 bf.append("\" regex is \""); 587 bf.append(regex); 588 bf.append('"'); 589 590 String msg = bf.toString(); 591 AggRules.getLogger().debug(msg); 592 } 593 return regex; 594 } 595 596 protected Recognizer.Matcher getMatcher(String name) { 597 598 final String charcase = getCharCase(); 599 final String regex; 600 int flag = 0; 601 602 if (charcase.equals("ignore")) { 603 // the case of name does not matter 604 // since the Pattern will be create to ignore case 605 regex = getRegex(name); 606 607 flag = java.util.regex.Pattern.CASE_INSENSITIVE; 608 609 } else if (charcase.equals("exact")) { 610 // the case of name is not changed 611 // since we are interested in exact case matching 612 regex = getRegex(name); 613 614 } else if (charcase.equals("upper")) { 615 // convert name to upper case 616 regex = getRegex(name.toUpperCase()); 617 618 } else { 619 // lower 620 // convert name to lower case 621 regex = getRegex(name.toLowerCase()); 622 623 } 624 // If regex is null, then return a matcher that matches nothing 625 if (regex == null) { 626 return new Recognizer.Matcher() { 627 public boolean matches(String name) { 628 return false; 629 } 630 }; 631 } 632 633 final java.util.regex.Pattern pattern = 634 java.util.regex.Pattern.compile(regex, flag); 635 636 return new Recognizer.Matcher() { 637 public boolean matches(String name) { 638 boolean b = pattern.matcher(name).matches(); 639 if (AggRules.getLogger().isDebugEnabled()) { 640 debug(name); 641 } 642 return b; 643 } 644 private void debug(String name) { 645 StringBuilder bf = new StringBuilder(64); 646 bf.append(NameMatcher.this.getName()); 647 bf.append(".Matcher.matches:"); 648 bf.append(" name \""); 649 bf.append(name); 650 bf.append("\" pattern \""); 651 bf.append(pattern.pattern()); 652 bf.append("\""); 653 if ((pattern.flags() & 654 java.util.regex.Pattern.CASE_INSENSITIVE) != 0) { 655 bf.append(" case_insensitive"); 656 } 657 658 String msg = bf.toString(); 659 AggRules.getLogger().debug(msg); 660 } 661 }; 662 } 663 // END pass-through code block --- 664 } 665 666 /** 667 * This is used to identify the "fact_count" column in an aggregate 668 * table. It allows one to match using regular exprssions. 669 * The default is that the name of the fact count colum is simply 670 * the string "fact_count". 671 */ 672 public static class FactCountMatch extends NameMatcher 673 { 674 public FactCountMatch() 675 { 676 } 677 678 public FactCountMatch(org.eigenbase.xom.DOMWrapper _def) 679 throws org.eigenbase.xom.XOMException 680 { 681 try { 682 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 683 _parser = _parser; 684 factCountName = (String)_parser.getAttribute("factCountName", "String", "fact_count", null, true); 685 pretemplate = (String)_parser.getAttribute("pretemplate", "String", null, null, false); 686 posttemplate = (String)_parser.getAttribute("posttemplate", "String", null, null, false); 687 basename = (String)_parser.getAttribute("basename", "String", null, null, false); 688 id = (String)_parser.getAttribute("id", "String", null, null, true); 689 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 690 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 691 } catch(org.eigenbase.xom.XOMException _ex) { 692 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 693 } 694 } 695 696 public String factCountName; // attribute default: fact_count 697 698 699 public String getName() 700 { 701 return "FactCountMatch"; 702 } 703 704 public void display(java.io.PrintWriter _out, int _indent) 705 { 706 _out.println(getName()); 707 displayAttribute(_out, "factCountName", factCountName, _indent+1); 708 displayAttribute(_out, "pretemplate", pretemplate, _indent+1); 709 displayAttribute(_out, "posttemplate", posttemplate, _indent+1); 710 displayAttribute(_out, "basename", basename, _indent+1); 711 displayAttribute(_out, "id", id, _indent+1); 712 displayAttribute(_out, "charcase", charcase, _indent+1); 713 displayAttribute(_out, "enabled", enabled, _indent+1); 714 } 715 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 716 { 717 _out.beginTag("FactCountMatch", new org.eigenbase.xom.XMLAttrVector() 718 .add("factCountName", factCountName) 719 .add("pretemplate", pretemplate) 720 .add("posttemplate", posttemplate) 721 .add("basename", basename) 722 .add("id", id) 723 .add("charcase", charcase) 724 .add("enabled", enabled) 725 ); 726 _out.endTag("FactCountMatch"); 727 } 728 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 729 { 730 boolean _diff = true; 731 FactCountMatch _cother = (FactCountMatch)_other; 732 _diff = _diff && displayAttributeDiff("factCountName", factCountName, _cother.factCountName, _out, _indent+1); 733 return _diff; 734 } 735 // BEGIN pass-through code block --- 736 public void validate(final AggRules rules, 737 final mondrian.recorder.MessageRecorder msgRecorder) { 738 msgRecorder.pushContextName(getName()); 739 try { 740 super.validate(rules, msgRecorder); 741 } finally { 742 msgRecorder.popContextName(); 743 } 744 } 745 public Recognizer.Matcher getMatcher() { 746 return super.getMatcher(factCountName); 747 } 748 // END pass-through code block --- 749 } 750 751 /** 752 * This is used to identify foreign key columns in a candidate 753 * aggregate table given the name of a foreign key column of the 754 * base fact table. This allows such foreign keys to be identified 755 * by using a regular exprsssion. The default is to simply 756 * match the base fact table's foreign key column name. 757 */ 758 public static class ForeignKeyMatch extends NameMatcher 759 { 760 public ForeignKeyMatch() 761 { 762 } 763 764 public ForeignKeyMatch(org.eigenbase.xom.DOMWrapper _def) 765 throws org.eigenbase.xom.XOMException 766 { 767 try { 768 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 769 _parser = _parser; 770 pretemplate = (String)_parser.getAttribute("pretemplate", "String", null, null, false); 771 posttemplate = (String)_parser.getAttribute("posttemplate", "String", null, null, false); 772 basename = (String)_parser.getAttribute("basename", "String", null, null, false); 773 id = (String)_parser.getAttribute("id", "String", null, null, true); 774 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 775 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 776 } catch(org.eigenbase.xom.XOMException _ex) { 777 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 778 } 779 } 780 781 782 783 public String getName() 784 { 785 return "ForeignKeyMatch"; 786 } 787 788 public void display(java.io.PrintWriter _out, int _indent) 789 { 790 _out.println(getName()); 791 displayAttribute(_out, "pretemplate", pretemplate, _indent+1); 792 displayAttribute(_out, "posttemplate", posttemplate, _indent+1); 793 displayAttribute(_out, "basename", basename, _indent+1); 794 displayAttribute(_out, "id", id, _indent+1); 795 displayAttribute(_out, "charcase", charcase, _indent+1); 796 displayAttribute(_out, "enabled", enabled, _indent+1); 797 } 798 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 799 { 800 _out.beginTag("ForeignKeyMatch", new org.eigenbase.xom.XMLAttrVector() 801 .add("pretemplate", pretemplate) 802 .add("posttemplate", posttemplate) 803 .add("basename", basename) 804 .add("id", id) 805 .add("charcase", charcase) 806 .add("enabled", enabled) 807 ); 808 _out.endTag("ForeignKeyMatch"); 809 } 810 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 811 { 812 boolean _diff = true; 813 ForeignKeyMatch _cother = (ForeignKeyMatch)_other; 814 return _diff; 815 } 816 // BEGIN pass-through code block --- 817 public void validate(final AggRules rules, 818 final mondrian.recorder.MessageRecorder msgRecorder) { 819 msgRecorder.pushContextName(getName()); 820 try { 821 super.validate(rules, msgRecorder); 822 } finally { 823 msgRecorder.popContextName(); 824 } 825 } 826 public Recognizer.Matcher getMatcher(final String foreignKeyName) { 827 return super.getMatcher(foreignKeyName); 828 } 829 // END pass-through code block --- 830 } 831 832 /** 833 * This is used to identify which tables in the database might 834 * be aggregate table of a given fact table. 835 * It is expected that aggregate table names will include the 836 * base fact table name with additional text before and/or 837 * after. 838 * It is not allow for both the prepending and appending 839 * regular expression text to be null (if it were, then only 840 * aggregate tables who names were the same as (modulo case) 841 * would match - which is surely not allowed). 842 */ 843 public static class TableMatch extends NameMatcher 844 { 845 public TableMatch() 846 { 847 } 848 849 public TableMatch(org.eigenbase.xom.DOMWrapper _def) 850 throws org.eigenbase.xom.XOMException 851 { 852 try { 853 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 854 _parser = _parser; 855 pretemplate = (String)_parser.getAttribute("pretemplate", "String", null, null, false); 856 posttemplate = (String)_parser.getAttribute("posttemplate", "String", null, null, false); 857 basename = (String)_parser.getAttribute("basename", "String", null, null, false); 858 id = (String)_parser.getAttribute("id", "String", null, null, true); 859 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 860 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 861 } catch(org.eigenbase.xom.XOMException _ex) { 862 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 863 } 864 } 865 866 867 868 public String getName() 869 { 870 return "TableMatch"; 871 } 872 873 public void display(java.io.PrintWriter _out, int _indent) 874 { 875 _out.println(getName()); 876 displayAttribute(_out, "pretemplate", pretemplate, _indent+1); 877 displayAttribute(_out, "posttemplate", posttemplate, _indent+1); 878 displayAttribute(_out, "basename", basename, _indent+1); 879 displayAttribute(_out, "id", id, _indent+1); 880 displayAttribute(_out, "charcase", charcase, _indent+1); 881 displayAttribute(_out, "enabled", enabled, _indent+1); 882 } 883 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 884 { 885 _out.beginTag("TableMatch", new org.eigenbase.xom.XMLAttrVector() 886 .add("pretemplate", pretemplate) 887 .add("posttemplate", posttemplate) 888 .add("basename", basename) 889 .add("id", id) 890 .add("charcase", charcase) 891 .add("enabled", enabled) 892 ); 893 _out.endTag("TableMatch"); 894 } 895 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 896 { 897 boolean _diff = true; 898 TableMatch _cother = (TableMatch)_other; 899 return _diff; 900 } 901 // BEGIN pass-through code block --- 902 public void validate(final AggRules rules, 903 final mondrian.recorder.MessageRecorder msgRecorder) { 904 msgRecorder.pushContextName(getName()); 905 try { 906 if ((pretemplate == null) && (posttemplate == null)) { 907 String msg = "Must have at least one template non-null"; 908 msgRecorder.reportError(msg); 909 } 910 super.validate(rules, msgRecorder); 911 } finally { 912 msgRecorder.popContextName(); 913 } 914 } 915 public Recognizer.Matcher getMatcher(final String name) { 916 return super.getMatcher(name); 917 } 918 // END pass-through code block --- 919 } 920 921 /** 922 * This allows one to create an element that matches against a 923 * single template, where the template is an attribute. 924 * While much loved, this is currently not used. 925 */ 926 public static abstract class Mapper extends CaseMatcher 927 { 928 public Mapper() 929 { 930 } 931 932 public Mapper(org.eigenbase.xom.DOMWrapper _def) 933 throws org.eigenbase.xom.XOMException 934 { 935 try { 936 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 937 _parser = _parser; 938 template = (String)_parser.getAttribute("template", "String", null, null, true); 939 space = (String)_parser.getAttribute("space", "String", "_", null, false); 940 dot = (String)_parser.getAttribute("dot", "String", "_", null, false); 941 id = (String)_parser.getAttribute("id", "String", null, null, true); 942 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 943 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 944 } catch(org.eigenbase.xom.XOMException _ex) { 945 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 946 } 947 } 948 949 public String template; // required attribute 950 public String space; // attribute default: _ 951 public String dot; // attribute default: _ 952 953 954 public String getName() 955 { 956 return "Mapper"; 957 } 958 959 public void display(java.io.PrintWriter _out, int _indent) 960 { 961 _out.println(getName()); 962 displayAttribute(_out, "template", template, _indent+1); 963 displayAttribute(_out, "space", space, _indent+1); 964 displayAttribute(_out, "dot", dot, _indent+1); 965 displayAttribute(_out, "id", id, _indent+1); 966 displayAttribute(_out, "charcase", charcase, _indent+1); 967 displayAttribute(_out, "enabled", enabled, _indent+1); 968 } 969 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 970 { 971 _out.beginTag("(%Mapper;)", new org.eigenbase.xom.XMLAttrVector() 972 .add("template", template) 973 .add("space", space) 974 .add("dot", dot) 975 .add("id", id) 976 .add("charcase", charcase) 977 .add("enabled", enabled) 978 ); 979 _out.endTag("(%Mapper;)"); 980 } 981 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 982 { 983 boolean _diff = true; 984 Mapper _cother = (Mapper)_other; 985 _diff = _diff && displayAttributeDiff("template", template, _cother.template, _out, _indent+1); 986 _diff = _diff && displayAttributeDiff("space", space, _cother.space, _out, _indent+1); 987 _diff = _diff && displayAttributeDiff("dot", dot, _cother.dot, _out, _indent+1); 988 return _diff; 989 } 990 // BEGIN pass-through code block --- 991 public String getTemplate() { 992 return template; 993 } 994 public String getSpace() { 995 return space; 996 } 997 public String getDot() { 998 return dot; 999 } 1000 protected static final int BAD_ID = -1; 1001 1002 protected String[] templateParts; 1003 protected int[] templateNamePos; 1004 1005 /** 1006 * It is hoped that no one will need to match more than 50 names 1007 * in a template. Currently, this implementation, requires only 3. 1008 */ 1009 private static final int MAX_SIZE = 50; 1010 1011 public void validate(final AggRules rules, 1012 final mondrian.recorder.MessageRecorder msgRecorder) { 1013 msgRecorder.pushContextName(getName()); 1014 try { 1015 super.validate(rules, msgRecorder); 1016 1017 String[] ss = new String[MAX_SIZE+1]; 1018 int[] poss = new int[MAX_SIZE]; 1019 1020 String template = getTemplate(); 1021 int count = 0; 1022 1023 int end = 0; 1024 int previousEnd = 0; 1025 int start = template.indexOf("${", end); 1026 while (count < MAX_SIZE) { 1027 if (start == -1) { 1028 if (count == 0) { 1029 // there are no ${} in template which 1030 // is an error 1031 String msg = "Bad template \"" + 1032 template + 1033 "\", no ${} entries"; 1034 msgRecorder.reportError(msg); 1035 return; 1036 } 1037 // its OK, there are "count" ${} 1038 templateNamePos = new int[count]; 1039 System.arraycopy(poss, 0, templateNamePos, 0, count); 1040 1041 ss[count++] = 1042 template.substring(end, template.length()); 1043 templateParts = new String[count]; 1044 System.arraycopy(ss, 0, templateParts, 0, count); 1045 1046 return; 1047 } 1048 1049 previousEnd = end; 1050 end = template.indexOf('}', start); 1051 if (end == -1) { 1052 // there was a "${" but not '}' in template 1053 String msg = "Bad template \"" + 1054 template + 1055 "\", it had a \"${\", but no '}'"; 1056 msgRecorder.reportError(msg); 1057 return; 1058 } 1059 1060 String name = template.substring(start+2, end); 1061 int pos = convertNameToID(name, msgRecorder); 1062 if (pos == BAD_ID) { 1063 return; 1064 } 1065 1066 poss[count] = pos; 1067 ss[count] = template.substring(previousEnd, start); 1068 1069 start = template.indexOf("${", end); 1070 end++; 1071 1072 count++; 1073 } 1074 1075 } finally { 1076 msgRecorder.popContextName(); 1077 } 1078 } 1079 1080 1081 protected abstract String[] getTemplateNames(); 1082 1083 private int convertNameToID(final String name, 1084 final mondrian.recorder.MessageRecorder msgRecorder) { 1085 1086 if (name == null) { 1087 String msg = "Template name is null"; 1088 msgRecorder.reportError(msg); 1089 return BAD_ID; 1090 } 1091 1092 String[] names = getTemplateNames(); 1093 for (int i = 0; i < names.length; i++) { 1094 if (names[i].equals(name)) { 1095 return i; 1096 } 1097 } 1098 1099 String msg = "Bad template name \"" + 1100 name + 1101 "\""; 1102 msgRecorder.reportError(msg); 1103 return BAD_ID; 1104 } 1105 1106 public String getRegex(final String[] names) { 1107 final String space = getSpace(); 1108 final String dot = getDot(); 1109 1110 final StringBuilder buf = new StringBuilder(); 1111 1112 // 1113 // Remember that: 1114 // templateParts.length == templateNamePos.length+1 1115 // 1116 buf.append(templateParts[0]); 1117 for (int i = 0; i < templateNamePos.length; i++) { 1118 String n = names[templateNamePos[i]]; 1119 1120 if (space != null) { 1121 n = n.replaceAll(" ", space); 1122 } 1123 if (dot != null) { 1124 n = n.replaceAll("\\.", dot); 1125 } 1126 1127 buf.append(n); 1128 buf.append(templateParts[i+1]); 1129 } 1130 1131 String regex = buf.toString(); 1132 1133 if (AggRules.getLogger().isDebugEnabled()) { 1134 StringBuilder bf = new StringBuilder(64); 1135 bf.append(getName()); 1136 bf.append(".getRegex:"); 1137 bf.append(" for names "); 1138 for (int i = 0; i < names.length; i++) { 1139 bf.append('"'); 1140 bf.append(names[i]); 1141 bf.append('"'); 1142 if (i+1 < names.length) { 1143 bf.append(", "); 1144 } 1145 } 1146 bf.append(" regex is \""); 1147 bf.append(regex); 1148 bf.append('"'); 1149 1150 String msg = bf.toString(); 1151 AggRules.getLogger().debug(msg); 1152 } 1153 return regex; 1154 } 1155 1156 protected Recognizer.Matcher getMatcher(final String[] names) { 1157 1158 final String charcase = getCharCase(); 1159 final String regex; 1160 int flag = 0; 1161 1162 if (charcase.equals("ignore")) { 1163 // the case of name does not matter 1164 // since the Pattern will be create to ignore case 1165 regex = getRegex(names); 1166 1167 flag = java.util.regex.Pattern.CASE_INSENSITIVE; 1168 1169 } else if (charcase.equals("exact")) { 1170 // the case of name is not changed 1171 // since we are interested in exact case matching 1172 regex = getRegex(names); 1173 1174 } else if (charcase.equals("upper")) { 1175 // convert name to upper case 1176 String[] ucNames = new String[names.length]; 1177 for (int i = 0; i < names.length; i++) { 1178 ucNames[i] = names[i].toUpperCase(); 1179 } 1180 1181 regex = getRegex(ucNames); 1182 1183 } else { 1184 // lower 1185 // convert name to lower case 1186 String[] lcNames = new String[names.length]; 1187 for (int i = 0; i < names.length; i++) { 1188 lcNames[i] = names[i].toLowerCase(); 1189 } 1190 1191 regex = getRegex(lcNames); 1192 1193 } 1194 final java.util.regex.Pattern pattern = 1195 java.util.regex.Pattern.compile(regex, flag); 1196 1197 return new Recognizer.Matcher() { 1198 public boolean matches(String name) { 1199 boolean b = pattern.matcher(name).matches(); 1200 if (AggRules.getLogger().isDebugEnabled()) { 1201 debug(name); 1202 } 1203 return b; 1204 } 1205 private void debug(String name) { 1206 StringBuilder bf = new StringBuilder(64); 1207 bf.append(Mapper.this.getName()); 1208 bf.append(".Matcher.matches:"); 1209 bf.append(" name \""); 1210 bf.append(name); 1211 bf.append("\" pattern \""); 1212 bf.append(pattern.pattern()); 1213 bf.append("\""); 1214 if ((pattern.flags() & 1215 java.util.regex.Pattern.CASE_INSENSITIVE) != 0) { 1216 bf.append(" case_insensitive"); 1217 } 1218 1219 String msg = bf.toString(); 1220 AggRules.getLogger().debug(msg); 1221 } 1222 }; 1223 1224 } 1225 // END pass-through code block --- 1226 } 1227 1228 /** 1229 * This element is used in a vector of child elements when 1230 * one wishes to have one or more regular expressions associated 1231 * with matching a given string. The parent element must 1232 * initialize Regex object by calling its validate method 1233 * passing in an array of template names. 1234 * The cdata content is a regular expression with embedded 1235 * template names. Each name must be surrounded by "${" and "}". 1236 * Each time this is used for a new set of names, the names 1237 * replace the template names in the regular expression. 1238 * For example, if the charcase="lower", the attribute 1239 * dot="-" (the default dot value is "_"), the template names are: 1240 * "city", "state", and "country" 1241 * and the cdata is: 1242 * .*_${country}_.*_${city} 1243 * Then when the names: 1244 * "San Francisco", "California", and "U.S.A" 1245 * are passed in, the regular expression becomes: 1246 * .*_u-s-a_.*_san_francisco 1247 * Note that a given template name can only appear ONCE in the 1248 * template content, the cdata content. As an example, the 1249 * following cdata template is not supported: 1250 * .*_${country}_.*_${city}_${country} 1251 */ 1252 public static class Regex extends CaseMatcher 1253 { 1254 public Regex() 1255 { 1256 } 1257 1258 public Regex(org.eigenbase.xom.DOMWrapper _def) 1259 throws org.eigenbase.xom.XOMException 1260 { 1261 try { 1262 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1263 _parser = _parser; 1264 space = (String)_parser.getAttribute("space", "String", "_", null, false); 1265 dot = (String)_parser.getAttribute("dot", "String", "_", null, false); 1266 id = (String)_parser.getAttribute("id", "String", null, null, true); 1267 charcase = (String)_parser.getAttribute("charcase", "String", "ignore", _charcase_values, false); 1268 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1269 cdata = _parser.getText(); 1270 } catch(org.eigenbase.xom.XOMException _ex) { 1271 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1272 } 1273 } 1274 1275 public String space; // attribute default: _ 1276 public String dot; // attribute default: _ 1277 1278 public String cdata; // All text goes here 1279 public String getName() 1280 { 1281 return "Regex"; 1282 } 1283 1284 public void display(java.io.PrintWriter _out, int _indent) 1285 { 1286 _out.println(getName()); 1287 displayAttribute(_out, "space", space, _indent+1); 1288 displayAttribute(_out, "dot", dot, _indent+1); 1289 displayAttribute(_out, "id", id, _indent+1); 1290 displayAttribute(_out, "charcase", charcase, _indent+1); 1291 displayAttribute(_out, "enabled", enabled, _indent+1); 1292 displayString(_out, "cdata", cdata, _indent+1); 1293 } 1294 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1295 { 1296 _out.beginTag("Regex", new org.eigenbase.xom.XMLAttrVector() 1297 .add("space", space) 1298 .add("dot", dot) 1299 .add("id", id) 1300 .add("charcase", charcase) 1301 .add("enabled", enabled) 1302 ); 1303 _out.cdata(cdata); 1304 _out.endTag("Regex"); 1305 } 1306 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1307 { 1308 boolean _diff = true; 1309 Regex _cother = (Regex)_other; 1310 _diff = _diff && displayAttributeDiff("space", space, _cother.space, _out, _indent+1); 1311 _diff = _diff && displayAttributeDiff("dot", dot, _cother.dot, _out, _indent+1); 1312 _diff = _diff && displayStringDiff("cdata", cdata, _cother.cdata, _out, _indent+1); 1313 return _diff; 1314 } 1315 // BEGIN pass-through code block --- 1316 public String getSpace() { 1317 return space; 1318 } 1319 public String getDot() { 1320 return dot; 1321 } 1322 public String getTemplate() { 1323 return cdata; 1324 } 1325 1326 protected static final int BAD_ID = -1; 1327 1328 protected String[] templateParts; 1329 1330 /** 1331 * This is a one-to-one mapping, each template name can appear 1332 * at most once. 1333 */ 1334 protected int[] templateNamePos; 1335 1336 /** 1337 * It is hoped that no one will need to match more than 50 names 1338 * in a template. Currently, this implementation, requires only 3. 1339 */ 1340 private static final int MAX_SIZE = 50; 1341 1342 public void validate(final AggRules rules, 1343 final String[] templateNames, 1344 final mondrian.recorder.MessageRecorder msgRecorder) { 1345 msgRecorder.pushContextName(getName()); 1346 try { 1347 super.validate(rules, msgRecorder); 1348 1349 String[] ss = new String[MAX_SIZE+1]; 1350 int[] poss = new int[MAX_SIZE]; 1351 1352 String template = getTemplate(); 1353 int count = 0; 1354 1355 int end = 0; 1356 int previousEnd = 0; 1357 int start = template.indexOf("${", end); 1358 // if no templateNames, then there better not be 1359 // any ${}s 1360 if (templateNames.length == 0) { 1361 if (start == -1) { 1362 // everything is ok 1363 templateParts = new String[1]; 1364 templateParts[0] = template; 1365 templateNamePos = new int[0]; 1366 } else { 1367 String msg = "Bad template \"" + 1368 template + 1369 "\", no ${} entries but there are "+ 1370 "template names" ; 1371 msgRecorder.reportError(msg); 1372 } 1373 return; 1374 } 1375 while (count < MAX_SIZE) { 1376 if (start == -1) { 1377 if (count == 0) { 1378 // there are no ${} in template which 1379 // is an error 1380 String msg = "Bad template \"" + 1381 template + 1382 "\", no ${} entries"; 1383 msgRecorder.reportError(msg); 1384 return; 1385 } 1386 // its OK, there are "count" ${} 1387 templateNamePos = new int[count]; 1388 System.arraycopy(poss, 0, templateNamePos, 0, count); 1389 1390 ss[count++] = 1391 template.substring(end, template.length()); 1392 templateParts = new String[count]; 1393 System.arraycopy(ss, 0, templateParts, 0, count); 1394 1395 return; 1396 } 1397 1398 previousEnd = end; 1399 end = template.indexOf('}', start); 1400 if (end == -1) { 1401 // there was a "${" but not '}' in template 1402 String msg = "Bad template \"" + 1403 template + 1404 "\", it had a \"${\", but no '}'"; 1405 msgRecorder.reportError(msg); 1406 return; 1407 } 1408 1409 String name = template.substring(start+2, end); 1410 int pos = convertNameToID(name, 1411 templateNames, 1412 msgRecorder); 1413 if (pos == BAD_ID) { 1414 return; 1415 } 1416 1417 poss[count] = pos; 1418 ss[count] = template.substring(previousEnd, start); 1419 1420 start = template.indexOf("${", end); 1421 end++; 1422 1423 count++; 1424 } 1425 1426 } finally { 1427 msgRecorder.popContextName(); 1428 } 1429 } 1430 private int convertNameToID(final String name, 1431 final String[] templateNames, 1432 final mondrian.recorder.MessageRecorder msgRecorder) { 1433 1434 if (name == null) { 1435 String msg = "Template name is null"; 1436 msgRecorder.reportError(msg); 1437 return BAD_ID; 1438 } 1439 1440 for (int i = 0; i < templateNames.length; i++) { 1441 if (templateNames[i].equals(name)) { 1442 return i; 1443 } 1444 } 1445 1446 String msg = "Bad template name \"" + 1447 name + 1448 "\""; 1449 msgRecorder.reportError(msg); 1450 return BAD_ID; 1451 } 1452 public String getRegex(final String[] names) { 1453 final String space = getSpace(); 1454 final String dot = getDot(); 1455 1456 final StringBuilder buf = new StringBuilder(); 1457 1458 // 1459 // Remember that: 1460 // templateParts.length == templateNamePos.length+1 1461 // 1462 buf.append(templateParts[0]); 1463 for (int i = 0; i < templateNamePos.length; i++) { 1464 String n = names[templateNamePos[i]]; 1465 if (n == null) { 1466 // its ok for a name to be null, it just 1467 // eliminates the current regex from consideration 1468 return null; 1469 } 1470 1471 if (space != null) { 1472 n = n.replaceAll(" ", space); 1473 } 1474 if (dot != null) { 1475 n = n.replaceAll("\\.", dot); 1476 } 1477 1478 buf.append(n); 1479 buf.append(templateParts[i+1]); 1480 } 1481 1482 String regex = buf.toString(); 1483 1484 if (AggRules.getLogger().isDebugEnabled()) { 1485 StringBuilder bf = new StringBuilder(64); 1486 bf.append(getName()); 1487 bf.append(".getRegex:"); 1488 bf.append(" for names "); 1489 for (int i = 0; i < names.length; i++) { 1490 bf.append('"'); 1491 bf.append(names[i]); 1492 bf.append('"'); 1493 if (i+1 < names.length) { 1494 bf.append(", "); 1495 } 1496 } 1497 bf.append(" regex is \""); 1498 bf.append(regex); 1499 bf.append('"'); 1500 1501 String msg = bf.toString(); 1502 AggRules.getLogger().debug(msg); 1503 } 1504 1505 return regex; 1506 } 1507 protected java.util.regex.Pattern getPattern(final String[] names) { 1508 1509 final String charcase = getCharCase(); 1510 1511 if (charcase.equals("ignore")) { 1512 // the case of name does not matter 1513 // since the Pattern will be create to ignore case 1514 final String regex = getRegex(names); 1515 if (regex == null) { 1516 return null; 1517 } 1518 1519 final java.util.regex.Pattern pattern = 1520 java.util.regex.Pattern.compile(regex, 1521 java.util.regex.Pattern.CASE_INSENSITIVE); 1522 1523 return pattern; 1524 1525 } else if (charcase.equals("exact")) { 1526 // the case of name is not changed 1527 // since we are interested in exact case matching 1528 final String regex = getRegex(names); 1529 if (regex == null) { 1530 return null; 1531 } 1532 1533 final java.util.regex.Pattern pattern = 1534 java.util.regex.Pattern.compile(regex); 1535 1536 return pattern; 1537 1538 } else if (charcase.equals("upper")) { 1539 // convert name to upper case 1540 String[] ucNames = new String[names.length]; 1541 for (int i = 0; i < names.length; i++) { 1542 String name = names[i]; 1543 ucNames[i] = (name == null) 1544 ? null: name.toUpperCase(); 1545 } 1546 1547 final String regex = getRegex(ucNames); 1548 if (regex == null) { 1549 return null; 1550 } 1551 1552 final java.util.regex.Pattern pattern = 1553 java.util.regex.Pattern.compile(regex); 1554 1555 return pattern; 1556 1557 } else { 1558 // lower 1559 // convert name to lower case 1560 String[] lcNames = new String[names.length]; 1561 for (int i = 0; i < names.length; i++) { 1562 String name = names[i]; 1563 lcNames[i] = (name == null) 1564 ? null: name.toLowerCase(); 1565 } 1566 1567 final String regex = getRegex(lcNames); 1568 if (regex == null) { 1569 return null; 1570 } 1571 1572 final java.util.regex.Pattern pattern = 1573 java.util.regex.Pattern.compile(regex); 1574 1575 return pattern; 1576 } 1577 } 1578 // END pass-through code block --- 1579 } 1580 1581 /** 1582 */ 1583 public static abstract class RegexMapper extends Base 1584 { 1585 public RegexMapper() 1586 { 1587 } 1588 1589 public RegexMapper(org.eigenbase.xom.DOMWrapper _def) 1590 throws org.eigenbase.xom.XOMException 1591 { 1592 try { 1593 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1594 _parser = _parser; 1595 org.eigenbase.xom.NodeDef[] _tempArray = null; 1596 _tempArray = _tempArray; 1597 id = (String)_parser.getAttribute("id", "String", null, null, true); 1598 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1599 _tempArray = _parser.getArray(Regex.class, 0, 0); 1600 regexs = new Regex[_tempArray.length]; 1601 for(int _i=0; _i<regexs.length; _i++) 1602 regexs[_i] = (Regex)_tempArray[_i]; 1603 } catch(org.eigenbase.xom.XOMException _ex) { 1604 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1605 } 1606 } 1607 1608 public String id; // required attribute 1609 1610 /** 1611 * This is an array of Regex. A match occurs if any one of 1612 * the Regex matches; it is the equivalent of or-ing the 1613 * regular expressions together. A candidate string is processed 1614 * sequentially by each Regex in their document order until 1615 * one matches. In none match, well, none match. 1616 */ 1617 public Regex[] regexs; //optional array 1618 1619 public String getName() 1620 { 1621 return "RegexMapper"; 1622 } 1623 1624 public void display(java.io.PrintWriter _out, int _indent) 1625 { 1626 _out.println(getName()); 1627 displayAttribute(_out, "id", id, _indent+1); 1628 displayAttribute(_out, "enabled", enabled, _indent+1); 1629 displayElementArray(_out, "regexs", regexs, _indent+1); 1630 } 1631 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1632 { 1633 _out.beginTag("(%RegexMapper;)", new org.eigenbase.xom.XMLAttrVector() 1634 .add("id", id) 1635 .add("enabled", enabled) 1636 ); 1637 displayXMLElementArray(_out, regexs); 1638 _out.endTag("(%RegexMapper;)"); 1639 } 1640 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1641 { 1642 boolean _diff = true; 1643 RegexMapper _cother = (RegexMapper)_other; 1644 _diff = _diff && displayAttributeDiff("id", id, _cother.id, _out, _indent+1); 1645 _diff = _diff && displayElementArrayDiff("regexs", regexs, _cother.regexs, _out, _indent+1); 1646 return _diff; 1647 } 1648 // BEGIN pass-through code block --- 1649 protected String getTag() { 1650 return id; 1651 } 1652 1653 public void validate(final AggRules rules, 1654 final mondrian.recorder.MessageRecorder msgRecorder) { 1655 msgRecorder.pushContextName(getName()); 1656 try { 1657 1658 String[] templateNames = getTemplateNames(); 1659 1660 for (int i = 0; i < regexs.length; i++) { 1661 Regex regex = regexs[i]; 1662 regex.validate(rules, templateNames, msgRecorder); 1663 } 1664 1665 } finally { 1666 msgRecorder.popContextName(); 1667 } 1668 } 1669 1670 1671 /** 1672 * This must be defined in derived classes. It returns an array of 1673 * symbolic names that are the symbolic names allowed to appear 1674 * in the regular expression templates. 1675 * 1676 * @return array of symbol names 1677 */ 1678 protected abstract String[] getTemplateNames(); 1679 1680 protected Recognizer.Matcher getMatcher(final String[] names) { 1681 1682 final java.util.regex.Pattern[] patterns = 1683 new java.util.regex.Pattern[regexs.length]; 1684 1685 for (int i = 0; i < regexs.length; i++) { 1686 Regex regex = regexs[i]; 1687 patterns[i] = regex.getPattern(names); 1688 } 1689 1690 return new Recognizer.Matcher() { 1691 public boolean matches(String name) { 1692 for (int i = 0; i < patterns.length; i++) { 1693 java.util.regex.Pattern pattern = patterns[i]; 1694 if ((pattern != null) && 1695 pattern.matcher(name).matches()) { 1696 1697 if (AggRules.getLogger().isDebugEnabled()) { 1698 debug(name, pattern); 1699 } 1700 1701 return true; 1702 } 1703 } 1704 return false; 1705 } 1706 private void debug(String name, java.util.regex.Pattern p) { 1707 StringBuilder bf = new StringBuilder(64); 1708 bf.append("DefaultDef.RegexMapper"); 1709 bf.append(".Matcher.matches:"); 1710 bf.append(" name \""); 1711 bf.append(name); 1712 bf.append("\" matches regex \""); 1713 bf.append(p.pattern()); 1714 bf.append("\""); 1715 if ((p.flags() & 1716 java.util.regex.Pattern.CASE_INSENSITIVE) != 0) { 1717 bf.append(" case_insensitive"); 1718 } 1719 1720 String msg = bf.toString(); 1721 AggRules.getLogger().debug(msg); 1722 } 1723 }; 1724 } 1725 // END pass-through code block --- 1726 } 1727 1728 public static abstract class Ref extends Base 1729 { 1730 public Ref() 1731 { 1732 } 1733 1734 public Ref(org.eigenbase.xom.DOMWrapper _def) 1735 throws org.eigenbase.xom.XOMException 1736 { 1737 try { 1738 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1739 _parser = _parser; 1740 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 1741 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1742 } catch(org.eigenbase.xom.XOMException _ex) { 1743 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1744 } 1745 } 1746 1747 public String refId; // required attribute 1748 1749 1750 public String getName() 1751 { 1752 return "Ref"; 1753 } 1754 1755 public void display(java.io.PrintWriter _out, int _indent) 1756 { 1757 _out.println(getName()); 1758 displayAttribute(_out, "refId", refId, _indent+1); 1759 displayAttribute(_out, "enabled", enabled, _indent+1); 1760 } 1761 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1762 { 1763 _out.beginTag("(%Ref;)", new org.eigenbase.xom.XMLAttrVector() 1764 .add("refId", refId) 1765 .add("enabled", enabled) 1766 ); 1767 _out.endTag("(%Ref;)"); 1768 } 1769 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1770 { 1771 boolean _diff = true; 1772 Ref _cother = (Ref)_other; 1773 _diff = _diff && displayAttributeDiff("refId", refId, _cother.refId, _out, _indent+1); 1774 return _diff; 1775 } 1776 // BEGIN pass-through code block --- 1777 protected String getTag() { 1778 return getRefId(); 1779 } 1780 public String getRefId() { 1781 return refId; 1782 } 1783 // END pass-through code block --- 1784 } 1785 1786 public static class LevelMapRef extends Ref 1787 { 1788 public LevelMapRef() 1789 { 1790 } 1791 1792 public LevelMapRef(org.eigenbase.xom.DOMWrapper _def) 1793 throws org.eigenbase.xom.XOMException 1794 { 1795 try { 1796 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1797 _parser = _parser; 1798 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 1799 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1800 } catch(org.eigenbase.xom.XOMException _ex) { 1801 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1802 } 1803 } 1804 1805 1806 1807 public String getName() 1808 { 1809 return "LevelMapRef"; 1810 } 1811 1812 public void display(java.io.PrintWriter _out, int _indent) 1813 { 1814 _out.println(getName()); 1815 displayAttribute(_out, "refId", refId, _indent+1); 1816 displayAttribute(_out, "enabled", enabled, _indent+1); 1817 } 1818 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1819 { 1820 _out.beginTag("LevelMapRef", new org.eigenbase.xom.XMLAttrVector() 1821 .add("refId", refId) 1822 .add("enabled", enabled) 1823 ); 1824 _out.endTag("LevelMapRef"); 1825 } 1826 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1827 { 1828 boolean _diff = true; 1829 LevelMapRef _cother = (LevelMapRef)_other; 1830 return _diff; 1831 } 1832 // BEGIN pass-through code block --- 1833 public void validate(final AggRules rules, 1834 final mondrian.recorder.MessageRecorder msgRecorder) { 1835 msgRecorder.pushContextName(getName()); 1836 try { 1837 if (! rules.hasLevelMap(getRefId())) { 1838 String msg = "No LevelMap has id equal to refid \"" + 1839 getRefId() + 1840 "\""; 1841 msgRecorder.reportError(msg); 1842 } 1843 } finally { 1844 msgRecorder.popContextName(); 1845 } 1846 } 1847 // END pass-through code block --- 1848 } 1849 1850 public static class MeasureMapRef extends Ref 1851 { 1852 public MeasureMapRef() 1853 { 1854 } 1855 1856 public MeasureMapRef(org.eigenbase.xom.DOMWrapper _def) 1857 throws org.eigenbase.xom.XOMException 1858 { 1859 try { 1860 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1861 _parser = _parser; 1862 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 1863 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1864 } catch(org.eigenbase.xom.XOMException _ex) { 1865 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1866 } 1867 } 1868 1869 1870 1871 public String getName() 1872 { 1873 return "MeasureMapRef"; 1874 } 1875 1876 public void display(java.io.PrintWriter _out, int _indent) 1877 { 1878 _out.println(getName()); 1879 displayAttribute(_out, "refId", refId, _indent+1); 1880 displayAttribute(_out, "enabled", enabled, _indent+1); 1881 } 1882 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1883 { 1884 _out.beginTag("MeasureMapRef", new org.eigenbase.xom.XMLAttrVector() 1885 .add("refId", refId) 1886 .add("enabled", enabled) 1887 ); 1888 _out.endTag("MeasureMapRef"); 1889 } 1890 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1891 { 1892 boolean _diff = true; 1893 MeasureMapRef _cother = (MeasureMapRef)_other; 1894 return _diff; 1895 } 1896 // BEGIN pass-through code block --- 1897 public void validate(final AggRules rules, 1898 final mondrian.recorder.MessageRecorder msgRecorder) { 1899 msgRecorder.pushContextName(getName()); 1900 try { 1901 if (! rules.hasMeasureMap(getRefId())) { 1902 String msg = "No MeasureMap has id equal to refid \"" + 1903 getRefId() + 1904 "\""; 1905 msgRecorder.reportError(msg); 1906 } 1907 } finally { 1908 msgRecorder.popContextName(); 1909 } 1910 } 1911 // END pass-through code block --- 1912 } 1913 1914 public static class IgnoreMapRef extends Ref 1915 { 1916 public IgnoreMapRef() 1917 { 1918 } 1919 1920 public IgnoreMapRef(org.eigenbase.xom.DOMWrapper _def) 1921 throws org.eigenbase.xom.XOMException 1922 { 1923 try { 1924 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1925 _parser = _parser; 1926 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 1927 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1928 } catch(org.eigenbase.xom.XOMException _ex) { 1929 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1930 } 1931 } 1932 1933 1934 1935 public String getName() 1936 { 1937 return "IgnoreMapRef"; 1938 } 1939 1940 public void display(java.io.PrintWriter _out, int _indent) 1941 { 1942 _out.println(getName()); 1943 displayAttribute(_out, "refId", refId, _indent+1); 1944 displayAttribute(_out, "enabled", enabled, _indent+1); 1945 } 1946 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 1947 { 1948 _out.beginTag("IgnoreMapRef", new org.eigenbase.xom.XMLAttrVector() 1949 .add("refId", refId) 1950 .add("enabled", enabled) 1951 ); 1952 _out.endTag("IgnoreMapRef"); 1953 } 1954 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 1955 { 1956 boolean _diff = true; 1957 IgnoreMapRef _cother = (IgnoreMapRef)_other; 1958 return _diff; 1959 } 1960 // BEGIN pass-through code block --- 1961 public void validate(final AggRules rules, 1962 final mondrian.recorder.MessageRecorder msgRecorder) { 1963 msgRecorder.pushContextName(getName()); 1964 try { 1965 if (! rules.hasIgnoreMap(getRefId())) { 1966 String msg = "No IgnoreMap has id equal to refid \"" + 1967 getRefId() + 1968 "\""; 1969 msgRecorder.reportError(msg); 1970 } 1971 } finally { 1972 msgRecorder.popContextName(); 1973 } 1974 } 1975 // END pass-through code block --- 1976 } 1977 1978 public static class FactCountMatchRef extends Ref 1979 { 1980 public FactCountMatchRef() 1981 { 1982 } 1983 1984 public FactCountMatchRef(org.eigenbase.xom.DOMWrapper _def) 1985 throws org.eigenbase.xom.XOMException 1986 { 1987 try { 1988 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 1989 _parser = _parser; 1990 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 1991 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 1992 } catch(org.eigenbase.xom.XOMException _ex) { 1993 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 1994 } 1995 } 1996 1997 1998 1999 public String getName() 2000 { 2001 return "FactCountMatchRef"; 2002 } 2003 2004 public void display(java.io.PrintWriter _out, int _indent) 2005 { 2006 _out.println(getName()); 2007 displayAttribute(_out, "refId", refId, _indent+1); 2008 displayAttribute(_out, "enabled", enabled, _indent+1); 2009 } 2010 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2011 { 2012 _out.beginTag("FactCountMatchRef", new org.eigenbase.xom.XMLAttrVector() 2013 .add("refId", refId) 2014 .add("enabled", enabled) 2015 ); 2016 _out.endTag("FactCountMatchRef"); 2017 } 2018 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2019 { 2020 boolean _diff = true; 2021 FactCountMatchRef _cother = (FactCountMatchRef)_other; 2022 return _diff; 2023 } 2024 // BEGIN pass-through code block --- 2025 public void validate(final AggRules rules, 2026 final mondrian.recorder.MessageRecorder msgRecorder) { 2027 msgRecorder.pushContextName(getName()); 2028 try { 2029 if (! rules.hasFactCountMatch(getRefId())) { 2030 String msg = "No FactCountMatch has id equal to refid \"" + 2031 getRefId() + 2032 "\""; 2033 msgRecorder.reportError(msg); 2034 } 2035 } finally { 2036 msgRecorder.popContextName(); 2037 } 2038 } 2039 // END pass-through code block --- 2040 } 2041 2042 public static class ForeignKeyMatchRef extends Ref 2043 { 2044 public ForeignKeyMatchRef() 2045 { 2046 } 2047 2048 public ForeignKeyMatchRef(org.eigenbase.xom.DOMWrapper _def) 2049 throws org.eigenbase.xom.XOMException 2050 { 2051 try { 2052 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2053 _parser = _parser; 2054 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 2055 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2056 } catch(org.eigenbase.xom.XOMException _ex) { 2057 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2058 } 2059 } 2060 2061 2062 2063 public String getName() 2064 { 2065 return "ForeignKeyMatchRef"; 2066 } 2067 2068 public void display(java.io.PrintWriter _out, int _indent) 2069 { 2070 _out.println(getName()); 2071 displayAttribute(_out, "refId", refId, _indent+1); 2072 displayAttribute(_out, "enabled", enabled, _indent+1); 2073 } 2074 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2075 { 2076 _out.beginTag("ForeignKeyMatchRef", new org.eigenbase.xom.XMLAttrVector() 2077 .add("refId", refId) 2078 .add("enabled", enabled) 2079 ); 2080 _out.endTag("ForeignKeyMatchRef"); 2081 } 2082 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2083 { 2084 boolean _diff = true; 2085 ForeignKeyMatchRef _cother = (ForeignKeyMatchRef)_other; 2086 return _diff; 2087 } 2088 // BEGIN pass-through code block --- 2089 public void validate(final AggRules rules, 2090 final mondrian.recorder.MessageRecorder msgRecorder) { 2091 msgRecorder.pushContextName(getName()); 2092 try { 2093 if (! rules.hasForeignKeyMatch(getRefId())) { 2094 String msg = "No ForeignKeyMatch has id equal to refid \"" + 2095 getRefId() + 2096 "\""; 2097 msgRecorder.reportError(msg); 2098 } 2099 } finally { 2100 msgRecorder.popContextName(); 2101 } 2102 } 2103 // END pass-through code block --- 2104 } 2105 2106 public static class TableMatchRef extends Ref 2107 { 2108 public TableMatchRef() 2109 { 2110 } 2111 2112 public TableMatchRef(org.eigenbase.xom.DOMWrapper _def) 2113 throws org.eigenbase.xom.XOMException 2114 { 2115 try { 2116 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2117 _parser = _parser; 2118 refId = (String)_parser.getAttribute("refId", "String", null, null, true); 2119 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2120 } catch(org.eigenbase.xom.XOMException _ex) { 2121 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2122 } 2123 } 2124 2125 2126 2127 public String getName() 2128 { 2129 return "TableMatchRef"; 2130 } 2131 2132 public void display(java.io.PrintWriter _out, int _indent) 2133 { 2134 _out.println(getName()); 2135 displayAttribute(_out, "refId", refId, _indent+1); 2136 displayAttribute(_out, "enabled", enabled, _indent+1); 2137 } 2138 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2139 { 2140 _out.beginTag("TableMatchRef", new org.eigenbase.xom.XMLAttrVector() 2141 .add("refId", refId) 2142 .add("enabled", enabled) 2143 ); 2144 _out.endTag("TableMatchRef"); 2145 } 2146 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2147 { 2148 boolean _diff = true; 2149 TableMatchRef _cother = (TableMatchRef)_other; 2150 return _diff; 2151 } 2152 // BEGIN pass-through code block --- 2153 public void validate(final AggRules rules, 2154 final mondrian.recorder.MessageRecorder msgRecorder) { 2155 msgRecorder.pushContextName(getName()); 2156 try { 2157 if (! rules.hasTableMatch(getRefId())) { 2158 String msg = "No TableMatch has id equal to refid \"" + 2159 getRefId() + 2160 "\""; 2161 msgRecorder.reportError(msg); 2162 } 2163 } finally { 2164 msgRecorder.popContextName(); 2165 } 2166 } 2167 // END pass-through code block --- 2168 } 2169 2170 /** 2171 * This is the template that maps from a combination of level 2172 * usage_prefix 2173 * hierarchy_name 2174 * level_name 2175 * level_column_name 2176 */ 2177 public static class LevelMap extends RegexMapper 2178 { 2179 public LevelMap() 2180 { 2181 } 2182 2183 public LevelMap(org.eigenbase.xom.DOMWrapper _def) 2184 throws org.eigenbase.xom.XOMException 2185 { 2186 try { 2187 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2188 _parser = _parser; 2189 org.eigenbase.xom.NodeDef[] _tempArray = null; 2190 _tempArray = _tempArray; 2191 id = (String)_parser.getAttribute("id", "String", null, null, true); 2192 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2193 _tempArray = _parser.getArray(Regex.class, 0, 0); 2194 regexs = new Regex[_tempArray.length]; 2195 for(int _i=0; _i<regexs.length; _i++) 2196 regexs[_i] = (Regex)_tempArray[_i]; 2197 } catch(org.eigenbase.xom.XOMException _ex) { 2198 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2199 } 2200 } 2201 2202 2203 2204 public String getName() 2205 { 2206 return "LevelMap"; 2207 } 2208 2209 public void display(java.io.PrintWriter _out, int _indent) 2210 { 2211 _out.println(getName()); 2212 displayAttribute(_out, "id", id, _indent+1); 2213 displayAttribute(_out, "enabled", enabled, _indent+1); 2214 displayElementArray(_out, "regexs", regexs, _indent+1); 2215 } 2216 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2217 { 2218 _out.beginTag("LevelMap", new org.eigenbase.xom.XMLAttrVector() 2219 .add("id", id) 2220 .add("enabled", enabled) 2221 ); 2222 displayXMLElementArray(_out, regexs); 2223 _out.endTag("LevelMap"); 2224 } 2225 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2226 { 2227 boolean _diff = true; 2228 LevelMap _cother = (LevelMap)_other; 2229 _diff = _diff && displayElementArrayDiff("regexs", regexs, _cother.regexs, _out, _indent+1); 2230 return _diff; 2231 } 2232 // BEGIN pass-through code block --- 2233 private static final String[] TEMPLATE_NAMES = new String[] { 2234 "usage_prefix", 2235 "hierarchy_name", 2236 "level_name", 2237 "level_column_name" 2238 }; 2239 protected String[] getTemplateNames() { 2240 return TEMPLATE_NAMES; 2241 } 2242 2243 protected Recognizer.Matcher getMatcher( 2244 final String usagePrefix, 2245 final String hierarchyName, 2246 final String levelName, 2247 final String levelColumnName) { 2248 return getMatcher(new String[] { 2249 usagePrefix, 2250 hierarchyName, 2251 levelName, 2252 levelColumnName 2253 }); 2254 } 2255 // END pass-through code block --- 2256 } 2257 2258 /** 2259 * This is the template that maps from a combination of measure 2260 * measure_name, 2261 * measure_column_name, and 2262 * aggregate_name ("count", "sum", "avg", "min", "max", 2263 * "distinct-count"). 2264 */ 2265 public static class MeasureMap extends RegexMapper 2266 { 2267 public MeasureMap() 2268 { 2269 } 2270 2271 public MeasureMap(org.eigenbase.xom.DOMWrapper _def) 2272 throws org.eigenbase.xom.XOMException 2273 { 2274 try { 2275 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2276 _parser = _parser; 2277 org.eigenbase.xom.NodeDef[] _tempArray = null; 2278 _tempArray = _tempArray; 2279 id = (String)_parser.getAttribute("id", "String", null, null, true); 2280 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2281 _tempArray = _parser.getArray(Regex.class, 0, 0); 2282 regexs = new Regex[_tempArray.length]; 2283 for(int _i=0; _i<regexs.length; _i++) 2284 regexs[_i] = (Regex)_tempArray[_i]; 2285 } catch(org.eigenbase.xom.XOMException _ex) { 2286 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2287 } 2288 } 2289 2290 2291 2292 public String getName() 2293 { 2294 return "MeasureMap"; 2295 } 2296 2297 public void display(java.io.PrintWriter _out, int _indent) 2298 { 2299 _out.println(getName()); 2300 displayAttribute(_out, "id", id, _indent+1); 2301 displayAttribute(_out, "enabled", enabled, _indent+1); 2302 displayElementArray(_out, "regexs", regexs, _indent+1); 2303 } 2304 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2305 { 2306 _out.beginTag("MeasureMap", new org.eigenbase.xom.XMLAttrVector() 2307 .add("id", id) 2308 .add("enabled", enabled) 2309 ); 2310 displayXMLElementArray(_out, regexs); 2311 _out.endTag("MeasureMap"); 2312 } 2313 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2314 { 2315 boolean _diff = true; 2316 MeasureMap _cother = (MeasureMap)_other; 2317 _diff = _diff && displayElementArrayDiff("regexs", regexs, _cother.regexs, _out, _indent+1); 2318 return _diff; 2319 } 2320 // BEGIN pass-through code block --- 2321 private static final String[] TEMPLATE_NAMES = new String[] { 2322 "measure_name", 2323 "measure_column_name", 2324 "aggregate_name" 2325 }; 2326 protected String[] getTemplateNames() { 2327 return TEMPLATE_NAMES; 2328 } 2329 protected Recognizer.Matcher getMatcher( 2330 final String measureName, 2331 final String measuerColumnName, 2332 final String aggregateName) { 2333 return getMatcher(new String[] { 2334 measureName, 2335 measuerColumnName, 2336 aggregateName 2337 }); 2338 } 2339 // END pass-through code block --- 2340 } 2341 2342 /** 2343 * This is the template used to specify columns to be ignored. 2344 * There are NO template names. One simply uses a regular 2345 * expression. 2346 */ 2347 public static class IgnoreMap extends RegexMapper 2348 { 2349 public IgnoreMap() 2350 { 2351 } 2352 2353 public IgnoreMap(org.eigenbase.xom.DOMWrapper _def) 2354 throws org.eigenbase.xom.XOMException 2355 { 2356 try { 2357 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2358 _parser = _parser; 2359 org.eigenbase.xom.NodeDef[] _tempArray = null; 2360 _tempArray = _tempArray; 2361 id = (String)_parser.getAttribute("id", "String", null, null, true); 2362 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2363 _tempArray = _parser.getArray(Regex.class, 0, 0); 2364 regexs = new Regex[_tempArray.length]; 2365 for(int _i=0; _i<regexs.length; _i++) 2366 regexs[_i] = (Regex)_tempArray[_i]; 2367 } catch(org.eigenbase.xom.XOMException _ex) { 2368 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2369 } 2370 } 2371 2372 2373 2374 public String getName() 2375 { 2376 return "IgnoreMap"; 2377 } 2378 2379 public void display(java.io.PrintWriter _out, int _indent) 2380 { 2381 _out.println(getName()); 2382 displayAttribute(_out, "id", id, _indent+1); 2383 displayAttribute(_out, "enabled", enabled, _indent+1); 2384 displayElementArray(_out, "regexs", regexs, _indent+1); 2385 } 2386 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2387 { 2388 _out.beginTag("IgnoreMap", new org.eigenbase.xom.XMLAttrVector() 2389 .add("id", id) 2390 .add("enabled", enabled) 2391 ); 2392 displayXMLElementArray(_out, regexs); 2393 _out.endTag("IgnoreMap"); 2394 } 2395 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2396 { 2397 boolean _diff = true; 2398 IgnoreMap _cother = (IgnoreMap)_other; 2399 _diff = _diff && displayElementArrayDiff("regexs", regexs, _cother.regexs, _out, _indent+1); 2400 return _diff; 2401 } 2402 // BEGIN pass-through code block --- 2403 private static final String[] TEMPLATE_NAMES = new String[] { }; 2404 protected String[] getTemplateNames() { 2405 return TEMPLATE_NAMES; 2406 } 2407 protected Recognizer.Matcher getMatcher() { 2408 return getMatcher(new String[]{}); 2409 } 2410 // END pass-through code block --- 2411 } 2412 2413 /** 2414 * A RolapConnection uses one AggRule. If no name is specified, then 2415 * the AggRule which is marked as default==true is used (validation 2416 * fails if one and only one AggRule is not marked as the default). 2417 * An AggRule has manditory child elements for matching the 2418 * aggregate table names, aggregate table fact count column, 2419 * foreign key columns, the measure columns, and the hierarchy level 2420 * columns. These child elements can be specified as direct children 2421 * of an AggRule element or by reference to elements defined as a 2422 * pier to the AggRule (using references allows reuse of the child 2423 * elements and with one quick edit the reference to use can be 2424 * changed by changing the refid attribute value). 2425 */ 2426 public static class AggRule extends Base 2427 { 2428 public AggRule() 2429 { 2430 } 2431 2432 public AggRule(org.eigenbase.xom.DOMWrapper _def) 2433 throws org.eigenbase.xom.XOMException 2434 { 2435 try { 2436 org.eigenbase.xom.DOMElementParser _parser = new org.eigenbase.xom.DOMElementParser(_def, "", DefaultDef.class); 2437 _parser = _parser; 2438 tag = (String)_parser.getAttribute("tag", "String", null, null, true); 2439 countColumn = (String)_parser.getAttribute("countColumn", "String", "fact_count", null, true); 2440 enabled = (Boolean)_parser.getAttribute("enabled", "Boolean", "true", null, false); 2441 ignoreMap = (IgnoreMap)_parser.getElement(IgnoreMap.class, false); 2442 ignoreMapRef = (IgnoreMapRef)_parser.getElement(IgnoreMapRef.class, false); 2443 factCountMatch = (FactCountMatch)_parser.getElement(FactCountMatch.class, false); 2444 factCountMatchRef = (FactCountMatchRef)_parser.getElement(FactCountMatchRef.class, false); 2445 foreignKeyMatch = (ForeignKeyMatch)_parser.getElement(ForeignKeyMatch.class, false); 2446 foreignKeyMatchRef = (ForeignKeyMatchRef)_parser.getElement(ForeignKeyMatchRef.class, false); 2447 tableMatch = (TableMatch)_parser.getElement(TableMatch.class, false); 2448 tableMatchRef = (TableMatchRef)_parser.getElement(TableMatchRef.class, false); 2449 levelMap = (LevelMap)_parser.getElement(LevelMap.class, false); 2450 levelMapRef = (LevelMapRef)_parser.getElement(LevelMapRef.class, false); 2451 measureMap = (MeasureMap)_parser.getElement(MeasureMap.class, false); 2452 measureMapRef = (MeasureMapRef)_parser.getElement(MeasureMapRef.class, false); 2453 } catch(org.eigenbase.xom.XOMException _ex) { 2454 throw new org.eigenbase.xom.XOMException("In " + getName() + ": " + _ex.getMessage()); 2455 } 2456 } 2457 2458 public String tag; // required attribute 2459 public String countColumn; // attribute default: fact_count 2460 2461 /** 2462 */ 2463 public IgnoreMap ignoreMap; //optional element 2464 /** 2465 */ 2466 public IgnoreMapRef ignoreMapRef; //optional element 2467 /** 2468 */ 2469 public FactCountMatch factCountMatch; //optional element 2470 /** 2471 */ 2472 public FactCountMatchRef factCountMatchRef; //optional element 2473 /** 2474 */ 2475 public ForeignKeyMatch foreignKeyMatch; //optional element 2476 /** 2477 */ 2478 public ForeignKeyMatchRef foreignKeyMatchRef; //optional element 2479 /** 2480 */ 2481 public TableMatch tableMatch; //optional element 2482 /** 2483 */ 2484 public TableMatchRef tableMatchRef; //optional element 2485 /** 2486 */ 2487 public LevelMap levelMap; //optional element 2488 /** 2489 */ 2490 public LevelMapRef levelMapRef; //optional element 2491 /** 2492 */ 2493 public MeasureMap measureMap; //optional element 2494 /** 2495 */ 2496 public MeasureMapRef measureMapRef; //optional element 2497 2498 public String getName() 2499 { 2500 return "AggRule"; 2501 } 2502 2503 public void display(java.io.PrintWriter _out, int _indent) 2504 { 2505 _out.println(getName()); 2506 displayAttribute(_out, "tag", tag, _indent+1); 2507 displayAttribute(_out, "countColumn", countColumn, _indent+1); 2508 displayAttribute(_out, "enabled", enabled, _indent+1); 2509 displayElement(_out, "ignoreMap", ignoreMap, _indent+1); 2510 displayElement(_out, "ignoreMapRef", ignoreMapRef, _indent+1); 2511 displayElement(_out, "factCountMatch", factCountMatch, _indent+1); 2512 displayElement(_out, "factCountMatchRef", factCountMatchRef, _indent+1); 2513 displayElement(_out, "foreignKeyMatch", foreignKeyMatch, _indent+1); 2514 displayElement(_out, "foreignKeyMatchRef", foreignKeyMatchRef, _indent+1); 2515 displayElement(_out, "tableMatch", tableMatch, _indent+1); 2516 displayElement(_out, "tableMatchRef", tableMatchRef, _indent+1); 2517 displayElement(_out, "levelMap", levelMap, _indent+1); 2518 displayElement(_out, "levelMapRef", levelMapRef, _indent+1); 2519 displayElement(_out, "measureMap", measureMap, _indent+1); 2520 displayElement(_out, "measureMapRef", measureMapRef, _indent+1); 2521 } 2522 public void displayXML(org.eigenbase.xom.XMLOutput _out, int _indent) 2523 { 2524 _out.beginTag("AggRule", new org.eigenbase.xom.XMLAttrVector() 2525 .add("tag", tag) 2526 .add("countColumn", countColumn) 2527 .add("enabled", enabled) 2528 ); 2529 displayXMLElement(_out, ignoreMap); 2530 displayXMLElement(_out, ignoreMapRef); 2531 displayXMLElement(_out, factCountMatch); 2532 displayXMLElement(_out, factCountMatchRef); 2533 displayXMLElement(_out, foreignKeyMatch); 2534 displayXMLElement(_out, foreignKeyMatchRef); 2535 displayXMLElement(_out, tableMatch); 2536 displayXMLElement(_out, tableMatchRef); 2537 displayXMLElement(_out, levelMap); 2538 displayXMLElement(_out, levelMapRef); 2539 displayXMLElement(_out, measureMap); 2540 displayXMLElement(_out, measureMapRef); 2541 _out.endTag("AggRule"); 2542 } 2543 public boolean displayDiff(org.eigenbase.xom.ElementDef _other, java.io.PrintWriter _out, int _indent) 2544 { 2545 boolean _diff = true; 2546 AggRule _cother = (AggRule)_other; 2547 _diff = _diff && displayAttributeDiff("tag", tag, _cother.tag, _out, _indent+1); 2548 _diff = _diff && displayAttributeDiff("countColumn", countColumn, _cother.countColumn, _out, _indent+1); 2549 _diff = _diff && displayElementDiff("ignoreMap", ignoreMap, _cother.ignoreMap, _out, _indent+1); 2550 _diff = _diff && displayElementDiff("ignoreMapRef", ignoreMapRef, _cother.ignoreMapRef, _out, _indent+1); 2551 _diff = _diff && displayElementDiff("factCountMatch", factCountMatch, _cother.factCountMatch, _out, _indent+1); 2552 _diff = _diff && displayElementDiff("factCountMatchRef", factCountMatchRef, _cother.factCountMatchRef, _out, _indent+1); 2553 _diff = _diff && displayElementDiff("foreignKeyMatch", foreignKeyMatch, _cother.foreignKeyMatch, _out, _indent+1); 2554 _diff = _diff && displayElementDiff("foreignKeyMatchRef", foreignKeyMatchRef, _cother.foreignKeyMatchRef, _out, _indent+1); 2555 _diff = _diff && displayElementDiff("tableMatch", tableMatch, _cother.tableMatch, _out, _indent+1); 2556 _diff = _diff && displayElementDiff("tableMatchRef", tableMatchRef, _cother.tableMatchRef, _out, _indent+1); 2557 _diff = _diff && displayElementDiff("levelMap", levelMap, _cother.levelMap, _out, _indent+1); 2558 _diff = _diff && displayElementDiff("levelMapRef", levelMapRef, _cother.levelMapRef, _out, _indent+1); 2559 _diff = _diff && displayElementDiff("measureMap", measureMap, _cother.measureMap, _out, _indent+1); 2560 _diff = _diff && displayElementDiff("measureMapRef", measureMapRef, _cother.measureMapRef, _out, _indent+1); 2561 return _diff; 2562 } 2563 // BEGIN pass-through code block --- 2564 private boolean isOk(final Base base) { 2565 return ((base != null) && base.isEnabled()); 2566 } 2567 private boolean isRef(final AggRules rules, 2568 final mondrian.recorder.MessageRecorder msgRecorder, 2569 final Base base, 2570 final Base baseRef, 2571 final String baseName) { 2572 if (! isOk(base)) { 2573 if (isOk(baseRef)) { 2574 baseRef.validate(rules, msgRecorder); 2575 return true; 2576 } else { 2577 String msg = "Neither base " + 2578 baseName + 2579 " or baseref " + 2580 baseName + 2581 "Ref is ok"; 2582 msgRecorder.reportError(msg); 2583 return false; 2584 } 2585 } else if (isOk(baseRef)) { 2586 String msg = "Both base " + 2587 base.getName() + 2588 " and baseref " + 2589 baseRef.getName() + 2590 " are ok"; 2591 msgRecorder.reportError(msg); 2592 return false; 2593 } else { 2594 base.validate(rules, msgRecorder); 2595 return false; 2596 } 2597 } 2598 // called after a constructor is called 2599 public void validate(final AggRules rules, 2600 final mondrian.recorder.MessageRecorder msgRecorder) { 2601 msgRecorder.pushContextName(getName()); 2602 try { 2603 // IgnoreMap is optional 2604 if (ignoreMap != null) { 2605 ignoreMap.validate(rules, msgRecorder); 2606 } else if (ignoreMapRef != null) { 2607 ignoreMapRef.validate(rules, msgRecorder); 2608 ignoreMap = 2609 rules.lookupIgnoreMap(ignoreMapRef.getRefId()); 2610 } 2611 if (isRef(rules, msgRecorder, factCountMatch, 2612 factCountMatchRef, "FactCountMatch")) { 2613 factCountMatch = rules.lookupFactCountMatch( 2614 factCountMatchRef.getRefId()); 2615 } 2616 if (isRef(rules, msgRecorder, foreignKeyMatch, 2617 foreignKeyMatchRef, "ForeignKeyMatch")) { 2618 foreignKeyMatch = rules.lookupForeignKeyMatch( 2619 foreignKeyMatchRef.getRefId()); 2620 } 2621 if (isRef(rules, msgRecorder, tableMatch, 2622 tableMatchRef, "TableMatch")) { 2623 tableMatch = 2624 rules.lookupTableMatch(tableMatchRef.getRefId()); 2625 } 2626 if (isRef(rules, msgRecorder, levelMap, 2627 levelMapRef, "LevelMap")) { 2628 levelMap = rules.lookupLevelMap(levelMapRef.getRefId()); 2629 } 2630 if (isRef(rules, msgRecorder, measureMap, 2631 measureMapRef, "MeasureMap")) { 2632 measureMap = 2633 rules.lookupMeasureMap(measureMapRef.getRefId()); 2634 } 2635 } finally { 2636 msgRecorder.popContextName(); 2637 } 2638 } 2639 public String getTag() { 2640 return tag; 2641 } 2642 public String getCountColumn() { 2643 return countColumn; 2644 } 2645 public FactCountMatch getFactCountMatch() { 2646 return factCountMatch; 2647 } 2648 public ForeignKeyMatch getForeignKeyMatch() { 2649 return foreignKeyMatch; 2650 } 2651 public TableMatch getTableMatch() { 2652 return tableMatch; 2653 } 2654 public LevelMap getLevelMap() { 2655 return levelMap; 2656 } 2657 public MeasureMap getMeasureMap() { 2658 return measureMap; 2659 } 2660 public IgnoreMap getIgnoreMap() { 2661 return ignoreMap; 2662 } 2663 // END pass-through code block --- 2664 } 2665 2666 2667 }