1 13 package com.tonbeller.jpivot.table.span; 14 15 import java.beans.PropertyChangeListener ; 16 import java.beans.PropertyChangeSupport ; 17 import java.util.ArrayList ; 18 import java.util.Collection ; 19 import java.util.Collections ; 20 import java.util.HashMap ; 21 import java.util.HashSet ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.Set ; 26 27 import javax.servlet.http.HttpSession ; 28 29 import org.apache.log4j.Logger; 30 31 import com.tonbeller.jpivot.core.ModelChangeEvent; 32 import com.tonbeller.jpivot.core.ModelChangeListener; 33 import com.tonbeller.jpivot.olap.model.Member; 34 import com.tonbeller.jpivot.olap.model.MemberPropertyMeta; 35 import com.tonbeller.jpivot.olap.model.OlapModel; 36 import com.tonbeller.jpivot.olap.model.Property; 37 import com.tonbeller.jpivot.olap.model.impl.PropertyImpl; 38 import com.tonbeller.jpivot.olap.navi.MemberProperties; 39 import com.tonbeller.jpivot.ui.Available; 40 import com.tonbeller.wcf.controller.RequestContext; 41 42 46 public class PropertySpanBuilder implements PropertyConfig, ModelChangeListener, Available { 47 48 private MemberProperties extension; 49 private OlapModel model; 50 51 private List [] propertyColumns; 52 private int PCOUNT; 53 private int HCOUNT; 54 private SpanCalc spanCalc; 55 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this); 56 private static Logger logger = Logger.getLogger(PropertySpanBuilder.class); 57 58 59 private List visiblePropertyMetas = null; 60 private boolean showProperties = false; 61 62 65 private Map emptyPropertyMap = new HashMap (); 66 67 70 private ScopedPropertyMetaSet metaSet; 71 72 private AllPropertiesMap allPropertiesMap; 73 74 83 static class AllPropertiesMap { 84 private Map map = new HashMap (); 85 private Set set = new HashSet (); 86 87 void add(Member member) { 88 if (member == null) 89 return; 90 91 if (set.contains(member)) 92 return; 93 set.add(member); 94 95 Property[] props = member.getProperties(); 96 props = PropertyUtils.normalize(props); 97 List list = new ArrayList (); 98 for (int i = 0; i < props.length; i++) { 99 Property p = props[i]; 100 if (PropertyUtils.isInline(p.getName())) 102 continue; 103 list.add(p); 104 } 105 map.put(member, list); 106 } 107 108 List getProperties(Member member) { 109 return (List ) map.get(member); 110 } 111 } 112 113 class PropertyLookup { 114 Map map = new HashMap (); 115 void clear() { 116 map.clear(); 117 } 118 void addAll(Collection properties) { 119 for (Iterator it = properties.iterator(); it.hasNext();) { 120 Property p = (Property) it.next(); 121 map.put(p.getName(), p); 122 } 123 } 124 Property getProperty(String name) { 125 return (Property) map.get(name); 126 } 127 } 128 129 132 PropertySpanBuilder(MemberProperties extension) { 133 this.model = null; 134 this.extension = extension; 135 } 136 137 public PropertySpanBuilder(OlapModel model) { 138 this.model = model; 139 this.extension = (MemberProperties) model.getExtension(MemberProperties.ID); 140 } 141 142 public void initialize(RequestContext context) { 143 model.addModelChangeListener(this); 144 } 145 public void destroy(HttpSession session) { 146 model.removeModelChangeListener(this); 147 } 148 149 public void modelChanged(ModelChangeEvent e) { 150 } 151 152 public void structureChanged(ModelChangeEvent e) { 153 extension = (MemberProperties) model.getExtension(MemberProperties.ID); 154 setVisiblePropertyMetas(null); 155 setShowProperties(false); 156 } 157 158 public boolean isAvailable() { 159 return model.getExtension(MemberProperties.ID) != null; 160 } 161 162 163 private void reset(SpanCalc spanCalc) { 164 this.emptyPropertyMap.clear(); 166 this.allPropertiesMap = new AllPropertiesMap(); 167 this.metaSet = new ScopedPropertyMetaSet(extension); 168 this.spanCalc = spanCalc; 169 this.HCOUNT = spanCalc.getHierarchyCount(); 170 this.PCOUNT = spanCalc.getPositionCount(); 171 172 collectProperties(); 173 initializePropertyColumns(); 174 } 175 176 179 void collectProperties() { 180 Span[][] spans = spanCalc.getSpans(); 181 182 for (int hi = 0; hi < HCOUNT; hi++) { 183 for (int pi = 0; pi < PCOUNT; pi++) { 184 Span s = spans[pi][hi]; 185 if (s.isMember()) { 186 Member m = s.getMember(); 187 metaSet.addMember(m); 188 allPropertiesMap.add(m); 189 } 190 } 191 } 192 } 193 194 199 void initializePropertyColumns() { 200 propertyColumns = new List [HCOUNT]; 201 for (int i = 0; i < HCOUNT; i++) 202 propertyColumns[i] = Collections.EMPTY_LIST; 203 204 if (PCOUNT == 0) 206 return; 207 208 Set [] scopes = new Set [HCOUNT]; 211 Span[][] spans = spanCalc.getSpans(); 212 for (int hi = 0; hi < HCOUNT; hi++) { 213 Set set = new HashSet (); 214 for (int pi = 0; pi < PCOUNT; pi++) 215 set.add(getScope(spans[pi][hi])); 216 scopes[hi] = set; 217 } 218 219 Set done = new HashSet (); 221 for (int hi = 0; hi < HCOUNT; hi++) { 222 MemberPropertyMetaFilter scopesFilter = metaSet.createScopesFilter(scopes[hi]); 226 MemberPropertyMetaFilter inlineFilter = metaSet.createIgnoreInlineFilter(); 227 228 if (hi == (HCOUNT - 1) || !scopes[hi].equals(scopes[hi + 1])) { 229 ScopedPropertyMetaSet sub = metaSet.metaSet(scopesFilter); 230 sub.removeAll(done); 231 if (visiblePropertyMetas == null) 232 propertyColumns[hi] = sub.metaList(inlineFilter); 233 else 234 propertyColumns[hi] = sub.intersectList(visiblePropertyMetas); 235 done.addAll(propertyColumns[hi]); 236 } 237 } 238 } 239 240 Object getScope(Span s) { 241 if (!s.isMember()) 243 return s; 244 return extension.getPropertyScope((Member) s.getMember().getRootDecoree()); 245 } 246 247 251 public void addPropertySpans(SpanCalc sc) { 252 if (extension == null || !showProperties) 253 return; 254 logger.info("adding properties"); 255 256 reset(sc); 258 259 int newHierCount = spanCalc.getHierarchyCount(); 261 for (int hi = 0; hi < HCOUNT; hi++) 262 newHierCount += propertyColumns[hi].size(); 263 264 Span[][] dst = new Span[PCOUNT][]; 266 for (int pi = 0; pi < PCOUNT; pi++) 267 dst[pi] = new Span[newHierCount]; 268 Span[][] src = spanCalc.getSpans(); 269 270 PropertyLookup lookup = new PropertyLookup(); 272 for (int pi = 0; pi < PCOUNT; pi++) { 273 int dstHierIndex = 0; 274 lookup.clear(); 275 for (int hi = 0; hi < HCOUNT; hi++) { 276 Span span = src[pi][hi]; 277 dst[pi][dstHierIndex++] = span; 278 279 if (span.isMember()) 280 lookup.addAll(allPropertiesMap.getProperties(span.getMember())); 281 282 Object scope = getScope(span); 284 for (Iterator it = propertyColumns[hi].iterator(); it.hasNext();) { 285 MemberPropertyMeta mpm = (MemberPropertyMeta) it.next(); 286 Property prop = null; 287 if (mpm.getScope().equals(scope)) 288 prop = lookup.getProperty(mpm.getName()); 289 if (prop == null) 290 prop = emptyProperty(mpm.getName(), mpm.getLabel()); 291 dst[pi][dstHierIndex++] = new Span(span.getAxis(), span.getPosition(), prop); 292 } 293 } 294 } 295 296 spanCalc.setSpans(dst); 297 } 298 299 305 Property emptyProperty(String name, String label) { 306 Property p = (Property) emptyPropertyMap.get(name); 307 if (p != null) 308 return p; 309 PropertyImpl pi = new PropertyImpl(); 310 pi.setName(name); 311 pi.setLabel(label); 312 pi.setValue(""); 313 emptyPropertyMap.put(name, pi); 314 return pi; 315 } 316 317 318 319 public boolean isShowProperties() { 320 return showProperties; 321 } 322 323 public void setShowProperties(boolean b) { 324 Object oldValue = new Boolean (showProperties); 325 this.showProperties = b; 326 setVisiblePropertiesExtension(); 327 Object newValue = new Boolean (showProperties); 328 propertyChangeSupport.firePropertyChange("showProperties", oldValue, newValue); 329 } 330 331 public void setVisiblePropertyMetas(List metas) { 332 Object oldValue = visiblePropertyMetas; 333 this.visiblePropertyMetas = metas; 334 setVisiblePropertiesExtension(); 335 Object newValue = visiblePropertyMetas; 336 propertyChangeSupport.firePropertyChange("visiblePropertyMetas", oldValue, newValue); 337 } 338 339 public List getVisiblePropertyMetas() { 340 return visiblePropertyMetas; 341 } 342 343 public void addPropertyChangeListener(PropertyChangeListener l) { 344 propertyChangeSupport.addPropertyChangeListener(l); 345 } 346 public void removePropertyChangeListener(PropertyChangeListener l) { 347 propertyChangeSupport.removePropertyChangeListener(l); 348 } 349 350 public static class BookmarkState { 351 boolean showProperties = false; 352 List visibleProperties = null; 353 public boolean isShowProperties() { 354 return showProperties; 355 } 356 public List getVisibleProperties() { 357 return visibleProperties; 358 } 359 public void setShowProperties(boolean b) { 360 showProperties = b; 361 } 362 public void setVisibleProperties(List list) { 363 visibleProperties = list; 364 } 365 } 366 367 public Object getBookmarkState(int levelOfDetail) { 368 BookmarkState x = new BookmarkState(); 369 x.setShowProperties(isShowProperties()); 370 if (visiblePropertyMetas != null) { 371 ArrayList metas = new ArrayList (); 372 metas.addAll(visiblePropertyMetas); 373 x.setVisibleProperties(metas); 374 } 375 return x; 376 } 377 378 public void setBookmarkState(Object state) { 379 if (!(state instanceof BookmarkState)) 380 return; 381 BookmarkState x = (BookmarkState) state; 382 setVisiblePropertyMetas(x.getVisibleProperties()); 383 setShowProperties(x.isShowProperties()); 384 } 385 386 387 390 protected void setVisiblePropertiesExtension() { 391 if (extension == null) 392 return; 393 if (!showProperties || visiblePropertyMetas == null) { 394 extension.setVisibleProperties(new MemberPropertyMeta[0]); 395 return; 396 } 397 MemberPropertyMeta[] mps = new MemberPropertyMeta[visiblePropertyMetas.size()]; 398 mps = (MemberPropertyMeta[]) visiblePropertyMetas.toArray(mps); 399 extension.setVisibleProperties(mps); 400 } 401 402 403 } 404 | Popular Tags |