1 13 14 package com.tonbeller.jpivot.mondrian; 15 16 import java.net.URI ; 17 import java.net.URISyntaxException ; 18 import java.util.ArrayList ; 19 import java.util.LinkedList ; 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Locale ; 26 import java.util.Map ; 27 import java.util.Set ; 28 29 import javax.servlet.ServletContext ; 30 import javax.sql.DataSource ; 31 32 import mondrian.mdx.DimensionExpr; 33 import mondrian.mdx.HierarchyExpr; 34 import mondrian.mdx.LevelExpr; 35 import mondrian.mdx.MdxVisitorImpl; 36 import mondrian.mdx.MemberExpr; 37 import mondrian.mdx.ParameterExpr; 38 import mondrian.mdx.UnresolvedFunCall; 39 import mondrian.olap.Category; 40 import mondrian.olap.Cube; 41 import mondrian.olap.Exp; 42 import mondrian.olap.Formula; 43 import mondrian.olap.FunCall; 44 import mondrian.olap.Literal; 45 import mondrian.olap.MondrianException; 46 import mondrian.olap.Parameter; 47 import mondrian.olap.ParameterImpl; 48 import mondrian.olap.Query; 49 import mondrian.olap.QueryAxis; 50 import mondrian.olap.Role; 51 import mondrian.olap.SchemaReader; 52 import mondrian.olap.Syntax; 53 import mondrian.olap.Util; 54 import mondrian.olap.type.NumericType; 55 import mondrian.olap.type.Type; 56 import mondrian.olap.ResultLimitExceededException; 57 import mondrian.olap.MemoryLimitExceededException; 58 import mondrian.rolap.RolapConnection; 59 import mondrian.rolap.RolapConnectionProperties; 60 import mondrian.spi.CatalogLocator; 61 import mondrian.spi.impl.ServletContextCatalogLocator; 62 import mondrian.util.MemoryMonitor; 63 import mondrian.util.MemoryMonitorFactory; 64 65 import org.apache.log4j.Logger; 66 67 import com.tonbeller.jpivot.core.Extension; 68 import com.tonbeller.jpivot.core.ModelChangeEvent; 69 import com.tonbeller.jpivot.core.ModelChangeListener; 70 import com.tonbeller.jpivot.olap.model.Dimension; 71 import com.tonbeller.jpivot.olap.model.Member; 72 import com.tonbeller.jpivot.olap.model.OlapException; 73 import com.tonbeller.jpivot.olap.model.OlapModel; 74 import com.tonbeller.jpivot.olap.model.Result; 75 import com.tonbeller.jpivot.olap.navi.SortRank; 76 import com.tonbeller.jpivot.olap.query.ExpBean; 77 import com.tonbeller.jpivot.olap.query.MdxOlapModel; 78 import com.tonbeller.jpivot.olap.query.Memento; 79 import com.tonbeller.jpivot.olap.query.PositionNodeBean; 80 import com.tonbeller.jpivot.olap.query.QueryAdapter; 81 import com.tonbeller.wcf.bookmarks.Bookmarkable; 82 83 86 public class MondrianModel extends MdxOlapModel implements OlapModel, 87 QueryAdapter.QueryAdapterHolder { 88 89 static Logger logger = Logger.getLogger(MondrianModel.class); 90 91 static final String LOGICAL_MDX_PROP = "com.tonbeller.jpivot.mondrian.logical.mdx"; 92 93 97 private String connectString = null; 98 private Util.PropertyList connectProperties = null; 99 100 103 private String jdbcDriver = null; 104 private mondrian.olap.Connection monConnection = null; 105 106 109 private String mdxQuery; 110 111 private String currentMdx; 112 private MondrianResult result = null; 113 private HashMap hDimensions = new HashMap (); 114 private HashMap hHierarchies = new HashMap (); 115 private HashMap hLevels = new HashMap (); 116 private HashMap hMembers = new HashMap (); 117 private ArrayList aMeasures = new ArrayList (); 118 119 private List aLogicalModel = new LinkedList (); 120 121 private MondrianQueryAdapter queryAdapter = null; 122 private Listener listener = null; 123 124 private boolean isInitialized = false; 125 private String ID = null; 126 private Locale loc = null; 127 128 private String sessionId = null; 129 private String dynresolver = null; 130 131 private String dynLocale = null;; 133 134 private boolean connectionPooling = true; 136 private DataSource externalDataSource = null; 137 138 private ServletContext servletContext = null; 139 140 private Object bookMark = null; 141 142 private String dataSourceChangeListener = null; 143 144 public String getID() { 145 return ID; 146 } 147 148 149 152 final void checkListener() throws MemoryLimitExceededException { 153 if (this.listener != null) { 154 this.listener.check(); 155 } 156 } 157 158 public void setID(String ID) { 159 this.ID = ID; 160 } 161 162 165 public MondrianModel() { 166 this.mdxQuery = null; 167 this.currentMdx = null; 168 169 addModelChangeListener(new ModelChangeListener() { 170 public void modelChanged(ModelChangeEvent e) { 171 result = null; } 173 174 public void structureChanged(ModelChangeEvent e) { 175 result = null; } 177 }); 178 179 } 180 181 186 public QueryAdapter getQueryAdapter() { 187 return queryAdapter; 188 } 189 190 196 public synchronized Result getResult() throws OlapException { 197 198 if (result != null) { 199 return result; 200 } 201 202 if (!isInitialized) { 203 throw new OlapException("Model not initialized"); 204 } 205 206 this.listener = new Listener(); 207 MemoryMonitor mm = MemoryMonitorFactory.getMemoryMonitor(); 208 try { 209 mm.addListener(this.listener); 210 211 queryAdapter.onExecute(); 212 213 mondrian.olap.Result monResult = null; 214 boolean tryagain = false; 215 216 try { 217 String mdx = null; 218 if (Boolean.getBoolean(LOGICAL_MDX_PROP)) { 219 mondrian.olap.Query modiQuery = rewriteMDXQuery(queryAdapter.getMonQuery()); 220 queryAdapter.setMonQuery(modiQuery); 221 mdx = queryAdapter.getMonQuery().toString(); 222 setCurrentMdx(mdx); 223 } 224 if (logger.isDebugEnabled()) { 225 if (mdx == null) { 226 mdx = queryAdapter.getMonQuery().toString(); 227 } 228 logger.debug(mdx); 229 } 230 this.listener.check(); 232 233 long t1 = System.currentTimeMillis(); 234 monResult = monConnection.execute(queryAdapter.getMonQuery()); 235 236 this.listener.check(); 238 239 if (logger.isInfoEnabled()) { 240 long t2 = System.currentTimeMillis(); 241 logger.info("query execution time " + (t2 - t1) + " ms"); 242 } 243 244 } catch (MondrianException ex) { 245 Throwable rootCause = getRootCause(ex); 246 if (rootCause instanceof ResultLimitExceededException) { 247 logger.warn("Mondrian result limit exceeded: " + rootCause.getMessage()); 249 if (bookMark != null) { 250 setBookmarkState(bookMark); 251 tryagain = true; 252 } 253 } else if (rootCause instanceof mondrian.olap.InvalidHierarchyException) { 254 logger.warn("Mondrian Hierarchy with no members: " + 256 rootCause.getMessage()); 257 throw new EmptyCubeException(rootCause); 258 } else { 259 throw new OlapException(ex); 261 } 262 263 if (!tryagain) { 264 throw new ResultTooLargeException(ex); 265 } 266 } 267 if (tryagain) { 268 try { 271 long t1 = System.currentTimeMillis(); 272 monResult = monConnection.execute(queryAdapter.getMonQuery()); 273 this.listener.check(); 275 276 if (logger.isInfoEnabled()) { 277 long t2 = System.currentTimeMillis(); 278 logger.info("rollback query execution time " + (t2 - t1) + " ms"); 279 } 280 281 } catch (MondrianException ex) { 282 throw new ResultTooLargeException( 285 "Error running previous query (prior to Result Overflow)", ex); 286 } 287 } 288 result = new MondrianResult(monResult, this); 289 if (tryagain) { 290 result.setOverflowOccured(true); 291 } 292 293 queryAdapter.afterExecute(result); 294 295 if (!tryagain) { 297 bookMark = getBookmarkState(EXTENSIONAL); 298 } 299 } finally { 300 mm.removeListener(this.listener); 301 this.listener = null; 302 } 303 304 return result; 305 } 306 307 312 MondrianResult currentResult() { 313 return result; 314 } 315 316 319 public Dimension[] getDimensions() { 320 return (Dimension[]) hDimensions.values().toArray(new Dimension[0]); 321 } 322 323 326 public Member[] getMeasures() { 327 return (Member[]) aMeasures.toArray(new Member[0]); 328 } 329 330 338 public void setConnectString(String connectString) { 339 this.connectString = connectString; 340 result = null; 341 queryAdapter = null; 342 monConnection = null; 343 if (logger.isInfoEnabled()) 344 logger.info("connectString=" + connectString); 345 } 346 347 353 public void setConnectProperties(Util.PropertyList properties) { 354 connectProperties = properties; 355 result = null; 356 queryAdapter = null; 357 monConnection = null; 358 if (logger.isInfoEnabled()) 359 logger.info("connectProperties=" + connectProperties); 360 } 361 362 363 369 public void setJdbcDriver(String jdbcDriver) { 370 this.jdbcDriver = jdbcDriver; 371 result = null; 372 queryAdapter = null; 373 monConnection = null; 374 if (logger.isInfoEnabled()) 375 logger.info("jdbcDriver=" + jdbcDriver); 376 } 377 378 384 public void setMdxQuery(String mdxQuery) { 385 386 if (logger.isInfoEnabled()) 387 logger.info("setMdxQuery:" + mdxQuery); 388 389 this.mdxQuery = mdxQuery; 390 this.currentMdx = mdxQuery.replaceAll("\r", ""); 391 result = null; 392 queryAdapter = null; 393 } 394 395 398 public void initialize() throws OlapException { 399 logger.info(this); 400 boolean logInfo = logger.isInfoEnabled(); 401 402 if (jdbcDriver != null) { 404 try { 405 Class.forName(jdbcDriver); 406 } catch (Exception ex) { 407 String err = "Could not load Jdbc Driver " + jdbcDriver; 408 logger.error(err); 409 throw new OlapException(err); 410 } 411 } 412 413 Util.PropertyList properties = getConnectProperties(); 414 415 boolean updatedProperties = false; 416 417 if (properties == null) { 418 properties = Util.parseConnectString(connectString); 419 updatedProperties = true; 420 } 421 422 String catString = properties.get("Catalog"); 424 URI uri = null; 425 try { 426 if (catString != null) { 427 uri = new URI (catString); 428 } 429 } catch (URISyntaxException e) { 430 } 433 434 if (uri != null && uri.getScheme().equalsIgnoreCase("http") && sessionId != null) { 435 if (uri.getQuery() != null) { 438 catString = catString + "&sessionId=" + sessionId; 439 } else { 440 catString = catString + "?sessionId=" + sessionId; 441 } 442 properties.put(RolapConnectionProperties.Catalog.name(), catString); 443 updatedProperties = true; 444 } 445 446 if (dynresolver != null && dynresolver.length() > 0) { 447 properties.put(RolapConnectionProperties.DynamicSchemaProcessor.name(), dynresolver); 448 updatedProperties = true; 449 } 450 if (dynLocale!=null) { 451 properties.put(RolapConnectionProperties.Locale.name(), dynLocale); 452 updatedProperties = true; 453 } 454 if (dataSourceChangeListener != null && dataSourceChangeListener.length() > 0) { 455 properties.put(RolapConnectionProperties.DataSourceChangeListener.name(), dataSourceChangeListener); 456 updatedProperties = true; 457 } 458 459 if (!connectionPooling) { 461 properties.put(RolapConnectionProperties.PoolNeeded.name(), "false"); 462 updatedProperties = true; 463 } 464 465 if (updatedProperties) { 466 setConnectProperties(properties); 467 } 468 469 CatalogLocator catalogLocator = new ServletContextCatalogLocator(servletContext); 470 471 monConnection = mondrian.olap.DriverManager.getConnection(properties, catalogLocator, externalDataSource, false); 473 474 if (monConnection == null) { 475 String err = "Could not create Mondrian connection:" + properties; 476 logger.error(err); 477 throw new OlapException(err); 478 } 479 if (logInfo) 480 logger.info("MondrianModel: opening connection " + properties); 481 482 loc = getLocale(); if (loc != null) { 486 if (logInfo) { 487 String msg = "Locale language=" + loc.getLanguage() + " Country=" + loc.getCountry(); 488 logger.info(msg); 489 } 490 ((RolapConnection) monConnection).setLocale(loc); 491 } 492 493 mondrian.olap.Query monQuery; 494 try { 495 monQuery = parseMDX(); 496 } catch (OlapException e) { 497 String err = e.getMessage(); 498 logger.error(err); 499 throw new OlapException(err); 500 } 501 resetMetaData(monQuery); 503 queryAdapter = new MondrianQueryAdapter(this, monQuery); 504 505 MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID); 506 if (sortExt != null) 507 sortExt.reset(); 508 509 isInitialized = true; 510 511 Map extMap = getExtensions(); 513 Collection extensions = extMap.values(); 514 for (Iterator iter = extensions.iterator(); iter.hasNext();) { 515 Extension extension = (Extension) iter.next(); 516 extension.modelInitialized(); 517 } 518 } 519 520 525 private mondrian.olap.Query parseMDX() throws OlapException { 526 mondrian.olap.Query monQuery; 527 try { 528 monQuery = getConnection().parseQuery(mdxQuery); 529 } catch (MondrianException ex) { 530 logger.error("Parse Failure", ex); 531 Throwable rootCause = getRootCause(ex); 533 throw new OlapException(rootCause.getMessage()); 534 } catch (Exception ex) { 535 logger.fatal("unexpected parse failure " + ex.getMessage()); 537 throw new OlapException(ex); 538 } 539 if (monQuery == null) { 540 logger.fatal("unexpected parse failure"); 541 throw new OlapException("unexpected parse failure"); 542 } 543 return monQuery; 544 } 545 546 549 private Throwable getRootCause(MondrianException ex) { 550 Throwable rootCause = ex; 551 Throwable cause = ex.getCause(); 552 while (cause != null && cause != rootCause) { 553 rootCause = cause; 554 cause = cause.getCause(); 555 } 556 return rootCause; 557 } 558 559 565 private void addDimension(mondrian.olap.Dimension monDimension) { 566 String uniqueName = monDimension.getUniqueName(); 567 if (!hDimensions.containsKey(uniqueName)) { 568 MondrianDimension dimension = new MondrianDimension(monDimension, this); 569 hDimensions.put(uniqueName, dimension); 570 mondrian.olap.Hierarchy[] monHiers = monDimension.getHierarchies(); 572 for (int i = 0; i < monHiers.length; i++) { 573 this.addHierarchy(monHiers[i], dimension); 574 } 575 } 576 } 577 578 584 private void addHierarchy(mondrian.olap.Hierarchy monHierarchy, MondrianDimension dimension) { 585 String uniqueName = monHierarchy.getUniqueName(); 586 if (!hHierarchies.containsKey(uniqueName)) { 587 MondrianHierarchy hierarchy = new MondrianHierarchy(monHierarchy, dimension, this); 588 hHierarchies.put(uniqueName, hierarchy); 589 SchemaReader scr = monConnection.getSchemaReader(); 591 mondrian.olap.Level[] monLevels = scr.getHierarchyLevels(monHierarchy); 592 for (int i = 0; i < monLevels.length; i++) { 593 this.addLevel(monLevels[i], hierarchy); 594 } 595 } 596 } 597 598 604 protected void addLevel(mondrian.olap.Level monLevel, MondrianHierarchy hierarchy) { 605 String uniqueName = monLevel.getUniqueName(); 606 if (!hLevels.containsKey(uniqueName)) { 607 MondrianLevel level = new MondrianLevel(monLevel, hierarchy, this); 608 hLevels.put(uniqueName, level); 609 } 610 } 611 612 619 public MondrianMember addMember(mondrian.olap.Member monMember) { 620 String uniqueName = monMember.getUniqueName(); 621 if (hMembers.containsKey(uniqueName)) { 622 return (MondrianMember) hMembers.get(uniqueName); 623 } else { 624 mondrian.olap.Level monLevel = monMember.getLevel(); 625 MondrianLevel level = this.lookupLevel(monLevel.getUniqueName()); 626 MondrianMember member = new MondrianMember(monMember, level, this); 627 hMembers.put(uniqueName, member); 628 if (monMember.isMeasure()) 629 aMeasures.add(member); 630 return member; 631 } 632 } 633 634 639 public void removeMember(String uniqueName) { 640 if (hMembers.containsKey(uniqueName)) { 641 MondrianMember m = (MondrianMember) hMembers.get(uniqueName); 642 if (aMeasures.contains(m)) 643 aMeasures.remove(m); 644 hMembers.remove(uniqueName); 645 } 646 } 647 648 655 public MondrianDimension lookupDimension(String uniqueName) { 656 return (MondrianDimension) hDimensions.get(uniqueName); 657 } 658 659 666 public MondrianHierarchy lookupHierarchy(String uniqueName) { 667 return (MondrianHierarchy) hHierarchies.get(uniqueName); 668 } 669 670 677 public Member lookupMemberByUName(String uniqueName) { 678 MondrianMember m = (MondrianMember) hMembers.get(uniqueName); 683 if (m != null) 684 return m; 685 final SchemaReader scr = this.getConnection().getSchemaReader(); 686 687 String [] uniqueNameParts = Util.explode(uniqueName); 688 689 695 696 Cube cube = queryAdapter.getMonQuery().getCube(); 697 mondrian.olap.Member monMember = (mondrian.olap.Member) Util.lookupCompound(scr, cube, 698 uniqueNameParts, false, Category.Member); 699 if (monMember != null) 700 return addMember(monMember); 701 702 if (monMember == null) { 703 Formula[] formulas = queryAdapter.getMonQuery().getFormulas(); 706 for (int i = 0; i < formulas.length; i++) { 707 monMember = formulas[i].getMdxMember(); 708 if (uniqueName.equals(monMember.getUniqueName())) 709 return addMember(monMember); 710 } 711 } 712 return null; 713 } 714 715 722 public MondrianLevel lookupLevel(String uniqueName) { 723 return (MondrianLevel) hLevels.get(uniqueName); 724 } 725 726 730 private boolean canAccess(mondrian.olap.Dimension dim) { 731 Role role = this.monConnection.getRole(); 732 if (!role.canAccess(dim)) 733 return false; 734 mondrian.olap.Hierarchy[] hiers = dim.getHierarchies(); 735 for (int i = 0; i < hiers.length; i++) { 736 if (role.canAccess(hiers[i])) 737 return true; 738 } 739 return false; 740 } 741 742 745 private void resetMetaData(mondrian.olap.Query monQuery) { 746 this.hDimensions = new HashMap (); 747 this.hHierarchies = new HashMap (); 748 this.hLevels = new HashMap (); 749 this.hMembers = new HashMap (); 750 this.aMeasures = new ArrayList (); 751 752 mondrian.olap.Cube cube = monQuery.getCube(); 754 mondrian.olap.Dimension[] monDims = cube.getDimensions(); 755 for (int i = 0; i < monDims.length; i++) { 756 if (canAccess(monDims[i])) 758 this.addDimension(monDims[i]); 759 } 760 761 SchemaReader sr = cube.getSchemaReader(null); 762 for (int i = 0; i < monDims.length; i++) { 763 mondrian.olap.Hierarchy[] monHiers = monDims[i].getHierarchies(); 764 for (int j = 0; j < monHiers.length; j++) { 765 List calcMembers = sr.getCalculatedMembers(monHiers[j]); 766 for (Iterator it = calcMembers.iterator(); it.hasNext();) { 767 this.addMember((mondrian.olap.Member) it.next()); 768 } 769 } 770 } 771 } 772 773 778 public mondrian.olap.Connection getConnection() { 779 return monConnection; 780 } 781 782 788 public String getCurrentMdx() { 789 if (result != null) 792 return currentMdx; 793 else if (queryAdapter == null) { 794 return mdxQuery; 795 } else { 796 try { 798 getResult(); 799 } catch (Exception e) { 800 logger.error("unexpected Exeption getResult " + e.toString()); 801 throw new RuntimeException (e); 802 } 803 return currentMdx; 804 } 805 } 806 807 815 boolean setUserMdx(String mdxQuery) throws OlapException { 816 if (this.currentMdx.equals(mdxQuery)) 817 return false; 818 819 String saveMdx = this.mdxQuery; 820 this.mdxQuery = mdxQuery; 821 if (logger.isInfoEnabled()) 822 logger.info("setUserMdx =" + mdxQuery); 823 824 mondrian.olap.Query monQuery = null; 825 try { 826 monQuery = parseMDX(); 827 } catch (OlapException e) { 828 logger.error("setUserMdx failed " + e.getMessage()); 829 this.mdxQuery = saveMdx; 831 throw e; } 833 resetMetaData(monQuery); 835 queryAdapter = new MondrianQueryAdapter(this, monQuery); 836 837 MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID); 839 if (sortExt != null) 840 sortExt.reset(); 841 842 result = null; 843 this.currentMdx = mdxQuery.replace('\r', ' '); 844 845 return true; 846 } 847 848 853 protected String getMdxQuery() { 854 return mdxQuery; 855 } 856 857 public Object getRootDecoree() { 858 return this; 859 } 860 861 864 public void destroy() { 865 logger.info(null); 866 super.destroy(); 867 if (monConnection != null) { 868 if (logger.isDebugEnabled()) 869 logger.debug("MondrianModel: closing connection " + monConnection); 870 monConnection.close(); 871 monConnection = null; 872 } 873 this.sessionId = null; 874 } 875 876 882 protected void setCurrentMdx(String currentMdx) { 883 this.currentMdx = currentMdx.replaceAll("\r", ""); 885 } 886 887 892 protected mondrian.olap.Connection getMonConnection() { 893 return monConnection; 894 } 895 896 901 protected String getJdbcDriver() { 902 return jdbcDriver; 903 } 904 905 910 protected String getConnectString() { 911 return connectString; 912 } 913 914 919 protected Util.PropertyList getConnectProperties() { 920 return connectProperties; 921 } 922 923 928 public Object getBookmarkState(int levelOfDetail) { 929 if (this.result == null) 930 return null; 931 try { 932 if (levelOfDetail == Bookmarkable.EXTENSIONAL) 933 return getExtensionalBookmarkState(); 934 return getIntensionalBookmarkState(); 935 } catch (OlapException e) { 936 logger.error(null, e); 937 throw new RuntimeException (e); 938 } 939 } 940 941 945 private Object getExtensionalBookmarkState() throws OlapException { 946 MondrianMemento memento = createMemento(); 947 memento.setMdxQuery(currentMdx); 951 boolean useQuax = queryAdapter.isUseQuax(); 952 memento.setUseQuax(useQuax); 953 if (useQuax) { 954 MondrianQuax[] quaxes = (MondrianQuax[]) queryAdapter.getQuaxes(); 955 MondrianQuaxBean[] quaxBeans = new MondrianQuaxBean[quaxes.length]; 956 for (int i = 0; i < quaxes.length; i++) { 957 quaxBeans[i] = new MondrianQuaxBean(); 958 beanFromQuax(quaxBeans[i], quaxes[i]); 959 } memento.setQuaxes(quaxBeans); 962 } 963 return memento; 964 } 965 966 971 private Object getIntensionalBookmarkState() throws OlapException { 972 MondrianMemento memento = createMemento(); 973 memento.setUseQuax(true); 974 MondrianAxis[] axes = (MondrianAxis[]) result.getAxes(); 975 MondrianQuaxBean[] quaxBeans = new MondrianQuaxBean[axes.length]; 976 for (int i = 0; i < axes.length; i++) 977 quaxBeans[i] = intensionalQuaxBeanFromAxis(axes[i]); 978 memento.setQuaxes(quaxBeans); 979 String newMdx = intensionalMdx(quaxBeans); 983 memento.setMdxQuery(newMdx); 984 return memento; 985 } 986 987 990 private String intensionalMdx(MondrianQuaxBean[] quaxBeans) { 991 992 String saveMdx = this.currentMdx; 993 Query cloneQuery = queryAdapter.getMonQuery().safeClone(); 994 MondrianQuax quaxes[] = new MondrianQuax[quaxBeans.length]; 995 for (int i = 0; i < quaxes.length; i++) { 996 MondrianQuax q = (MondrianQuax) queryAdapter.getQuaxes()[i]; 997 QueryAxis a = queryAdapter.getMonQuery().axes[i]; 998 quaxes[i] = new MondrianQuax(q.getOrdinal(), a, this); 999 } 1000 try { 1001 quaxesFromBeans(quaxes, quaxBeans); 1002 } catch (OlapException e) { 1003 logger.error(null, e); 1004 throw new IllegalArgumentException (e.toString()); 1005 } 1006 MondrianQuax saveQuaxes[] = (MondrianQuax[]) queryAdapter.getQuaxes(); 1007 queryAdapter.setQuaxes(quaxes); 1008 Query mQuery = queryAdapter.getMonQuery(); 1009 mQuery.setSlicerAxis(null); 1011 queryAdapter.onExecute(); 1013 Formula[] formulas = mQuery.getFormulas(); 1015 for (int i = 0; i < formulas.length; i++) { 1016 mondrian.olap.Member m = formulas[i].getMdxMember(); 1017 boolean remove = false; 1018 if (!m.getDimension().isMeasures()) { 1019 remove = true; 1021 } else { 1022 mondrian.olap.Exp exp = formulas[i].getExpression(); 1023 if (notMeasures(exp)) 1024 remove = true; 1025 } 1026 if (remove) { 1027 String name = formulas[i].getMdxMember().getUniqueName(); 1028 if (mQuery.canRemoveFormula(name)) { 1029 mQuery.removeFormula(name, true); 1030 } else { 1031 logger.fatal("cannot remove formula " + formulas[i].getName()); 1032 } 1033 } 1034 } 1035 1036 queryAdapter.onExecute(); String newMdx = this.currentMdx; 1038 queryAdapter.setQuaxes(saveQuaxes); 1040 queryAdapter.setMonQuery(cloneQuery); 1041 this.currentMdx = saveMdx; 1042 return newMdx; 1043 } 1044 1045 1049 private boolean notMeasures(mondrian.olap.Exp exp) { 1050 if (exp instanceof mondrian.olap.Member) { 1051 mondrian.olap.Member m = (mondrian.olap.Member) exp; 1052 if (m.getDimension().isMeasures()) 1053 return false; 1054 else 1055 return true; 1056 } else if (exp instanceof mondrian.olap.FunCall) { 1057 mondrian.olap.FunCall f = (FunCall) exp; 1058 Exp[] args = f.getArgs(); 1059 for (int i = 0; i < args.length; i++) { 1060 if (notMeasures(args[i])) 1061 return true; 1062 } 1063 } 1064 return false; 1065 } 1066 1067 1071 private MondrianMemento createMemento() { 1072 MondrianMemento memento = new MondrianMemento(); 1073 memento.setJdbcDriver(jdbcDriver); 1074 memento.setConnectString(connectString); 1075 memento.setVersion(MondrianMemento.CURRENT_VERSION); 1076 memento.setAxesSwapped(queryAdapter.isSwapAxes()); 1078 MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID); 1080 if (sortExt != null) 1081 storeSort(sortExt, memento); 1082 return memento; 1083 } 1084 1085 private MondrianQuaxBean intensionalQuaxBeanFromAxis(MondrianAxis axis) throws OlapException { 1086 MondrianQuaxBean quaxBean = new MondrianQuaxBean(); 1087 MondrianHierarchy[] hiers = (MondrianHierarchy[]) axis.getHierarchies(); 1088 1089 quaxBean.setNDimension(hiers.length); 1090 quaxBean.setHierarchizeNeeded(false); 1091 quaxBean.setOrdinal(axis.getOrdinal()); 1092 1093 PositionNodeBean rootBean = new PositionNodeBean(); 1094 rootBean.setReference(null); 1095 quaxBean.setPosTreeRoot(rootBean); 1096 1097 PositionNodeBean parentBean = rootBean; 1098 for (int i = 0; i < hiers.length; i++) { 1099 ExpBean expBean; 1100 if (hiers[i].getDimension().isMeasure()) { 1101 Exp exp = createMeasuresExp(axis, i); 1102 expBean = createBeanFromExp(exp); 1103 } else { 1104 ExpBean hierBean = createBeanFromExp(hiers[i].getMonHierarchy()); 1107 expBean = new ExpBean(); 1108 expBean.setType(ExpBean.TYPE_TOPLEVEL_MEMBERS); 1109 expBean.setArgs(new ExpBean[] { hierBean}); 1110 } 1111 PositionNodeBean nodeBean = new PositionNodeBean(); 1112 nodeBean.setReference(expBean); 1113 parentBean.setChildren(new PositionNodeBean[] { nodeBean}); 1114 parentBean = nodeBean; 1115 } 1116 return quaxBean; 1117 } 1118 1119 1124 private Exp createMeasuresExp(MondrianAxis axis, int i) { 1125 List measuresList = new ArrayList (); 1126 Set measuresSet = new HashSet (); 1127 for (Iterator it = axis.getPositions().iterator(); it.hasNext();) { 1128 MondrianPosition mp = (MondrianPosition) it.next(); 1129 MondrianMember member = (MondrianMember) mp.getMembers()[i]; 1130 if (measuresSet.add(member)) 1131 measuresList.add(new MemberExpr(member.getMonMember())); 1132 } 1133 if (measuresList.size() == 1) 1134 return (Exp) measuresList.get(0); 1135 Exp[] args = (Exp[]) measuresList.toArray(new Exp[measuresList.size()]); 1136 return new UnresolvedFunCall("{}", Syntax.Braces, args); 1137 } 1138 1139 1144 public void setBookmarkState(Object state) { 1145 1146 MondrianMemento memento = (MondrianMemento) state; 1147 int version = memento.getVersion(); 1148 if (version <= 1) { 1149 logger.warn("Bookmark is of old state (not supported any more in the future)!\nPlease save again!"); 1150 } 1151 mdxQuery = memento.getMdxQuery(); 1152 1153 if (isInitialized) { 1154 1156 mondrian.olap.Query monQuery = null; 1157 try { 1158 monQuery = parseMDX(); 1159 } catch (OlapException e) { 1160 String err = e.getMessage(); 1162 logger.fatal(err); 1163 throw new RuntimeException (err); 1164 } 1165 1166 resetMetaData(monQuery); 1168 1169 queryAdapter = new MondrianQueryAdapter(this, monQuery); 1170 1171 MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID); 1172 if (sortExt != null) 1173 sortExt.reset(); 1174 1175 } else { 1176 1177 connectString = memento.getConnectString(); 1178 jdbcDriver = memento.getJdbcDriver(); 1179 1180 try { 1184 initialize(); 1185 } catch (OlapException e) { 1186 String err = e.getMessage(); 1188 logger.fatal(err); 1189 throw new RuntimeException (err); 1190 } 1191 } 1193 1194 boolean useQuax = true; 1195 if (version >= 3) { 1196 useQuax = memento.isUseQuax(); 1197 queryAdapter.setUseQuax(useQuax); 1198 } 1199 1200 if (useQuax) { 1201 MondrianQuaxBean[] quaxBeans = (MondrianQuaxBean[]) memento.getQuaxes(); 1203 MondrianQuax quaxes[] = (MondrianQuax[]) queryAdapter.getQuaxes(); 1204 1206 if (version <= 1) { 1207 for (int i = 0; i < quaxes.length; i++) { 1208 boolean qubonMode = quaxBeans[i].isQubonMode(); 1209 1210 quaxes[i].setQubonMode(qubonMode); 1211 1212 if (qubonMode) 1214 MondrianOldStuff.handleQubonMode(quaxes[i], quaxBeans[i], this); 1215 else 1216 MondrianOldStuff.handleDrillExMode(quaxes[i], quaxBeans[i], this); 1217 } 1218 } else { 1219 try { 1220 quaxesFromBeans(quaxes, quaxBeans); 1221 } catch (OlapException e) { 1222 logger.error(null, e); 1223 throw new IllegalArgumentException (e.toString()); 1224 } 1225 } 1226 } 1227 1228 MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID); 1230 restoreSort(sortExt, memento); 1231 1232 queryAdapter.setSwapAxes(memento.isAxesSwapped()); 1234 1235 fireModelChanged(); 1239 } 1240 1241 private Exp[] createExpsFromBeans(ExpBean[] beans) throws OlapException { 1242 Exp[] exps = new Exp[beans.length]; 1243 for (int i = 0; i < beans.length; i++) { 1244 exps[i] = (Exp) createExpFromBean(beans[i]); 1245 } 1246 return exps; 1247 } 1248 1249 1255 protected Object createExpFromBean(ExpBean expBean) throws OlapException { 1256 if (expBean.getType() == ExpBean.TYPE_TOPLEVEL_MEMBERS) { 1257 SchemaReader scr = getMonConnection().getSchemaReader(); 1258 Exp[] args = createExpsFromBeans(expBean.getArgs()); 1259 HierarchyExpr he = (HierarchyExpr) args[0]; 1260 mondrian.olap.Hierarchy h = he.getHierarchy(); 1261 return MondrianUtil.topLevelMembers(h, false, scr); 1262 } 1263 1264 if (expBean.getType() == ExpBean.TYPE_MEMBER) { 1265 MondrianMember member = (MondrianMember) lookupMemberByUName(expBean.getName()); 1266 if (member == null) { 1267 throw new OlapException("could not find member " + expBean.getName()); 1269 } 1270 return new MemberExpr(member.getMonMember()); 1271 } 1272 1273 if (expBean.getType() == ExpBean.TYPE_FUNCALL) { 1274 String name = expBean.getName(); 1276 ExpBean[] argBeans = expBean.getArgs(); 1277 Exp[] args = createExpsFromBeans(argBeans); 1278 if ("Parameter".equalsIgnoreCase(name)) { 1279 String paramId = String.valueOf(((Literal)args[0]).getValue()); 1280 Exp value = args[2]; 1281 Type type = value.getType(); 1282 String descr = ""; 1283 if (args.length == 4) 1284 descr = (String )((Literal)args[3]).getValue(); 1285 return new ParameterExpr(new ParameterImpl(paramId, value, descr, type)); 1286 } else if ("ParamRef".equalsIgnoreCase(name)) { 1287 throw new IllegalArgumentException (name); 1289 } 1290 Syntax syntax = MondrianUtil.funCallSyntax(name, argBeans.length); 1291 return new UnresolvedFunCall(name, syntax, args); 1292 } 1293 1294 if (expBean.getType() == ExpBean.TYPE_LEVEL) { 1295 MondrianLevel lev = this.lookupLevel(expBean.getName()); 1297 if (lev == null) { 1298 throw new OlapException("could not find Level " + expBean.getName()); 1300 } 1301 return new LevelExpr(lev.getMonLevel()); 1302 } else if (expBean.getType() == ExpBean.TYPE_HIER) { 1303 MondrianHierarchy hier = this.lookupHierarchy(expBean.getName()); 1305 if (hier == null) { 1306 throw new OlapException("could not find Hierarchy " + expBean.getName()); 1308 } 1309 return new HierarchyExpr(hier.getMonHierarchy()); 1310 } else if (expBean.getType() == ExpBean.TYPE_DIM) { 1311 MondrianDimension dim = this.lookupDimension(expBean.getName()); 1313 if (dim == null) { 1314 throw new OlapException("could not find Dimension " + expBean.getName()); 1316 } 1317 return new DimensionExpr(dim.getMonDimension()); 1318 } else if (expBean.getType() == ExpBean.TYPE_STRING_LITERAL) { 1319 String str = (String ) expBean.getLiteralValue(); 1321 return Literal.createString(str); 1322 } else if (expBean.getType() == ExpBean.TYPE_INTEGER_LITERAL) { 1323 Integer iii = (Integer ) expBean.getLiteralValue(); 1325 return Literal.create(iii); 1326 } else if (expBean.getType() == ExpBean.TYPE_DOUBLE_LITERAL) { 1327 Double ddd = (Double ) expBean.getLiteralValue(); 1329 return Literal.create(ddd); 1330 } else 1331 throw new OlapException("Invalid ExpBean Type " + expBean.getType()); 1332 1333 } 1334 1335 protected ExpBean createBeanFromExp(Object exp) throws OlapException { 1336 ExpBean bean = new ExpBean(); 1337 1338 if (exp instanceof mondrian.olap.Member) { 1339 mondrian.olap.Member m = (mondrian.olap.Member) exp; 1340 bean.setType(ExpBean.TYPE_MEMBER); 1341 bean.setName(m.getUniqueName()); 1342 bean.setArgs(new ExpBean[0]); 1343 } else if (exp instanceof mondrian.olap.Level) { 1344 mondrian.olap.Level lev = (mondrian.olap.Level) exp; 1345 bean.setType(ExpBean.TYPE_LEVEL); 1346 bean.setName(lev.getUniqueName()); 1347 bean.setArgs(new ExpBean[0]); 1348 } else if (exp instanceof mondrian.olap.Hierarchy) { 1349 mondrian.olap.Hierarchy hier = (mondrian.olap.Hierarchy) exp; 1350 bean.setType(ExpBean.TYPE_HIER); 1351 bean.setName(hier.getUniqueName()); 1352 bean.setArgs(new ExpBean[0]); 1353 } else if (exp instanceof mondrian.olap.Dimension) { 1354 mondrian.olap.Dimension dim = (mondrian.olap.Dimension) exp; 1355 bean.setType(ExpBean.TYPE_DIM); 1356 bean.setName(dim.getUniqueName()); 1357 bean.setArgs(new ExpBean[0]); 1358 } else if (exp instanceof mondrian.olap.FunCall) { 1359 FunCall f = (FunCall) exp; 1360 bean.setType(ExpBean.TYPE_FUNCALL); 1361 bean.setName(f.getFunName()); 1362 bean.setArgs(createBeansFromExps(f.getArgs())); 1363 } else if (exp instanceof ParameterExpr) { 1364 Parameter p = ((ParameterExpr)exp).getParameter(); 1365 bean.setType(ExpBean.TYPE_FUNCALL); 1366 bean.setName("Parameter"); 1367 bean.setArgs(createBeansFromExps(getParamterArgs(p))); 1368 } else if (exp instanceof MemberExpr) { 1370 mondrian.olap.Member m = ((MemberExpr) exp).getMember(); 1371 bean.setType(ExpBean.TYPE_MEMBER); 1372 bean.setName(m.getUniqueName()); 1373 bean.setArgs(new ExpBean[0]); 1374 } else if (exp instanceof LevelExpr) { 1375 mondrian.olap.Level lev = ((LevelExpr) exp).getLevel(); 1376 bean.setType(ExpBean.TYPE_LEVEL); 1377 bean.setName(lev.getUniqueName()); 1378 bean.setArgs(new ExpBean[0]); 1379 } else if (exp instanceof HierarchyExpr) { 1380 mondrian.olap.Hierarchy hier = ((HierarchyExpr) exp).getHierarchy(); 1381 bean.setType(ExpBean.TYPE_HIER); 1382 bean.setName(hier.getUniqueName()); 1383 bean.setArgs(new ExpBean[0]); 1384 } else if (exp instanceof DimensionExpr) { 1385 mondrian.olap.Dimension dim = ((DimensionExpr) exp).getDimension(); 1386 bean.setType(ExpBean.TYPE_DIM); 1387 bean.setName(dim.getUniqueName()); 1388 bean.setArgs(new ExpBean[0]); 1389 } else if (exp instanceof mondrian.olap.Literal) { 1390 mondrian.olap.Literal lit = (mondrian.olap.Literal) exp; 1391 Object val = lit.getValue(); 1392 if (lit.getCategory() == Category.Numeric) { 1393 if (val instanceof Integer ) 1394 bean.setType(ExpBean.TYPE_INTEGER_LITERAL); 1395 else 1396 bean.setType(ExpBean.TYPE_DOUBLE_LITERAL); 1397 } else { 1398 bean.setType(ExpBean.TYPE_STRING_LITERAL); 1400 } 1401 bean.setLiteralValue(val); 1402 bean.setArgs(new ExpBean[0]); 1403 } else { 1404 logger.fatal("cannot create ExpBean type =" + exp.getClass().toString()); 1405 throw new IllegalArgumentException (exp.getClass().toString()); 1406 } 1407 1408 return bean; 1409 } 1410 1411 1417 private Exp[] getParamterArgs(Parameter p) { 1418 Exp expName = Literal.createString(p.getName()); 1419 Exp expValue; 1420 Exp expType; 1421 1422 Object objValue = p.getValue(); 1424 if (objValue == null) 1425 objValue = p.getDefaultExp(); 1426 if (objValue instanceof Literal) 1427 objValue = ((Literal)objValue).getValue(); 1428 else if (objValue instanceof MemberExpr) 1429 objValue = ((MemberExpr)objValue).getMember(); 1430 1431 if (objValue instanceof String ) { 1432 expValue = Literal.createString((String )objValue); 1433 expType = Literal.createSymbol("STRING"); 1434 } else if (objValue instanceof Double ) { 1435 expValue = Literal.create((Double )objValue); 1436 expType = Literal.createSymbol("NUMBER"); 1437 } else if (objValue instanceof Integer ) { 1438 expValue = Literal.create((Integer )objValue); 1439 expType = Literal.createSymbol("NUMBER"); 1440 } else if (objValue instanceof mondrian.olap.Member) { 1441 mondrian.olap.Member m = (mondrian.olap.Member)objValue; 1442 expValue = new MemberExpr(m); 1443 expType = new DimensionExpr(m.getDimension()); 1444 } else throw new IllegalArgumentException ("unknown Param value: " + objValue + ": " + objValue.getClass()); 1445 1446 Exp expDescr = p.getDescription() != null ? Literal.createString(p.getDescription()):Literal.createString(""); 1447 return new Exp[]{expName, expType, expValue, expDescr}; 1448 } 1449 1450 private ExpBean[] createBeansFromExps(Object [] exps) throws OlapException { 1451 ExpBean[] beans = new ExpBean[exps.length]; 1452 for (int i = 0; i < exps.length; i++) { 1453 beans[i] = createBeanFromExp(exps[i]); 1454 } 1455 return beans; 1456 } 1457 1458 public DataSource getSqlDataSource() { 1459 return ((RolapConnection) monConnection).getDataSource(); 1460 } 1461 1462 public String getDynresolver() { 1463 return dynresolver; 1464 } 1465 1466 public void setDynresolver(String dynresolver) { 1467 this.dynresolver = dynresolver; 1468 } 1469 1470 public void setServletContext(ServletContext servletContext) { 1471 this.servletContext = servletContext; 1472 } 1473 1474 1477 public boolean isConnectionPooling() { 1478 return connectionPooling; 1479 } 1480 1481 1484 public void setConnectionPooling(boolean connectionPooling) { 1485 this.connectionPooling = connectionPooling; 1486 } 1487 1488 1491 public DataSource getExternalDataSource() { 1492 return externalDataSource; 1493 } 1494 1495 1498 public void setExternalDataSource(DataSource externalDataSource) { 1499 this.externalDataSource = externalDataSource; 1500 } 1501 1505 public String getDynLocale() { 1506 return this.dynLocale; 1507 } 1508 1509 1513 public void setDynLocale(String dynLocale) { 1514 this.dynLocale = dynLocale; 1515 } 1516 1517 1521 public String getDataSourceChangeListener() { 1522 return this.dataSourceChangeListener; 1523 } 1524 1525 1529 public void setDataSourceChangeListener(String dataSourceChangeListener) { 1530 this.dataSourceChangeListener = dataSourceChangeListener; 1531 } 1532 1533 1539 protected mondrian.olap.Query rewriteMDXQuery(mondrian.olap.Query query) { 1540 try { 1541 QueryVisitor visitor = new QueryVisitor(); 1542 QueryAxis[] axes = query.getAxes(); 1543 for (int i = 0; i < axes.length; i++) { 1544 axes[i].accept(visitor); 1545 } 1546 1547 1548 String originalQuery = query.toString(); 1564 if (logger.isDebugEnabled()) { 1565 logger.debug("rewriteMDXQuery: originalQuery="+originalQuery); 1566 } 1567 visitor.cleanUpPhysicalModel(); 1568 removeLogicalNameFromList("[Time]"); 1569 1570 boolean changeHappened = false; 1571 Iterator ite = visitor.getPhysicalModel().iterator(); 1572 while (ite.hasNext()) { 1573 List list = (List ) ite.next(); 1574 Iterator memIterator = list.iterator(); 1575 1576 loop: 1577 while (memIterator.hasNext()) { 1578 String memberName = 1579 ((mondrian.olap.Member)memIterator.next()).toString(); 1580 String [] uniqueNameParts = Util.explode(memberName); 1581 String dimension = uniqueNameParts[0]; 1582 1583 Iterator logicalIt = aLogicalModel.iterator(); 1584 while (logicalIt.hasNext()) { 1585 String logicalName = (String ) logicalIt.next(); 1586 1587 1595 if (logicalName.startsWith(dimension) && 1596 isAtSameLevel(memberName, logicalName) ) { 1597 originalQuery = replaceEnumeratedQuery( 1598 originalQuery, 1599 memberName, 1600 logicalName); 1601 changeHappened = true; 1602 break loop; 1604 } 1605 } 1606 break loop; 1610 } 1611 } 1612 1613 mondrian.olap.Query result = query; 1614 1615 if (changeHappened) { 1616 result = getConnection().parseQuery(originalQuery); 1620 visitor = new QueryVisitor(); 1621 axes = result.getAxes(); 1622 for (int i = 0; i < axes.length; i++) { 1623 axes[i].accept(visitor); 1624 } 1625 } 1626 1627 aLogicalModel = visitor.getLogicalModel(); 1628 1629 return result; 1630 1631 } catch (Exception e) { logger.warn(" Error in rewriting MDX Query " ); 1633 e.printStackTrace(); 1634 aLogicalModel.clear(); 1635 1636 return query; 1638 } finally { 1639 } 1641 } 1642 1643 1644 1652 public String replaceEnumeratedQuery(final String query, 1653 final String memberName, 1654 final String logicalName) { 1655 if (logger.isDebugEnabled()) { 1656 logger.debug("replaceEnumeratedQuery: Given Query is " + query); 1657 } 1658 1659 StringBuffer result = new StringBuffer (200); 1660 1661 int index = query.indexOf(memberName); 1662 result.append(query.substring(0, index)); 1664 result.append(logicalName); 1666 1667 index = query.indexOf("}", index); 1668 result.append(query.substring(index)); 1670 1671 if (logger.isDebugEnabled()) { 1672 logger.debug("replaceEnumeratedQuery: Resultant Query is " + 1673 result.toString()); 1674 } 1675 1676 return result.toString(); 1677 } 1678 1679 1686 public boolean isAtSameLevel(final String memberName, 1687 final String logicalName) { 1688 final String [] memberUniqueNameParts = Util.explode(memberName); 1689 final String [] logicalUniqueNameParts = Util.explode(logicalName); 1690 return (memberUniqueNameParts.length == logicalUniqueNameParts.length); 1691 1692 } 1693 1694 1698 static class QueryVisitor extends MdxVisitorImpl { 1699 1700 private LinkedList logicalDimensionList; 1703 private List physicalDimensionList; 1704 private List enumMemberList; 1705 1706 private QueryVisitor() { 1707 this.logicalDimensionList = new LinkedList (); 1708 this.physicalDimensionList = new ArrayList (); 1709 this.enumMemberList = new ArrayList (); 1710 1711 } 1712 public Object visit(mondrian.mdx.UnresolvedFunCall call) { 1713 1714 if (call.getFunName().equalsIgnoreCase("children") || 1715 call.getFunName().equalsIgnoreCase("members" )) { 1716 logicalDimensionList.add(call.toString()); 1717 enumMemberList = new ArrayList (); 1718 physicalDimensionList.add(enumMemberList); 1719 1720 } else if (call.getFunName().equals("{}")) { 1721 enumMemberList = new ArrayList (); 1722 physicalDimensionList.add(enumMemberList); 1723 } 1724 1725 return null; 1726 } 1727 public Object visit(mondrian.mdx.ResolvedFunCall call) { 1728 1729 if (call.getFunName().equalsIgnoreCase("children") || 1730 call.getFunName().equalsIgnoreCase("members" )) { 1731 1732 logicalDimensionList.add(call.toString()); 1733 enumMemberList = new ArrayList (); 1734 physicalDimensionList.add(enumMemberList); 1735 1736 } else if (call.getFunName().equals("{}")) { 1737 enumMemberList = new ArrayList (); 1738 physicalDimensionList.add(enumMemberList); 1739 } 1740 1741 return null; 1742 } 1743 public Object visit(mondrian.mdx.MemberExpr memberExpr) { 1744 mondrian.olap.Member member = memberExpr.getMember(); 1745 enumMemberList.add(member); 1746 1747 return null; 1748 } 1749 public LinkedList getLogicalModel() { 1750 return logicalDimensionList; 1751 } 1752 1753 public List getPhysicalModel() { 1754 return physicalDimensionList; 1755 } 1756 1757 1772 public void cleanUpPhysicalModel() { 1773 List newList = new ArrayList (); 1774 for(int i = 0; i < physicalDimensionList.size(); i++) { 1776 List aList = (List ) physicalDimensionList.get(i); 1777 if (aList.size() != 1 && allSameDimension(aList)) { 1778 newList.add(aList); 1779 } 1780 } 1781 physicalDimensionList = newList; 1782 } 1783 1784 1785 public void print(Object msg) { 1787 System.out.println(msg); 1788 } 1789 public void printLists() { 1791 Iterator it = logicalDimensionList.iterator(); 1792 while(it.hasNext()) { 1793 print((String )it.next()); 1794 } 1795 print(" going to print members "); 1796 it = physicalDimensionList.iterator(); 1797 while(it.hasNext()) { 1798 List list = (List )it.next(); 1799 Iterator ite = list.iterator(); 1800 while (ite.hasNext()) { 1801 print((mondrian.olap.Member)ite.next()); 1802 } 1803 print(" Going to print next member lists"); 1804 } 1805 } 1806 1807 1815 private boolean allSameDimension(List list) { 1816 if (list.size() == 0) { 1817 return false; 1818 } 1819 1820 String firstMemberName = 1822 ((mondrian.olap.Member) list.get(0)).toString(); 1823 String [] uniqueNameParts = Util.explode(firstMemberName); 1824 String dimName = uniqueNameParts[0]; 1826 boolean result = true; 1827 Iterator it = list.iterator(); 1828 while (it.hasNext()) { 1829 String name = ((mondrian.olap.Member) it.next()).toString(); 1831 if (! name.startsWith(dimName)) { 1832 result = false; 1833 break; 1834 } 1835 } 1836 1837 return result; 1838 } 1839 } 1840 1841 1844 protected void removeLogicalNameFromList(final String hierName) { 1845 for (int i = 0; i < aLogicalModel.size(); i++) { 1846 String listName = (String ) aLogicalModel.get(i); 1847 if (listName.startsWith(hierName)) { 1848 aLogicalModel.remove(i); 1849 break; 1850 } 1851 } 1852 } 1853 class Listener implements MemoryMonitor.Listener { 1854 String oomMsg; 1855 Listener() { 1856 } 1857 public void memoryUsageNotification(long used, long max) { 1858 StringBuffer buf = new StringBuffer (200); 1859 buf.append("OutOfMemory used="); 1860 buf.append(used); 1861 buf.append(", max="); 1862 buf.append(max); 1863 buf.append(" for mdx: "); 1864 buf.append(queryAdapter.getMonQuery().toMdx()); 1865 this.oomMsg = buf.toString(); 1866 } 1867 final void check() throws MemoryLimitExceededException { 1868 if (oomMsg != null) { 1869 throw new MemoryLimitExceededException(oomMsg); 1870 } 1871 } 1872 } 1873 1874 1875} 1877 1878 | Popular Tags |