1 11 package org.eclipse.team.core.synchronize; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Set ; 21 22 import org.eclipse.core.resources.IContainer; 23 import org.eclipse.core.resources.IResource; 24 import org.eclipse.core.resources.IWorkspaceRoot; 25 import org.eclipse.core.runtime.IPath; 26 import org.eclipse.core.runtime.IStatus; 27 import org.eclipse.core.runtime.Path; 28 import org.eclipse.team.internal.core.Messages; 29 import org.eclipse.team.internal.core.TeamPlugin; 30 import org.eclipse.team.internal.core.subscribers.SyncInfoTreeChangeEvent; 31 import org.eclipse.team.internal.core.subscribers.SyncSetChangedEvent; 32 33 42 public class SyncInfoTree extends SyncInfoSet { 43 44 protected Map parents = Collections.synchronizedMap(new HashMap ()); 45 46 49 public SyncInfoTree() { 50 super(); 51 } 52 53 58 public SyncInfoTree(SyncInfo[] infos) { 59 super(infos); 60 for (int i = 0; i < infos.length; i++) { 61 SyncInfo info = infos[i]; 62 IResource local = info.getLocal(); 63 addToParents(local, local); 64 } 65 } 66 67 75 public synchronized boolean hasMembers(IResource resource) { 76 if (resource.getType() == IResource.FILE) return false; 77 IContainer parent = (IContainer)resource; 78 if (parent.getType() == IResource.ROOT) return !isEmpty(); 79 IPath path = parent.getFullPath(); 80 Set allDescendants = (Set )parents.get(path); 81 return (allDescendants != null && !allDescendants.isEmpty()); 82 } 83 84 102 public synchronized SyncInfo[] getSyncInfos(IResource resource, int depth) { 103 if (depth == IResource.DEPTH_ZERO || resource.getType() == IResource.FILE) { 104 SyncInfo info = getSyncInfo(resource); 105 if (info == null) { 106 return new SyncInfo[0]; 107 } else { 108 return new SyncInfo[] { info }; 109 } 110 } 111 if (depth == IResource.DEPTH_ONE) { 112 List result = new ArrayList (); 113 SyncInfo info = getSyncInfo(resource); 114 if (info != null) { 115 result.add(info); 116 } 117 IResource[] members = members(resource); 118 for (int i = 0; i < members.length; i++) { 119 IResource member = members[i]; 120 info = getSyncInfo(member); 121 if (info != null) { 122 result.add(info); 123 } 124 } 125 return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); 126 } 127 if(resource.getType() == IResource.ROOT) { 129 return getSyncInfos(); 130 } 131 return internalGetDeepSyncInfo((IContainer)resource); 133 } 134 135 141 private synchronized SyncInfo[] internalGetDeepSyncInfo(IContainer resource) { 142 List infos = new ArrayList (); 143 IResource[] children = internalGetOutOfSyncDescendants(resource); 144 for (int i = 0; i < children.length; i++) { 145 IResource child = children[i]; 146 SyncInfo info = getSyncInfo(child); 147 if(info != null) { 148 infos.add(info); 149 } else { 150 TeamPlugin.log(IStatus.INFO, Messages.SyncInfoTree_0 + child.getFullPath(), null); 151 } 152 } 153 return (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()]); 154 } 155 156 160 protected SyncSetChangedEvent createEmptyChangeEvent() { 161 return new SyncInfoTreeChangeEvent(this); 162 } 163 164 167 public void add(SyncInfo info) { 168 try { 169 beginInput(); 170 boolean alreadyExists = getSyncInfo(info.getLocal()) != null; 171 super.add(info); 172 if(! alreadyExists) { 173 IResource local = info.getLocal(); 174 addToParents(local, local); 175 } 176 } finally { 177 endInput(null); 178 } 179 } 180 181 184 public void remove(IResource resource) { 185 try { 186 beginInput(); 187 super.remove(resource); 188 removeFromParents(resource, resource); 189 } finally { 190 endInput(null); 191 } 192 193 } 194 195 198 public void clear() { 199 try { 200 beginInput(); 201 super.clear(); 202 synchronized(this) { 203 parents.clear(); 204 } 205 } finally { 206 endInput(null); 207 } 208 } 209 210 private synchronized boolean addToParents(IResource resource, IResource parent) { 211 if (parent.getType() == IResource.ROOT) { 212 return false; 213 } 214 boolean addedParent = false; 216 if (parent.getType() == IResource.FILE) { 217 addedParent = true; 219 } else { 220 Set children = (Set )parents.get(parent.getFullPath()); 221 if (children == null) { 222 children = new HashSet (); 223 parents.put(parent.getFullPath(), children); 224 addedParent = true; 226 } 227 children.add(resource); 228 } 229 if (!addToParents(resource, parent.getParent()) && addedParent) { 231 internalAddedSubtreeRoot(parent); 232 } 233 return addedParent; 234 } 235 236 private synchronized boolean removeFromParents(IResource resource, IResource parent) { 237 if (parent.getType() == IResource.ROOT) { 238 return false; 239 } 240 boolean removedParent = false; 242 if (parent.getType() == IResource.FILE) { 243 removedParent = true; 245 } else { 246 Set children = (Set )parents.get(parent.getFullPath()); 247 if (children != null) { 248 children.remove(resource); 249 if (children.isEmpty()) { 250 parents.remove(parent.getFullPath()); 251 removedParent = true; 252 } 253 } 254 } 255 if (!removeFromParents(resource, parent.getParent()) && removedParent) { 257 internalRemovedSubtreeRoot(parent); 258 } 259 return removedParent; 260 } 261 262 private void internalAddedSubtreeRoot(IResource parent) { 263 ((SyncInfoTreeChangeEvent)getChangeEvent()).addedSubtreeRoot(parent); 264 } 265 266 private void internalRemovedSubtreeRoot(IResource parent) { 267 ((SyncInfoTreeChangeEvent)getChangeEvent()).removedSubtreeRoot(parent); 268 } 269 270 281 public void remove(IResource resource, int depth) { 282 try { 283 beginInput(); 284 if (getSyncInfo(resource) != null) { 285 remove(resource); 286 } 287 if (depth == IResource.DEPTH_ZERO || resource.getType() == IResource.FILE) return; 288 if (depth == IResource.DEPTH_ONE) { 289 IResource[] members = members(resource); 290 for (int i = 0; i < members.length; i++) { 291 IResource member = members[i]; 292 if (getSyncInfo(member) != null) { 293 remove(member); 294 } 295 } 296 } else if (depth == IResource.DEPTH_INFINITE) { 297 IResource [] toRemove = internalGetOutOfSyncDescendants((IContainer)resource); 298 for (int i = 0; i < toRemove.length; i++) { 299 remove(toRemove[i]); 300 } 301 } 302 } finally { 303 endInput(null); 304 } 305 } 306 307 311 protected synchronized IResource[] internalGetOutOfSyncDescendants(IContainer resource) { 312 Set allChildren = (Set )parents.get(resource.getFullPath()); 314 if (allChildren == null) return new IResource[0]; 315 return (IResource[]) allChildren.toArray(new IResource[allChildren.size()]); 316 } 317 318 private synchronized IResource[] internalMembers(IWorkspaceRoot root) { 319 Set possibleChildren = parents.keySet(); 320 Set children = new HashSet (); 321 for (Iterator it = possibleChildren.iterator(); it.hasNext();) { 322 Object next = it.next(); 323 IResource element = root.findMember((IPath)next); 324 if (element != null) { 325 children.add(element.getProject()); 326 } 327 } 328 return (IResource[]) children.toArray(new IResource[children.size()]); 329 } 330 331 339 public synchronized IResource[] members(IResource resource) { 340 if (resource.getType() == IResource.FILE) return new IResource[0]; 341 IContainer parent = (IContainer)resource; 342 if (parent.getType() == IResource.ROOT) return internalMembers((IWorkspaceRoot)parent); 343 Set children = new HashSet (); 346 IPath path = parent.getFullPath(); 347 Set possibleChildren = (Set )parents.get(path); 348 if(possibleChildren != null) { 349 for (Iterator it = possibleChildren.iterator(); it.hasNext();) { 350 Object next = it.next(); 351 IResource element = (IResource)next; 352 IPath childPath = element.getFullPath(); 353 IResource modelObject = null; 354 if(childPath.segmentCount() == (path.segmentCount() + 1)) { 355 modelObject = element; 356 357 } else if (childPath.segmentCount() > path.segmentCount()) { 358 IContainer childFolder = parent.getFolder(new Path(null, childPath.segment(path.segmentCount()))); 359 modelObject = childFolder; 360 } 361 if (modelObject != null) { 362 children.add(modelObject); 363 } 364 } 365 } 366 return (IResource[]) children.toArray(new IResource[children.size()]); 367 } 368 369 } 370 | Popular Tags |