1 19 20 package org.netbeans.modules.java.tools; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyChangeSupport ; 25 26 import java.util.*; 27 28 import org.openide.loaders.DataFilter; 29 import org.openide.loaders.DataObject; 30 31 54 public class MultiDataContainer implements DataObject.Container, PropertyChangeListener { 55 58 public static final String PROP_CONTAINERS = "containers"; 60 63 public static final String PROP_CONTENTS = "contents"; 65 68 private static final DataObject[] EMPTY_CHILDREN = {}; 69 70 73 DataObject[] children; 74 75 79 Collection contents; 80 81 85 DataFilter filter; 86 87 91 boolean refreshChildren; 92 93 97 Map nestedContainers; 98 99 102 Map containerContents; 103 104 PropertyChangeSupport propSupport; 105 106 110 public MultiDataContainer() { 111 this(DataFilter.ALL); 112 } 113 114 117 public MultiDataContainer(DataFilter filter) { 118 this(Collections.EMPTY_LIST, filter); 119 } 120 121 125 public MultiDataContainer(Collection sourceContainers, DataFilter filter) { 126 this.contents = sourceContainers; 127 this.filter = filter; 128 this.children = EMPTY_CHILDREN; 129 this.refreshChildren = true; 130 this.nestedContainers = new TreeMap(); 131 } 132 133 138 public void setContents(Collection containers) { 139 140 synchronized (this) { 141 if (contents.equals(containers)) 142 return; 143 for (Iterator it = contents.iterator(); it.hasNext(); ) { 144 DataObject.Container cont = (DataObject.Container)it.next(); 145 cont.removePropertyChangeListener(this); 146 } 147 contents = Collections.unmodifiableCollection(containers); 148 for (Iterator it = contents.iterator(); it.hasNext(); ) { 149 DataObject.Container cont = (DataObject.Container)it.next(); 150 cont.addPropertyChangeListener(this); 151 } 152 invalidateChildren(); 153 } 154 fireContentsChange(); 155 } 156 157 160 private void invalidateChildren() { 161 synchronized (this) { 162 refreshChildren = true; 163 } 164 } 165 166 170 private void fireContentsChange() { 171 if (this.propSupport == null) 172 return; 173 propSupport.firePropertyChange(PROP_CONTENTS, null, null); 174 fireChildrenChange(); 175 } 176 177 180 private void fireChildrenChange() { 181 if (this.propSupport == null) 182 return; 183 propSupport.firePropertyChange(PROP_CHILDREN, null, null); 184 } 185 186 189 public Collection getContents() { 190 return contents; 191 } 192 193 197 public DataObject[] getChildren() { 198 if (refreshChildren) { 199 synchronized (this) { 200 refreshChildren = false; 201 refreshData(); 202 } 203 } 204 return children; 205 } 206 207 210 public Map getContainers() { 211 return nestedContainers; 212 } 213 214 217 private void refreshData() { 218 Set knownKeys = new HashSet(31); 219 Collection newChildren = new LinkedList(); 220 Map newContainers = new HashMap(31); 221 222 int rejected = 0; 223 224 for (Iterator it = getContents().iterator(); it.hasNext(); ) { 225 rejected += addContainer(newContainers, knownKeys, newChildren, (DataObject.Container)it.next()); 226 } 227 228 boolean containersChanged = false; 229 230 for (Iterator it = newContainers.entrySet().iterator(); it.hasNext(); ) { 232 Map.Entry en = (Map.Entry)it.next(); 233 Object k = en.getKey(); 234 Collection sources = (Collection)en.getValue(); 235 MultiDataContainer nested; 236 237 nested = (MultiDataContainer)nestedContainers.get(k); 238 if (nested == null) { 239 System.err.println("creating nested container for " + k); nested = createContainer(sources); 241 containersChanged = true; 242 } else { 243 nested.setContents(sources); 244 } 245 en.setValue(nested); 246 } 247 if (nestedContainers != null) { 248 for (Iterator it = nestedContainers.keySet().iterator(); !containersChanged && it.hasNext(); ) { 249 containersChanged &= newContainers.containsKey(it.next()); 250 } 251 } else { 252 containersChanged |= !newContainers.isEmpty(); 253 } 254 255 synchronized (this) { 256 this.nestedContainers = newContainers; 257 this.children = (DataObject[])newChildren.toArray(new DataObject[newChildren.size()]); 258 } 259 if (containersChanged) { 260 propSupport.firePropertyChange(PROP_CONTAINERS, null, null); 261 } 262 } 263 264 269 private int addContainer(Map containers, Set presentKeys, Collection contents, 270 DataObject.Container folder) { 271 272 System.err.println("addContainer: " + folder); DataObject[] children = folder.getChildren(); 274 int rejected = 0; 275 276 for (int i = 0; i < children.length; i++) { 277 Object key; 278 DataObject obj = children[i]; 279 Object o = obj; 280 281 key = createKey(obj); 282 if (!filter.acceptDataObject(obj)) { 284 System.err.println("addContainer: " + obj + " was rejected. "); rejected++; 286 continue; 287 } 288 289 if (isContainer(obj)) { 291 System.err.println("got container: " + obj + " with key " + key); Collection c = (Collection)containers.get(key); 293 if (c == null) { 294 c = new LinkedList(); 295 containers.put(key, c); 296 System.err.println("new container"); } 298 c.add(obj); 299 } else { 300 if (presentKeys.add(key)) 303 contents.add(o); 304 } 305 } 306 return rejected; 307 } 308 309 313 public DataFilter getFilter() { 314 return filter; 315 } 316 317 322 public MultiDataContainer createContainer(Collection initialSources) { 323 return new MultiDataContainer(initialSources, getFilter()); 324 } 325 326 330 public void addPropertyChangeListener(PropertyChangeListener l) 331 throws IllegalArgumentException { 332 if (l == null) 333 throw new IllegalArgumentException ("eee"); synchronized (this) { 335 if (propSupport == null) 336 propSupport = new PropertyChangeSupport (this); 337 } 338 propSupport.addPropertyChangeListener(l); 339 } 340 341 347 protected Object createKey(DataObject d) { 348 return d.getName(); 349 } 350 351 355 protected boolean isContainer(DataObject d) { 356 return d.getCookie(DataObject.Container.class) != null; 357 } 358 359 362 public void removePropertyChangeListener(PropertyChangeListener l) { 363 if (propSupport == null) 364 return; 365 propSupport.removePropertyChangeListener(l); 366 } 367 368 372 public final void propertyChange(PropertyChangeEvent event) { 373 if (PROP_CHILDREN.equals(event.getPropertyName())) { 374 invalidateChildren(); 375 fireChildrenChange(); 376 } 377 } 378 } 379 | Popular Tags |