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