1 10 package mondrian.xmla; 11 12 import mondrian.olap.*; 13 import mondrian.olap.Category; 14 import mondrian.olap.FunTable; 15 import mondrian.olap.fun.FunInfo; 16 import mondrian.rolap.RolapCube; 17 import mondrian.rolap.RolapLevel; 18 import mondrian.rolap.RolapSchema; 19 import mondrian.rolap.RolapAggregator; 20 import mondrian.rolap.RolapMember; 21 22 import java.lang.reflect.Field ; 23 import java.lang.reflect.Method ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.util.*; 26 import java.text.SimpleDateFormat ; 27 import java.text.Format ; 28 29 39 enum RowsetDefinition { 40 54 DISCOVER_DATASOURCES( 55 "DISCOVER_DATASOURCES", 0, 56 "Returns a list of XML for Analysis data sources available on the server or Web Service.", 57 new Column[] { 58 DiscoverDatasourcesRowset.DataSourceName, 59 DiscoverDatasourcesRowset.DataSourceDescription, 60 DiscoverDatasourcesRowset.URL, 61 DiscoverDatasourcesRowset.DataSourceInfo, 62 DiscoverDatasourcesRowset.ProviderName, 63 DiscoverDatasourcesRowset.ProviderType, 64 DiscoverDatasourcesRowset.AuthenticationMode, 65 }, 66 null ) { 67 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 68 return new DiscoverDatasourcesRowset(request, handler); 69 } 70 }, 71 72 80 DISCOVER_SCHEMA_ROWSETS( 81 "DISCOVER_SCHEMA_ROWSETS", 2, 82 "Returns the names, values, and other information of all supported RequestType enumeration values.", 83 new Column[] { 84 DiscoverSchemaRowsetsRowset.SchemaName, 85 DiscoverSchemaRowsetsRowset.SchemaGuid, 86 DiscoverSchemaRowsetsRowset.Restrictions, 87 DiscoverSchemaRowsetsRowset.Description, 88 }, 89 null ) { 90 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 91 return new DiscoverSchemaRowsetsRowset(request, handler); 92 } 93 protected void writeRowsetXmlSchemaRowDef(SaxWriter writer) { 94 writer.startElement("xsd:complexType", new String [] { 95 "name", "row" 96 }); 97 writer.startElement("xsd:sequence"); 98 for (Column column : columnDefinitions) { 99 final String name = XmlaUtil.encodeElementName(column.name); 100 101 if (column == DiscoverSchemaRowsetsRowset.Restrictions) { 102 writer.startElement("xsd:element", new String []{ 103 "sql:field", column.name, 104 "name", name, 105 "minOccurs", "0", 106 "maxOccurs", "unbounded" 107 }); 108 writer.startElement("xsd:complexType"); 109 writer.startElement("xsd:sequence"); 110 writer.element("xsd:element", new String []{ 111 "name", "Name", 112 "type", "xsd:string", 113 "sql:field", "Name" 114 }); 115 writer.element("xsd:element", new String []{ 116 "name", "Type", 117 "type", "xsd:string", 118 "sql:field", "Type" 119 }); 120 121 writer.endElement(); writer.endElement(); writer.endElement(); 125 } else { 126 final String xsdType = column.type.columnType; 127 128 String [] attrs; 129 if (column.nullable) { 130 if (column.unbounded) { 131 attrs = new String []{ 132 "sql:field", column.name, 133 "name", name, 134 "type", xsdType, 135 "minOccurs", "0", 136 "maxOccurs", "unbounded" 137 }; 138 } else { 139 attrs = new String []{ 140 "sql:field", column.name, 141 "name", name, 142 "type", xsdType, 143 "minOccurs", "0" 144 }; 145 } 146 } else { 147 if (column.unbounded) { 148 attrs = new String []{ 149 "sql:field", column.name, 150 "name", name, 151 "type", xsdType, 152 "maxOccurs", "unbounded" 153 }; 154 } else { 155 attrs = new String []{ 156 "sql:field", column.name, 157 "name", name, 158 "type", xsdType 159 }; 160 } 161 } 162 writer.element("xsd:element", attrs); 163 } 164 } 165 writer.endElement(); writer.endElement(); } 168 }, 169 170 178 DISCOVER_ENUMERATORS( 179 "DISCOVER_ENUMERATORS", 3, 180 "Returns a list of names, data types, and enumeration values for enumerators supported by the provider of a specific data source.", 181 new Column[] { 182 DiscoverEnumeratorsRowset.EnumName, 183 DiscoverEnumeratorsRowset.EnumDescription, 184 DiscoverEnumeratorsRowset.EnumType, 185 DiscoverEnumeratorsRowset.ElementName, 186 DiscoverEnumeratorsRowset.ElementDescription, 187 DiscoverEnumeratorsRowset.ElementValue, 188 }, 189 null ) { 190 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 191 return new DiscoverEnumeratorsRowset(request, handler); 192 } 193 }, 194 195 203 DISCOVER_PROPERTIES( 204 "DISCOVER_PROPERTIES", 1, 205 "Returns a list of information and values about the requested properties that are supported by the specified data source provider.", 206 new Column[] { 207 DiscoverPropertiesRowset.PropertyName, 208 DiscoverPropertiesRowset.PropertyDescription, 209 DiscoverPropertiesRowset.PropertyType, 210 DiscoverPropertiesRowset.PropertyAccessType, 211 DiscoverPropertiesRowset.IsRequired, 212 DiscoverPropertiesRowset.Value, 213 }, 214 null ) { 215 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 216 return new DiscoverPropertiesRowset(request, handler); 217 } 218 }, 219 220 228 DISCOVER_KEYWORDS( 229 "DISCOVER_KEYWORDS", 4, 230 "Returns an XML list of keywords reserved by the provider.", 231 new Column[] { 232 DiscoverKeywordsRowset.Keyword, 233 }, 234 null ) { 235 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 236 return new DiscoverKeywordsRowset(request, handler); 237 } 238 }, 239 240 248 DISCOVER_LITERALS( 249 "DISCOVER_LITERALS", 5, 250 "Returns information about literals supported by the provider.", 251 new Column[] { 252 DiscoverLiteralsRowset.LiteralName, 253 DiscoverLiteralsRowset.LiteralValue, 254 DiscoverLiteralsRowset.LiteralInvalidChars, 255 DiscoverLiteralsRowset.LiteralInvalidStartingChars, 256 DiscoverLiteralsRowset.LiteralMaxLength, 257 }, 258 null ) { 259 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 260 return new DiscoverLiteralsRowset(request, handler); 261 } 262 }, 263 264 272 DBSCHEMA_CATALOGS( 273 "DBSCHEMA_CATALOGS", 6, 274 "Returns information about literals supported by the provider.", 275 new Column[] { 276 DbschemaCatalogsRowset.CatalogName, 277 DbschemaCatalogsRowset.Description, 278 DbschemaCatalogsRowset.Roles, 279 DbschemaCatalogsRowset.DateModified, 280 }, 281 new Column[] { 282 DbschemaCatalogsRowset.CatalogName, 283 }) { 284 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 285 return new DbschemaCatalogsRowset(request, handler); 286 } 287 }, 288 289 298 DBSCHEMA_COLUMNS( 299 "DBSCHEMA_COLUMNS", 7, null, 300 new Column[] { 301 DbschemaColumnsRowset.TableCatalog, 302 DbschemaColumnsRowset.TableSchema, 303 DbschemaColumnsRowset.TableName, 304 DbschemaColumnsRowset.ColumnName, 305 DbschemaColumnsRowset.OrdinalPosition, 306 DbschemaColumnsRowset.ColumnHasDefault, 307 DbschemaColumnsRowset.ColumnFlags, 308 DbschemaColumnsRowset.IsNullable, 309 DbschemaColumnsRowset.DataType, 310 DbschemaColumnsRowset.CharacterMaximumLength, 311 DbschemaColumnsRowset.CharacterOctetLength, 312 DbschemaColumnsRowset.NumericPrecision, 313 DbschemaColumnsRowset.NumericScale, 314 }, 315 new Column[] { 316 DbschemaColumnsRowset.TableCatalog, 317 DbschemaColumnsRowset.TableSchema, 318 DbschemaColumnsRowset.TableName, 319 }) { 320 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 321 return new DbschemaColumnsRowset(request, handler); 322 } 323 }, 324 325 333 DBSCHEMA_PROVIDER_TYPES( 334 "DBSCHEMA_PROVIDER_TYPES", 8, null, 335 new Column[] { 336 DbschemaProviderTypesRowset.TypeName, 337 DbschemaProviderTypesRowset.DataType, 338 DbschemaProviderTypesRowset.ColumnSize, 339 DbschemaProviderTypesRowset.LiteralPrefix, 340 DbschemaProviderTypesRowset.LiteralSuffix, 341 DbschemaProviderTypesRowset.IsNullable, 342 DbschemaProviderTypesRowset.CaseSensitive, 343 DbschemaProviderTypesRowset.Searchable, 344 DbschemaProviderTypesRowset.UnsignedAttribute, 345 DbschemaProviderTypesRowset.FixedPrecScale, 346 DbschemaProviderTypesRowset.AutoUniqueValue, 347 DbschemaProviderTypesRowset.IsLong, 348 DbschemaProviderTypesRowset.BestMatch, 349 }, 350 new Column[] { 351 DbschemaProviderTypesRowset.DataType, 352 }) { 353 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 354 return new DbschemaProviderTypesRowset(request, handler); 355 } 356 }, 357 358 370 DBSCHEMA_TABLES( 371 "DBSCHEMA_TABLES", 9, null, 372 new Column[] { 373 DbschemaTablesRowset.TableCatalog, 374 DbschemaTablesRowset.TableSchema, 375 DbschemaTablesRowset.TableName, 376 DbschemaTablesRowset.TableType, 377 DbschemaTablesRowset.TableGuid, 378 DbschemaTablesRowset.Description, 379 DbschemaTablesRowset.TablePropId, 380 DbschemaTablesRowset.DateCreated, 381 DbschemaTablesRowset.DateModified, 382 }, 384 new Column[] { 385 DbschemaTablesRowset.TableType, 386 DbschemaTablesRowset.TableCatalog, 387 DbschemaTablesRowset.TableSchema, 388 DbschemaTablesRowset.TableName, 389 }) { 390 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 391 return new DbschemaTablesRowset(request, handler); 392 } 393 }, 394 395 403 DBSCHEMA_TABLES_INFO( 404 "DBSCHEMA_TABLES_INFO", 10, null, 405 new Column[] { 406 DbschemaTablesInfoRowset.TableCatalog, 407 DbschemaTablesInfoRowset.TableSchema, 408 DbschemaTablesInfoRowset.TableName, 409 DbschemaTablesInfoRowset.TableType, 410 DbschemaTablesInfoRowset.TableGuid, 411 DbschemaTablesInfoRowset.Bookmarks, 412 DbschemaTablesInfoRowset.BookmarkType, 413 DbschemaTablesInfoRowset.BookmarkDataType, 414 DbschemaTablesInfoRowset.BookmarkMaximumLength, 415 DbschemaTablesInfoRowset.BookmarkInformation, 416 DbschemaTablesInfoRowset.TableVersion, 417 DbschemaTablesInfoRowset.Cardinality, 418 DbschemaTablesInfoRowset.Description, 419 DbschemaTablesInfoRowset.TablePropId, 420 }, 421 null ) { 422 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 423 return new DbschemaTablesInfoRowset(request, handler); 424 } 425 }, 426 427 454 MDSCHEMA_ACTIONS( 455 "MDSCHEMA_ACTIONS", 11, null, new Column[] { 456 MdschemaActionsRowset.CubeName, 457 MdschemaActionsRowset.Coordinate, 458 MdschemaActionsRowset.CoordinateType, 459 }, new Column[] { 460 MdschemaActionsRowset.CubeName, 463 }) { 464 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 465 return new MdschemaActionsRowset(request, handler); 466 } 467 }, 468 469 492 MDSCHEMA_CUBES( 493 "MDSCHEMA_CUBES", 12, null, 494 new Column[] { 495 MdschemaCubesRowset.CatalogName, 496 MdschemaCubesRowset.SchemaName, 497 MdschemaCubesRowset.CubeName, 498 MdschemaCubesRowset.CubeType, 499 MdschemaCubesRowset.CubeGuid, 500 MdschemaCubesRowset.CreatedOn, 501 MdschemaCubesRowset.LastSchemaUpdate, 502 MdschemaCubesRowset.SchemaUpdatedBy, 503 MdschemaCubesRowset.LastDataUpdate, 504 MdschemaCubesRowset.DataUpdatedBy, 505 MdschemaCubesRowset.IsDrillthroughEnabled, 506 MdschemaCubesRowset.IsWriteEnabled, 507 MdschemaCubesRowset.IsLinkable, 508 MdschemaCubesRowset.IsSqlEnabled, 509 MdschemaCubesRowset.Description 510 }, 511 new Column[] { 512 MdschemaCubesRowset.CatalogName, 513 MdschemaCubesRowset.SchemaName, 514 MdschemaCubesRowset.CubeName, 515 }) { 516 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 517 return new MdschemaCubesRowset(request, handler); 518 } 519 }, 520 521 541 MDSCHEMA_DIMENSIONS( 542 "MDSCHEMA_DIMENSIONS", 13, null, 543 new Column[] { 544 MdschemaDimensionsRowset.CatalogName, 545 MdschemaDimensionsRowset.SchemaName, 546 MdschemaDimensionsRowset.CubeName, 547 MdschemaDimensionsRowset.DimensionName, 548 MdschemaDimensionsRowset.DimensionUniqueName, 549 MdschemaDimensionsRowset.DimensionGuid, 550 MdschemaDimensionsRowset.DimensionCaption, 551 MdschemaDimensionsRowset.DimensionOrdinal, 552 MdschemaDimensionsRowset.DimensionType, 553 MdschemaDimensionsRowset.DimensionCardinality, 554 MdschemaDimensionsRowset.DefaultHierarchy, 555 MdschemaDimensionsRowset.Description, 556 MdschemaDimensionsRowset.IsVirtual, 557 MdschemaDimensionsRowset.IsReadWrite, 558 MdschemaDimensionsRowset.DimensionUniqueSettings, 559 MdschemaDimensionsRowset.DimensionMasterUniqueName, 560 MdschemaDimensionsRowset.DimensionIsVisible, 561 }, 562 new Column[] { 563 MdschemaDimensionsRowset.CatalogName, 564 MdschemaDimensionsRowset.SchemaName, 565 MdschemaDimensionsRowset.CubeName, 566 MdschemaDimensionsRowset.DimensionName, 567 }) { 568 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 569 return new MdschemaDimensionsRowset(request, handler); 570 } 571 }, 572 573 595 MDSCHEMA_FUNCTIONS( 596 "MDSCHEMA_FUNCTIONS", 14, null, 597 new Column[] { 598 MdschemaFunctionsRowset.FunctionName, 599 MdschemaFunctionsRowset.Description, 600 MdschemaFunctionsRowset.ParameterList, 601 MdschemaFunctionsRowset.ReturnType, 602 MdschemaFunctionsRowset.Origin, 603 MdschemaFunctionsRowset.InterfaceName, 604 MdschemaFunctionsRowset.LibraryName, 605 MdschemaFunctionsRowset.Caption, 606 }, 607 new Column[] { 608 MdschemaFunctionsRowset.LibraryName, 609 MdschemaFunctionsRowset.InterfaceName, 610 MdschemaFunctionsRowset.FunctionName, 611 MdschemaFunctionsRowset.Origin, 612 }) { 613 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 614 return new MdschemaFunctionsRowset(request, handler); 615 } 616 }, 617 618 649 MDSCHEMA_HIERARCHIES( 650 "MDSCHEMA_HIERARCHIES", 15, null, 651 new Column[] { 652 MdschemaHierarchiesRowset.CatalogName, 653 MdschemaHierarchiesRowset.SchemaName, 654 MdschemaHierarchiesRowset.CubeName, 655 MdschemaHierarchiesRowset.DimensionUniqueName, 656 MdschemaHierarchiesRowset.HierarchyName, 657 MdschemaHierarchiesRowset.HierarchyUniqueName, 658 MdschemaHierarchiesRowset.HierarchyGuid, 659 MdschemaHierarchiesRowset.HierarchyCaption, 660 MdschemaHierarchiesRowset.DimensionType, 661 MdschemaHierarchiesRowset.HierarchyCardinality, 662 MdschemaHierarchiesRowset.DefaultMember, 663 MdschemaHierarchiesRowset.AllMember, 664 MdschemaHierarchiesRowset.Description, 665 MdschemaHierarchiesRowset.Structure, 666 MdschemaHierarchiesRowset.IsVirtual, 667 MdschemaHierarchiesRowset.IsReadWrite, 668 MdschemaHierarchiesRowset.DimensionUniqueSettings, 669 MdschemaHierarchiesRowset.DimensionIsVisible, 670 MdschemaHierarchiesRowset.HierarchyOrdinal, 671 MdschemaHierarchiesRowset.DimensionIsShared, 672 MdschemaHierarchiesRowset.ParentChild, 673 }, 674 new Column[] { 675 MdschemaHierarchiesRowset.CatalogName, 676 MdschemaHierarchiesRowset.SchemaName, 677 MdschemaHierarchiesRowset.CubeName, 678 MdschemaHierarchiesRowset.DimensionUniqueName, 679 MdschemaHierarchiesRowset.HierarchyName, 680 }) { 681 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 682 return new MdschemaHierarchiesRowset(request, handler); 683 } 684 }, 685 686 726 MDSCHEMA_LEVELS( 727 "MDSCHEMA_LEVELS", 16, null, 728 new Column[] { 729 MdschemaLevelsRowset.CatalogName, 730 MdschemaLevelsRowset.SchemaName, 731 MdschemaLevelsRowset.CubeName, 732 MdschemaLevelsRowset.DimensionUniqueName, 733 MdschemaLevelsRowset.HierarchyUniqueName, 734 MdschemaLevelsRowset.LevelName, 735 MdschemaLevelsRowset.LevelUniqueName, 736 MdschemaLevelsRowset.LevelGuid, 737 MdschemaLevelsRowset.LevelCaption, 738 MdschemaLevelsRowset.LevelNumber, 739 MdschemaLevelsRowset.LevelCardinality, 740 MdschemaLevelsRowset.LevelType, 741 MdschemaLevelsRowset.CustomRollupSettings, 742 MdschemaLevelsRowset.LevelUniqueSettings, 743 MdschemaLevelsRowset.LevelIsVisible, 744 MdschemaLevelsRowset.Description, 745 }, 746 new Column[] { 747 MdschemaLevelsRowset.CatalogName, 748 MdschemaLevelsRowset.SchemaName, 749 MdschemaLevelsRowset.CubeName, 750 MdschemaLevelsRowset.DimensionUniqueName, 751 MdschemaLevelsRowset.HierarchyUniqueName, 752 MdschemaLevelsRowset.LevelNumber, 753 }) { 754 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 755 return new MdschemaLevelsRowset(request, handler); 756 } 757 }, 758 759 792 MDSCHEMA_MEASURES( 793 "MDSCHEMA_MEASURES", 17, null, 794 new Column[] { 795 MdschemaMeasuresRowset.CatalogName, 796 MdschemaMeasuresRowset.SchemaName, 797 MdschemaMeasuresRowset.CubeName, 798 MdschemaMeasuresRowset.MeasureName, 799 MdschemaMeasuresRowset.MeasureUniqueName, 800 MdschemaMeasuresRowset.MeasureCaption, 801 MdschemaMeasuresRowset.MeasureGuid, 802 MdschemaMeasuresRowset.MeasureAggregator, 803 MdschemaMeasuresRowset.DataType, 804 MdschemaMeasuresRowset.MeasureIsVisible, 805 MdschemaMeasuresRowset.LevelsList, 806 MdschemaMeasuresRowset.Description, 807 }, 808 new Column[] { 809 MdschemaMeasuresRowset.CatalogName, 810 MdschemaMeasuresRowset.SchemaName, 811 MdschemaMeasuresRowset.CubeName, 812 MdschemaMeasuresRowset.MeasureName, 813 }) { 814 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 815 return new MdschemaMeasuresRowset(request, handler); 816 } 817 }, 818 819 852 MDSCHEMA_MEMBERS( 853 "MDSCHEMA_MEMBERS", 18, null, 854 new Column[] { 855 MdschemaMembersRowset.CatalogName, 856 MdschemaMembersRowset.SchemaName, 857 MdschemaMembersRowset.CubeName, 858 MdschemaMembersRowset.DimensionUniqueName, 859 MdschemaMembersRowset.HierarchyUniqueName, 860 MdschemaMembersRowset.LevelUniqueName, 861 MdschemaMembersRowset.LevelNumber, 862 MdschemaMembersRowset.MemberOrdinal, 863 MdschemaMembersRowset.MemberName, 864 MdschemaMembersRowset.MemberUniqueName, 865 MdschemaMembersRowset.MemberType, 866 MdschemaMembersRowset.MemberGuid, 867 MdschemaMembersRowset.MemberCaption, 868 MdschemaMembersRowset.ChildrenCardinality, 869 MdschemaMembersRowset.ParentLevel, 870 MdschemaMembersRowset.ParentUniqueName, 871 MdschemaMembersRowset.ParentCount, 872 MdschemaMembersRowset.TreeOp, 873 MdschemaMembersRowset.Depth, 874 }, 875 new Column[] { 876 MdschemaMembersRowset.CatalogName, 877 MdschemaMembersRowset.SchemaName, 878 MdschemaMembersRowset.CubeName, 879 MdschemaMembersRowset.DimensionUniqueName, 880 MdschemaMembersRowset.HierarchyUniqueName, 881 MdschemaMembersRowset.LevelUniqueName, 882 MdschemaMembersRowset.LevelNumber, 883 MdschemaMembersRowset.MemberOrdinal, 884 }) { 885 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 886 return new MdschemaMembersRowset(request, handler); 887 } 888 }, 889 890 938 MDSCHEMA_PROPERTIES( 939 "MDSCHEMA_PROPERTIES", 19, null, 940 new Column[] { 941 MdschemaPropertiesRowset.CatalogName, 942 MdschemaPropertiesRowset.SchemaName, 943 MdschemaPropertiesRowset.CubeName, 944 MdschemaPropertiesRowset.DimensionUniqueName, 945 MdschemaPropertiesRowset.HierarchyUniqueName, 946 MdschemaPropertiesRowset.LevelUniqueName, 947 MdschemaPropertiesRowset.MemberUniqueName, 948 MdschemaPropertiesRowset.PropertyName, 949 MdschemaPropertiesRowset.PropertyCaption, 950 MdschemaPropertiesRowset.PropertyType, 951 MdschemaPropertiesRowset.DataType, 952 MdschemaPropertiesRowset.PropertyContentType, 953 MdschemaPropertiesRowset.Description 954 }, 955 null ) { 956 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 957 return new MdschemaPropertiesRowset(request, handler); 958 } 959 }, 960 961 982 MDSCHEMA_SETS( 983 "MDSCHEMA_SETS", 20, null, 984 new Column[] { 985 MdschemaSetsRowset.CatalogName, 986 MdschemaSetsRowset.SchemaName, 987 MdschemaSetsRowset.CubeName, 988 MdschemaSetsRowset.SetName, 989 MdschemaSetsRowset.Scope, 990 }, 991 new Column[] { 992 MdschemaSetsRowset.CatalogName, 993 MdschemaSetsRowset.SchemaName, 994 MdschemaSetsRowset.CubeName, 995 }) { 996 public Rowset getRowset(XmlaRequest request, XmlaHandler handler) { 997 return new MdschemaSetsRowset(request, handler); 998 } 999 }; 1000 1001 final Column[] columnDefinitions; 1002 final Column[] sortColumnDefinitions; 1003 1004 1010 private static final String dateModified = "2005-01-25T17:35:32"; 1011 private final String description; 1012 1013 1023 RowsetDefinition( 1024 String name, 1025 int ordinal, 1026 String description, 1027 Column[] columnDefinitions, 1028 Column[] sortColumnDefinitions) 1029 { 1030 this.columnDefinitions = columnDefinitions; 1031 this.sortColumnDefinitions = sortColumnDefinitions; 1032 this.description = description; 1033 } 1034 1035 public abstract Rowset getRowset(XmlaRequest request, XmlaHandler handler); 1036 1037 public Column lookupColumn(String name) { 1038 for (Column columnDefinition : columnDefinitions) { 1039 if (columnDefinition.name.equals(name)) { 1040 return columnDefinition; 1041 } 1042 } 1043 return null; 1044 } 1045 1046 1051 Comparator<Rowset.Row> getComparator() { 1052 if (sortColumnDefinitions == null) { 1053 return null; 1054 } 1055 return new Comparator<Rowset.Row>() { 1056 public int compare(Rowset.Row row1, Rowset.Row row2) { 1057 for (Column sortColumn : sortColumnDefinitions) { 1059 Comparable val1 = (Comparable ) row1.get(sortColumn.name); 1060 Comparable val2 = (Comparable ) row2.get(sortColumn.name); 1061 if ((val1 == null) && (val2 == null)) { 1062 continue; 1064 } else if (val1 == null) { 1065 return -1; 1066 } else if (val2 == null) { 1067 return 1; 1068 } else if (val1 instanceof String && 1069 val2 instanceof String ) { 1070 int v = 1071 ((String ) val1).compareToIgnoreCase((String ) val2); 1072 if (v != 0) { 1074 return v; 1075 } 1076 } else { 1077 int v = val1.compareTo(val2); 1078 if (v != 0) { 1080 return v; 1081 } 1082 } 1083 } 1084 return 0; 1085 } 1086 }; 1087 } 1088 1089 1099 void writeRowsetXmlSchema(SaxWriter writer) { 1100 writeRowsetXmlSchemaTop(writer); 1101 writeRowsetXmlSchemaRowDef(writer); 1102 writeRowsetXmlSchemaBottom(writer); 1103 } 1104 protected void writeRowsetXmlSchemaTop(SaxWriter writer) { 1105 writer.startElement("xsd:schema", new String [] { 1106 "xmlns:xsd", XmlaConstants.NS_XSD, 1107 "xmlns", XmlaConstants.NS_XMLA_ROWSET, 1108 "xmlns:xsi", XmlaConstants.NS_XSI, 1109 "xmlns:sql", "urn:schemas-microsoft-com:xml-sql", 1110 "targetNamespace", XmlaConstants.NS_XMLA_ROWSET, 1111 "elementFormDefault", "qualified" 1112 }); 1113 1114 writer.startElement("xsd:element", new String [] { 1115 "name", "root" 1116 }); 1117 writer.startElement("xsd:complexType"); 1118 writer.startElement("xsd:sequence"); 1119 writer.element("xsd:element", new String [] { 1120 "name", "row", 1121 "type", "row", 1122 "minOccurs", "0", 1123 "maxOccurs", "unbounded" 1124 }); 1125 writer.endElement(); writer.endElement(); writer.endElement(); 1129 writer.startElement("xsd:simpleType", new String [] { 1132 "name", "uuid" 1133 }); 1134 writer.startElement("xsd:restriction", new String [] { 1135 "base", "xsd:string" 1136 }); 1137 writer.element("xsd:pattern", new String [] { 1138 "value", "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" 1139 }); 1140 1141 writer.endElement(); writer.endElement(); 1144 } 1145 protected void writeRowsetXmlSchemaRowDef(SaxWriter writer) { 1146 writer.startElement("xsd:complexType", new String [] { 1147 "name", "row" 1148 }); 1149 writer.startElement("xsd:sequence"); 1150 for (Column column : columnDefinitions) { 1151 final String name = XmlaUtil.encodeElementName(column.name); 1152 final String xsdType = column.type.columnType; 1153 1154 String [] attrs; 1155 if (column.nullable) { 1156 if (column.unbounded) { 1157 attrs = new String []{ 1158 "sql:field", column.name, 1159 "name", name, 1160 "type", xsdType, 1161 "minOccurs", "0", 1162 "maxOccurs", "unbounded" 1163 }; 1164 } else { 1165 attrs = new String []{ 1166 "sql:field", column.name, 1167 "name", name, 1168 "type", xsdType, 1169 "minOccurs", "0" 1170 }; 1171 } 1172 } else { 1173 if (column.unbounded) { 1174 attrs = new String []{ 1175 "sql:field", column.name, 1176 "name", name, 1177 "type", xsdType, 1178 "maxOccurs", "unbounded" 1179 }; 1180 } else { 1181 attrs = new String []{ 1182 "sql:field", column.name, 1183 "name", name, 1184 "type", xsdType 1185 }; 1186 } 1187 } 1188 writer.element("xsd:element", attrs); 1189 } 1190 writer.endElement(); writer.endElement(); } 1193 protected void writeRowsetXmlSchemaBottom(SaxWriter writer) { 1194 writer.endElement(); } 1196 1197 enum Type { 1198 String("xsd:string"), 1199 StringArray("xsd:string"), 1200 Array("xsd:string"), 1201 Enumeration("xsd:string"), 1202 EnumerationArray("xsd:string"), 1203 EnumString("xsd:string"), 1204 Boolean("xsd:boolean"), 1205 StringSometimesArray("xsd:string"), 1206 Integer("xsd:int"), 1207 UnsignedInteger("xsd:unsignedInt"), 1208 DateTime("xsd:dateTime"), 1209 Short("xsd:short"), 1210 UUID("uuid"), 1211 UnsignedShort("xsd:unsignedShort"), 1212 Long("xsd:long"), 1213 UnsignedLong("xsd:unsignedLong"); 1214 1215 public final String columnType; 1216 1217 Type(String columnType) { 1218 this.columnType = columnType; 1219 } 1220 1221 boolean isEnum() { 1222 return this == Enumeration || 1223 this == EnumerationArray || 1224 this == EnumString; 1225 } 1226 1227 String getName() { 1228 return this == String ? "string" : name(); 1229 } 1230 } 1231 1232 private static DBType getDBTypeFromProperty(Property prop) { 1233 switch (prop.getType()) { 1234 case TYPE_STRING: 1235 return DBType.WSTR; 1236 case TYPE_NUMERIC: 1237 return DBType.R8; 1238 case TYPE_BOOLEAN: 1239 return DBType.BOOL; 1240 case TYPE_OTHER: 1241 default: 1242 return DBType.WSTR; 1244 } 1245 } 1246 1247 1252 1253 enum DBType { 1254 1258 I4("INTEGER", 3, "DBTYPE_I4", "A four-byte, signed integer: INTEGER"), 1259 1260 R8("DOUBLE", 5, 1261 "DBTYPE_R8", "A double-precision floating-point value: Double"), 1262 1263 CY("CURRENCY", 6, "DBTYPE_CY", "A currency value: LARGE_INTEGER, Currency is a fixed-point number with four digits to the right of the decimal point. It is stored in an eight-byte signed integer, scaled by 10,000."), 1264 1265 BOOL("BOOLEAN", 11, "DBTYPE_BOOL", "A Boolean value stored in the same way as in Automation: VARIANT_BOOL; 0 means false and ~0 (bitwise, the value is not 0; that is, all bits are set to 1) means true."), 1266 1267 1270 VARIANT("VARIANT", 12, "DBTYPE_VARIANT", "An Automation VARIANT"), 1271 1272 1275 UI2("UNSIGNED_SHORT", 18, "DBTYPE_UI2", "A two-byte, unsigned integer"), 1276 1277 1280 UI4("UNSIGNED_INTEGER", 19, "DBTYPE_UI4", "A four-byte, unsigned integer"), 1281 1282 1286 I8("LARGE_INTEGER", 20, "DBTYPE_I8", "An eight-byte, signed integer: LARGE_INTEGER"), 1287 1288 1291 WSTR("STRING", 130, "DBTYPE_WSTR", "A null-terminated Unicode character string: wchar_t[length]; If DBTYPE_WSTR is used by itself, the number of bytes allocated for the string, including the null-termination character, is specified by cbMaxLen in the DBBINDING structure. If DBTYPE_WSTR is combined with DBTYPE_BYREF, the number of bytes allocated for the string, including the null-termination character, is at least the length of the string plus two. In either case, the actual length of the string is determined from the bound length value. The maximum length of the string is the number of allocated bytes divided by sizeof(wchar_t) and truncated to the nearest integer."); 1292 1293 1294 1306 1307 private final String userName; 1308 private final int userOrdinal; 1309 private final String description; 1310 1318 1319 String dbTypeIndicator; 1320 1321 DBType( 1322 String userName, 1323 int userOrdinal, 1324 String dbTypeIndicator, 1325 String description) 1326 { 1327 this.userName = userName; 1328 this.userOrdinal = userOrdinal; 1329 this.description = description; 1330 this.dbTypeIndicator = dbTypeIndicator; 1331 } 1332 1333 } 1334 1335 static class Column { 1336 1337 1340 static final boolean RESTRICTION = true; 1341 1344 static final boolean NOT_RESTRICTION = false; 1345 1346 1349 static final boolean REQUIRED = false; 1350 1353 static final boolean OPTIONAL = true; 1354 1355 1358 static final boolean ONE_MAX = false; 1359 1362 static final boolean UNBOUNDED = true; 1363 1364 final String name; 1365 final Type type; 1366 final Enumeration enumeration; 1367 final String description; 1368 final boolean restriction; 1369 final boolean nullable; 1370 final boolean unbounded; 1371 1372 1387 Column( 1388 String name, 1389 Type type, 1390 Enumeration enumeratedType, 1391 boolean restriction, 1392 boolean nullable, 1393 String description) 1394 { 1395 this( 1396 name, type, enumeratedType, 1397 restriction, nullable, ONE_MAX, description); 1398 } 1399 1400 Column( 1401 String name, 1402 Type type, 1403 Enumeration enumeratedType, 1404 boolean restriction, 1405 boolean nullable, 1406 boolean unbounded, 1407 String description) 1408 { 1409 assert type != null; 1410 assert (type == Type.Enumeration || 1411 type == Type.EnumerationArray || 1412 type == Type.EnumString) == 1413 (enumeratedType != null); 1414 assert description == null || description.indexOf('\r') == -1; 1418 this.name = name; 1419 this.type = type; 1420 this.enumeration = enumeratedType; 1421 this.description = description; 1422 this.restriction = restriction; 1423 this.nullable = nullable; 1424 this.unbounded = unbounded; 1425 } 1426 1427 1432 protected Object get(Object row) { 1433 return getFromAccessor(row); 1434 } 1435 1436 1443 protected final Object getFromField(Object row) { 1444 try { 1445 String javaFieldName = name.substring(0, 1).toLowerCase() + 1446 name.substring(1); 1447 Field field = row.getClass().getField(javaFieldName); 1448 return field.get(row); 1449 } catch (NoSuchFieldException e) { 1450 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1451 } catch (SecurityException e) { 1452 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1453 } catch (IllegalAccessException e) { 1454 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1455 } 1456 } 1457 1458 1465 protected final Object getFromAccessor(Object row) { 1466 try { 1467 String javaMethodName = "get" + name; 1468 Method method = row.getClass().getMethod(javaMethodName); 1469 return method.invoke(row); 1470 } catch (SecurityException e) { 1471 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1472 } catch (IllegalAccessException e) { 1473 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1474 } catch (NoSuchMethodException e) { 1475 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1476 } catch (InvocationTargetException e) { 1477 throw Util.newInternal(e, "Error while accessing rowset column " + name); 1478 } 1479 } 1480 1481 public String getColumnType() { 1482 if (type.isEnum()) { 1483 return enumeration.type.columnType; 1484 } 1485 return type.columnType; 1486 } 1487 } 1488 1489 1492 static class DiscoverDatasourcesRowset extends Rowset { 1493 private static final Column DataSourceName = 1494 new Column( 1495 "DataSourceName", 1496 Type.String, 1497 null, 1498 Column.RESTRICTION, 1499 Column.REQUIRED, 1500 "The name of the data source, such as FoodMart 2000."); 1501 private static final Column DataSourceDescription = 1502 new Column( 1503 "DataSourceDescription", 1504 Type.String, 1505 null, 1506 Column.NOT_RESTRICTION, 1507 Column.OPTIONAL, 1508 "A description of the data source, as entered by the publisher."); 1509 private static final Column URL = 1510 new Column( 1511 "URL", 1512 Type.String, 1513 null, 1514 Column.RESTRICTION, 1515 Column.OPTIONAL, 1516 "The unique path that shows where to invoke the XML for Analysis methods for that data source."); 1517 private static final Column DataSourceInfo = 1518 new Column( 1519 "DataSourceInfo", 1520 Type.String, 1521 null, 1522 Column.NOT_RESTRICTION, 1523 Column.OPTIONAL, 1524 "A string containing any additional information required to connect to the data source. This can include the Initial Catalog property or other information for the provider.\n" + 1525 "Example: \"Provider=MSOLAP;Data Source=Local;\""); 1526 private static final Column ProviderName = 1527 new Column( 1528 "ProviderName", 1529 Type.String, 1530 null, 1531 Column.RESTRICTION, 1532 Column.OPTIONAL, 1533 "The name of the provider behind the data source. \n" + 1534 "Example: \"MSDASQL\""); 1535 private static final Column ProviderType = 1536 new Column( 1537 "ProviderType", 1538 Type.EnumerationArray, 1539 Enumeration.ProviderType.enumeration, 1540 Column.RESTRICTION, 1541 Column.REQUIRED, 1542 Column.UNBOUNDED, 1543 "The types of data supported by the provider. May include one or more of the following types. Example follows this table.\n" + 1544 "TDP: tabular data provider.\n" + 1545 "MDP: multidimensional data provider.\n" + 1546 "DMP: data mining provider. A DMP provider implements the OLE DB for Data Mining specification."); 1547 private static final Column AuthenticationMode = 1548 new Column( 1549 "AuthenticationMode", 1550 Type.EnumString, 1551 Enumeration.AuthenticationMode.enumeration, 1552 Column.RESTRICTION, 1553 Column.REQUIRED, 1554 "Specification of what type of security mode the data source uses. Values can be one of the following:\n" + 1555 "Unauthenticated: no user ID or password needs to be sent.\n" + 1556 "Authenticated: User ID and Password must be included in the information required for the connection.\n" + 1557 "Integrated: the data source uses the underlying security to determine authorization, such as Integrated Security provided by Microsoft Internet Information Services (IIS)."); 1558 1559 public DiscoverDatasourcesRowset(XmlaRequest request, XmlaHandler handler) { 1560 super(DISCOVER_DATASOURCES, request, handler); 1561 } 1562 1563 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 1564 for (DataSourcesConfig.DataSource ds : handler 1565 .getDataSourceEntries().values()) { 1566 Row row = new Row(); 1567 row.set(DataSourceName.name, ds.getDataSourceName()); 1568 row.set(DataSourceDescription.name, 1569 ds.getDataSourceDescription()); 1570 row.set(URL.name, ds.getURL()); 1571 row.set(DataSourceInfo.name, ds.getDataSourceName()); 1572 row.set(ProviderName.name, ds.getProviderName()); 1573 row.set(ProviderType.name, ds.getProviderType()); 1574 row.set(AuthenticationMode.name, ds.getAuthenticationMode()); 1575 addRow(row, rows); 1576 } 1577 } 1578 protected void setProperty(PropertyDefinition propertyDef, String value) { 1579 switch (propertyDef) { 1580 case Content: 1581 break; 1582 default: 1583 super.setProperty(propertyDef, value); 1584 } 1585 } 1586 } 1587 1588 static class DiscoverSchemaRowsetsRowset extends Rowset { 1589 private static final Column SchemaName = 1590 new Column( 1591 "SchemaName", 1592 Type.StringArray, 1593 null, 1594 Column.RESTRICTION, 1595 Column.REQUIRED, 1596 "The name of the schema/request. This returns the values in the RequestTypes enumeration, plus any additional types supported by the provider. The provider defines rowset structures for the additional types"); 1597 private static final Column SchemaGuid = 1598 new Column( 1599 "SchemaGuid", 1600 Type.UUID, 1601 null, 1602 Column.NOT_RESTRICTION, 1603 Column.OPTIONAL, 1604 "The GUID of the schema."); 1605 private static final Column Restrictions = 1606 new Column( 1607 "Restrictions", 1608 Type.Array, 1609 null, 1610 Column.NOT_RESTRICTION, 1611 Column.REQUIRED, 1612 "An array of the restrictions suppoted by provider. An example follows this table."); 1613 private static final Column Description = 1614 new Column( 1615 "Description", 1616 Type.String, 1617 null, 1618 Column.NOT_RESTRICTION, 1619 Column.REQUIRED, 1620 "A localizable description of the schema"); 1621 1622 public DiscoverSchemaRowsetsRowset(XmlaRequest request, XmlaHandler handler) { 1623 super(DISCOVER_SCHEMA_ROWSETS, request, handler); 1624 } 1625 1626 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 1627 RowsetDefinition[] rowsetDefinitions = 1628 RowsetDefinition.class.getEnumConstants().clone(); 1629 Arrays.sort( 1630 rowsetDefinitions, 1631 new Comparator<Enum >() { 1632 public int compare(Enum o1, Enum o2) { 1633 return o1.name().compareTo(o2.name()); 1634 } 1635 }); 1636 for (RowsetDefinition rowsetDefinition : rowsetDefinitions) { 1637 Row row = new Row(); 1638 row.set(SchemaName.name, rowsetDefinition.name()); 1639 1640 1643 row.set(Restrictions.name, getRestrictions(rowsetDefinition)); 1644 1645 String desc = rowsetDefinition.getDescription(); 1646 row.set(Description.name, (desc == null) ? "" : desc); 1647 addRow(row, rows); 1648 } 1649 } 1650 1651 private List<XmlElement> getRestrictions(RowsetDefinition rowsetDefinition) { 1652 List<XmlElement> restrictionList = new ArrayList<XmlElement>(); 1653 final Column[] columns = rowsetDefinition.columnDefinitions; 1654 for (Column column : columns) { 1655 if (column.restriction) { 1656 restrictionList.add( 1657 new XmlElement(Restrictions.name, 1658 null, 1659 new XmlElement[]{ 1660 new XmlElement("Name", null, column.name), 1661 new XmlElement("Type", 1662 null, 1663 column.getColumnType()) 1664 })); 1665 } 1666 } 1667 return restrictionList; 1668 } 1669 1670 protected void setProperty(PropertyDefinition propertyDef, String value) { 1671 switch (propertyDef) { 1672 case Content: 1673 break; 1674 default: 1675 super.setProperty(propertyDef, value); 1676 } 1677 } 1678 } 1679 1680 public String getDescription() { 1681 return description; 1682 } 1683 1684 static class DiscoverPropertiesRowset extends Rowset { 1685 private final RestrictionTest propertyNameRT; 1686 DiscoverPropertiesRowset(XmlaRequest request, XmlaHandler handler) { 1687 super(DISCOVER_PROPERTIES, request, handler); 1688 propertyNameRT = getRestrictionTest(PropertyName); 1689 } 1690 1691 private static final Column PropertyName = 1692 new Column( 1693 "PropertyName", 1694 Type.StringSometimesArray, 1695 null, 1696 Column.RESTRICTION, 1697 Column.REQUIRED, 1698 "The name of the property."); 1699 private static final Column PropertyDescription = 1700 new Column( 1701 "PropertyDescription", 1702 Type.String, 1703 null, 1704 Column.NOT_RESTRICTION, 1705 Column.REQUIRED, 1706 "A localizable text description of the property."); 1707 private static final Column PropertyType = 1708 new Column( 1709 "PropertyType", 1710 Type.String, 1711 null, 1712 Column.NOT_RESTRICTION, 1713 Column.REQUIRED, 1714 "The XML data type of the property."); 1715 private static final Column PropertyAccessType = 1716 new Column( 1717 "PropertyAccessType", 1718 Type.EnumString, 1719 Enumeration.Access.enumeration, 1720 Column.NOT_RESTRICTION, 1721 Column.REQUIRED, 1722 "Access for the property. The value can be Read, Write, or ReadWrite."); 1723 private static final Column IsRequired = 1724 new Column( 1725 "IsRequired", 1726 Type.Boolean, 1727 null, 1728 Column.NOT_RESTRICTION, 1729 Column.REQUIRED, 1730 "True if a property is required, false if it is not required."); 1731 private static final Column Value = 1732 new Column( 1733 "Value", 1734 Type.String, 1735 null, 1736 Column.NOT_RESTRICTION, 1737 Column.REQUIRED, 1738 "The current value of the property."); 1739 1740 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 1741 for (PropertyDefinition propertyDefinition : PropertyDefinition.class 1742 .getEnumConstants()) { 1743 if (!propertyNameRT.passes(propertyDefinition.name())) { 1744 continue; 1745 } 1746 Row row = new Row(); 1747 row.set(PropertyName.name, propertyDefinition.name()); 1748 row.set(PropertyDescription.name, propertyDefinition.description); 1749 row.set(PropertyType.name, propertyDefinition.type.getName()); 1750 row.set(PropertyAccessType.name, propertyDefinition.access); 1751 row.set(IsRequired.name, false); 1752 row.set(Value.name, propertyDefinition.value); 1753 addRow(row, rows); 1754 } 1755 } 1756 protected void setProperty(PropertyDefinition propertyDef, String value) { 1757 switch (propertyDef) { 1758 case Content: 1759 break; 1760 default: 1761 super.setProperty(propertyDef, value); 1762 } 1763 } 1764 } 1765 1766 static class DiscoverEnumeratorsRowset extends Rowset { 1767 DiscoverEnumeratorsRowset(XmlaRequest request, XmlaHandler handler) { 1768 super(DISCOVER_ENUMERATORS, request, handler); 1769 } 1770 1771 private static final Column EnumName = 1772 new Column( 1773 "EnumName", 1774 Type.StringArray, 1775 null, 1776 Column.RESTRICTION, 1777 Column.REQUIRED, 1778 "The name of the enumerator that contains a set of values."); 1779 private static final Column EnumDescription = 1780 new Column( 1781 "EnumDescription", 1782 Type.String, 1783 null, 1784 Column.NOT_RESTRICTION, 1785 Column.OPTIONAL, 1786 "A localizable description of the enumerator."); 1787 private static final Column EnumType = 1788 new Column( 1789 "EnumType", 1790 Type.String, 1791 null, 1792 Column.NOT_RESTRICTION, 1793 Column.REQUIRED, 1794 "The data type of the Enum values."); 1795 private static final Column ElementName = 1796 new Column( 1797 "ElementName", 1798 Type.String, 1799 null, 1800 Column.NOT_RESTRICTION, 1801 Column.REQUIRED, 1802 "The name of one of the value elements in the enumerator set.\n" + "Example: TDP"); 1803 private static final Column ElementDescription = 1804 new Column( 1805 "ElementDescription", 1806 Type.String, 1807 null, 1808 Column.NOT_RESTRICTION, 1809 Column.OPTIONAL, 1810 "A localizable description of the element (optional)."); 1811 private static final Column ElementValue = 1812 new Column( 1813 "ElementValue", 1814 Type.String, 1815 null, 1816 Column.NOT_RESTRICTION, 1817 Column.OPTIONAL, 1818 "The value of the element.\n" + "Example: 01"); 1819 1820 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 1821 List<Enumeration> enumerators = getEnumerators(); 1822 for (Enumeration enumerator : enumerators) { 1823 final String [] valueNames = enumerator.getNames(); 1824 for (String valueName : valueNames) { 1825 final Enum <?> value = enumerator.getValue(valueName, true); 1826 Row row = new Row(); 1827 row.set(EnumName.name, enumerator.name); 1828 row.set(EnumDescription.name, enumerator.description); 1829 1830 row.set(EnumType.name, "string"); 1834 1835 String name = 1836 value instanceof Enumeration.EnumWithName ? 1837 ((Enumeration.EnumWithName) value).userName() : 1838 value.name(); 1839 row.set(ElementName.name, name); 1840 1841 if (value instanceof Enumeration.EnumWithDesc) { 1842 String description = 1843 ((Enumeration.EnumWithDesc) value).getDescription(); 1844 row.set(ElementDescription.name, description); 1845 } 1846 1847 switch (enumerator.type) { 1848 case String: 1849 case StringArray: 1850 break; 1852 default: 1853 int ordinal = 1854 value instanceof Enumeration.EnumWithOrdinal ? 1855 ((Enumeration.EnumWithOrdinal) value).userOrdinal() : 1856 value.ordinal(); 1857 row.set(ElementValue.name, ordinal); 1858 break; 1859 } 1860 addRow(row, rows); 1861 } 1862 } 1863 } 1864 1865 private static List<Enumeration> getEnumerators() { 1866 SortedSet<Enumeration> enumeratorSet = new TreeSet<Enumeration>( 1867 new Comparator<Enumeration>() { 1868 public int compare(Enumeration o1, Enumeration o2) { 1869 return o1.name.compareTo(o2.name); 1870 } 1871 } 1872 ); 1873 for (RowsetDefinition rowsetDefinition : RowsetDefinition.class.getEnumConstants()) { 1874 for (Column column : rowsetDefinition.columnDefinitions) { 1875 if (column.enumeration != null) { 1876 enumeratorSet.add(column.enumeration); 1877 } 1878 } 1879 } 1880 return new ArrayList<Enumeration>(enumeratorSet); 1881 } 1882 1883 protected void setProperty(PropertyDefinition propertyDef, String value) { 1884 switch (propertyDef) { 1885 case Content: 1886 break; 1887 default: 1888 super.setProperty(propertyDef, value); 1889 } 1890 } 1891 } 1892 1893 static class DiscoverKeywordsRowset extends Rowset { 1894 DiscoverKeywordsRowset(XmlaRequest request, XmlaHandler handler) { 1895 super(DISCOVER_KEYWORDS, request, handler); 1896 } 1897 1898 private static final Column Keyword = 1899 new Column( 1900 "Keyword", 1901 Type.StringSometimesArray, 1902 null, 1903 Column.RESTRICTION, 1904 Column.REQUIRED, 1905 "A list of all the keywords reserved by a provider.\n" + 1906 "Example: AND"); 1907 1908 private static final String [] keywords = new String [] { 1909 "$AdjustedProbability", "$Distance", "$Probability", 1910 "$ProbabilityStDev", "$ProbabilityStdDeV", "$ProbabilityVariance", 1911 "$StDev", "$StdDeV", "$Support", "$Variance", 1912 "AddCalculatedMembers", "Action", "After", "Aggregate", "All", 1913 "Alter", "Ancestor", "And", "Append", "As", "ASC", "Axis", 1914 "Automatic", "Back_Color", "BASC", "BDESC", "Before", 1915 "Before_And_After", "Before_And_Self", "Before_Self_After", 1916 "BottomCount", "BottomPercent", "BottomSum", "Break", "Boolean", 1917 "Cache", "Calculated", "Call", "Case", "Catalog_Name", "Cell", 1918 "Cell_Ordinal", "Cells", "Chapters", "Children", 1919 "Children_Cardinality", "ClosingPeriod", "Cluster", 1920 "ClusterDistance", "ClusterProbability", "Clusters", 1921 "CoalesceEmpty", "Column_Values", "Columns", "Content", 1922 "Contingent", "Continuous", "Correlation", "Cousin", "Covariance", 1923 "CovarianceN", "Create", "CreatePropertySet", "CrossJoin", "Cube", 1924 "Cube_Name", "CurrentMember", "CurrentCube", "Custom", "Cyclical", 1925 "DefaultMember", "Default_Member", "DESC", "Descendents", 1926 "Description", "Dimension", "Dimension_Unique_Name", "Dimensions", 1927 "Discrete", "Discretized", "DrillDownLevel", 1928 "DrillDownLevelBottom", "DrillDownLevelTop", "DrillDownMember", 1929 "DrillDownMemberBottom", "DrillDownMemberTop", "DrillTrough", 1930 "DrillUpLevel", "DrillUpMember", "Drop", "Else", "Empty", "End", 1931 "Equal_Areas", "Exclude_Null", "ExcludeEmpty", "Exclusive", 1932 "Expression", "Filter", "FirstChild", "FirstRowset", 1933 "FirstSibling", "Flattened", "Font_Flags", "Font_Name", 1934 "Font_size", "Fore_Color", "Format_String", "Formatted_Value", 1935 "Formula", "From", "Generate", "Global", "Head", "Hierarchize", 1936 "Hierarchy", "Hierary_Unique_name", "IIF", "IsEmpty", 1937 "Include_Null", "Include_Statistics", "Inclusive", "Input_Only", 1938 "IsDescendant", "Item", "Lag", "LastChild", "LastPeriods", 1939 "LastSibling", "Lead", "Level", "Level_Unique_Name", "Levels", 1940 "LinRegIntercept", "LinRegR2", "LinRegPoint", "LinRegSlope", 1941 "LinRegVariance", "Long", "MaxRows", "Median", "Member", 1942 "Member_Caption", "Member_Guid", "Member_Name", "Member_Ordinal", 1943 "Member_Type", "Member_Unique_Name", "Members", 1944 "Microsoft_Clustering", "Microsoft_Decision_Trees", "Mining", 1945 "Model", "Model_Existence_Only", "Models", "Move", "MTD", "Name", 1946 "Nest", "NextMember", "Non", "Normal", "Not", "Ntext", "Nvarchar", 1947 "OLAP", "On", "OpeningPeriod", "OpenQuery", "Or", "Ordered", 1948 "Ordinal", "Pages", "Pages", "ParallelPeriod", "Parent", 1949 "Parent_Level", "Parent_Unique_Name", "PeriodsToDate", "PMML", 1950 "Predict", "Predict_Only", "PredictAdjustedProbability", 1951 "PredictHistogram", "Prediction", "PredictionScore", 1952 "PredictProbability", "PredictProbabilityStDev", 1953 "PredictProbabilityVariance", "PredictStDev", "PredictSupport", 1954 "PredictVariance", "PrevMember", "Probability", 1955 "Probability_StDev", "Probability_StdDev", "Probability_Variance", 1956 "Properties", "Property", "QTD", "RangeMax", "RangeMid", 1957 "RangeMin", "Rank", "Recursive", "Refresh", "Related", "Rename", 1958 "Rollup", "Rows", "Schema_Name", "Sections", "Select", "Self", 1959 "Self_And_After", "Sequence_Time", "Server", "Session", "Set", 1960 "SetToArray", "SetToStr", "Shape", "Skip", "Solve_Order", "Sort", 1961 "StdDev", "Stdev", "StripCalculatedMembers", "StrToSet", 1962 "StrToTuple", "SubSet", "Support", "Tail", "Text", "Thresholds", 1963 "ToggleDrillState", "TopCount", "TopPercent", "TopSum", 1964 "TupleToStr", "Under", "Uniform", "UniqueName", "Use", "Value", 1965 "Value", "Var", "Variance", "VarP", "VarianceP", "VisualTotals", 1966 "When", "Where", "With", "WTD", "Xor", 1967 }; 1968 1969 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 1970 for (String keyword : keywords) { 1971 Row row = new Row(); 1972 row.set(Keyword.name, keyword); 1973 addRow(row, rows); 1974 } 1975 } 1976 protected void setProperty(PropertyDefinition propertyDef, String value) { 1977 switch (propertyDef) { 1978 case Content: 1979 break; 1980 default: 1981 super.setProperty(propertyDef, value); 1982 } 1983 } 1984 } 1985 1986 static class DiscoverLiteralsRowset extends Rowset { 1987 DiscoverLiteralsRowset(XmlaRequest request, XmlaHandler handler) { 1988 super(DISCOVER_LITERALS, request, handler); 1989 } 1990 1991 private static final Column LiteralName = new Column( 1992 "LiteralName", 1993 Type.StringSometimesArray, 1994 null, 1995 Column.RESTRICTION, 1996 Column.REQUIRED, 1997 "The name of the literal described in the row.\n" + "Example: DBLITERAL_LIKE_PERCENT"); 1998 1999 private static final Column LiteralValue = new Column( 2000 "LiteralValue", 2001 Type.String, 2002 null, 2003 Column.NOT_RESTRICTION, 2004 Column.REQUIRED, 2005 "Contains the actual literal value.\n" + "Example, if LiteralName is DBLITERAL_LIKE_PERCENT and the percent character (%) is used to match zero or more characters in a LIKE clause, this column's value would be \"%\"."); 2006 2007 private static final Column LiteralInvalidChars = new Column( 2008 "LiteralInvalidChars", 2009 Type.String, 2010 null, 2011 Column.NOT_RESTRICTION, 2012 Column.REQUIRED, 2013 "The characters, in the literal, that are not valid.\n" + "For example, if table names can contain anything other than a numeric character, this string would be \"0123456789\"."); 2014 2015 private static final Column LiteralInvalidStartingChars = new Column( 2016 "LiteralInvalidStartingChars", 2017 Type.String, 2018 null, 2019 Column.NOT_RESTRICTION, 2020 Column.REQUIRED, 2021 "The characters that are not valid as the first character of the literal. If the literal can start with any valid character, this is null."); 2022 2023 private static final Column LiteralMaxLength = new Column( 2024 "LiteralMaxLength", 2025 Type.Integer, 2026 null, 2027 Column.NOT_RESTRICTION, 2028 Column.REQUIRED, 2029 "The maximum number of characters in the literal. If there is no maximum or the maximum is unknown, the value is ?1."); 2030 2031 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 2032 emit(Enumeration.Literal.class, response); 2033 } 2034 protected void setProperty(PropertyDefinition propertyDef, String value) { 2035 switch (propertyDef) { 2036 case Content: 2037 break; 2038 default: 2039 super.setProperty(propertyDef, value); 2040 } 2041 } 2042 2043 } 2044 2045 static class DbschemaCatalogsRowset extends Rowset { 2046 private final RestrictionTest catalogNameRT; 2047 DbschemaCatalogsRowset(XmlaRequest request, XmlaHandler handler) { 2048 super(DBSCHEMA_CATALOGS, request, handler); 2049 catalogNameRT = getRestrictionTest(CatalogName); 2050 } 2051 2052 private static final Column CatalogName = 2053 new Column( 2054 "CATALOG_NAME", 2055 Type.String, 2056 null, 2057 Column.RESTRICTION, 2058 Column.REQUIRED, 2059 "Catalog name. Cannot be NULL."); 2060 private static final Column Description = 2061 new Column( 2062 "DESCRIPTION", 2063 Type.String, 2064 null, 2065 Column.NOT_RESTRICTION, 2066 Column.REQUIRED, 2067 "Human-readable description of the catalog."); 2068 private static final Column Roles = 2069 new Column( 2070 "ROLES", 2071 Type.String, 2072 null, 2073 Column.NOT_RESTRICTION, 2074 Column.REQUIRED, 2075 "A comma delimited list of roles to which the current user belongs. An asterisk (*) is included as a role if the current user is a server or database administrator. Username is appended to ROLES if one of the roles uses dynamic security."); 2076 private static final Column DateModified = 2077 new Column( 2078 "DATE_MODIFIED", 2079 Type.DateTime, 2080 null, 2081 Column.NOT_RESTRICTION, 2082 Column.OPTIONAL, 2083 "The date that the catalog was last modified."); 2084 2085 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 2086 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 2087 DataSourcesConfig.Catalog[] catalogs = ds.catalogs.catalogs; 2088 String role = request.getRole(); 2089 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 2090 if (dsCatalog == null || dsCatalog.definition == null) { 2091 continue; 2092 } 2093 Connection connection = handler.getConnection(dsCatalog, role); 2094 if (connection == null) { 2095 continue; 2096 } 2097 if (!catalogNameRT.passes(dsCatalog.name)) { 2098 continue; 2099 } 2100 final RolapSchema schema = (RolapSchema) connection.getSchema(); 2101 2102 Row row = new Row(); 2103 row.set(CatalogName.name, dsCatalog.name); 2104 2105 row.set(Description.name, "No description available"); 2107 2108 StringBuilder buf = new StringBuilder (100); 2111 serialize(buf, schema.roleNames()); 2112 row.set(Roles.name, buf.toString()); 2113 2114 if (false) { 2117 row.set(DateModified.name, dateModified); 2118 } 2119 addRow(row, rows); 2120 } 2121 } 2122 2123 protected void setProperty(PropertyDefinition propertyDef, String value) { 2124 switch (propertyDef) { 2125 case Content: 2126 break; 2127 default: 2128 super.setProperty(propertyDef, value); 2129 } 2130 } 2131 } 2132 2133 static class DbschemaColumnsRowset extends Rowset { 2134 private final RestrictionTest tableCatalogRT; 2135 private final RestrictionTest tableNameRT; 2136 private final RestrictionTest columnNameRT; 2137 DbschemaColumnsRowset(XmlaRequest request, XmlaHandler handler) { 2138 super(DBSCHEMA_COLUMNS, request, handler); 2139 tableCatalogRT = getRestrictionTest(TableCatalog); 2140 tableNameRT = getRestrictionTest(TableName); 2141 columnNameRT = getRestrictionTest(ColumnName); 2142 } 2143 2144 private static final Column TableCatalog = 2145 new Column( 2146 "TABLE_CATALOG", 2147 Type.String, 2148 null, 2149 Column.RESTRICTION, 2150 Column.REQUIRED, 2151 "The name of the Database."); 2152 private static final Column TableSchema = 2153 new Column( 2154 "TABLE_SCHEMA", 2155 Type.String, 2156 null, 2157 Column.RESTRICTION, 2158 Column.OPTIONAL, 2159 null); 2160 private static final Column TableName = 2161 new Column( 2162 "TABLE_NAME", 2163 Type.String, 2164 null, 2165 Column.RESTRICTION, 2166 Column.REQUIRED, 2167 "The name of the cube."); 2168 private static final Column ColumnName = 2169 new Column( 2170 "COLUMN_NAME", 2171 Type.String, 2172 null, 2173 Column.RESTRICTION, 2174 Column.REQUIRED, 2175 "The name of the attribute hierarchy or measure."); 2176 private static final Column OrdinalPosition = 2177 new Column( 2178 "ORDINAL_POSITION", 2179 Type.UnsignedInteger, 2180 null, 2181 Column.NOT_RESTRICTION, 2182 Column.REQUIRED, 2183 "The position of the column, beginning with 1."); 2184 private static final Column ColumnHasDefault = 2185 new Column( 2186 "COLUMN_HAS_DEFAULT", 2187 Type.Boolean, 2188 null, 2189 Column.NOT_RESTRICTION, 2190 Column.OPTIONAL, 2191 "Not supported."); 2192 2203 private static final Column ColumnFlags = 2204 new Column( 2205 "COLUMN_FLAGS", 2206 Type.UnsignedInteger, 2207 null, 2208 Column.NOT_RESTRICTION, 2209 Column.REQUIRED, 2210 "A DBCOLUMNFLAGS bitmask indicating column properties."); 2211 private static final Column IsNullable = 2212 new Column( 2213 "IS_NULLABLE", 2214 Type.Boolean, 2215 null, 2216 Column.NOT_RESTRICTION, 2217 Column.REQUIRED, 2218 "Always returns false."); 2219 private static final Column DataType = 2220 new Column( 2221 "DATA_TYPE", 2222 Type.UnsignedShort, 2223 null, 2224 Column.NOT_RESTRICTION, 2225 Column.REQUIRED, 2226 "The data type of the column. Returns a string for dimension columns and a variant for measures."); 2227 private static final Column CharacterMaximumLength = 2228 new Column( 2229 "CHARACTER_MAXIMUM_LENGTH", 2230 Type.UnsignedInteger, 2231 null, 2232 Column.NOT_RESTRICTION, 2233 Column.OPTIONAL, 2234 "The maximum possible length of a value within the column."); 2235 private static final Column CharacterOctetLength = 2236 new Column( 2237 "CHARACTER_OCTET_LENGTH", 2238 Type.UnsignedInteger, 2239 null, 2240 Column.NOT_RESTRICTION, 2241 Column.OPTIONAL, 2242 "The maximum possible length of a value within the column, in bytes, for character or binary columns."); 2243 private static final Column NumericPrecision = 2244 new Column( 2245 "NUMERIC_PRECISION", 2246 Type.UnsignedShort, 2247 null, 2248 Column.NOT_RESTRICTION, 2249 Column.OPTIONAL, 2250 "The maximum precision of the column for numeric data types other than DBTYPE_VARNUMERIC."); 2251 private static final Column NumericScale = 2252 new Column( 2253 "NUMERIC_SCALE", 2254 Type.Short, 2255 null, 2256 Column.NOT_RESTRICTION, 2257 Column.OPTIONAL, 2258 "The number of digits to the right of the decimal point for DBTYPE_DECIMAL, DBTYPE_NUMERIC, DBTYPE_VARNUMERIC. Otherwise, this is NULL."); 2259 2260 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 2261 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 2262 DataSourcesConfig.Catalog[] catalogs = ds.catalogs.catalogs; 2263 String roleStr = request.getRole(); 2264 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 2265 if (dsCatalog == null || dsCatalog.definition == null) { 2266 continue; 2267 } 2268 Connection connection = 2269 handler.getConnection(dsCatalog, roleStr); 2270 if (connection == null) { 2271 continue; 2272 } 2273 Role role = connection.getSchema().lookupRole(roleStr); 2274 final RolapSchema schema = (RolapSchema) connection.getSchema(); 2275 String catalogName = dsCatalog.name; 2276 if (!tableCatalogRT.passes(catalogName)) { 2277 continue; 2278 } 2279 2281 int ordinalPosition = 1; 2282 Row row; 2283 2284 for (Cube cube1 : sortedCubes(schema)) { 2285 RolapCube cube = (RolapCube) cube1; 2286 SchemaReader schemaReader = cube.getSchemaReader(role); 2287 String cubeName = cube.getName(); 2288 if (!tableNameRT.passes(cubeName)) { 2289 continue; 2290 } 2291 for (Dimension dimension : cube.getDimensions()) { 2292 Hierarchy[] hierarchies = dimension.getHierarchies(); 2293 for (Hierarchy hierarchy1 : hierarchies) { 2294 HierarchyBase hierarchy = 2295 (HierarchyBase) hierarchy1; 2296 ordinalPosition = populateHierarchy( 2297 schemaReader, cube, hierarchy, 2298 ordinalPosition, rows); 2299 } 2300 } 2301 2302 RolapMember[] rms = cube.getMeasuresMembers(); 2303 for (int k = 1; k < rms.length; k++) { 2304 RolapMember member = rms[k]; 2305 2306 Boolean isVisible = (Boolean ) 2310 member.getPropertyValue(Property.VISIBLE.name); 2311 if (isVisible != null && !isVisible) { 2312 continue; 2313 } 2314 2315 String memberName = member.getName(); 2316 if (!columnNameRT.passes("Measures:" + memberName)) { 2317 continue; 2318 } 2319 2320 row = new Row(); 2321 row.set(TableCatalog.name, catalogName); 2322 row.set(TableName.name, cubeName); 2323 row.set(ColumnName.name, "Measures:" + memberName); 2324 row.set(OrdinalPosition.name, ordinalPosition++); 2325 row.set(ColumnHasDefault.name, false); 2326 row.set(ColumnFlags.name, 0); 2327 row.set(IsNullable.name, false); 2328 row.set(DataType.name, DBType.R8.userOrdinal); 2333 row.set(NumericPrecision.name, 16); 2336 row.set(NumericScale.name, 255); 2337 addRow(row, rows); 2338 } 2339 } 2340 } 2341 } 2342 2343 private int populateHierarchy( 2344 SchemaReader schemaReader, 2345 RolapCube cube, 2346 HierarchyBase hierarchy, 2347 int ordinalPosition, 2348 List<Row> rows) { 2349 2350 if (!canAccess(schemaReader, hierarchy)) { 2352 return ordinalPosition; 2353 } 2354 String schemaName = cube.getSchema().getName(); 2355 String cubeName = cube.getName(); 2356 String hierarchyName = hierarchy.getName(); 2357 2358 if (hierarchy.hasAll()) { 2359 Row row = new Row(); 2360 row.set(TableCatalog.name, schemaName); 2361 row.set(TableName.name, cubeName); 2362 row.set(ColumnName.name, hierarchyName + ":(All)!NAME"); 2363 row.set(OrdinalPosition.name, ordinalPosition++); 2364 row.set(ColumnHasDefault.name, false); 2365 row.set(ColumnFlags.name, 0); 2366 row.set(IsNullable.name, false); 2367 row.set(DataType.name, DBType.WSTR.userOrdinal); 2369 row.set(CharacterMaximumLength.name, 0); 2370 row.set(CharacterOctetLength.name, 0); 2371 addRow(row, rows); 2372 2373 row = new Row(); 2374 row.set(TableCatalog.name, schemaName); 2375 row.set(TableName.name, cubeName); 2376 row.set(ColumnName.name, hierarchyName + ":(All)!UNIQUE_NAME"); 2377 row.set(OrdinalPosition.name, ordinalPosition++); 2378 row.set(ColumnHasDefault.name, false); 2379 row.set(ColumnFlags.name, 0); 2380 row.set(IsNullable.name, false); 2381 row.set(DataType.name, DBType.WSTR.userOrdinal); 2383 row.set(CharacterMaximumLength.name, 0); 2384 row.set(CharacterOctetLength.name, 0); 2385 addRow(row, rows); 2386 2387 if (false) { 2388 row = new Row(); 2391 row.set(TableCatalog.name, schemaName); 2392 row.set(TableName.name, cubeName); 2393 row.set(ColumnName.name, hierarchyName + ":(All)!KEY"); 2394 row.set(OrdinalPosition.name, ordinalPosition++); 2395 row.set(ColumnHasDefault.name, false); 2396 row.set(ColumnFlags.name, 0); 2397 row.set(IsNullable.name, false); 2398 row.set(DataType.name, DBType.BOOL.userOrdinal); 2400 row.set(NumericPrecision.name, 255); 2401 row.set(NumericScale.name, 255); 2402 addRow(row, rows); 2403 } 2404 } 2405 2406 Level[] levels = hierarchy.getLevels(); 2407 for (Level level : levels) { 2408 ordinalPosition = populateLevel( 2409 cube, hierarchy, level, ordinalPosition, rows); 2410 } 2411 return ordinalPosition; 2412 } 2413 2414 private int populateLevel( 2415 Cube cube, 2416 HierarchyBase hierarchy, 2417 Level level, 2418 int ordinalPosition, List<Row> rows) { 2419 2420 String schemaName = cube.getSchema().getName(); 2421 String cubeName = cube.getName(); 2422 String hierarchyName = hierarchy.getName(); 2423 String levelName = level.getName(); 2424 2425 Row row = new Row(); 2426 row.set(TableCatalog.name, schemaName); 2427 row.set(TableName.name, cubeName); 2428 row.set(ColumnName.name, 2429 hierarchyName + ':' + levelName + "!NAME"); 2430 row.set(OrdinalPosition.name, ordinalPosition++); 2431 row.set(ColumnHasDefault.name, false); 2432 row.set(ColumnFlags.name, 0); 2433 row.set(IsNullable.name, false); 2434 row.set(DataType.name, DBType.WSTR.userOrdinal); 2436 row.set(CharacterMaximumLength.name, 0); 2437 row.set(CharacterOctetLength.name, 0); 2438 addRow(row, rows); 2439 2440 row = new Row(); 2441 row.set(TableCatalog.name, schemaName); 2442 row.set(TableName.name, cubeName); 2443 row.set(ColumnName.name, 2444 hierarchyName + ':' + levelName + "!UNIQUE_NAME"); 2445 row.set(OrdinalPosition.name, ordinalPosition++); 2446 row.set(ColumnHasDefault.name, false); 2447 row.set(ColumnFlags.name, 0); 2448 row.set(IsNullable.name, false); 2449 row.set(DataType.name, DBType.WSTR.userOrdinal); 2451 row.set(CharacterMaximumLength.name, 0); 2452 row.set(CharacterOctetLength.name, 0); 2453 addRow(row, rows); 2454 2455 2472 Property[] props = level.getProperties(); 2473 for (Property prop : props) { 2474 String propName = prop.getName(); 2475 2476 row = new Row(); 2477 row.set(TableCatalog.name, schemaName); 2478 row.set(TableName.name, cubeName); 2479 row.set(ColumnName.name, 2480 hierarchyName + ':' + levelName + '!' + propName); 2481 row.set(OrdinalPosition.name, ordinalPosition++); 2482 row.set(ColumnHasDefault.name, false); 2483 row.set(ColumnFlags.name, 0); 2484 row.set(IsNullable.name, false); 2485 2486 DBType dbType = getDBTypeFromProperty(prop); 2487 row.set(DataType.name, dbType.userOrdinal); 2488 2489 switch (prop.getType()) { 2490 case TYPE_STRING: 2491 row.set(CharacterMaximumLength.name, 0); 2492 row.set(CharacterOctetLength.name, 0); 2493 break; 2494 case TYPE_NUMERIC: 2495 row.set(NumericPrecision.name, 16); 2498 row.set(NumericScale.name, 255); 2499 break; 2500 case TYPE_BOOLEAN: 2501 row.set(NumericPrecision.name, 255); 2502 row.set(NumericScale.name, 255); 2503 break; 2504 case TYPE_OTHER: 2505 row.set(CharacterMaximumLength.name, 0); 2508 row.set(CharacterOctetLength.name, 0); 2509 break; 2510 } 2511 addRow(row, rows); 2512 } 2513 return ordinalPosition; 2514 } 2515 protected void setProperty(PropertyDefinition propertyDef, String value) { 2516 switch (propertyDef) { 2517 case Content: 2518 break; 2519 default: 2520 super.setProperty(propertyDef, value); 2521 } 2522 } 2523 } 2524 2525 static class DbschemaProviderTypesRowset extends Rowset { 2526 private final RestrictionTest dataTypeRT; 2527 DbschemaProviderTypesRowset(XmlaRequest request, XmlaHandler handler) { 2528 super(DBSCHEMA_PROVIDER_TYPES, request, handler); 2529 dataTypeRT = getRestrictionTest(DataType); 2530 } 2531 2532 2538 2541 private static final Column TypeName = 2542 new Column( 2543 "TYPE_NAME", 2544 Type.String, 2545 null, 2546 Column.NOT_RESTRICTION, 2547 Column.REQUIRED, 2548 "The provider-specific data type name."); 2549 private static final Column DataType = 2550 new Column( 2551 "DATA_TYPE", 2552 Type.UnsignedShort, 2553 null, 2554 Column.RESTRICTION, 2555 Column.REQUIRED, 2556 "The indicator of the data type."); 2557 private static final Column ColumnSize = 2558 new Column( 2559 "COLUMN_SIZE", 2560 Type.UnsignedInteger, 2561 null, 2562 Column.NOT_RESTRICTION, 2563 Column.REQUIRED, 2564 "The length of a non-numeric column. If the data type is numeric, this is the upper bound on the maximum precision of the data type."); 2565 private static final Column LiteralPrefix = 2566 new Column( 2567 "LITERAL_PREFIX", 2568 Type.String, 2569 null, 2570 Column.NOT_RESTRICTION, 2571 Column.OPTIONAL, 2572 "The character or characters used to prefix a literal of this type in a text command."); 2573 private static final Column LiteralSuffix = 2574 new Column( 2575 "LITERAL_SUFFIX", 2576 Type.String, 2577 null, 2578 Column.NOT_RESTRICTION, 2579 Column.OPTIONAL, 2580 "The character or characters used to suffix a literal of this type in a text command."); 2581 private static final Column IsNullable = 2582 new Column( 2583 "IS_NULLABLE", 2584 Type.Boolean, 2585 null, 2586 Column.NOT_RESTRICTION, 2587 Column.OPTIONAL, 2588 "A Boolean that indicates whether the data type is nullable. NULL-- indicates that it is not known whether the data type is nullable."); 2589 private static final Column CaseSensitive = 2590 new Column( 2591 "CASE_SENSITIVE", 2592 Type.Boolean, 2593 null, 2594 Column.NOT_RESTRICTION, 2595 Column.OPTIONAL, 2596 "A Boolean that indicates whether the data type is a characters type and case-sensitive."); 2597 private static final Column Searchable = 2598 new Column( 2599 "SEARCHABLE", 2600 Type.UnsignedInteger, 2601 null, 2602 Column.NOT_RESTRICTION, 2603 Column.OPTIONAL, 2604 "An integer indicating how the data type can be used in searches if the provider supports ICommandText; otherwise, NULL."); 2605 private static final Column UnsignedAttribute = 2606 new Column( 2607 "UNSIGNED_ATTRIBUTE", 2608 Type.Boolean, 2609 null, 2610 Column.NOT_RESTRICTION, 2611 Column.OPTIONAL, 2612 "A Boolean that indicates whether the data type is unsigned."); 2613 private static final Column FixedPrecScale = 2614 new Column( 2615 "FIXED_PREC_SCALE", 2616 Type.Boolean, 2617 null, 2618 Column.NOT_RESTRICTION, 2619 Column.OPTIONAL, 2620 "A Boolean that indicates whether the data type has a fixed precision and scale."); 2621 private static final Column AutoUniqueValue = 2622 new Column( 2623 "AUTO_UNIQUE_VALUE", 2624 Type.Boolean, 2625 null, 2626 Column.NOT_RESTRICTION, 2627 Column.OPTIONAL, 2628 "A Boolean that indicates whether the data type is autoincrementing."); 2629 private static final Column IsLong = 2630 new Column( 2631 "IS_LONG", 2632 Type.Boolean, 2633 null, 2634 Column.NOT_RESTRICTION, 2635 Column.OPTIONAL, 2636 "A Boolean that indicates whether the data type is a binary large object (BLOB) and has very long data."); 2637 private static final Column BestMatch = 2638 new Column( 2639 "BEST_MATCH", 2640 Type.Boolean, 2641 null, 2642 Column.RESTRICTION, 2643 Column.OPTIONAL, 2644 "A Boolean that indicates whether the data type is a best match."); 2645 2646 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 2647 Row row; 2649 2650 Integer dt = DBType.I4.userOrdinal; 2652 if (dataTypeRT.passes(dt)) { 2653 row = new Row(); 2654 row.set(TypeName.name, DBType.I4.userName); 2655 row.set(DataType.name, dt); 2656 row.set(ColumnSize.name, 8); 2657 row.set(IsNullable.name, true); 2658 row.set(Searchable.name, null); 2659 row.set(UnsignedAttribute.name, false); 2660 row.set(FixedPrecScale.name, false); 2661 row.set(AutoUniqueValue.name, false); 2662 row.set(IsLong.name, false); 2663 row.set(BestMatch.name, true); 2664 addRow(row, rows); 2665 } 2666 2667 dt = DBType.R8.userOrdinal; 2669 if (dataTypeRT.passes(dt)) { 2670 row = new Row(); 2671 row.set(TypeName.name, DBType.R8.userName); 2672 row.set(DataType.name, dt); 2673 row.set(ColumnSize.name, 16); 2674 row.set(IsNullable.name, true); 2675 row.set(Searchable.name, null); 2676 row.set(UnsignedAttribute.name, false); 2677 row.set(FixedPrecScale.name, false); 2678 row.set(AutoUniqueValue.name, false); 2679 row.set(IsLong.name, false); 2680 row.set(BestMatch.name, true); 2681 addRow(row, rows); 2682 } 2683 2684 dt = DBType.CY.userOrdinal; 2686 if (dataTypeRT.passes(dt)) { 2687 row = new Row(); 2688 row.set(TypeName.name, DBType.CY.userName); 2689 row.set(DataType.name, dt); 2690 row.set(ColumnSize.name, 8); 2691 row.set(IsNullable.name, true); 2692 row.set(Searchable.name, null); 2693 row.set(UnsignedAttribute.name, false); 2694 row.set(FixedPrecScale.name, false); 2695 row.set(AutoUniqueValue.name, false); 2696 row.set(IsLong.name, false); 2697 row.set(BestMatch.name, true); 2698 addRow(row, rows); 2699 } 2700 2701 dt = DBType.BOOL.userOrdinal; 2703 if (dataTypeRT.passes(dt)) { 2704 row = new Row(); 2705 row.set(TypeName.name, DBType.BOOL.userName); 2706 row.set(DataType.name, dt); 2707 row.set(ColumnSize.name, 1); 2708 row.set(IsNullable.name, true); 2709 row.set(Searchable.name, null); 2710 row.set(UnsignedAttribute.name, false); 2711 row.set(FixedPrecScale.name, false); 2712 row.set(AutoUniqueValue.name, false); 2713 row.set(IsLong.name, false); 2714 row.set(BestMatch.name, true); 2715 addRow(row, rows); 2716 } 2717 2718 dt = DBType.I8.userOrdinal; 2720 if (dataTypeRT.passes(dt)) { 2721 row = new Row(); 2722 row.set(TypeName.name, DBType.I8.userName); 2723 row.set(DataType.name, dt); 2724 row.set(ColumnSize.name, 16); 2725 row.set(IsNullable.name, true); 2726 row.set(Searchable.name, null); 2727 row.set(UnsignedAttribute.name, false); 2728 row.set(FixedPrecScale.name, false); 2729 row.set(AutoUniqueValue.name, false); 2730 row.set(IsLong.name, false); 2731 row.set(BestMatch.name, true); 2732 addRow(row, rows); 2733 } 2734 2735 dt = DBType.WSTR.userOrdinal; 2737 if (dataTypeRT.passes(dt)) { 2738 row = new Row(); 2739 row.set(TypeName.name, DBType.WSTR.userName); 2740 row.set(DataType.name, dt); 2741 row.set(ColumnSize.name, 255); 2743 row.set(LiteralPrefix.name, "\""); 2744 row.set(LiteralSuffix.name, "\""); 2745 row.set(IsNullable.name, true); 2746 row.set(CaseSensitive.name, false); 2747 row.set(Searchable.name, null); 2748 row.set(FixedPrecScale.name, false); 2749 row.set(AutoUniqueValue.name, false); 2750 row.set(IsLong.name, false); 2751 row.set(BestMatch.name, true); 2752 addRow(row, rows); 2753 } 2754 } 2755 protected void setProperty(PropertyDefinition propertyDef, String value) { 2756 switch (propertyDef) { 2757 case Content: 2758 break; 2759 default: 2760 super.setProperty(propertyDef, value); 2761 } 2762 } 2763 } 2764 2765 static class DbschemaTablesRowset extends Rowset { 2766 private final RestrictionTest tableCatalogRT; 2767 private final RestrictionTest tableNameRT; 2768 private final RestrictionTest tableTypeRT; 2769 DbschemaTablesRowset(XmlaRequest request, XmlaHandler handler) { 2770 super(DBSCHEMA_TABLES, request, handler); 2771 tableCatalogRT = getRestrictionTest(TableCatalog); 2772 tableNameRT = getRestrictionTest(TableName); 2773 tableTypeRT = getRestrictionTest(TableType); 2774 } 2775 2776 private static final Column TableCatalog = 2777 new Column( 2778 "TABLE_CATALOG", 2779 Type.String, 2780 null, 2781 Column.RESTRICTION, 2782 Column.REQUIRED, 2783 "The name of the catalog to which this object belongs."); 2784 private static final Column TableSchema = 2785 new Column( 2786 "TABLE_SCHEMA", 2787 Type.String, 2788 null, 2789 Column.RESTRICTION, 2790 Column.OPTIONAL, 2791 "The name of the cube to which this object belongs."); 2792 private static final Column TableName = 2793 new Column( 2794 "TABLE_NAME", 2795 Type.String, 2796 null, 2797 Column.RESTRICTION, 2798 Column.REQUIRED, 2799 "The name of the object, if TABLE_TYPE is TABLE."); 2800 private static final Column TableType = 2801 new Column( 2802 "TABLE_TYPE", 2803 Type.String, 2804 null, 2805 Column.RESTRICTION, 2806 Column.REQUIRED, 2807 "The type of the table. TABLE indicates the object is a measure group. SYSTEM TABLE indicates the object is a dimension."); 2808 2809 private static final Column TableGuid = 2810 new Column( 2811 "TABLE_GUID", 2812 Type.UUID, 2813 null, 2814 Column.NOT_RESTRICTION, 2815 Column.OPTIONAL, 2816 "Not supported."); 2817 private static final Column Description = 2818 new Column( 2819 "DESCRIPTION", 2820 Type.String, 2821 null, 2822 Column.NOT_RESTRICTION, 2823 Column.OPTIONAL, 2824 "A human-readable description of the object."); 2825 private static final Column TablePropId = 2826 new Column( 2827 "TABLE_PROPID", 2828 Type.UnsignedInteger, 2829 null, 2830 Column.NOT_RESTRICTION, 2831 Column.OPTIONAL, 2832 "Not supported."); 2833 private static final Column DateCreated = 2834 new Column( 2835 "DATE_CREATED", 2836 Type.DateTime, 2837 null, 2838 Column.NOT_RESTRICTION, 2839 Column.OPTIONAL, 2840 "Not supported."); 2841 private static final Column DateModified = 2842 new Column( 2843 "DATE_MODIFIED", 2844 Type.DateTime, 2845 null, 2846 Column.NOT_RESTRICTION, 2847 Column.OPTIONAL, 2848 "The date the object was last modified."); 2849 2850 2860 2861 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 2862 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 2863 DataSourcesConfig.Catalog[] catalogs = 2864 handler.getCatalogs(request, ds); 2865 String roleStr = request.getRole(); 2866 2867 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 2868 if (dsCatalog == null || dsCatalog.definition == null) { 2869 continue; 2870 } 2871 Connection connection = 2872 handler.getConnection(dsCatalog, roleStr); 2873 if (connection == null) { 2874 continue; 2875 } 2876 Role role = connection.getSchema().lookupRole(roleStr); 2877 final RolapSchema schema = (RolapSchema) connection.getSchema(); 2878 String catalogName = dsCatalog.name; 2879 if (!tableCatalogRT.passes(catalogName)) { 2880 continue; 2881 } 2882 2883 2885 Row row; 2886 for (Cube cube1 : sortedCubes(schema)) { 2887 RolapCube cube = (RolapCube) cube1; 2888 String cubeName = cube.getName(); 2889 2890 String tableName = cubeName; 2891 if (!tableNameRT.passes(tableName)) { 2892 continue; 2893 } 2894 SchemaReader schemaReader = cube.getSchemaReader(role); 2895 2896 String desc = cube.getDescription(); 2897 if (desc == null) { 2898 desc = catalogName + " - " + cubeName + " Cube"; 2900 } 2901 2902 2903 if (tableTypeRT.passes("TABLE")) { 2904 row = new Row(); 2905 row.set(TableCatalog.name, catalogName); 2906 row.set(TableName.name, tableName); 2907 row.set(TableType.name, "TABLE"); 2908 row.set(Description.name, desc); 2909 if (false) { 2910 row.set(DateModified.name, dateModified); 2911 } 2912 addRow(row, rows); 2913 } 2914 2915 2916 if (tableTypeRT.passes("SYSTEM TABLE")) { 2917 for (Dimension dimension : cube.getDimensions()) { 2918 if (dimension.isMeasures()) { 2919 continue; 2920 } 2921 Hierarchy[] hierarchies = 2922 dimension.getHierarchies(); 2923 for (Hierarchy hierarchy1 : hierarchies) { 2924 HierarchyBase hierarchy = 2925 (HierarchyBase) hierarchy1; 2926 populateHierarchy(schemaReader, cube, 2927 hierarchy, rows); 2928 } 2929 } 2930 } 2931 } 2932 } 2933 } 2934 2935 private void populateHierarchy( 2936 SchemaReader schemaReader, 2937 RolapCube cube, 2938 HierarchyBase hierarchy, 2939 List<Row> rows) { 2940 2941 if (!canAccess(schemaReader, hierarchy)) { 2943 return; 2944 } 2945 2974 Level[] levels = hierarchy.getLevels(); 2975 for (Level level : levels) { 2976 populateLevel(cube, hierarchy, level, rows); 2977 } 2978 } 2979 2980 private void populateLevel( 2981 RolapCube cube, 2982 HierarchyBase hierarchy, 2983 Level level, 2984 List<Row> rows) { 2985 2986 String schemaName = cube.getSchema().getName(); 2987 String cubeName = cube.getName(); 2988 String hierarchyName = hierarchy.getName(); 2989 String levelName = level.getName(); 2990 2991 String tableName = cubeName + 2992 ':' + hierarchyName + ':' + levelName; 2993 2994 String desc = level.getDescription(); 2995 if (desc == null) { 2996 desc = schemaName + 2998 " - " + 2999 cubeName + 3000 " Cube - " + 3001 hierarchyName + 3002 " Hierarchy - " + 3003 levelName + 3004 " Level"; 3005 } 3006 3007 Row row = new Row(); 3008 row.set(TableCatalog.name, schemaName); 3009 row.set(TableName.name, tableName); 3010 row.set(TableType.name, "SYSTEM TABLE"); 3011 row.set(Description.name, desc); 3012 if (false) row.set(DateModified.name, dateModified); 3013 addRow(row, rows); 3014 } 3015 3016 protected void setProperty(PropertyDefinition propertyDef, String value) { 3017 switch (propertyDef) { 3018 case Content: 3019 break; 3020 default: 3021 super.setProperty(propertyDef, value); 3022 } 3023 } 3024 } 3025 3026 static class DbschemaTablesInfoRowset extends Rowset { 3028 DbschemaTablesInfoRowset(XmlaRequest request, XmlaHandler handler) { 3029 super(DBSCHEMA_TABLES_INFO, request, handler); 3030 } 3031 3032 private static final Column TableCatalog = 3033 new Column( 3034 "TABLE_CATALOG", 3035 Type.String, 3036 null, 3037 Column.RESTRICTION, 3038 Column.OPTIONAL, 3039 "Catalog name. NULL if the provider does not support catalogs."); 3040 private static final Column TableSchema = 3041 new Column( 3042 "TABLE_SCHEMA", 3043 Type.String, 3044 null, 3045 Column.RESTRICTION, 3046 Column.OPTIONAL, 3047 "Unqualified schema name. NULL if the provider does not support schemas."); 3048 private static final Column TableName = 3049 new Column( 3050 "TABLE_NAME", 3051 Type.String, 3052 null, 3053 Column.RESTRICTION, 3054 Column.REQUIRED, 3055 "Table name."); 3056 private static final Column TableType = 3057 new Column( 3058 "TABLE_TYPE", 3059 Type.String, 3060 null, 3061 Column.RESTRICTION, 3062 Column.REQUIRED, 3063 "Table type. One of the following or a provider-specific value: ALIAS, TABLE, SYNONYM, SYSTEM TABLE, VIEW, GLOBAL TEMPORARY, LOCAL TEMPORARY, EXTERNAL TABLE, SYSTEM VIEW"); 3064 private static final Column TableGuid = 3065 new Column( 3066 "TABLE_GUID", 3067 Type.UUID, 3068 null, 3069 Column.NOT_RESTRICTION, 3070 Column.OPTIONAL, 3071 "GUID that uniquely identifies the table. Providers that do not use GUIDs to identify tables should return NULL in this column."); 3072 3073 private static final Column Bookmarks = 3074 new Column( 3075 "BOOKMARKS", 3076 Type.Boolean, 3077 null, 3078 Column.NOT_RESTRICTION, 3079 Column.REQUIRED, 3080 "Whether this table supports bookmarks. Allways is false."); 3081 private static final Column BookmarkType = 3082 new Column( 3083 "BOOKMARK_TYPE", 3084 Type.Integer, 3085 null, 3086 Column.NOT_RESTRICTION, 3087 Column.OPTIONAL, 3088 "Default bookmark type supported on this table."); 3089 private static final Column BookmarkDataType = 3090 new Column( 3091 "BOOKMARK_DATATYPE", 3092 Type.UnsignedShort, 3093 null, 3094 Column.NOT_RESTRICTION, 3095 Column.OPTIONAL, 3096 "The indicator of the bookmark's native data type."); 3097 private static final Column BookmarkMaximumLength = 3098 new Column( 3099 "BOOKMARK_MAXIMUM_LENGTH", 3100 Type.UnsignedInteger, 3101 null, 3102 Column.NOT_RESTRICTION, 3103 Column.OPTIONAL, 3104 "Maximum length of the bookmark in bytes."); 3105 private static final Column BookmarkInformation = 3106 new Column( 3107 "BOOKMARK_INFORMATION", 3108 Type.UnsignedInteger, 3109 null, 3110 Column.NOT_RESTRICTION, 3111 Column.OPTIONAL, 3112 "A bitmask specifying additional information about bookmarks over the rowset. "); 3113 private static final Column TableVersion = 3114 new Column( 3115 "TABLE_VERSION", 3116 Type.Long, 3117 null, 3118 Column.NOT_RESTRICTION, 3119 Column.OPTIONAL, 3120 "Version number for this table or NULL if the provider does not support returning table version information."); 3121 private static final Column Cardinality = 3122 new Column( 3123 "CARDINALITY", 3124 Type.UnsignedLong, 3125 null, 3126 Column.NOT_RESTRICTION, 3127 Column.REQUIRED, 3128 "Cardinality (number of rows) of the table."); 3129 private static final Column Description = 3130 new Column( 3131 "DESCRIPTION", 3132 Type.String, 3133 null, 3134 Column.NOT_RESTRICTION, 3135 Column.OPTIONAL, 3136 "Human-readable description of the table."); 3137 private static final Column TablePropId = 3138 new Column( 3139 "TABLE_PROPID", 3140 Type.UnsignedInteger, 3141 null, 3142 Column.NOT_RESTRICTION, 3143 Column.OPTIONAL, 3144 "Property ID of the table. Return null."); 3145 3146 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 3147 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 3148 DataSourcesConfig.Catalog[] catalogs = 3149 handler.getCatalogs(request, ds); 3150 String role = request.getRole(); 3151 3152 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 3153 if (dsCatalog == null || dsCatalog.definition == null) { 3154 continue; 3155 } 3156 Connection connection = handler.getConnection(dsCatalog, role); 3157 if (connection == null) { 3158 continue; 3159 } 3160 final RolapSchema schema = (RolapSchema) connection.getSchema(); 3161 String catalogName = dsCatalog.name; 3162 3164 for (Cube cube1 : sortedCubes(schema)) { 3168 RolapCube cube = (RolapCube) cube1; 3169 String cubeName = cube.getName(); 3170 String desc = cube.getDescription(); 3171 if (desc == null) { 3172 desc = catalogName + " - " + cubeName + " Cube"; 3174 } 3175 int cardinality = 1000000; 3177 String version = "null"; 3178 3179 Row row = new Row(); 3180 row.set(TableCatalog.name, catalogName); 3181 row.set(TableName.name, cubeName); 3182 row.set(TableType.name, "TABLE"); 3183 row.set(Bookmarks.name, false); 3184 row.set(TableVersion.name, version); 3185 row.set(Cardinality.name, cardinality); 3186 row.set(Description.name, desc); 3187 addRow(row, rows); 3188 } 3189 } 3190 } 3191 protected void setProperty(PropertyDefinition propertyDef, String value) { 3192 switch (propertyDef) { 3193 case Content: 3194 break; 3195 default: 3196 super.setProperty(propertyDef, value); 3197 } 3198 } 3199 } 3200 3201 static class MdschemaActionsRowset extends Rowset { 3202 MdschemaActionsRowset(XmlaRequest request, XmlaHandler handler) { 3203 super(MDSCHEMA_ACTIONS, request, handler); 3204 } 3205 3206 private static final Column CubeName = 3207 new Column( 3208 "CUBE_NAME", 3209 Type.String, 3210 null, 3211 Column.RESTRICTION, 3212 Column.REQUIRED, 3213 null); 3214 private static final Column Coordinate = 3215 new Column( 3216 "COORDINATE", 3217 Type.String, 3218 null, 3219 Column.RESTRICTION, 3220 Column.REQUIRED, 3221 null); 3222 private static final Column CoordinateType = 3223 new Column( 3224 "COORDINATE_TYPE", 3225 Type.Integer, 3226 null, 3227 Column.RESTRICTION, 3228 Column.REQUIRED, 3229 null); 3230 3238 3239 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 3240 throw new XmlaException( 3241 CLIENT_FAULT_FC, 3242 HSB_UNSUPPORTED_OPERATION_CODE, 3243 HSB_UNSUPPORTED_OPERATION_FAULT_FS, 3244 new UnsupportedOperationException ("MDSCHEMA_ACTIONS")); 3245 } 3246 } 3247 3248 static class MdschemaCubesRowset extends Rowset { 3250 private final RestrictionTest catalogNameRT; 3251 private final RestrictionTest cubeNameRT; 3252 MdschemaCubesRowset(XmlaRequest request, XmlaHandler handler) { 3253 super(MDSCHEMA_CUBES, request, handler); 3254 catalogNameRT = getRestrictionTest(CatalogName); 3255 cubeNameRT = getRestrictionTest(CubeName); 3256 } 3257 3258 private static final String MD_CUBTYPE_CUBE = "CUBE"; 3259 private static final String MD_CUBTYPE_VIRTUAL_CUBE = "VIRTUAL CUBE"; 3260 3261 private static final Column CatalogName = 3262 new Column( 3263 "CATALOG_NAME", 3264 Type.String, 3265 null, 3266 Column.RESTRICTION, 3267 Column.OPTIONAL, 3268 "The name of the catalog to which this cube belongs."); 3269 private static final Column SchemaName = 3270 new Column( 3271 "SCHEMA_NAME", 3272 Type.String, 3273 null, 3274 Column.RESTRICTION, 3275 Column.OPTIONAL, 3276 "The name of the schema to which this cube belongs."); 3277 private static final Column CubeName = 3278 new Column( 3279 "CUBE_NAME", 3280 Type.String, 3281 null, 3282 Column.RESTRICTION, 3283 Column.REQUIRED, 3284 "Name of the cube."); 3285 private static final Column CubeType = 3286 new Column( 3287 "CUBE_TYPE", 3288 Type.String, 3289 null, 3290 Column.RESTRICTION, 3291 Column.REQUIRED, 3292 "Cube type."); 3293 private static final Column CubeGuid = 3294 new Column( 3295 "CUBE_GUID", 3296 Type.UUID, 3297 null, 3298 Column.NOT_RESTRICTION, 3299 Column.OPTIONAL, 3300 "Cube type."); 3301 private static final Column CreatedOn = 3302 new Column( 3303 "CREATED_ON", 3304 Type.DateTime, 3305 null, 3306 Column.NOT_RESTRICTION, 3307 Column.OPTIONAL, 3308 "Date and time of cube creation."); 3309 private static final Column LastSchemaUpdate = 3310 new Column( 3311 "LAST_SCHEMA_UPDATE", 3312 Type.DateTime, 3313 null, 3314 Column.NOT_RESTRICTION, 3315 Column.OPTIONAL, 3316 "Date and time of last schema update."); 3317 private static final Column SchemaUpdatedBy = 3318 new Column( 3319 "SCHEMA_UPDATED_BY", 3320 Type.String, 3321 null, 3322 Column.NOT_RESTRICTION, 3323 Column.OPTIONAL, 3324 "User ID of the person who last updated the schema."); 3325 private static final Column LastDataUpdate = 3326 new Column( 3327 "LAST_DATA_UPDATE", 3328 Type.DateTime, 3329 null, 3330 Column.NOT_RESTRICTION, 3331 Column.OPTIONAL, 3332 "Date and time of last data update."); 3333 private static final Column DataUpdatedBy = 3334 new Column( 3335 "DATA_UPDATED_BY", 3336 Type.String, 3337 null, 3338 Column.NOT_RESTRICTION, 3339 Column.OPTIONAL, 3340 "User ID of the person who last updated the data. "); 3341 private static final Column IsDrillthroughEnabled = 3342 new Column( 3343 "IS_DRILLTHROUGH_ENABLED", 3344 Type.Boolean, 3345 null, 3346 Column.NOT_RESTRICTION, 3347 Column.REQUIRED, 3348 "Describes whether DRILLTHROUGH can be performed on the members of a cube"); 3349 private static final Column IsWriteEnabled = 3350 new Column( 3351 "IS_WRITE_ENABLED", 3352 Type.Boolean, 3353 null, 3354 Column.NOT_RESTRICTION, 3355 Column.REQUIRED, 3356 "Describes whether a cube is write-enabled"); 3357 private static final Column IsLinkable = 3358 new Column( 3359 "IS_LINKABLE", 3360 Type.Boolean, 3361 null, 3362 Column.NOT_RESTRICTION, 3363 Column.REQUIRED, 3364 "Describes whether a cube can be used in a linked cube"); 3365 private static final Column IsSqlEnabled = 3366 new Column( 3367 "IS_SQL_ENABLED", 3368 Type.Boolean, 3369 null, 3370 Column.NOT_RESTRICTION, 3371 Column.REQUIRED, 3372 "Describes whether or not SQL can be used on the cube"); 3373 private static final Column Description = 3374 new Column( 3375 "DESCRIPTION", 3376 Type.String, 3377 null, 3378 Column.NOT_RESTRICTION, 3379 Column.OPTIONAL, 3380 "A user-friendly description of the dimension."); 3381 3382 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 3383 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 3384 DataSourcesConfig.Catalog[] catalogs = 3385 handler.getCatalogs(request, ds); 3386 String roleStr = request.getRole(); 3387 3388 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 3389 if (dsCatalog == null || dsCatalog.definition == null) { 3390 continue; 3391 } 3392 Connection connection = 3393 handler.getConnection(dsCatalog, roleStr); 3394 if (connection == null) { 3395 continue; 3396 } 3397 Role role = connection.getSchema().lookupRole(roleStr); 3398 String catalogName = dsCatalog.name; 3399 if (!catalogNameRT.passes(catalogName)) { 3400 continue; 3401 } 3402 3403 final RolapSchema schema = (RolapSchema) connection.getSchema(); 3404 3405 for (Cube cube : sortedCubes(schema)) { 3406 SchemaReader schemaReader = cube.getSchemaReader(role); 3407 if (!canAccess(schemaReader, cube)) { 3409 continue; 3410 } 3411 if (!cubeNameRT.passes(cube.getName())) { 3412 continue; 3413 } 3414 3415 String desc = cube.getDescription(); 3416 if (desc == null) { 3417 desc = catalogName + 3418 " Schema - " + 3419 cube.getName() + 3420 " Cube"; 3421 } 3422 3423 Row row = new Row(); 3424 row.set(CatalogName.name, catalogName); 3425 row.set(CubeName.name, cube.getName()); 3427 row.set(CubeType.name, 3428 ((RolapCube) cube).isVirtual() 3429 ? MD_CUBTYPE_VIRTUAL_CUBE : MD_CUBTYPE_CUBE); 3430 row.set(IsDrillthroughEnabled.name, true); 3437 row.set(IsWriteEnabled.name, false); 3438 row.set(IsLinkable.name, false); 3439 row.set(IsSqlEnabled.name, false); 3440 row.set(Description.name, desc); 3441 row.set(LastSchemaUpdate.name, lastUpdateDate(schema)); 3442 addRow(row, rows); 3443 } 3444 } 3445 } 3446 3447 private String lastUpdateDate(RolapSchema schema) { 3448 Format formatter = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss"); 3449 return formatter.format(schema.getSchemaLoadDate()); 3450 } 3451 3452 protected void setProperty(PropertyDefinition propertyDef, String value) { 3453 switch (propertyDef) { 3454 case Content: 3455 break; 3456 default: 3457 super.setProperty(propertyDef, value); 3458 } 3459 } 3460 } 3461 3462 static class MdschemaDimensionsRowset extends Rowset { 3464 private final RestrictionTest schemaNameRT; 3465 private final RestrictionTest cubeNameRT; 3466 private final RestrictionTest dimensionUniqueNameRT; 3467 private final RestrictionTest dimensionNameRT; 3468 MdschemaDimensionsRowset(XmlaRequest request, XmlaHandler handler) { 3469 super(MDSCHEMA_DIMENSIONS, request, handler); 3470 schemaNameRT = getRestrictionTest(SchemaName); 3471 cubeNameRT = getRestrictionTest(CubeName); 3472 dimensionUniqueNameRT = getRestrictionTest(DimensionUniqueName); 3473 dimensionNameRT = getRestrictionTest(DimensionName); 3474 } 3475 3476 public static final int MD_DIMTYPE_OTHER = 3; 3477 public static final int MD_DIMTYPE_MEASURE = 2; 3478 public static final int MD_DIMTYPE_TIME = 1; 3479 3480 private static final Column CatalogName = 3481 new Column( 3482 "CATALOG_NAME", 3483 Type.String, 3484 null, 3485 Column.RESTRICTION, 3486 Column.OPTIONAL, 3487 "The name of the database."); 3488 private static final Column SchemaName = 3489 new Column( 3490 "SCHEMA_NAME", 3491 Type.String, 3492 null, 3493 Column.RESTRICTION, 3494 Column.OPTIONAL, 3495 "Not supported."); 3496 private static final Column CubeName = 3497 new Column( 3498 "CUBE_NAME", 3499 Type.String, 3500 null, 3501 Column.RESTRICTION, 3502 Column.REQUIRED, 3503 "The name of the cube."); 3504 private static final Column DimensionName = 3505 new Column( 3506 "DIMENSION_NAME", 3507 Type.String, 3508 null, 3509 Column.RESTRICTION, 3510 Column.REQUIRED, 3511 "The name of the dimension. "); 3512 private static final Column DimensionUniqueName = 3513 new Column( 3514 "DIMENSION_UNIQUE_NAME", 3515 Type.String, 3516 null, 3517 Column.RESTRICTION, 3518 Column.REQUIRED, 3519 "The unique name of the dimension."); 3520 private static final Column DimensionGuid = 3521 new Column( 3522 "DIMENSION_GUID", 3523 Type.UUID, 3524 null, 3525 Column.NOT_RESTRICTION, 3526 Column.OPTIONAL, 3527 "Not supported."); 3528 private static final Column DimensionCaption = 3529 new Column( 3530 "DIMENSION_CAPTION", 3531 Type.String, 3532 null, 3533 Column.NOT_RESTRICTION, 3534 Column.REQUIRED, 3535 "The caption of the dimension."); 3536 private static final Column DimensionOrdinal = 3537 new Column( 3538 "DIMENSION_ORDINAL", 3539 Type.UnsignedInteger, 3540 null, 3541 Column.NOT_RESTRICTION, 3542 Column.REQUIRED, 3543 "The position of the dimension within the cube."); 3544 3550 private static final Column DimensionType = 3551 new Column( 3552 "DIMENSION_TYPE", 3553 Type.Short, 3554 null, 3555 Column.NOT_RESTRICTION, 3556 Column.REQUIRED, 3557 "The type of the dimension."); 3558 private static final Column DimensionCardinality = 3559 new Column( 3560 "DIMENSION_CARDINALITY", 3561 Type.UnsignedInteger, 3562 null, 3563 Column.NOT_RESTRICTION, 3564 Column.REQUIRED, 3565 "The number of members in the key attribute."); 3566 private static final Column DefaultHierarchy = 3567 new Column( 3568 "DEFAULT_HIERARCHY", 3569 Type.String, 3570 null, 3571 Column.NOT_RESTRICTION, 3572 Column.REQUIRED, 3573 "A hierarchy from the dimension. Preserved for backwards compatibility."); 3574 private static final Column Description = 3575 new Column( 3576 "DESCRIPTION", 3577 Type.String, 3578 null, 3579 Column.NOT_RESTRICTION, 3580 Column.OPTIONAL, 3581 "A user-friendly description of the dimension."); 3582 private static final Column IsVirtual = 3583 new Column( 3584 "IS_VIRTUAL", 3585 Type.Boolean, 3586 null, 3587 Column.NOT_RESTRICTION, 3588 Column.OPTIONAL, 3589 "Always FALSE."); 3590 private static final Column IsReadWrite = 3591 new Column("IS_READWRITE", 3592 Type.Boolean, 3593 null, 3594 Column.NOT_RESTRICTION, 3595 Column.OPTIONAL, 3596 "A Boolean that indicates whether the dimension is write-enabled."); 3597 3600 private static final Column DimensionUniqueSettings = 3601 new Column( 3602 "DIMENSION_UNIQUE_SETTINGS", 3603 Type.Integer, 3604 null, 3605 Column.NOT_RESTRICTION, 3606 Column.OPTIONAL, 3607 "A bitmap that specifies which columns contain unique values if the dimension contains only members with unique names."); 3608 private static final Column DimensionMasterUniqueName = 3609 new Column( 3610 "DIMENSION_MASTER_UNIQUE_NAME", 3611 Type.String, 3612 null, 3613 Column.NOT_RESTRICTION, 3614 Column.OPTIONAL, 3615 "Always NULL."); 3616 private static final Column DimensionIsVisible = 3617 new Column( 3618 "DIMENSION_IS_VISIBLE", 3619 Type.Boolean, 3620 null, 3621 Column.NOT_RESTRICTION, 3622 Column.OPTIONAL, 3623 "Always TRUE."); 3624 3625 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 3626 DataSourcesConfig.DataSource ds = 3627 handler.getDataSource(request); 3628 String roleStr = request.getRole(); 3629 DataSourcesConfig.Catalog[] catalogs = 3630 handler.getCatalogs(request, ds); 3631 3632 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 3633 if (dsCatalog == null || dsCatalog.definition == null) { 3634 continue; 3635 } 3636 String catalogName = dsCatalog.name; 3637 if (!schemaNameRT.passes(catalogName)) { 3638 continue; 3639 } 3640 3641 Connection connection = 3642 handler.getConnection(dsCatalog, roleStr); 3643 if (connection == null) { 3644 continue; 3645 } 3646 Role role = connection.getSchema().lookupRole(roleStr); 3647 populateCatalog(connection, role, catalogName, rows); 3648 } 3649 } 3650 protected void populateCatalog(Connection connection, 3651 Role role, 3652 String catalogName, 3653 List<Row> rows) 3654 throws XmlaException { 3655 3656 for (Cube cube : sortedCubes(connection.getSchema())) { 3657 if (!cubeNameRT.passes(cube.getName())) { 3658 continue; 3659 } 3660 SchemaReader schemaReader = cube.getSchemaReader(role); 3661 populateCube(schemaReader, catalogName, cube, rows); 3662 } 3663 } 3664 protected void populateCube(SchemaReader schemaReader, 3665 String catalogName, 3666 Cube cube, 3667 List<Row> rows) 3668 throws XmlaException { 3669 3670 for (Dimension dimension : cube.getDimensions()) { 3671 String name = dimension.getName(); 3672 String unique = dimension.getUniqueName(); 3673 if (dimensionNameRT.passes(name) && 3674 dimensionUniqueNameRT.passes(unique)) { 3675 populateDimension(schemaReader, catalogName, 3676 cube, dimension, rows); 3677 } 3678 } 3679 } 3680 protected void populateDimension(SchemaReader schemaReader, 3681 String catalogName, 3682 Cube cube, 3683 Dimension dimension, 3684 List<Row> rows) 3685 throws XmlaException { 3686 3687 if (!canAccess(schemaReader, dimension)) { 3689 return; 3690 } 3691 String desc = dimension.getDescription(); 3692 if (desc == null) { 3693 desc = cube.getName() + 3694 " Cube - " + 3695 dimension.getName() + 3696 " Dimension"; 3697 } 3698 3699 Row row = new Row(); 3700 row.set(CatalogName.name, catalogName); 3701 row.set(CubeName.name, cube.getName()); 3704 row.set(DimensionName.name, dimension.getName()); 3705 row.set(DimensionUniqueName.name, dimension.getUniqueName()); 3706 row.set(DimensionCaption.name, dimension.getCaption()); 3707 row.set(DimensionOrdinal.name, dimension.getOrdinal(cube)); 3708 row.set(DimensionType.name, getDimensionType(dimension)); 3709 3710 Hierarchy firstHierarchy = dimension.getHierarchies()[0]; 3721 Level[] levels = firstHierarchy.getLevels(); 3722 Level lastLevel = levels[levels.length-1]; 3723 3724 3725 3726 3733 3734 int n=schemaReader.getLevelCardinality(lastLevel, true, true); 3736 row.set(DimensionCardinality.name, n+1); 3737 3738 row.set(DefaultHierarchy.name, dimension.getUniqueName()); 3740 row.set(Description.name, desc); 3741 row.set(IsVirtual.name, false); 3742 row.set(IsReadWrite.name, false); 3744 row.set(DimensionUniqueSettings.name, 0); 3748 row.set(DimensionIsVisible.name, true); 3749 3750 addRow(row, rows); 3751 } 3752 3753 protected void setProperty(PropertyDefinition propertyDef, String value) { 3754 switch (propertyDef) { 3755 case Content: 3756 break; 3757 default: 3758 super.setProperty(propertyDef, value); 3759 } 3760 } 3761 } 3762 3763 static int getDimensionType(Dimension dim) { 3764 if (dim.isMeasures()) 3765 return MdschemaDimensionsRowset.MD_DIMTYPE_MEASURE; 3766 else if (DimensionType.TimeDimension.equals(dim.getDimensionType())) { 3767 return MdschemaDimensionsRowset.MD_DIMTYPE_TIME; 3768 } else { 3769 return MdschemaDimensionsRowset.MD_DIMTYPE_OTHER; 3770 } 3771 } 3772 3773 static class MdschemaFunctionsRowset extends Rowset { 3774 3777 enum VarType { 3778 Empty("Uninitialized (default)"), 3779 Null("Contains no valid data"), 3780 Integer("Integer subtype"), 3781 Long("Long subtype"), 3782 Single("Single subtype"), 3783 Double("Double subtype"), 3784 Currency("Currency subtype"), 3785 Date("Date subtype"), 3786 String("String subtype"), 3787 Object("Object subtype"), 3788 Error("Error subtype"), 3789 Boolean("Boolean subtype"), 3790 Variant("Variant subtype"), 3791 DataObject("DataObject subtype"), 3792 Decimal("Decimal subtype"), 3793 Byte("Byte subtype"), 3794 Array("Array subtype"); 3795 3796 static VarType forCategory(int category) { 3797 switch (category) { 3798 case Category.Unknown: 3799 return Empty; 3802 case Category.Array: 3803 return Array; 3804 case Category.Dimension: 3805 case Category.Hierarchy: 3806 case Category.Level: 3807 case Category.Member: 3808 case Category.Set: 3809 case Category.Tuple: 3810 case Category.Cube: 3811 case Category.Value: 3812 return Variant; 3813 case Category.Logical: 3814 return Boolean; 3815 case Category.Numeric: 3816 return Double; 3817 case Category.String: 3818 case Category.Symbol: 3819 case Category.Constant: 3820 return String; 3821 case Category.Integer: 3822 case Category.Mask: 3823 return Integer; 3824 } 3825 return Empty; 3827 } 3828 3829 VarType(String description) { 3830 Util.discard(description); 3831 } 3832 } 3833 3834 private final RestrictionTest functionNameRT; 3835 MdschemaFunctionsRowset(XmlaRequest request, XmlaHandler handler) { 3836 super(MDSCHEMA_FUNCTIONS, request, handler); 3837 functionNameRT = getRestrictionTest(FunctionName); 3838 } 3839 3840 private static final Column FunctionName = 3841 new Column( 3842 "FUNCTION_NAME", 3843 Type.String, 3844 null, 3845 Column.RESTRICTION, 3846 Column.REQUIRED, 3847 "The name of the function."); 3848 private static final Column Description = 3849 new Column( 3850 "DESCRIPTION", 3851 Type.String, 3852 null, 3853 Column.NOT_RESTRICTION, 3854 Column.OPTIONAL, 3855 "A description of the function."); 3856 private static final Column ParameterList = 3857 new Column( 3858 "PARAMETER_LIST", 3859 Type.String, 3860 null, 3861 Column.NOT_RESTRICTION, 3862 Column.OPTIONAL, 3863 "A comma delimited list of parameters."); 3864 private static final Column ReturnType = 3865 new Column( 3866 "RETURN_TYPE", 3867 Type.Integer, 3868 null, 3869 Column.NOT_RESTRICTION, 3870 Column.REQUIRED, 3871 "The VARTYPE of the return data type of the function."); 3872 private static final Column Origin = 3873 new Column( 3874 "ORIGIN", 3875 Type.Integer, 3876 null, 3877 Column.RESTRICTION, 3878 Column.REQUIRED, 3879 "The origin of the function: 1 for MDX functions. 2 for user-defined functions."); 3880 private static final Column InterfaceName = 3881 new Column( 3882 "INTERFACE_NAME", 3883 Type.String, 3884 null, 3885 Column.RESTRICTION, 3886 Column.REQUIRED, 3887 "The name of the interface for user-defined functions"); 3888 private static final Column LibraryName = 3889 new Column( 3890 "LIBRARY_NAME", 3891 Type.String, 3892 null, 3893 Column.RESTRICTION, 3894 Column.OPTIONAL, 3895 "The name of the type library for user-defined functions. NULL for MDX functions."); 3896 private static final Column Caption = 3897 new Column( 3898 "CAPTION", 3899 Type.String, 3900 null, 3901 Column.NOT_RESTRICTION, 3902 Column.OPTIONAL, 3903 "The display caption for the function."); 3904 3905 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 3906 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 3907 DataSourcesConfig.Catalog[] catalogs = 3908 handler.getCatalogs(request, ds); 3909 String role = request.getRole(); 3910 3911 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 3912 if (dsCatalog == null || dsCatalog.definition == null) { 3913 continue; 3914 } 3915 Connection connection = handler.getConnection(dsCatalog, role); 3916 if (connection == null) { 3917 continue; 3918 } 3919 final RolapSchema schema = (RolapSchema) connection.getSchema(); 3920 FunTable funTable = schema.getFunTable(); 3921 3922 StringBuilder buf = new StringBuilder (50); 3923 List<FunInfo> functions = funTable.getFunInfoList(); 3924 for (FunInfo fi : functions) { 3925 if (!functionNameRT.passes(fi.getName())) { 3926 continue; 3927 } 3928 3929 int[][] paramCategories = fi.getParameterCategories(); 3930 int[] returnCategories = fi.getReturnCategories(); 3931 3932 String description = fi.getDescription(); 3934 if (description != null) { 3935 description = Util.replace(fi.getDescription(), 3936 "\r", 3937 ""); 3938 } 3939 if ((paramCategories == null) || 3940 (paramCategories.length == 0)) { 3941 Row row = new Row(); 3942 row.set(FunctionName.name, fi.getName()); 3943 row.set(Description.name, description); 3944 row.set(ParameterList.name, "(none)"); 3945 row.set(ReturnType.name, 1); 3946 row.set(Origin.name, 1); 3947 row.set(InterfaceName.name, ""); 3950 row.set(Caption.name, fi.getName()); 3951 addRow(row, rows); 3952 3953 } else { 3954 for (int i = 0; i < paramCategories.length; i++) { 3955 int[] pc = paramCategories[i]; 3956 int returnCategory = returnCategories[i]; 3957 3958 Row row = new Row(); 3959 row.set(FunctionName.name, fi.getName()); 3960 row.set(Description.name, description); 3961 3962 buf.setLength(0); 3963 for (int j = 0; j < pc.length; j++) { 3964 int v = pc[j]; 3965 if (j > 0) { 3966 buf.append(", "); 3967 } 3968 buf.append(Category.instance.getDescription( 3969 v & Category.Mask)); 3970 } 3971 row.set(ParameterList.name, buf.toString()); 3972 3973 VarType varType = VarType.forCategory(returnCategory); 3974 row.set(ReturnType.name, varType.ordinal()); 3975 3976 row.set(Origin.name, 1); 3979 3980 3984 row.set(InterfaceName.name, ""); 3988 3989 row.set(Caption.name, fi.getName()); 3990 addRow(row, rows); 3991 } 3992 } 3993 } 3994 } 3995 } 3996 protected void setProperty(PropertyDefinition propertyDef, String value) { 3997 switch (propertyDef) { 3998 case Content: 3999 break; 4000 default: 4001 super.setProperty(propertyDef, value); 4002 } 4003 } 4004 } 4005 4006 4007 static class MdschemaHierarchiesRowset extends Rowset { 4008 private final RestrictionTest schemaNameRT; 4009 private final RestrictionTest cubeNameRT; 4010 private final RestrictionTest dimensionUniqueNameRT; 4011 private final RestrictionTest hierarchyUniqueNameRT; 4012 private final RestrictionTest hierarchyNameRT; 4013 MdschemaHierarchiesRowset(XmlaRequest request, XmlaHandler handler) { 4014 super(MDSCHEMA_HIERARCHIES, request, handler); 4015 schemaNameRT = getRestrictionTest(SchemaName); 4016 cubeNameRT = getRestrictionTest(CubeName); 4017 dimensionUniqueNameRT = getRestrictionTest(DimensionUniqueName); 4018 hierarchyUniqueNameRT = getRestrictionTest(HierarchyUniqueName); 4019 hierarchyNameRT = getRestrictionTest(HierarchyName); 4020 } 4021 4022 private static final Column CatalogName = 4023 new Column( 4024 "CATALOG_NAME", 4025 Type.String, 4026 null, 4027 Column.RESTRICTION, 4028 Column.OPTIONAL, 4029 "The name of the catalog to which this hierarchy belongs."); 4030 private static final Column SchemaName = 4031 new Column( 4032 "SCHEMA_NAME", 4033 Type.String, 4034 null, 4035 Column.RESTRICTION, 4036 Column.OPTIONAL, 4037 "Not supported"); 4038 private static final Column CubeName = 4039 new Column( 4040 "CUBE_NAME", 4041 Type.String, 4042 null, 4043 Column.RESTRICTION, 4044 Column.REQUIRED, 4045 "The name of the cube to which this hierarchy belongs."); 4046 private static final Column DimensionUniqueName = 4047 new Column( 4048 "DIMENSION_UNIQUE_NAME", 4049 Type.String, 4050 null, 4051 Column.RESTRICTION, 4052 Column.REQUIRED, 4053 "The unique name of the dimension to which this hierarchy belongs. "); 4054 private static final Column HierarchyName = 4055 new Column( 4056 "HIERARCHY_NAME", 4057 Type.String, 4058 null, 4059 Column.RESTRICTION, 4060 Column.REQUIRED, 4061 "The name of the hierarchy. Blank if there is only a single hierarchy in the dimension."); 4062 private static final Column HierarchyUniqueName = 4063 new Column( 4064 "HIERARCHY_UNIQUE_NAME", 4065 Type.String, 4066 null, 4067 Column.RESTRICTION, 4068 Column.REQUIRED, 4069 "The unique name of the hierarchy."); 4070 4071 private static final Column HierarchyGuid = 4072 new Column( 4073 "HIERARCHY_GUID", 4074 Type.UUID, 4075 null, 4076 Column.NOT_RESTRICTION, 4077 Column.OPTIONAL, 4078 "Hierarchy GUID."); 4079 4080 private static final Column HierarchyCaption = 4081 new Column( 4082 "HIERARCHY_CAPTION", 4083 Type.String, 4084 null, 4085 Column.NOT_RESTRICTION, 4086 Column.REQUIRED, 4087 "A label or a caption associated with the hierarchy."); 4088 private static final Column DimensionType = 4089 new Column( 4090 "DIMENSION_TYPE", 4091 Type.Short, 4092 null, 4093 Column.NOT_RESTRICTION, 4094 Column.REQUIRED, 4095 "The type of the dimension. "); 4096 private static final Column HierarchyCardinality = 4097 new Column( 4098 "HIERARCHY_CARDINALITY", 4099 Type.UnsignedInteger, 4100 null, 4101 Column.NOT_RESTRICTION, 4102 Column.REQUIRED, 4103 "The number of members in the hierarchy."); 4104 private static final Column DefaultMember = 4105 new Column( 4106 "DEFAULT_MEMBER", 4107 Type.String, 4108 null, 4109 Column.NOT_RESTRICTION, 4110 Column.OPTIONAL, 4111 "The default member for this hierarchy. "); 4112 private static final Column AllMember = 4113 new Column( 4114 "ALL_MEMBER", 4115 Type.String, 4116 null, 4117 Column.NOT_RESTRICTION, 4118 Column.OPTIONAL, 4119 "The member at the highest level of rollup in the hierarchy."); 4120 private static final Column Description = 4121 new Column( 4122 "DESCRIPTION", 4123 Type.String, 4124 null, 4125 Column.NOT_RESTRICTION, 4126 Column.OPTIONAL, 4127 "A human-readable description of the hierarchy. NULL if no description exists."); 4128 private static final Column Structure = 4129 new Column( 4130 "STRUCTURE", 4131 Type.Short, 4132 null, 4133 Column.NOT_RESTRICTION, 4134 Column.REQUIRED, 4135 "The structure of the hierarchy."); 4136 private static final Column IsVirtual = 4137 new Column( 4138 "IS_VIRTUAL", 4139 Type.Boolean, 4140 null, 4141 Column.NOT_RESTRICTION, 4142 Column.REQUIRED, 4143 "Always returns False."); 4144 private static final Column IsReadWrite = 4145 new Column( 4146 "IS_READWRITE", 4147 Type.Boolean, 4148 null, 4149 Column.NOT_RESTRICTION, 4150 Column.REQUIRED, 4151 "A Boolean that indicates whether the Write Back to dimension column is enabled."); 4152 private static final Column DimensionUniqueSettings = 4153 new Column( 4154 "DIMENSION_UNIQUE_SETTINGS", 4155 Type.Integer, 4156 null, 4157 Column.NOT_RESTRICTION, 4158 Column.REQUIRED, 4159 "Always returns MDDIMENSIONS_MEMBER_KEY_UNIQUE (1)."); 4160 private static final Column DimensionIsVisible = 4161 new Column( 4162 "DIMENSION_IS_VISIBLE", 4163 Type.Boolean, 4164 null, 4165 Column.NOT_RESTRICTION, 4166 Column.REQUIRED, 4167 "Always returns true."); 4168 private static final Column HierarchyOrdinal = 4169 new Column( 4170 "HIERARCHY_ORDINAL", 4171 Type.UnsignedInteger, 4172 null, 4173 Column.NOT_RESTRICTION, 4174 Column.REQUIRED, 4175 "The ordinal number of the hierarchy across all hierarchies of the cube."); 4176 private static final Column DimensionIsShared = 4177 new Column( 4178 "DIMENSION_IS_SHARED", 4179 Type.Boolean, 4180 null, 4181 Column.NOT_RESTRICTION, 4182 Column.REQUIRED, 4183 "Always returns true."); 4184 4185 4186 4189 private static final Column ParentChild = 4190 new Column( 4191 "PARENT_CHILD", 4192 Type.Boolean, 4193 null, 4194 Column.NOT_RESTRICTION, 4195 Column.OPTIONAL, 4196 "Is hierarchy a parent."); 4197 4198 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 4199 DataSourcesConfig.DataSource ds = 4200 handler.getDataSource(request); 4201 String roleStr = request.getRole(); 4202 DataSourcesConfig.Catalog[] catalogs = 4203 handler.getCatalogs(request, ds); 4204 4205 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 4206 if (dsCatalog == null || dsCatalog.definition == null) { 4207 continue; 4208 } 4209 String catalogName = dsCatalog.name; 4210 if (!schemaNameRT.passes(catalogName)) { 4211 continue; 4212 } 4213 4214 Connection connection = 4215 handler.getConnection(dsCatalog, roleStr); 4216 if (connection == null) { 4217 continue; 4218 } 4219 Role role = connection.getSchema().lookupRole(roleStr); 4220 populateCatalog(connection, role, catalogName, rows); 4221 } 4222 } 4223 protected void populateCatalog(Connection connection, 4224 Role role, 4225 String catalogName, 4226 List<Row> rows) 4227 throws XmlaException { 4228 try { 4229 for (Cube cube : sortedCubes(connection.getSchema())) { 4230 if (!cubeNameRT.passes(cube.getName())) { 4231 continue; 4232 } 4233 SchemaReader schemaReader = cube.getSchemaReader(role); 4234 populateCube(schemaReader, catalogName, cube, rows); 4235 } 4236 } finally { 4237 } 4238 } 4239 protected void populateCube(SchemaReader schemaReader, 4240 String catalogName, 4241 Cube cube, 4242 List<Row> rows) 4243 throws XmlaException { 4244 try { 4245 int ordinal = 0; 4246 for (Dimension dimension : cube.getDimensions()) { 4247 String unique = dimension.getUniqueName(); 4248 boolean genOutput = dimensionUniqueNameRT.passes(unique); 4251 ordinal = populateDimension( 4252 genOutput, 4253 schemaReader, catalogName, 4254 cube, dimension, ordinal, rows); 4255 } 4256 } finally { 4257 } 4258 } 4259 protected int populateDimension( 4260 boolean genOutput, 4261 SchemaReader schemaReader, 4262 String catalogName, 4263 Cube cube, 4264 Dimension dimension, 4265 int ordinal, 4266 List<Row> rows) 4267 throws XmlaException { 4268 try { 4269 Hierarchy[] hierarchies = dimension.getHierarchies(); 4270 for (Hierarchy hierarchy : hierarchies) { 4271 if (genOutput) { 4272 String unique = hierarchy.getUniqueName(); 4273 if (hierarchyNameRT.passes(hierarchy.getName()) && 4274 hierarchyUniqueNameRT.passes(unique)) { 4275 populateHierarchy(schemaReader, catalogName, 4276 cube, dimension, (HierarchyBase) hierarchy, 4277 ordinal++, rows); 4278 } else { 4279 ordinal++; 4280 } 4281 } else { 4282 ordinal++; 4283 } 4284 } 4285 return ordinal; 4286 } finally { 4287 } 4288 } 4289 protected void populateHierarchy(SchemaReader schemaReader, 4290 String catalogName, 4291 Cube cube, 4292 Dimension dimension, 4293 HierarchyBase hierarchy, 4294 int ordinal, 4295 List<Row> rows) 4296 throws XmlaException { 4297 4298 if (!canAccess(schemaReader, hierarchy)) { 4300 return; 4301 } 4302 4303 String desc = hierarchy.getDescription(); 4304 if (desc == null) { 4305 desc = cube.getName() + 4306 " Cube - " + 4307 hierarchy.getName() + 4308 " Hierarchy"; 4309 } 4310 4311 Row row = new Row(); 4312 row.set(CatalogName.name, catalogName); 4313 4314 4317 row.set(CubeName.name, cube.getName()); 4318 row.set(DimensionUniqueName.name, dimension.getUniqueName()); 4319 row.set(HierarchyName.name, hierarchy.getName()); 4320 row.set(HierarchyUniqueName.name, hierarchy.getUniqueName()); 4321 4323 row.set(HierarchyCaption.name, hierarchy.getCaption()); 4324 row.set(DimensionType.name, getDimensionType(dimension)); 4325 int cardinality = 4332 RolapMember.getHierarchyCardinality(schemaReader, hierarchy); 4333 row.set(HierarchyCardinality.name, cardinality); 4334 4335 row.set(DefaultMember.name, hierarchy.getDefaultMember()); 4336 if (hierarchy.hasAll()) { 4337 row.set(AllMember.name, 4338 Util.makeFqName(hierarchy, hierarchy.getAllMemberName())); 4339 } 4340 row.set(Description.name, desc); 4341 4342 row.set(Structure.name, hierarchy.isRagged() ? 1 : 0); 4346 4347 row.set(IsVirtual.name, false); 4348 row.set(IsReadWrite.name, false); 4349 4350 row.set(DimensionUniqueSettings.name, 0); 4352 4353 row.set(DimensionIsVisible.name, true); 4355 4356 row.set(HierarchyOrdinal.name, ordinal); 4357 4358 row.set(DimensionIsShared.name, true); 4360 4361 RolapLevel nonAllFirstLevel = 4362 (RolapLevel) hierarchy.getLevels()[ 4363 (hierarchy.hasAll() ? 1 : 0)]; 4364 row.set(ParentChild.name, nonAllFirstLevel.isParentChild()); 4365 addRow(row, rows); 4366 } 4367 4368 4369 4370 protected void setProperty(PropertyDefinition propertyDef, String value) { 4371 switch (propertyDef) { 4372 case Content: 4373 break; 4374 default: 4375 super.setProperty(propertyDef, value); 4376 } 4377 } 4378 } 4379 4380 static class MdschemaLevelsRowset extends Rowset { 4381 private final RestrictionTest schemaNameRT; 4382 private final RestrictionTest cubeNameRT; 4383 private final RestrictionTest dimensionUniqueNameRT; 4384 private final RestrictionTest hierarchyUniqueNameRT; 4385 private final RestrictionTest levelUniqueNameRT; 4386 private final RestrictionTest levelNameRT; 4387 MdschemaLevelsRowset(XmlaRequest request, XmlaHandler handler) { 4388 super(MDSCHEMA_LEVELS, request, handler); 4389 schemaNameRT = getRestrictionTest(SchemaName); 4390 cubeNameRT = getRestrictionTest(CubeName); 4391 dimensionUniqueNameRT = getRestrictionTest(DimensionUniqueName); 4392 hierarchyUniqueNameRT = getRestrictionTest(HierarchyUniqueName); 4393 levelUniqueNameRT = getRestrictionTest(LevelUniqueName); 4394 levelNameRT = getRestrictionTest(LevelName); 4395 } 4396 4397 public static final int MDLEVEL_TYPE_UNKNOWN = 0x0000; 4398 public static final int MDLEVEL_TYPE_REGULAR = 0x0000; 4399 public static final int MDLEVEL_TYPE_ALL = 0x0001; 4400 public static final int MDLEVEL_TYPE_CALCULATED = 0x0002; 4401 public static final int MDLEVEL_TYPE_TIME = 0x0004; 4402 public static final int MDLEVEL_TYPE_RESERVED1 = 0x0008; 4403 public static final int MDLEVEL_TYPE_TIME_YEARS = 0x0014; 4404 public static final int MDLEVEL_TYPE_TIME_HALF_YEAR = 0x0024; 4405 public static final int MDLEVEL_TYPE_TIME_QUARTERS = 0x0044; 4406 public static final int MDLEVEL_TYPE_TIME_MONTHS = 0x0084; 4407 public static final int MDLEVEL_TYPE_TIME_WEEKS = 0x0104; 4408 public static final int MDLEVEL_TYPE_TIME_DAYS = 0x0204; 4409 public static final int MDLEVEL_TYPE_TIME_HOURS = 0x0304; 4410 public static final int MDLEVEL_TYPE_TIME_MINUTES = 0x0404; 4411 public static final int MDLEVEL_TYPE_TIME_SECONDS = 0x0804; 4412 public static final int MDLEVEL_TYPE_TIME_UNDEFINED = 0x1004; 4413 4414 private static final Column CatalogName = 4415 new Column( 4416 "CATALOG_NAME", 4417 Type.String, 4418 null, 4419 Column.RESTRICTION, 4420 Column.OPTIONAL, 4421 "The name of the catalog to which this level belongs."); 4422 private static final Column SchemaName = 4423 new Column( 4424 "SCHEMA_NAME", 4425 Type.String, 4426 null, 4427 Column.RESTRICTION, 4428 Column.OPTIONAL, 4429 "The name of the schema to which this level belongs."); 4430 private static final Column CubeName = 4431 new Column( 4432 "CUBE_NAME", 4433 Type.String, 4434 null, 4435 Column.RESTRICTION, 4436 Column.REQUIRED, 4437 "The name of the cube to which this level belongs."); 4438 private static final Column DimensionUniqueName = 4439 new Column( 4440 "DIMENSION_UNIQUE_NAME", 4441 Type.String, 4442 null, 4443 Column.RESTRICTION, 4444 Column.REQUIRED, 4445 "The unique name of the dimension to which this level belongs."); 4446 private static final Column HierarchyUniqueName = 4447 new Column( 4448 "HIERARCHY_UNIQUE_NAME", 4449 Type.String, 4450 null, 4451 Column.RESTRICTION, 4452 Column.REQUIRED, 4453 "The unique name of the hierarchy."); 4454 private static final Column LevelName = 4455 new Column( 4456 "LEVEL_NAME", 4457 Type.String, 4458 null, 4459 Column.RESTRICTION, 4460 Column.REQUIRED, 4461 "The name of the level."); 4462 private static final Column LevelUniqueName = 4463 new Column( 4464 "LEVEL_UNIQUE_NAME", 4465 Type.String, 4466 null, 4467 Column.RESTRICTION, 4468 Column.REQUIRED, 4469 "The properly escaped unique name of the level."); 4470 private static final Column LevelGuid = 4471 new Column( 4472 "LEVEL_GUID", 4473 Type.UUID, 4474 null, 4475 Column.NOT_RESTRICTION, 4476 Column.OPTIONAL, 4477 "Level GUID."); 4478 private static final Column LevelCaption = 4479 new Column( 4480 "LEVEL_CAPTION", 4481 Type.String, 4482 null, 4483 Column.NOT_RESTRICTION, 4484 Column.REQUIRED, 4485 "A label or caption associated with the hierarchy."); 4486 private static final Column LevelNumber = 4487 new Column( 4488 "LEVEL_NUMBER", 4489 Type.UnsignedInteger, 4490 null, 4491 Column.NOT_RESTRICTION, 4492 Column.REQUIRED, 4493 "The distance of the level from the root of the hierarchy. Root level is zero (0)."); 4494 private static final Column LevelCardinality = 4495 new Column( 4496 "LEVEL_CARDINALITY", 4497 Type.UnsignedInteger, 4498 null, 4499 Column.NOT_RESTRICTION, 4500 Column.REQUIRED, 4501 "The number of members in the level. This value can be an approximation of the real cardinality."); 4502 private static final Column LevelType = 4503 new Column( 4504 "LEVEL_TYPE", 4505 Type.Integer, 4506 null, 4507 Column.NOT_RESTRICTION, 4508 Column.REQUIRED, 4509 "Type of the level"); 4510 private static final Column CustomRollupSettings = 4511 new Column( 4512 "CUSTOM_ROLLUP_SETTINGS", 4513 Type.Integer, 4514 null, 4515 Column.NOT_RESTRICTION, 4516 Column.REQUIRED, 4517 "A bitmap that specifies the custom rollup options."); 4518 private static final Column LevelUniqueSettings = 4519 new Column( 4520 "LEVEL_UNIQUE_SETTINGS", 4521 Type.Integer, 4522 null, 4523 Column.NOT_RESTRICTION, 4524 Column.REQUIRED, 4525 "A bitmap that specifies which columns contain unique values, if the level only has members with unique names or keys."); 4526 private static final Column LevelIsVisible = 4527 new Column( 4528 "LEVEL_IS_VISIBLE", 4529 Type.Boolean, 4530 null, 4531 Column.NOT_RESTRICTION, 4532 Column.REQUIRED, 4533 "A Boolean that indicates whether the level is visible."); 4534 private static final Column Description = 4535 new Column( 4536 "DESCRIPTION", 4537 Type.String, 4538 null, 4539 Column.NOT_RESTRICTION, 4540 Column.OPTIONAL, 4541 "A human-readable description of the level. NULL if no description exists."); 4542 4543 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 4544 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 4545 String roleStr = request.getRole(); 4546 DataSourcesConfig.Catalog[] catalogs = 4547 handler.getCatalogs(request, ds); 4548 4549 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 4550 if (dsCatalog == null || dsCatalog.definition == null) { 4551 continue; 4552 } 4553 String catalogName = dsCatalog.name; 4554 if (!schemaNameRT.passes(catalogName)) { 4555 continue; 4556 } 4557 4558 Connection connection = 4559 handler.getConnection(dsCatalog, roleStr); 4560 if (connection == null) { 4561 continue; 4562 } 4563 Role role = connection.getSchema().lookupRole(roleStr); 4564 populateCatalog(connection, role, catalogName, rows); 4565 } 4566 } 4567 protected void populateCatalog(Connection connection, 4568 Role role, 4569 String catalogName, 4570 List<Row> rows) 4571 throws XmlaException { 4572 4573 for (Cube cube : sortedCubes(connection.getSchema())) { 4574 if (!cubeNameRT.passes(cube.getName())) { 4575 continue; 4576 } 4577 SchemaReader schemaReader = cube.getSchemaReader(role); 4578 populateCube(schemaReader, catalogName, cube, rows); 4579 } 4580 } 4581 4582 protected void populateCube(SchemaReader schemaReader, 4583 String catalogName, 4584 Cube cube, 4585 List<Row> rows) 4586 throws XmlaException { 4587 try { 4588 for (Dimension dimension : cube.getDimensions()) { 4589 String uniqueName = dimension.getUniqueName(); 4590 if (dimensionUniqueNameRT.passes(uniqueName)) { 4591 populateDimension(schemaReader, catalogName, 4592 cube, dimension, rows); 4593 } 4594 } 4595 } finally { 4596 } 4597 } 4598 protected void populateDimension(SchemaReader schemaReader, 4599 String catalogName, 4600 Cube cube, 4601 Dimension dimension, 4602 List<Row> rows) 4603 throws XmlaException { 4604 try { 4605 Hierarchy[] hierarchies = dimension.getHierarchies(); 4606 for (Hierarchy hierarchy : hierarchies) { 4607 String uniqueName = hierarchy.getUniqueName(); 4608 if (hierarchyUniqueNameRT.passes(uniqueName)) { 4609 populateHierarchy(schemaReader, catalogName, 4610 cube, hierarchy, rows); 4611 } 4612 } 4613 } finally { 4614 } 4615 } 4616 protected void populateHierarchy(SchemaReader schemaReader, 4617 String catalogName, 4618 Cube cube, 4619 Hierarchy hierarchy, 4620 List<Row> rows) 4621 throws XmlaException { 4622 4623 final Level[] levels = hierarchy.getLevels(); 4624 for (Level level : levels) { 4625 String uniqueName = level.getUniqueName(); 4626 String name = level.getName(); 4627 if (levelUniqueNameRT.passes(uniqueName) && 4628 levelNameRT.passes(name)) { 4629 outputLevel(schemaReader, 4630 catalogName, cube, hierarchy, level, rows); 4631 } 4632 } 4633 } 4634 protected void outputLevel(SchemaReader schemaReader, 4635 String catalogName, 4636 Cube cube, 4637 Hierarchy hierarchy, 4638 Level level, 4639 List<Row> rows) 4640 throws XmlaException { 4641 4642 if (!canAccess(schemaReader, level)) { 4644 return; 4645 } 4646 String desc = level.getDescription(); 4647 if (desc == null) { 4648 desc = cube.getName() + 4649 " Cube - " + 4650 hierarchy.getName() + 4651 " Hierarchy" + 4652 level.getName() + 4653 " Level"; 4654 } 4655 4656 Row row = new Row(); 4657 row.set(CatalogName.name, catalogName); 4658 row.set(SchemaName.name, catalogName); 4659 row.set(CubeName.name, cube.getName()); 4660 row.set(DimensionUniqueName.name, 4661 hierarchy.getDimension().getUniqueName()); 4662 row.set(HierarchyUniqueName.name, hierarchy.getUniqueName()); 4663 row.set(LevelName.name, level.getName()); 4664 row.set(LevelUniqueName.name, level.getUniqueName()); 4665 row.set(LevelCaption.name, level.getCaption()); 4667 row.set(LevelNumber.name, level.getDepth()); 4669 4670 int n = schemaReader.getLevelCardinality(level, true, true); 4674 row.set(LevelCardinality.name, n); 4675 4676 row.set(LevelType.name, getLevelType(level)); 4677 4678 row.set(CustomRollupSettings.name, 0); 4680 4681 if (level instanceof RolapLevel) { 4682 RolapLevel rl = (RolapLevel) level; 4683 row.set(LevelUniqueSettings.name, 4684 (rl.isUnique() ? 1 : 0) + 4685 (rl.isAll() ? 2 : 0) 4686 ); 4687 } else { 4688 row.set(LevelUniqueSettings.name, 4691 (level.isAll() ? 2 : 0) 4692 ); 4693 } 4694 row.set(LevelIsVisible.name, true); 4695 row.set(Description.name, desc); 4696 addRow(row, rows); 4697 } 4698 4699 4700 private int getLevelType(Level lev) { 4701 int ret = 0; 4702 4703 if (lev.isAll()) { 4704 ret |= MDLEVEL_TYPE_ALL; 4705 } 4706 4707 mondrian.olap.LevelType type = lev.getLevelType(); 4708 switch (type) { 4709 case Regular: 4710 ret |= MDLEVEL_TYPE_REGULAR; 4711 break; 4712 case TimeDays: 4713 ret |= MDLEVEL_TYPE_TIME_DAYS; 4714 break; 4715 case TimeMonths: 4716 ret |= MDLEVEL_TYPE_TIME_MONTHS; 4717 break; 4718 case TimeQuarters: 4719 ret |= MDLEVEL_TYPE_TIME_QUARTERS; 4720 break; 4721 case TimeWeeks: 4722 ret |= MDLEVEL_TYPE_TIME_WEEKS; 4723 break; 4724 case TimeYears: 4725 ret |= MDLEVEL_TYPE_TIME_YEARS; 4726 break; 4727 default: 4728 ret |= MDLEVEL_TYPE_UNKNOWN; 4729 } 4730 4731 return ret; 4732 } 4733 protected void setProperty(PropertyDefinition propertyDef, String value) { 4734 switch (propertyDef) { 4735 case Content: 4736 break; 4737 default: 4738 super.setProperty(propertyDef, value); 4739 } 4740 } 4741 } 4742 4743 4744 static class MdschemaMeasuresRowset extends Rowset { 4746 public static final int MDMEASURE_AGGR_UNKNOWN = 0; 4747 public static final int MDMEASURE_AGGR_SUM = 1; 4748 public static final int MDMEASURE_AGGR_COUNT = 2; 4749 public static final int MDMEASURE_AGGR_MIN = 3; 4750 public static final int MDMEASURE_AGGR_MAX = 4; 4751 public static final int MDMEASURE_AGGR_AVG = 5; 4752 public static final int MDMEASURE_AGGR_VAR = 6; 4753 public static final int MDMEASURE_AGGR_STD = 7; 4754 public static final int MDMEASURE_AGGR_CALCULATED = 127; 4755 4756 private final RestrictionTest schemaNameRT; 4757 private final RestrictionTest cubeNameRT; 4758 private final RestrictionTest measureUniqueNameRT; 4759 private final RestrictionTest measureNameRT; 4760 MdschemaMeasuresRowset(XmlaRequest request, XmlaHandler handler) { 4761 super(MDSCHEMA_MEASURES, request, handler); 4762 schemaNameRT = getRestrictionTest(SchemaName); 4763 cubeNameRT = getRestrictionTest(CubeName); 4764 measureNameRT = getRestrictionTest(MeasureName); 4765 measureUniqueNameRT = getRestrictionTest(MeasureUniqueName); 4766 } 4767 4768 private static final Column CatalogName = 4769 new Column( 4770 "CATALOG_NAME", 4771 Type.String, 4772 null, 4773 Column.RESTRICTION, 4774 Column.OPTIONAL, 4775 "The name of the catalog to which this measure belongs. "); 4776 private static final Column SchemaName = 4777 new Column( 4778 "SCHEMA_NAME", 4779 Type.String, 4780 null, 4781 Column.RESTRICTION, 4782 Column.OPTIONAL, 4783 "The name of the schema to which this measure belongs."); 4784 private static final Column CubeName = 4785 new Column( 4786 "CUBE_NAME", 4787 Type.String, 4788 null, 4789 Column.RESTRICTION, 4790 Column.REQUIRED, 4791 "The name of the cube to which this measure belongs."); 4792 private static final Column MeasureName = 4793 new Column( 4794 "MEASURE_NAME", 4795 Type.String, 4796 null, 4797 Column.RESTRICTION, 4798 Column.REQUIRED, 4799 "The name of the measure."); 4800 private static final Column MeasureUniqueName = 4801 new Column( 4802 "MEASURE_UNIQUE_NAME", 4803 Type.String, 4804 null, 4805 Column.RESTRICTION, 4806 Column.REQUIRED, 4807 "The Unique name of the measure."); 4808 private static final Column MeasureCaption = 4809 new Column( 4810 "MEASURE_CAPTION", 4811 Type.String, 4812 null, 4813 Column.NOT_RESTRICTION, 4814 Column.REQUIRED, 4815 "A label or caption associated with the measure. "); 4816 private static final Column MeasureGuid = 4817 new Column( 4818 "MEASURE_GUID", 4819 Type.UUID, 4820 null, 4821 Column.NOT_RESTRICTION, 4822 Column.OPTIONAL, 4823 "Measure GUID."); 4824 private static final Column MeasureAggregator = 4825 new Column( 4826 "MEASURE_AGGREGATOR", 4827 Type.Integer, 4828 null, 4829 Column.NOT_RESTRICTION, 4830 Column.REQUIRED, 4831 "How a measure was derived. "); 4832 private static final Column DataType = 4833 new Column( 4834 "DATA_TYPE", 4835 Type.UnsignedShort, 4836 null, 4837 Column.NOT_RESTRICTION, 4838 Column.REQUIRED, 4839 "Data type of the measure."); 4840 private static final Column MeasureIsVisible = 4841 new Column( 4842 "MEASURE_IS_VISIBLE", 4843 Type.Boolean, 4844 null, 4845 Column.NOT_RESTRICTION, 4846 Column.REQUIRED, 4847 "A Boolean that always returns True. If the measure is not visible, it will not be included in the schema rowset."); 4848 private static final Column LevelsList = 4849 new Column( 4850 "LEVELS_LIST", 4851 Type.String, 4852 null, 4853 Column.NOT_RESTRICTION, 4854 Column.OPTIONAL, 4855 "A string that always returns NULL. EXCEPT that SQL Server returns non-null values!!!"); 4856 private static final Column Description = 4857 new Column( 4858 "DESCRIPTION", 4859 Type.String, 4860 null, 4861 Column.NOT_RESTRICTION, 4862 Column.OPTIONAL, 4863 "A human-readable description of the measure. "); 4864 4865 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 4866 DataSourcesConfig.DataSource ds = handler.getDataSource(request); 4867 String roleStr = request.getRole(); 4868 DataSourcesConfig.Catalog[] catalogs = 4869 handler.getCatalogs(request, ds); 4870 4871 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 4872 if (dsCatalog == null || dsCatalog.definition == null) { 4873 continue; 4874 } 4875 Connection connection = 4876 handler.getConnection(dsCatalog, roleStr); 4877 if (connection == null) { 4878 continue; 4879 } 4880 4881 String catalogName = dsCatalog.name; 4882 if (schemaNameRT.passes(catalogName)) { 4883 Role role = connection.getSchema().lookupRole(roleStr); 4884 populateCatalog(connection, role, catalogName, rows); 4885 } 4886 } 4887 } 4888 protected void populateCatalog( 4889 Connection connection, 4890 Role role, 4891 String catalogName, 4892 List<Row> rows) 4893 throws XmlaException { 4894 4895 StringBuilder buf = new StringBuilder (100); 4897 4898 for (Cube cube : sortedCubes(connection.getSchema())) { 4899 if (cubeNameRT.passes(cube.getName())) { 4900 SchemaReader schemaReader = cube.getSchemaReader(role); 4901 Dimension measuresDimension = cube.getDimensions()[0]; 4902 Hierarchy measuresHierarchy = 4903 measuresDimension.getHierarchies()[0]; 4904 Level measuresLevel = 4905 measuresHierarchy.getLevels()[0]; 4906 4907 buf.setLength(0); 4908 4909 int j = 0; 4910 for (Dimension dimension : cube.getDimensions()) { 4911 if (dimension.isMeasures()) { 4912 continue; 4913 } 4914 for (Hierarchy hierarchy : dimension.getHierarchies()) { 4915 Level[] levels = hierarchy.getLevels(); 4916 Level lastLevel = levels[levels.length - 1]; 4917 if (j++ > 0) { 4918 buf.append(','); 4919 } 4920 buf.append(lastLevel.getUniqueName()); 4921 } 4922 } 4923 String levelListStr = buf.toString(); 4924 4925 Member[] storedMembers = 4926 schemaReader.getLevelMembers(measuresLevel, false); 4927 for (Member member : storedMembers) { 4928 String name = member.getName(); 4929 String unique = member.getUniqueName(); 4930 if (measureNameRT.passes(name) && 4931 measureUniqueNameRT.passes(unique)) { 4932 populateMember(schemaReader, catalogName, 4933 member, cube, levelListStr, rows); 4934 } 4935 } 4936 4937 for (Member member : 4938 schemaReader.getCalculatedMembers(measuresHierarchy)) { 4939 String name = member.getName(); 4940 String unique = member.getUniqueName(); 4941 if (measureNameRT.passes(name) && 4942 measureUniqueNameRT.passes(unique)) { 4943 populateMember(schemaReader, catalogName, 4944 member, cube, null, rows); 4945 } 4946 } 4947 } 4948 } 4949 } 4950 4951 private void populateMember( 4952 SchemaReader schemaReader, 4953 String catalogName, 4954 Member member, 4955 Cube cube, 4956 String levelListStr, 4957 List<Row> rows) { 4958 4959 if (!canAccess(schemaReader, member)) { 4961 return; 4962 } 4963 4964 if (member instanceof MemberBase) { 4965 MemberBase mb = (MemberBase) member; 4966 Boolean isVisible = (Boolean ) 4967 mb.getPropertyValue(Property.VISIBLE.name); 4968 if (isVisible != null && !isVisible) { 4969 return; 4970 } 4971 } 4972 4973 String desc = member.getDescription(); 4975 if (desc == null) { 4976 desc = cube.getName() + 4977 " Cube - " + 4978 member.getName() + 4979 " Member"; 4980 } 4981 4982 Row row = new Row(); 4983 row.set(CatalogName.name, catalogName); 4984 4985 4988 row.set(CubeName.name, cube.getName()); 4989 row.set(MeasureName.name, member.getName()); 4990 row.set(MeasureUniqueName.name, member.getUniqueName()); 4991 row.set(MeasureCaption.name, member.getCaption()); 4992 4994 Object aggProp = 4995 member.getPropertyValue(Property.AGGREGATION_TYPE.getName()); 4996 int aggNumber = MDMEASURE_AGGR_UNKNOWN; 4997 if (aggProp != null) { 4998 RolapAggregator agg = (RolapAggregator) aggProp; 4999 if (agg == RolapAggregator.Sum) { 5000 aggNumber = MDMEASURE_AGGR_SUM; 5001 } else if (agg == RolapAggregator.Count) { 5002 aggNumber = MDMEASURE_AGGR_COUNT; 5003 } else if (agg == RolapAggregator.Min) { 5004 aggNumber = MDMEASURE_AGGR_MIN; 5005 } else if (agg == RolapAggregator.Max) { 5006 aggNumber = MDMEASURE_AGGR_MAX; 5007 } else if (agg == RolapAggregator.Avg) { 5008 aggNumber = MDMEASURE_AGGR_AVG; 5009 } 5010 } else { 5012 aggNumber = MDMEASURE_AGGR_CALCULATED; 5013 } 5014 row.set(MeasureAggregator.name, aggNumber); 5015 5016 int dbType = DBType.WSTR.userOrdinal; 5018 String datatype = (String ) 5019 member.getPropertyValue(Property.DATATYPE.getName()); 5020 if (datatype != null) { 5021 if (datatype.equals("Integer")) { 5022 dbType = DBType.I4.userOrdinal; 5023 } else if (datatype.equals("Numeric")) { 5024 dbType = DBType.R8.userOrdinal; 5025 } else { 5026 dbType = DBType.WSTR.userOrdinal; 5027 } 5028 } 5029 row.set(DataType.name, dbType); 5030 row.set(MeasureIsVisible.name, true); 5031 5032 if (levelListStr != null) { 5033 row.set(LevelsList.name, levelListStr); 5034 } 5035 5036 row.set(Description.name, desc); 5037 addRow(row, rows); 5038 } 5039 protected void setProperty(PropertyDefinition propertyDef, String value) { 5040 switch (propertyDef) { 5041 case Content: 5042 break; 5043 default: 5044 super.setProperty(propertyDef, value); 5045 } 5046 } 5047 } 5048 5049 static class MdschemaMembersRowset extends Rowset { 5050 private final RestrictionTest schemaNameRT; 5051 private final RestrictionTest cubeNameRT; 5052 private final RestrictionTest dimensionUniqueNameRT; 5053 private final RestrictionTest hierarchyUniqueNameRT; 5054 private final RestrictionTest memberNameRT; 5055 private final RestrictionTest memberUniqueNameRT; 5056 private final RestrictionTest memberTypeRT; 5057 5058 MdschemaMembersRowset(XmlaRequest request, XmlaHandler handler) { 5059 super(MDSCHEMA_MEMBERS, request, handler); 5060 schemaNameRT = getRestrictionTest(SchemaName); 5061 cubeNameRT = getRestrictionTest(CubeName); 5062 dimensionUniqueNameRT = getRestrictionTest(DimensionUniqueName); 5063 hierarchyUniqueNameRT = getRestrictionTest(HierarchyUniqueName); 5064 memberNameRT = getRestrictionTest(MemberName); 5065 memberUniqueNameRT = getRestrictionTest(MemberUniqueName); 5066 memberTypeRT = getRestrictionTest(MemberType); 5067 } 5068 5069 private static final Column CatalogName = 5070 new Column( 5071 "CATALOG_NAME", 5072 Type.String, 5073 null, 5074 Column.RESTRICTION, 5075 Column.OPTIONAL, 5076 "The name of the catalog to which this member belongs. "); 5077 private static final Column SchemaName = 5078 new Column( 5079 "SCHEMA_NAME", 5080 Type.String, 5081 null, 5082 Column.RESTRICTION, 5083 Column.OPTIONAL, 5084 "The name of the schema to which this member belongs. "); 5085 private static final Column CubeName = 5086 new Column( 5087 "CUBE_NAME", 5088 Type.String, 5089 null, 5090 Column.RESTRICTION, 5091 Column.REQUIRED, 5092 "Name of the cube to which this member belongs."); 5093 private static final Column DimensionUniqueName = 5094 new Column( 5095 "DIMENSION_UNIQUE_NAME", 5096 Type.String, 5097 null, 5098 Column.RESTRICTION, 5099 Column.REQUIRED, 5100 "Unique name of the dimension to which this member belongs. "); 5101 private static final Column HierarchyUniqueName = 5102 new Column( 5103 "HIERARCHY_UNIQUE_NAME", 5104 Type.String, 5105 null, 5106 Column.RESTRICTION, 5107 Column.REQUIRED, 5108 "Unique name of the hierarchy. If the member belongs to more than one hierarchy, there is one row for each hierarchy to which it belongs."); 5109 private static final Column LevelUniqueName = 5110 new Column( 5111 "LEVEL_UNIQUE_NAME", 5112 Type.String, 5113 null, 5114 Column.RESTRICTION, 5115 Column.REQUIRED, 5116 " Unique name of the level to which the member belongs."); 5117 private static final Column LevelNumber = 5118 new Column( 5119 "LEVEL_NUMBER", 5120 Type.UnsignedInteger, 5121 null, 5122 Column.RESTRICTION, 5123 Column.REQUIRED, 5124 "The distance of the member from the root of the hierarchy."); 5125 private static final Column MemberOrdinal = 5126 new Column( 5127 "MEMBER_ORDINAL", 5128 Type.UnsignedInteger, 5129 null, 5130 Column.NOT_RESTRICTION, 5131 Column.REQUIRED, 5132 "Ordinal number of the member. Sort rank of the member when members of this dimension are sorted in their natural sort order. If providers do not have the concept of natural ordering, this should be the rank when sorted by MEMBER_NAME."); 5133 private static final Column MemberName = 5134 new Column( 5135 "MEMBER_NAME", 5136 Type.String, 5137 null, 5138 Column.RESTRICTION, 5139 Column.REQUIRED, 5140 "Name of the member."); 5141 private static final Column MemberUniqueName = 5142 new Column( 5143 "MEMBER_UNIQUE_NAME", 5144 Type.String, 5145 null, 5146 Column.RESTRICTION, 5147 Column.REQUIRED, 5148 " Unique name of the member."); 5149 private static final Column MemberType = 5150 new Column( 5151 "MEMBER_TYPE", 5152 Type.Integer, 5153 null, 5154 Column.RESTRICTION, 5155 Column.REQUIRED, 5156 "Type of the member."); 5157 private static final Column MemberGuid = 5158 new Column( 5159 "MEMBER_GUID", 5160 Type.UUID, 5161 null, 5162 Column.NOT_RESTRICTION, 5163 Column.OPTIONAL, 5164 "Memeber GUID."); 5165 private static final Column MemberCaption = 5166 new Column( 5167 "MEMBER_CAPTION", 5168 Type.String, 5169 null, 5170 Column.RESTRICTION, 5171 Column.REQUIRED, 5172 "A label or caption associated with the member."); 5173 private static final Column ChildrenCardinality = 5174 new Column( 5175 "CHILDREN_CARDINALITY", 5176 Type.UnsignedInteger, 5177 null, 5178 Column.NOT_RESTRICTION, 5179 Column.REQUIRED, 5180 "Number of children that the member has."); 5181 private static final Column ParentLevel = 5182 new Column( 5183 "PARENT_LEVEL", 5184 Type.UnsignedInteger, 5185 null, 5186 Column.NOT_RESTRICTION, 5187 Column.REQUIRED, 5188 "The distance of the member's parent from the root level of the hierarchy. "); 5189 private static final Column ParentUniqueName = 5190 new Column( 5191 "PARENT_UNIQUE_NAME", 5192 Type.String, 5193 null, 5194 Column.NOT_RESTRICTION, 5195 Column.OPTIONAL, 5196 "Unique name of the member's parent."); 5197 private static final Column ParentCount = 5198 new Column( 5199 "PARENT_COUNT", 5200 Type.UnsignedInteger, 5201 null, 5202 Column.NOT_RESTRICTION, 5203 Column.REQUIRED, 5204 "Number of parents that this member has."); 5205 private static final Column TreeOp = 5206 new Column( 5207 "TREE_OP", 5208 Type.Enumeration, 5209 Enumeration.TreeOp.enumeration, 5210 Column.RESTRICTION, 5211 Column.OPTIONAL, 5212 "Tree Operation"); 5213 5214 private static final Column Depth = 5215 new Column( 5216 "DEPTH", 5217 Type.Integer, 5218 null, 5219 Column.NOT_RESTRICTION, 5220 Column.OPTIONAL, 5221 "depth"); 5222 5223 public void populate(XmlaResponse response, List<Row> rows) 5224 throws XmlaException { 5225 5226 DataSourcesConfig.DataSource ds = 5227 handler.getDataSource(request); 5228 String roleStr = request.getRole(); 5229 DataSourcesConfig.Catalog[] catalogs = 5230 handler.getCatalogs(request, ds); 5231 5232 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 5233 if (dsCatalog == null || dsCatalog.definition == null) { 5234 continue; 5235 } 5236 Connection connection = 5237 handler.getConnection(dsCatalog, roleStr); 5238 if (connection == null) { 5239 continue; 5240 } 5241 5242 String catalogName = dsCatalog.name; 5243 if (schemaNameRT.passes(catalogName)) { 5244 Role role = connection.getSchema().lookupRole(roleStr); 5245 populateCatalog(connection, role, catalogName, rows); 5246 } 5247 } 5248 } 5249 protected void populateCatalog(Connection connection, 5250 Role role, 5251 String catalogName, 5252 List<Row> rows) 5253 throws XmlaException { 5254 5255 for (Cube cube : sortedCubes(connection.getSchema())) { 5256 if (cubeNameRT.passes(cube.getName())) { 5257 SchemaReader schemaReader = cube.getSchemaReader(role); 5258 populateCube(schemaReader, catalogName, cube, rows); 5259 } 5260 } 5261 } 5262 protected void populateCube(SchemaReader schemaReader, 5263 String catalogName, 5264 Cube cube, 5265 List<Row> rows) 5266 throws XmlaException { 5267 5268 if (isRestricted(MemberUniqueName)) { 5269 outputUniqueMemberName(schemaReader, 5274 catalogName, cube, rows); 5275 } else if (isRestricted(LevelUniqueName)) { 5276 String levelUniqueName = 5279 getRestrictionValueAsString(LevelUniqueName); 5280 if (levelUniqueName == null) { 5281 return; 5284 } 5285 final String [] nameParts = Util.explode(levelUniqueName); 5286 Hierarchy hier = cube.lookupHierarchy(nameParts[0], false); 5287 if (hier == null) { 5288 return; 5289 } 5290 Level[] levels = hier.getLevels(); 5291 for (Level level : levels) { 5292 if (!level.getUniqueName().equals(levelUniqueName)) { 5293 continue; 5294 } 5295 Member[] members = 5298 cube.getSchemaReader(null).getLevelMembers(level, true); 5299 outputMembers(schemaReader, members, 5300 catalogName, cube, rows); 5301 } 5302 } else { 5303 for (Dimension dimension : cube.getDimensions()) { 5304 String uniqueName = dimension.getUniqueName(); 5305 if (dimensionUniqueNameRT.passes(uniqueName)) { 5306 populateDimension(schemaReader, catalogName, 5307 cube, dimension, rows); 5308 } 5309 } 5310 } 5311 } 5312 protected void populateDimension(SchemaReader schemaReader, 5313 String catalogName, 5314 Cube cube, 5315 Dimension dimension, 5316 List<Row> rows) 5317 throws XmlaException { 5318 5319 Hierarchy[] hierarchies = dimension.getHierarchies(); 5320 for (Hierarchy hierarchy : hierarchies) { 5321 String uniqueName = hierarchy.getUniqueName(); 5322 if (hierarchyUniqueNameRT.passes(uniqueName)) { 5323 populateHierarchy(schemaReader, catalogName, 5324 cube, hierarchy, rows); 5325 } 5326 } 5327 } 5328 protected void populateHierarchy(SchemaReader schemaReader, 5329 String catalogName, 5330 Cube cube, 5331 Hierarchy hierarchy, 5332 List<Row> rows) 5333 throws XmlaException { 5334 5335 5336 if (isRestricted(LevelNumber)) { 5337 int levelNumber = getRestrictionValueAsInt(LevelNumber); 5338 if (levelNumber == -1) { 5339 LOGGER.warn("RowsetDefinition.populateHierarchy: " + 5340 "LevelNumber invalid" 5341 ); 5342 return; 5343 } 5344 Level[] levels = hierarchy.getLevels(); 5345 if (levelNumber >= levels.length) { 5346 LOGGER.warn("RowsetDefinition.populateHierarchy: " + 5347 "LevelNumber (" + 5348 levelNumber + 5349 ") is greater than number of levels (" + 5350 levels.length + 5351 ") for hierarchy \"" + 5352 hierarchy.getUniqueName() + 5353 "\"" 5354 ); 5355 return; 5356 } 5357 5358 Level level = levels[levelNumber]; 5359 Member[] members = 5360 schemaReader.getLevelMembers(level, false); 5361 outputMembers(schemaReader, members, catalogName, cube, rows); 5362 } else { 5363 Member[][] membersArray = 5368 RolapMember.getAllMembers(schemaReader, hierarchy); 5369 for (Member[] members : membersArray) { 5370 outputMembers(schemaReader, members, 5371 catalogName, cube, rows); 5372 } 5373 } 5374 } 5375 5376 5379 private static boolean mask(int value, int mask) { 5380 return (value & mask) == mask; 5381 } 5382 5383 5389 private void populateMember( 5390 final SchemaReader schemaReader, 5391 String catalogName, 5392 Cube cube, 5393 Member member, 5394 int treeOp, 5395 List<Row> rows) { 5396 5397 if (mask(treeOp, Enumeration.TreeOp.Self.userOrdinal())) { 5399 outputMember(schemaReader, member, catalogName, cube, rows); 5400 } 5401 if (mask(treeOp, Enumeration.TreeOp.Siblings.userOrdinal())) { 5403 final Member parent = 5404 schemaReader.getMemberParent(member); 5405 final Member[] siblings = (parent == null) 5406 ? schemaReader.getHierarchyRootMembers(member.getHierarchy()) 5407 : schemaReader.getMemberChildren(parent); 5408 5409 for (Member sibling : siblings) { 5410 if (sibling == member) { 5411 continue; 5412 } 5413 populateMember( 5414 schemaReader, catalogName, 5415 cube, sibling, 5416 Enumeration.TreeOp.Self.userOrdinal(), rows); 5417 } 5418 } 5419 if (mask(treeOp, Enumeration.TreeOp.Descendants.userOrdinal())) { 5421 final Member[] children = schemaReader.getMemberChildren(member); 5422 for (Member child : children) { 5423 populateMember( 5424 schemaReader, catalogName, 5425 cube, child, 5426 Enumeration.TreeOp.Self.userOrdinal() | 5427 Enumeration.TreeOp.Descendants.userOrdinal(), 5428 rows); 5429 } 5430 } else if (mask(treeOp, Enumeration.TreeOp.Children.userOrdinal())) { 5431 final Member[] children = 5432 schemaReader.getMemberChildren(member); 5433 for (Member child : children) { 5434 populateMember( 5435 schemaReader, catalogName, 5436 cube, child, 5437 Enumeration.TreeOp.Self.userOrdinal(), rows); 5438 } 5439 } 5440 if (mask(treeOp, Enumeration.TreeOp.Ancestors.userOrdinal())) { 5442 final Member parent = schemaReader.getMemberParent(member); 5443 if (parent != null) { 5444 populateMember( 5445 schemaReader, catalogName, 5446 cube, parent, 5447 Enumeration.TreeOp.Self.userOrdinal() | 5448 Enumeration.TreeOp.Ancestors.userOrdinal(), rows); 5449 } 5450 } else if (mask(treeOp, Enumeration.TreeOp.Parent.userOrdinal())) { 5451 final Member parent = schemaReader.getMemberParent(member); 5452 if (parent != null) { 5453 populateMember( 5454 schemaReader, catalogName, 5455 cube, parent, 5456 Enumeration.TreeOp.Self.userOrdinal(), rows); 5457 } 5458 } 5459 } 5460 5461 protected ArrayList<Column> pruneRestrictions(ArrayList<Column> list) { 5462 if (list.contains(TreeOp)) { 5467 list.remove(TreeOp); 5468 list.remove(MemberUniqueName); 5469 } 5470 return list; 5471 } 5472 5473 private void outputMembers( 5474 final SchemaReader schemaReader, 5475 Member[] members, 5476 final String catalogName, 5477 Cube cube, List<Row> rows) { 5478 5479 for (Member member : members) { 5480 outputMember(schemaReader, member, catalogName, cube, rows); 5481 } 5482 } 5483 private void outputUniqueMemberName( 5484 final SchemaReader schemaReader, 5485 final String catalogName, 5486 Cube cube, List<Row> rows) { 5487 5488 String memberUniqueName = 5489 getRestrictionValueAsString(MemberUniqueName); 5490 if (memberUniqueName == null) { 5491 return; 5494 } 5495 final String [] nameParts = Util.explode(memberUniqueName); 5496 5497 Member member = schemaReader.getMemberByUniqueName( 5498 nameParts, false); 5499 5500 if (member == null) { 5501 return; 5502 } 5503 if (isRestricted(TreeOp)) { 5504 int treeOp = getRestrictionValueAsInt(TreeOp); 5505 if (treeOp == -1) { 5506 return; 5507 } 5508 populateMember( 5509 schemaReader, catalogName, 5510 cube, member, treeOp, rows); 5511 } else { 5512 outputMember(schemaReader, member, catalogName, cube, rows); 5513 } 5514 } 5515 5516 private void outputMember( 5517 final SchemaReader schemaReader, 5518 Member member, 5519 final String catalogName, 5520 Cube cube, List<Row> rows) { 5521 5522 if (!canAccess(schemaReader, member)) { 5524 return; 5525 } 5526 if (! memberNameRT.passes(member.getName())) { 5527 return; 5528 } 5529 if (! memberTypeRT.passes(member.getMemberType())) { 5530 return; 5531 } 5532 5533 if (member.getOrdinal() == -1) { 5534 RolapMember.setOrdinals(schemaReader, member); 5535 } 5536 5537 Boolean isVisible = (Boolean ) 5539 member.getPropertyValue(Property.VISIBLE.name); 5540 if (isVisible != null && !isVisible) { 5541 return; 5542 } 5543 5544 final Level level = member.getLevel(); 5545 final Hierarchy hierarchy = level.getHierarchy(); 5546 final Dimension dimension = hierarchy.getDimension(); 5547 Row row = new Row(); 5548 row.set(CatalogName.name, catalogName); 5549 row.set(SchemaName.name, catalogName); 5550 row.set(CubeName.name, cube.getName()); 5551 row.set(DimensionUniqueName.name, dimension.getUniqueName()); 5552 row.set(HierarchyUniqueName.name, hierarchy.getUniqueName()); 5553 row.set(LevelUniqueName.name, level.getUniqueName()); 5554 row.set(LevelNumber.name, level.getDepth()); 5555 row.set(MemberOrdinal.name, member.getOrdinal()); 5556 row.set(MemberName.name, member.getName()); 5557 row.set(MemberUniqueName.name, member.getUniqueName()); 5558 row.set(MemberType.name, member.getMemberType().ordinal()); 5559 row.set(MemberCaption.name, member.getCaption()); 5561 row.set(ChildrenCardinality.name, 5562 member.getPropertyValue(Property.CHILDREN_CARDINALITY.name)); 5563 row.set(ChildrenCardinality.name, 100); 5564 5565 row.set(ParentLevel.name, 5566 (member.getParentMember() == null) 5567 ? 0 : member.getParentMember().getDepth()); 5568 5569 String parentUniqueName = member.getParentUniqueName(); 5570 if (parentUniqueName != null) { 5571 row.set(ParentUniqueName.name, parentUniqueName); 5572 } else { 5573 } 5575 5576 row.set(ParentCount.name, member.getParentMember() == null ? 0 : 1); 5577 5578 row.set(Depth.name, member.getDepth()); 5579 addRow(row, rows); 5580 } 5581 protected void setProperty(PropertyDefinition propertyDef, String value) { 5582 switch (propertyDef) { 5583 case Content: 5584 break; 5585 default: 5586 super.setProperty(propertyDef, value); 5587 } 5588 } 5589 5590 5707 5708 } 5709 5710 static class MdschemaSetsRowset extends Rowset { 5711 MdschemaSetsRowset(XmlaRequest request, XmlaHandler handler) { 5712 super(MDSCHEMA_SETS, request, handler); 5713 } 5714 5715 private static final Column CatalogName = 5716 new Column( 5717 "CATALOG_NAME", 5718 Type.String, 5719 null, 5720 true, 5721 true, 5722 null); 5723 private static final Column SchemaName = 5724 new Column( 5725 "SCHEMA_NAME", 5726 Type.String, 5727 null, 5728 true, 5729 true, 5730 null); 5731 private static final Column CubeName = 5732 new Column( 5733 "CUBE_NAME", 5734 Type.String, 5735 null, 5736 true, 5737 false, 5738 null); 5739 private static final Column SetName = 5740 new Column( 5741 "SET_NAME", 5742 Type.String, 5743 null, 5744 true, 5745 false, 5746 null); 5747 private static final Column SetCaption = 5748 new Column( 5749 "SET_CAPTION", 5750 Type.String, 5751 null, 5752 true, 5753 true, 5754 null); 5755 private static final Column Scope = 5756 new Column( 5757 "SCOPE", 5758 Type.Integer, 5759 null, 5760 true, 5761 false, 5762 null); 5763 private static final Column Description = 5764 new Column("DESCRIPTION", 5765 Type.String, 5766 null, 5767 false, 5768 true, 5769 "A human-readable description of the measure."); 5770 5771 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 5772 throw new XmlaException( 5773 CLIENT_FAULT_FC, 5774 HSB_UNSUPPORTED_OPERATION_CODE, 5775 HSB_UNSUPPORTED_OPERATION_FAULT_FS, 5776 new UnsupportedOperationException ("MDSCHEMA_SETS")); 5777 } 5778 } 5779 5780 static class MdschemaPropertiesRowset extends Rowset { 5781 private final RestrictionTest schemaNameRT; 5782 private final RestrictionTest cubeNameRT; 5783 private final RestrictionTest dimensionUniqueNameRT; 5784 private final RestrictionTest hierarchyUniqueNameRT; 5785 private final RestrictionTest propertyNameRT; 5786 MdschemaPropertiesRowset(XmlaRequest request, XmlaHandler handler) { 5787 super(MDSCHEMA_PROPERTIES, request, handler); 5788 schemaNameRT = getRestrictionTest(SchemaName); 5789 cubeNameRT = getRestrictionTest(CubeName); 5790 dimensionUniqueNameRT = getRestrictionTest(DimensionUniqueName); 5791 hierarchyUniqueNameRT = getRestrictionTest(HierarchyUniqueName); 5792 propertyNameRT = getRestrictionTest(PropertyName); 5793 } 5794 5795 private static final int MDPROP_MEMBER = 0x01; 5796 private static final int MDPROP_CELL = 0x02; 5797 private static final int MDPROP_SYSTEM = 0x04; 5798 private static final int MDPROP_BLOB = 0x08; 5799 5800 private static final int MD_PROPTYPE_REGULAR = 0x00; 5801 5802 private static final Column CatalogName = 5803 new Column( 5804 "CATALOG_NAME", 5805 Type.String, 5806 null, 5807 Column.RESTRICTION, 5808 Column.OPTIONAL, 5809 "The name of the database."); 5810 private static final Column SchemaName = 5811 new Column( 5812 "SCHEMA_NAME", 5813 Type.String, 5814 null, 5815 Column.RESTRICTION, 5816 Column.OPTIONAL, 5817 "The name of the schema to which this property belongs."); 5818 private static final Column CubeName = 5819 new Column( 5820 "CUBE_NAME", 5821 Type.String, 5822 null, 5823 Column.RESTRICTION, 5824 Column.REQUIRED, 5825 "The name of the cube."); 5826 private static final Column DimensionUniqueName = 5827 new Column( 5828 "DIMENSION_UNIQUE_NAME", 5829 Type.String, 5830 null, 5831 Column.RESTRICTION, 5832 Column.REQUIRED, 5833 "The unique name of the dimension."); 5834 private static final Column HierarchyUniqueName = 5835 new Column( 5836 "HIERARCHY_UNIQUE_NAME", 5837 Type.String, 5838 null, 5839 Column.RESTRICTION, 5840 Column.REQUIRED, 5841 "The unique name of the hierarchy."); 5842 private static final Column LevelUniqueName = 5843 new Column( 5844 "LEVEL_UNIQUE_NAME", 5845 Type.String, 5846 null, 5847 Column.RESTRICTION, 5848 Column.REQUIRED, 5849 "The unique name of the level to which this property belongs."); 5850 private static final Column MemberUniqueName = 5852 new Column( 5853 "MEMBER_UNIQUE_NAME", 5854 Type.String, 5855 null, 5856 Column.RESTRICTION, 5857 Column.OPTIONAL, 5858 "The unique name of the member to which the property belongs."); 5859 private static final Column PropertyName = 5860 new Column( 5861 "PROPERTY_NAME", 5862 Type.String, 5863 null, 5864 Column.RESTRICTION, 5865 Column.REQUIRED, 5866 "Name of the property."); 5867 private static final Column PropertyType = 5868 new Column( 5869 "PROPERTY_TYPE", 5870 Type.Short, 5871 null, 5872 Column.RESTRICTION, 5873 Column.REQUIRED, 5874 "A bitmap that specifies the type of the property"); 5875 private static final Column PropertyCaption = 5876 new Column( 5877 "PROPERTY_CAPTION", 5878 Type.String, 5879 null, 5880 Column.NOT_RESTRICTION, 5881 Column.REQUIRED, 5882 "A label or caption associated with the property, used primarily for display purposes."); 5883 private static final Column DataType = 5884 new Column( 5885 "DATA_TYPE", 5886 Type.UnsignedShort, 5887 null, 5888 Column.NOT_RESTRICTION, 5889 Column.REQUIRED, 5890 "Data type of the property."); 5891 private static final Column PropertyContentType = 5892 new Column( 5893 "PROPERTY_CONTENT_TYPE", 5894 Type.Short, 5895 null, 5896 Column.RESTRICTION, 5897 Column.OPTIONAL, 5898 "The type of the property. "); 5899 private static final Column Description = 5900 new Column( 5901 "DESCRIPTION", 5902 Type.String, 5903 null, 5904 Column.NOT_RESTRICTION, 5905 Column.OPTIONAL, 5906 "A human-readable description of the measure. "); 5907 5908 public void populate(XmlaResponse response, List<Row> rows) throws XmlaException { 5909 DataSourcesConfig.DataSource ds = 5910 handler.getDataSource(request); 5911 String roleStr = request.getRole(); 5912 DataSourcesConfig.Catalog[] catalogs = 5913 handler.getCatalogs(request, ds); 5914 5915 for (DataSourcesConfig.Catalog dsCatalog : catalogs) { 5916 if (dsCatalog == null || dsCatalog.definition == null) { 5917 continue; 5918 } 5919 Connection connection = 5920 handler.getConnection(dsCatalog, roleStr); 5921 if (connection == null) { 5922 continue; 5923 } 5924 5925 String catalogName = dsCatalog.name; 5926 if (schemaNameRT.passes(catalogName)) { 5927 Role role = connection.getSchema().lookupRole(roleStr); 5928 populateCatalog(connection, role, catalogName, rows); 5929 } 5930 } 5931 } 5932 protected void populateCatalog(Connection connection, 5933 Role role, 5934 String catalogName, 5935 List<Row> rows) 5936 throws XmlaException { 5937 5938 for (Cube cube : sortedCubes(connection.getSchema())) { 5939 if (cubeNameRT.passes(cube.getName())) { 5940 SchemaReader schemaReader = cube.getSchemaReader(role); 5941 populateCube(schemaReader, catalogName, cube, rows); 5942 } 5943 } 5944 } 5945 5946 protected void populateCube(SchemaReader schemaReader, 5947 String catalogName, 5948 Cube cube, 5949 List<Row> rows) 5950 throws XmlaException { 5951 if (isRestricted(LevelUniqueName)) { 5952 String levelUniqueName = 5955 getRestrictionValueAsString(LevelUniqueName); 5956 if (levelUniqueName == null) { 5957 return; 5960 } 5961 final String [] nameParts = Util.explode(levelUniqueName); 5962 Hierarchy hier = cube.lookupHierarchy(nameParts[0], false); 5963 if (hier == null) { 5964 return; 5965 } 5966 Level[] levels = hier.getLevels(); 5967 for (Level level : levels) { 5968 if (level.getUniqueName().equals(levelUniqueName)) { 5969 populateLevel(schemaReader, catalogName, 5970 cube, level, rows); 5971 break; 5972 } 5973 } 5974 5975 } else { 5976 for (Dimension dimension : cube.getDimensions()) { 5977 String uniqueName = dimension.getUniqueName(); 5978 if (dimensionUniqueNameRT.passes(uniqueName)) { 5979 populateDimension(schemaReader, catalogName, 5980 cube, dimension, rows); 5981 } 5982 } 5983 } 5984 } 5985 private void populateDimension( 5986 final SchemaReader schemaReader, 5987 final String catalogName, 5988 Cube cube, Dimension dimension, List<Row> rows) { 5989 5990 Hierarchy[] hierarchies = dimension.getHierarchies(); 5991 for (Hierarchy hierarchy : hierarchies) { 5992 String unique = hierarchy.getUniqueName(); 5993 if (hierarchyUniqueNameRT.passes(unique)) { 5994 populateHierarchy(schemaReader, catalogName, 5995 cube, hierarchy, rows); 5996 } 5997 } 5998 } 5999 private void populateHierarchy( 6000 final SchemaReader schemaReader, 6001 final String catalogName, 6002 Cube cube, Hierarchy hierarchy, List<Row> rows) { 6003 6004 Level[] levels = hierarchy.getLevels(); 6005 for (Level level : levels) { 6006 populateLevel(schemaReader, catalogName, 6007 cube, level, rows); 6008 } 6009 } 6010 private void populateLevel( 6011 final SchemaReader schemaReader, 6012 final String catalogName, 6013 Cube cube, Level level, List<Row> rows) { 6014 6015 Property[] properties = level.getProperties(); 6016 for (Property property : properties) { 6017 if (propertyNameRT.passes(property.getName())) { 6018 outputProperty(schemaReader, property, 6019 catalogName, cube, level, rows); 6020 } 6021 } 6022 } 6023 6024 private void outputProperty( 6025 final SchemaReader schemaReader, 6026 Property property, 6027 final String catalogName, 6028 Cube cube, Level level, List<Row> rows) { 6029 6030 Hierarchy hierarchy = level.getHierarchy(); 6031 Dimension dimension = hierarchy.getDimension(); 6032 6033 String propertyName = property.getName(); 6034 6035 Row row = new Row(); 6036 row.set(CatalogName.name, catalogName); 6037 row.set(SchemaName.name, catalogName); 6038 row.set(CubeName.name, cube.getName()); 6039 row.set(DimensionUniqueName.name, dimension.getUniqueName()); 6040 row.set(HierarchyUniqueName.name, hierarchy.getUniqueName()); 6041 row.set(LevelUniqueName.name, level.getUniqueName()); 6042 6045 row.set(PropertyName.name, propertyName); 6046 row.set(PropertyType.name, MDPROP_MEMBER); 6048 row.set(PropertyContentType.name, MD_PROPTYPE_REGULAR); 6049 row.set(PropertyCaption.name, property.getCaption()); 6050 DBType dbType = getDBTypeFromProperty(property); 6051 row.set(DataType.name, dbType.userOrdinal); 6052 6053 String desc = cube.getName() + 6054 " Cube - " + 6055 hierarchy.getName() + 6056 " Hierarchy - " + 6057 level.getName() + 6058 " Level - " + 6059 property.getName() + 6060 " Property"; 6061 row.set(Description.name, desc); 6062 6063 addRow(row, rows); 6064 } 6065 6066 6067 protected void setProperty(PropertyDefinition propertyDef, String value) { 6068 switch (propertyDef) { 6069 case Content: 6070 break; 6071 default: 6072 super.setProperty(propertyDef, value); 6073 } 6074 } 6075 } 6076 6077 private static boolean canAccess(SchemaReader schemaReader, OlapElement elem) { 6078 Role role = schemaReader.getRole(); 6079 return role.canAccess(elem); 6080 } 6081 6082 private static <T extends Comparable > List<T> sort( 6083 Collection<T> collection) 6084 { 6085 Object [] a = collection.toArray(new Object [collection.size()]); 6086 Arrays.sort(a); 6087 return (List<T>) (List) Arrays.asList(a); 6088 } 6089 6090 private static <T> List<T> sortArray( 6091 T[] a, 6092 Comparator<T> comparator) 6093 { 6094 T[] a2 = a.clone(); 6095 Arrays.sort(a2, comparator); 6096 return Arrays.asList(a2); 6097 } 6098 6099 static void serialize(StringBuilder buf, Collection<String > strings) { 6100 int k = 0; 6101 for (String name : sort(strings)) { 6102 if (k++ > 0) { 6103 buf.append(','); 6104 } 6105 buf.append(name); 6106 } 6107 } 6108 6109 static List<Cube> sortedCubes(Schema schema) { 6110 final Cube[] cubes = schema.getCubes(); 6111 List<Cube> cubeList = sortArray( 6112 cubes, 6113 new Comparator<Cube>() { 6114 public int compare(Cube o1, Cube o2) { 6115 return o1.getName().compareTo(o2.getName()); 6116 } 6117 } 6118 ); 6119 return cubeList; 6120 } 6121} 6122 6123 | Popular Tags |