1 13 package org.openi.xmla.navigator.hierarchy; 14 15 import java.util.ArrayList ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Set ; 20 21 import org.apache.log4j.Logger; 22 import org.w3c.dom.Document ; 23 import org.w3c.dom.Element ; 24 25 import com.tonbeller.jpivot.core.ModelChangeEvent; 26 import com.tonbeller.jpivot.core.ModelChangeListener; 27 import com.tonbeller.jpivot.olap.model.Axis; 28 import com.tonbeller.jpivot.olap.model.Hierarchy; 29 import com.tonbeller.jpivot.olap.model.OlapException; 30 import com.tonbeller.jpivot.olap.model.OlapModel; 31 import com.tonbeller.jpivot.olap.model.Result; 32 import com.tonbeller.jpivot.olap.navi.ChangeSlicer; 33 import com.tonbeller.jpivot.olap.navi.MemberDeleter; 34 import com.tonbeller.jpivot.olap.navi.PlaceHierarchiesOnAxes; 35 import com.tonbeller.jpivot.olap.navi.PlaceMembersOnAxes; 36 import com.tonbeller.jpivot.ui.Available; 37 import com.tonbeller.tbutils.res.Resources; 38 import com.tonbeller.wcf.catedit.CategoryEditor; 39 import com.tonbeller.wcf.catedit.CategoryModelSupport; 40 import com.tonbeller.wcf.component.Component; 41 import com.tonbeller.wcf.controller.Dispatcher; 42 import com.tonbeller.wcf.controller.DispatcherSupport; 43 import com.tonbeller.wcf.controller.RequestContext; 44 import com.tonbeller.wcf.controller.RequestListener; 45 import com.tonbeller.wcf.selection.SelectionModel; 46 47 import com.tonbeller.jpivot.olap.mdxparse.CompoundId; 48 import com.tonbeller.jpivot.olap.mdxparse.Exp; 49 import com.tonbeller.jpivot.olap.mdxparse.FunCall; 50 import com.tonbeller.jpivot.olap.mdxparse.MemberProperty; 51 import com.tonbeller.jpivot.olap.mdxparse.ParsedQuery; 52 import com.tonbeller.jpivot.xmla.XMLA_Member; 53 import com.tonbeller.jpivot.xmla.XMLA_Model; 54 import com.tonbeller.jpivot.tags.OlapModelProxy; 55 import com.tonbeller.jpivot.olap.model.CachingOlapModel; 56 57 62 public class HierarchyNavigator extends CategoryEditor implements ModelChangeListener, Available { 63 64 public class CancelHandler implements RequestListener { 65 private boolean hide; 66 67 public CancelHandler(boolean hide) { 68 this.hide = hide; 69 } 70 71 public void request(RequestContext context) throws Exception { 72 editing = false; 73 revert(context); 75 if (hide) 76 setVisible(false); 77 } 78 } 79 80 public class OkHandler implements RequestListener { 81 private boolean hide; 82 83 public OkHandler(boolean hide) { 84 this.hide = hide; 85 } 86 87 102 103 public void request(RequestContext context) throws Exception { 104 editing = false; 105 boolean valid = validate(context); 106 for (Iterator it = categories.iterator(); it.hasNext();) 108 ((AbstractCategory) it.next()).deleteDeleted(); 109 for (Iterator it = categories.iterator(); it.hasNext();) 110 ((AbstractCategory) it.next()).prepareApplyChanges(); 111 112 List slicerMembersMdx = null; 113 114 for (Iterator it = categories.iterator(); it.hasNext();) { 115 AbstractCategory cat = (AbstractCategory)it.next(); 116 if(cat instanceof SlicerCategory) { 117 SlicerCategory scat = (SlicerCategory)cat; 118 List items = scat.getItems(); 119 Iterator iter = items.iterator(); 120 while(iter.hasNext()) { 121 HierarchyItem item = (HierarchyItem)iter.next(); 122 List selection = item.getSlicerSelection(); 123 if(selection.size()>1) { 124 slicerMembersMdx = new ArrayList (); 125 Iterator selIter = selection.iterator(); 126 List deleted = new ArrayList (); 127 while(selIter.hasNext()) { 128 XMLA_Member member = (XMLA_Member)selIter.next(); 129 deleted.add(member); 130 slicerMembersMdx.add(member.toMdx()); 131 } 132 for(Iterator delIter = deleted.iterator(); delIter.hasNext();) 133 selection.remove(delIter.next()); 134 } 135 } 136 } 137 138 cat.applyChanges(); 139 } 140 141 if (valid && hide) 142 setVisible(false); 143 144 if(slicerMembersMdx == null ) { 145 return; 146 } 147 148 XMLA_Model model = ((XMLA_Model)((CachingOlapModel)((OlapModelProxy)olapModel).getDelegate()).getDelegate()); 149 ParsedQuery pquery = model.getPQuery(); 150 151 String newMember = slicerMembersMdx.get(0).toString(); 152 newMember = newMember.substring(0, newMember.lastIndexOf(".")); 153 154 String names[] = new String [2]; 155 StringBuffer newSlicerName = new StringBuffer (""); 156 names[0] = newMember; 157 158 159 Exp cids[] = new Exp[slicerMembersMdx.size()]; 160 161 Iterator iter = slicerMembersMdx.iterator(); 162 for(int i=0 ; iter.hasNext(); i++){ 163 String name = (String )iter.next(); 164 name = name.substring(name.lastIndexOf(".") + 1); 165 cids[i] = new CompoundId(name, false); 166 name = name.replace('[',' '); 168 name = name.replace(']','_'); 169 newSlicerName.append(name.trim()); 170 } 171 172 newSlicerName.insert(0,'['); 173 newSlicerName.setCharAt(newSlicerName.length() -1,']'); 174 175 names[1] = newSlicerName.toString(); 176 177 FunCall fun = new FunCall("+",cids, FunCall.TypeInfix); 178 pquery.addFormula(names, fun, new MemberProperty[0]); 179 180 String fullname = slicerMembersMdx.get(0).toString(); 181 fullname = newMember.substring(0, newMember.lastIndexOf(".")<0 ? newMember.length(): newMember.lastIndexOf(".") ) + "." + names[1]; 182 183 FunCall slicer = (FunCall)pquery.getSlicer(); 184 185 Exp[] args = null; 186 187 int index = 0; 188 189 if(slicer != null ) { 190 index = slicer.getArgs().length; 191 args = new Exp[index +1 ]; 192 System.arraycopy(slicer.getArgs(),0,args,0,index); 193 } else { 194 args = new Exp[1]; 195 } 196 197 String []nameparts = fullname.split("\\."); 198 199 CompoundId cid = new CompoundId(nameparts[0], false); 200 for(int i=1 ; i < nameparts.length; i++) { 201 cid.append(nameparts[i], false); 202 } 203 204 args[index] = cid; 205 pquery.setSlicer(new FunCall("()", args, 6)); 206 } 207 208 } 209 210 private String acceptButtonId; 211 private String cancelButtonId; 212 private RequestListener acceptHandler; 213 private RequestListener revertHandler; 214 private String okButtonId; 215 private String revertButtonId; 216 private List categories = new ArrayList (); 217 private Resources resources; 218 219 224 private boolean editing = false; 225 226 private HierarchyItemClickHandler hierarchyItemClickHandler; 227 private OlapModel olapModel; 228 private CategoryModelSupport categoryModel; 229 private Dispatcher tempDispatcher = new DispatcherSupport(); 230 private SlicerCategory slicerCategory; 231 232 private static Logger logger = Logger.getLogger(HierarchyNavigator.class); 233 234 237 public HierarchyNavigator(String id, Component parent, OlapModel olapModel) { 238 super(id, parent); 239 240 logger.info("creating instance: " + this); 241 242 acceptButtonId = id + ".accept"; 243 cancelButtonId = id + ".cancel"; 244 okButtonId = id + ".ok"; 245 revertButtonId = id + ".revert"; 246 247 this.olapModel = olapModel; 248 olapModel.addModelChangeListener(this); 249 250 acceptHandler = new OkHandler(false); 251 revertHandler = new CancelHandler(false); 252 super.getDispatcher().addRequestListener(acceptButtonId, null, acceptHandler); 253 super.getDispatcher().addRequestListener(revertButtonId, null, revertHandler); 254 super.getDispatcher().addRequestListener(okButtonId, null, new OkHandler(true)); 255 super.getDispatcher().addRequestListener(cancelButtonId, null, new CancelHandler(true)); 256 super.getDispatcher().addRequestListener(null, null, tempDispatcher); 257 categoryModel = new CategoryModelSupport() { 258 public List getCategories() { 259 return categories; 260 } 261 }; 262 super.setModel(categoryModel); 263 super.setItemRenderer(new HierarchyItemRenderer()); 264 } 265 266 public void initialize(RequestContext context) throws Exception { 267 super.initialize(context); 268 resources = context.getResources(HierarchyNavigator.class); 269 } 270 271 275 public PlaceHierarchiesOnAxes getHierarchyExtension() { 276 return (PlaceHierarchiesOnAxes) olapModel.getExtension(PlaceHierarchiesOnAxes.ID); 277 } 278 279 283 public HierarchyItemClickHandler getHierarchyItemClickHandler() { 284 return hierarchyItemClickHandler; 285 } 286 287 291 public PlaceMembersOnAxes getMemberExtension() { 292 return (PlaceMembersOnAxes) olapModel.getExtension(PlaceMembersOnAxes.ID); 293 } 294 295 public MemberDeleter getDeleterExtension() { 296 return (MemberDeleter) olapModel.getExtension(MemberDeleter.ID); 297 } 298 299 303 public OlapModel getOlapModel() { 304 return olapModel; 305 } 306 307 311 public ChangeSlicer getSlicerExtension() { 312 return (ChangeSlicer) olapModel.getExtension(ChangeSlicer.ID); 313 } 314 315 319 Dispatcher getTempDispatcher() { 320 return tempDispatcher; 321 } 322 323 326 void initializeCategories() throws OlapException { 327 categories.clear(); 328 329 Result result = olapModel.getResult(); 330 Axis[] axes = result.getAxes(); 331 for (int index = 0; index < axes.length; index++) { 332 Axis axis = axes[index]; 333 String name = resources.getString("axis." + index + ".name"); 334 String icon = resources.getString("axis." + index + ".icon"); 335 AxisCategory axisCat = new AxisCategory(this, axis, name, icon); 336 categories.add(axisCat); 337 } 338 339 String name = resources.getString("slicer.name"); 341 String icon = resources.getString("slicer.icon"); 342 slicerCategory = new SlicerCategory(this, name, icon); 343 categories.add(slicerCategory); 344 } 345 346 350 public boolean isEditing() { 351 return editing; 352 } 353 354 void itemClicked(RequestContext context, HierarchyItem item, SelectionModel selection, 355 boolean allowChangeOrder) { 356 if (hierarchyItemClickHandler != null) 357 hierarchyItemClickHandler.itemClicked(context, item, selection, allowChangeOrder); 358 } 359 360 public Element render(RequestContext context, Document factory) throws Exception { 361 if (!editing) { 362 tempDispatcher.clear(); 363 initializeCategories(); 364 } 365 366 Element elem = super.render(context, factory); 367 368 elem.setAttribute("accept-id", acceptButtonId); 369 elem.setAttribute("accept-title", resources.getString("accept.title")); 370 elem.setAttribute("revert-id", revertButtonId); 371 elem.setAttribute("revert-title", resources.getString("revert.title")); 372 elem.setAttribute("ok-id", okButtonId); 373 elem.setAttribute("ok-title", resources.getString("ok.title")); 374 elem.setAttribute("cancel-id", cancelButtonId); 375 elem.setAttribute("cancel-title", resources.getString("cancel.title")); 376 377 return elem; 378 } 379 380 public void setEditing(boolean editing) { 381 this.editing = editing; 382 } 383 384 388 public void setHierarchyItemClickHandler(HierarchyItemClickHandler hierarchyItemClickHandler) { 389 this.hierarchyItemClickHandler = hierarchyItemClickHandler; 390 } 391 392 public void modelChanged(ModelChangeEvent e) { 393 editing = false; 395 } 396 397 public void structureChanged(ModelChangeEvent e) { 398 logger.info("cleaning up"); 399 setEditing(false); 401 tempDispatcher.clear(); 402 categories.clear(); 403 categoryModel.fireModelChanged(); 405 } 406 407 408 413 public HierarchyItem findHierarchyItem(Hierarchy hier) { 414 for (Iterator ci = categoryModel.getCategories().iterator(); ci.hasNext();) { 415 AbstractCategory ac = (AbstractCategory) ci.next(); 416 for (Iterator ii = ac.getItems().iterator(); ii.hasNext();) { 417 HierarchyItem hi = (HierarchyItem) ii.next(); 418 if (hi.getHierarchy().equals(hier)) 419 return hi; 420 } 421 } 422 return null; 423 } 424 425 public RequestListener getAcceptHandler() { 426 return acceptHandler; 427 } 428 429 public RequestListener getRevertHandler() { 430 return revertHandler; 431 } 432 433 441 public Set getSlicerDimensions() { 442 Set set = new HashSet (); 443 for (Iterator it = slicerCategory.getItems().iterator(); it.hasNext();) { 444 HierarchyItem hi = (HierarchyItem) it.next(); 445 set.add(hi.getHierarchy().getDimension()); 446 } 447 return set; 448 } 449 450 public Resources getRes() { 451 return resources; 452 } 453 454 public boolean isAvailable() { 455 return getHierarchyExtension() != null; 456 } 457 458 } | Popular Tags |