1 13 package com.tonbeller.jpivot.xmla; 14 15 import java.util.ArrayList ; 16 import java.util.Collection ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 21 import org.apache.log4j.Logger; 22 23 import com.tonbeller.jpivot.olap.mdxparse.CompoundId; 24 import com.tonbeller.jpivot.olap.mdxparse.Exp; 25 import com.tonbeller.jpivot.olap.mdxparse.FunCall; 26 import com.tonbeller.jpivot.olap.mdxparse.Parameter; 27 import com.tonbeller.jpivot.olap.mdxparse.ParsedQuery; 28 import com.tonbeller.jpivot.olap.mdxparse.QueryAxis; 29 import com.tonbeller.jpivot.olap.model.Dimension; 30 import com.tonbeller.jpivot.olap.model.Member; 31 import com.tonbeller.jpivot.olap.model.MemberPropertyMeta; 32 import com.tonbeller.jpivot.olap.model.OlapException; 33 import com.tonbeller.jpivot.olap.navi.MemberProperties; 34 import com.tonbeller.jpivot.olap.query.Quax; 35 import com.tonbeller.jpivot.olap.query.QuaxChangeListener; 36 import com.tonbeller.jpivot.olap.query.QueryAdapter; 37 import com.tonbeller.jpivot.util.StringUtil; 38 39 42 public class XMLA_QueryAdapter extends QueryAdapter implements QuaxChangeListener { 43 44 static Logger logger = Logger.getLogger(XMLA_QueryAdapter.class); 45 46 private ParsedQuery parsedQuery; 47 private ParsedQuery cloneQuery; 48 private XMLA_Result result; 49 private String originalMDX; 50 private int nAxes; 52 55 XMLA_QueryAdapter(XMLA_Model model) { 56 super(model); 57 58 genMDXHierarchize = true; 61 parsedQuery = model.getPQuery(); QueryAxis[] queryAxes = parsedQuery.getAxes(); 64 65 nAxes = queryAxes.length; 67 68 quaxes = new XMLA_Quax[nAxes]; 69 for (int i = 0; i < nAxes; i++) { 70 quaxes[i] = new XMLA_Quax(i, queryAxes[i], model); 71 quaxes[i].addChangeListener(this); 72 } 73 74 } 75 76 79 public void quaxChanged(Quax quax, Object source, boolean changedByNavi) { 80 useQuax = true; 81 Map paraMap = parsedQuery.getParaMap(); 83 int iOrdinal = quax.getOrdinal(); 84 Collection params = paraMap.values(); 85 List removeList = new ArrayList (); 86 for (Iterator iter = params.iterator(); iter.hasNext();) { 87 Parameter param = (Parameter) iter.next(); 88 int iAxis = param.getIAxis(); 89 if (iAxis == iOrdinal) { 90 removeList.add(param.getName().toUpperCase()); 93 } 94 } 95 for (Iterator iter = removeList.iterator(); iter.hasNext();) { 96 String objToRemove = (String ) iter.next(); 97 paraMap.remove(objToRemove); 98 } 99 } 100 101 104 public Quax[] getQuaxes() { 105 return quaxes; 106 } 107 108 118 protected void onExecute() { 119 120 if (useQuax) { 122 int iQuaxToSort = -1; 123 if (sortMan != null) 124 iQuaxToSort = sortMan.activeQuaxToSort(); 125 126 QueryAxis[] qAxes = parsedQuery.getAxes(); 127 for (int i = 0; i < quaxes.length; i++) { 128 boolean doHierarchize = false; 129 if (genMDXHierarchize && quaxes[i].isHierarchizeNeeded() && i != iQuaxToSort) { 130 doHierarchize = true; 131 if (logger.isDebugEnabled()) 132 logger.debug("MDX Generation added Hierarchize()"); 133 } 134 Exp eSet = (Exp) quaxes[i].genExp(doHierarchize); 135 qAxes[i].setExp(eSet); 136 } } 139 QueryAxis[] qAxes = parsedQuery.getAxes(); 141 for (int i = 0; i < quaxes.length; i++) { 142 XMLA_MemberProperties mPropExt = (XMLA_MemberProperties) model 143 .getExtension(MemberProperties.ID); 144 MemberPropertyMeta[] mprops = null; 145 if (mPropExt != null) 146 mprops = mPropExt.getVisibleProperties(); 147 if (mprops != null && mprops.length > 0) { 148 List dProps = new ArrayList (); 149 PropsLoop: for (int j = 0; j < mprops.length; j++) { 150 String hierUname = mprops[j].getScope(); 151 XMLA_Hierarchy hier = ((XMLA_Model) model).lookupHierByUName(hierUname); 152 String dimUname; 153 if (hier != null) { 154 dimUname = hier.getDimUniqueName(); 155 Dimension dim = hier.getDimension(); 157 Quax q = findQuax(dim); 158 if ((q == null) || !quaxes[i].equals(q)) 159 continue PropsLoop; 160 } else 161 continue PropsLoop; 162 CompoundId cid = new CompoundId(dimUname); 163 String propName = mprops[j].getName(); 164 cid.append(StringUtil.bracketsAround(propName)); 165 dProps.add(cid); 166 } 167 qAxes[i].setDimProps(dProps); 168 } 169 } 171 if (sortMan != null) { 173 if (!useQuax) { 174 if (cloneQuery == null) { 180 if (sortMan.isSortOnQuery()) 181 cloneQuery = (ParsedQuery) parsedQuery.clone(); 182 } else { 183 if (sortMan.isSortOnQuery()) 185 parsedQuery = (ParsedQuery) cloneQuery.clone(); 186 else 187 parsedQuery = cloneQuery; 188 } 189 } 190 sortMan.addSortToQuery(); 191 } 192 193 194 if (axesSwapped) { 196 swapAxes(); 197 } 198 199 Map cmpmap = ((XMLA_Model) model).getCalcMeasurePropMap(); 202 if (cmpmap != null && cmpmap.size() > 0) { 203 List cellProps = parsedQuery.getCellProps(); 204 CompoundId cid = new CompoundId("FONT_SIZE", false); 205 boolean found = false; 206 for (Iterator iter = cellProps.iterator(); iter.hasNext();) { 207 CompoundId ci = (CompoundId) iter.next(); 208 if (ci.toMdx().equalsIgnoreCase("FONT_SIZE")) { 209 found = true; 210 break; 211 } 212 } 213 if (!found) 214 cellProps.add(cid); 215 } 216 217 long t1 = System.currentTimeMillis(); 218 219 String mdx = parsedQuery.toMdx(); 220 221 if (logger.isDebugEnabled()) 222 logger.debug(mdx); 223 224 long t2 = System.currentTimeMillis(); 225 logger.info("monQuery.toString took " + (t2 - t1) + " millisec"); 226 227 ((XMLA_Model) model).setCurrentMdx(mdx); 228 229 } 230 231 protected void onExecuteDrill() { 232 long t1 = System.currentTimeMillis(); 233 234 String mdx = parsedQuery.toDrillMdx(); 236 237 if (logger.isDebugEnabled()) 238 logger.debug(mdx); 239 240 long t2 = System.currentTimeMillis(); 241 logger.info("monQuery.toString took " + (t2 - t1) + " millisec"); 242 243 ((XMLA_Model) model).setCurrentMdx(mdx); 244 245 } 246 247 248 251 String getCurrentMdx() { 252 String mdx = parsedQuery.toMdx(); 253 return mdx; 254 } 255 256 259 public ParsedQuery getParsedQuery() { 260 return parsedQuery; 261 } 262 263 268 protected Object createMemberSet(List memList) { 269 Exp[] exps = new Exp[memList.size()]; 270 int i = 0; 271 for (Iterator iter = memList.iterator(); iter.hasNext();) { 272 XMLA_Member m = (XMLA_Member) iter.next(); 273 exps[i++] = m; 274 } 275 FunCall f = new FunCall("{}", exps, FunCall.TypeBraces); 276 return f; 277 } 278 279 283 293 public boolean canExpand(Member member) { 294 295 if (((XMLA_Member) member).isCalculated()) 297 return false; 298 299 if (!isDrillable(member, false)) 300 return false; 301 302 Dimension dim = member.getLevel().getHierarchy().getDimension(); 303 Quax quax = findQuax(dim); 304 return (quax == null) ? false : quax.canExpand(member); 305 } 306 307 313 public boolean canExpand(Member[] pathMembers) { 314 315 Member m = pathMembers[pathMembers.length - 1]; 316 if (((XMLA_Member) m).isCalculated()) 318 return false; 319 320 if (!isDrillable(m, false)) 321 return false; 322 323 Dimension dim = m.getLevel().getHierarchy().getDimension(); 324 Quax quax = findQuax(dim); 325 326 return (quax == null) ? false : quax.canExpand(pathMembers); 327 } 328 329 332 public void expand(Member member) { 333 XMLA_Member m = (XMLA_Member) member; 334 if (isDrillable(m, true)) 335 super.expand(member); 336 else 337 model.fireModelChanged(); 338 } 339 340 344 public void expand(Member[] pathMembers) { 345 XMLA_Member m = (XMLA_Member) pathMembers[pathMembers.length - 1]; 346 if (isDrillable(m, true)) 347 super.expand(pathMembers); 348 else 349 model.fireModelChanged(); 350 } 351 352 357 public boolean canCollapse(Member member) { 358 if (((XMLA_Member) member).isCalculated()) 360 return false; 361 Dimension dim = member.getLevel().getHierarchy().getDimension(); 362 Quax quax = findQuax(dim); 363 364 return (quax == null) ? false : quax.canCollapse(member); 365 } 366 367 372 public boolean canCollapse(Member[] pathMembers) { 373 374 Member member = pathMembers[pathMembers.length - 1]; 375 if (((XMLA_Member) member).isCalculated()) 377 return false; 378 Dimension dim = member.getLevel().getHierarchy().getDimension(); 379 Quax quax = findQuax(dim); 380 381 return (quax == null) ? false : quax.canCollapse(pathMembers); 382 } 383 384 388 391 public boolean canDrillDown(Member member) { 392 393 if (!isDrillable(member, false)) 394 return false; 395 Dimension dim = member.getLevel().getHierarchy().getDimension(); 396 Quax quax = findQuax(dim); 397 return (quax == null) ? false : quax.canDrillDown(member); 398 } 399 400 404 408 void setSwapAxes(boolean swap) { 409 if (parsedQuery.getAxes().length >= 2) { 410 axesSwapped = swap; 411 if (logger.isInfoEnabled()) { 412 logger.info("swapAxes " + axesSwapped); 413 } 414 model.fireModelChanged(); 415 } 416 } 417 418 422 425 private void swapAxes() { 426 QueryAxis[] queryAxes = parsedQuery.getAxes(); 427 if (queryAxes.length >= 2) { 428 Exp exp = queryAxes[0].getExp(); 429 queryAxes[0].setExp(queryAxes[1].getExp()); 430 queryAxes[1].setExp(exp); 431 } 432 } 433 434 439 private boolean isDrillable(Member member, boolean allowComplete) { 440 XMLA_Member m = (XMLA_Member) member; 441 long ccard = m.getChildrenCardinality(); if (ccard >= 0) 443 return (ccard > 0); 444 XMLA_Level level = (XMLA_Level) member.getLevel(); 445 XMLA_Model xmod = (XMLA_Model) model; 446 XMLA_Hierarchy hier = (XMLA_Hierarchy) level.getHierarchy(); 447 if (xmod.isMicrosoft() && hier.getStructure() == XMLA_Hierarchy.STRUCTURE_FULLYBALANCED 450 && level.getChildLevel() != null) { 451 return true; 454 } 455 if (!allowComplete) 456 return true; 457 try { 458 xmod.completeMember(m); 459 } catch (OlapException e) { 460 logger.error("?", e); 461 return false; 462 } 463 return (m.getChildrenCardinality() > 0); 464 } 465 466 } | Popular Tags |