1 11 package org.eclipse.team.internal.ccvs.ui.repo; 12 13 import java.io.IOException ; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.Set ; 23 24 import org.eclipse.core.runtime.*; 25 import org.eclipse.osgi.util.NLS; 26 import org.eclipse.team.core.TeamException; 27 import org.eclipse.team.internal.ccvs.core.*; 28 import org.eclipse.team.internal.ccvs.core.client.Command; 29 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 30 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 31 import org.eclipse.team.internal.ccvs.ui.*; 32 import org.eclipse.team.internal.ccvs.ui.Policy; 33 import org.eclipse.team.internal.ccvs.ui.operations.RemoteLogOperation; 34 import org.eclipse.team.internal.ccvs.ui.operations.RemoteLogOperation.LogEntryCache; 35 36 public class RepositoryRoot extends PlatformObject { 37 38 public static final String [] DEFAULT_AUTO_REFRESH_FILES = { ".project" }; private static final String DEFINED_MODULE_PREFIX = "module:"; 41 ICVSRepositoryLocation root; 42 String name; 43 Map versionAndBranchTags = new HashMap (); 45 Map autoRefreshFiles = new HashMap (); 47 Map modulesCache; 49 Object modulesCacheLock = new Object (); 50 List dateTags = new ArrayList (); 52 53 public static class TagCacheEntry { 54 Set tags = new HashSet (); 55 long lastAccessTime; 56 private static final int CACHE_LIFESPAN_IN_DAYS = 7; 57 public TagCacheEntry() { 58 accessed(); 59 } 60 public boolean isExpired() { 61 long currentTime = System.currentTimeMillis(); 62 long ms = currentTime - lastAccessTime; 63 int seconds = (int)ms / 1000; 64 int hours = seconds / 60 / 60; 65 int days = hours / 24; 66 return days > CACHE_LIFESPAN_IN_DAYS; 67 } 68 public void accessed() { 69 lastAccessTime = System.currentTimeMillis(); 70 } 71 } 72 73 public RepositoryRoot(ICVSRepositoryLocation root) { 74 this.root = root; 75 } 76 77 81 public String getName() { 82 return name; 83 } 84 85 91 public ICVSRemoteFolder getRemoteFolder(String path, CVSTag tag, IProgressMonitor monitor) { 92 if (isDefinedModuleName(path)) { 93 return getDefinedModule(getDefinedModuleName(path), tag, monitor); 94 } else { 95 return root.getRemoteFolder(path, tag); 96 } 97 } 98 99 static boolean isDefinedModuleName(String path) { 100 return path.startsWith(DEFINED_MODULE_PREFIX); 101 } 102 103 static String getDefinedModuleName(String path) { 104 return path.substring(DEFINED_MODULE_PREFIX.length()); 105 } 106 107 static String asDefinedModulePath(String path) { 108 return DEFINED_MODULE_PREFIX + path; 109 } 110 111 118 private ICVSRemoteFolder getDefinedModule(String path, CVSTag tag, IProgressMonitor monitor) { 119 Map cache = getDefinedModulesCache(tag, monitor); 120 ICVSRemoteFolder folder = (ICVSRemoteFolder)cache.get(path); 121 if (folder != null) { 122 folder = (ICVSRemoteFolder)folder.forTag(tag); 123 } 124 return folder; 125 } 126 127 private Map getDefinedModulesCache(CVSTag tag, IProgressMonitor monitor) { 128 if (modulesCache == null) { 129 try { 130 ICVSRemoteResource[] folders = root.members(CVSTag.DEFAULT, true, monitor); 132 synchronized(modulesCacheLock) { 133 modulesCache = new HashMap (); 134 for (int i = 0; i < folders.length; i++) { 135 ICVSRemoteResource resource = folders[i]; 136 modulesCache.put(resource.getName(), resource); 137 } 138 } 139 } catch (CVSException e) { 140 CVSUIPlugin.log(e); 142 return new HashMap (); 145 } 146 } 147 return modulesCache; 148 } 149 150 public ICVSRemoteResource[] getDefinedModules(CVSTag tag, IProgressMonitor monitor) { 151 Map cache = getDefinedModulesCache(tag, monitor); 152 return (ICVSRemoteResource[]) cache.values().toArray(new ICVSRemoteResource[cache.size()]); 153 } 154 155 public static String getRemotePathFor(ICVSResource resource) throws CVSException { 156 if (resource.isFolder()) { 157 if (resource instanceof ICVSRemoteFolder) { 158 ICVSRemoteFolder remoteFolder = (ICVSRemoteFolder) resource; 159 if (remoteFolder.isDefinedModule()) { 160 return asDefinedModulePath(remoteFolder.getName()); 161 } 162 } 163 FolderSyncInfo info = ((ICVSFolder)resource).getFolderSyncInfo(); 164 if (info == null) 165 throw new CVSException(NLS.bind(CVSUIMessages.RepositoryRoot_folderInfoMissing, new String [] { resource.getName() })); 166 return info.getRepository(); 167 } else { 168 FolderSyncInfo info = resource.getParent().getFolderSyncInfo(); 169 if (info == null) 170 throw new CVSException(NLS.bind(CVSUIMessages.RepositoryRoot_folderInfoMissing, new String [] { resource.getParent().getName() })); 171 String path = new Path(null, info.getRepository()).append(resource.getName()).toString(); 172 return path; 173 } 174 } 175 176 180 public ICVSRepositoryLocation getRoot() { 181 return root; 182 } 183 184 188 public void setName(String name) { 189 this.name = name; 190 } 191 192 199 public void addTags(String remotePath, CVSTag[] tags) { 200 addDateTags(tags); 201 addVersionAndBranchTags(remotePath, tags); 202 } 203 204 private void addDateTags(CVSTag[] tags){ 205 for(int i = 0; i < tags.length; i++){ 206 if(tags[i].getType() == CVSTag.DATE){ 207 dateTags.add(tags[i]); 208 } 209 } 210 } 211 private void addVersionAndBranchTags(String remotePath, CVSTag[] tags) { 212 String name = getCachePathFor(remotePath); 214 215 TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(name); 217 if (entry == null) { 218 entry = new TagCacheEntry(); 219 versionAndBranchTags.put(name, entry); 220 } else { 221 entry.accessed(); 222 } 223 224 for (int i = 0; i < tags.length; i++) { 226 if(tags[i].getType() != CVSTag.DATE){ 227 entry.tags.add(tags[i]); 228 } 229 } 230 } 231 232 236 public void addDateTag(CVSTag tag) { 237 if (!dateTags.contains(tag)) { 238 dateTags.add(tag); 239 } 240 } 241 public void removeDateTag(CVSTag tag) { 242 if (dateTags.contains(tag)) { 243 dateTags.remove(tag); 244 } 245 } 246 250 public CVSTag[] getDateTags() { 251 return (CVSTag[]) dateTags.toArray(new CVSTag[dateTags.size()]); 252 } 253 254 259 public void removeTags(String remotePath, CVSTag[] tags) { 260 removeDateTags(tags); 261 removeVersionAndBranchTags(remotePath, tags); 262 } 263 264 private void removeDateTags(CVSTag[] tags) { 265 if(dateTags.isEmpty())return; 266 for (int i = 0; i < tags.length; i++) { 268 dateTags.remove(tags[i]); 269 } 270 } 271 272 private void removeVersionAndBranchTags(String remotePath, CVSTag[] tags) { 273 String name = getCachePathFor(remotePath); 275 276 TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(name); 278 if (entry == null) { 279 return; 280 } 281 282 for (int i = 0; i < tags.length; i++) { 284 entry.tags.remove(tags[i]); 285 } 286 entry.accessed(); 287 } 288 289 295 public String [] getAutoRefreshFiles(String remotePath) { 296 String name = getCachePathFor(remotePath); 297 Set files = (Set )autoRefreshFiles.get(name); 298 if (files == null || files.isEmpty()) { 299 if (isDefinedModuleName(remotePath)) { 301 return new String [0]; 302 } 303 List result = new ArrayList (); 304 for (int i = 0; i < DEFAULT_AUTO_REFRESH_FILES.length; i++) { 305 String relativePath = DEFAULT_AUTO_REFRESH_FILES[i]; 306 result.add(new Path(null, remotePath).append(relativePath).toString()); 307 } 308 return (String []) result.toArray(new String [result.size()]); 309 } else { 310 return (String []) files.toArray(new String [files.size()]); 311 } 312 } 313 314 320 public void setAutoRefreshFiles(String remotePath, String [] autoRefreshFiles) { 321 Set newFiles = new HashSet (Arrays.asList(autoRefreshFiles)); 322 if (autoRefreshFiles.length == DEFAULT_AUTO_REFRESH_FILES.length) { 324 boolean isDefault = true; 325 for (int i = 0; i < DEFAULT_AUTO_REFRESH_FILES.length; i++) { 326 String filePath = DEFAULT_AUTO_REFRESH_FILES[i]; 327 if (!newFiles.contains(new Path(null, remotePath).append(filePath).toString())) { 328 isDefault = false; 329 break; 330 } 331 } 332 if (isDefault) { 333 this.autoRefreshFiles.remove(getCachePathFor(remotePath)); 334 return; 335 } 336 } 337 this.autoRefreshFiles.put(getCachePathFor(remotePath), newFiles); 338 } 339 340 343 public CVSTag[] refreshDefinedTags(ICVSFolder folder, boolean recurse, IProgressMonitor monitor) throws TeamException { 344 monitor.beginTask(null, 100); 345 CVSTag[] tags = null; 346 if (!recurse && !folder.getFolderSyncInfo().isVirtualDirectory()) { 347 tags = fetchTagsUsingAutoRefreshFiles(folder, Policy.subMonitorFor(monitor, 50)); 349 } 350 if (tags == null || tags.length == 0) { 351 tags = fetchTagsUsingLog(folder, recurse, Policy.subMonitorFor(monitor, 50)); 354 } 355 if (tags != null && tags.length > 0) { 356 String remotePath = getRemotePathFor(folder); 357 addTags(remotePath, tags); 358 } 359 monitor.done(); 360 return tags; 361 } 362 363 private CVSTag[] fetchTagsUsingLog(ICVSFolder folder, final boolean recurse, IProgressMonitor monitor) throws CVSException { 364 LogEntryCache logEntries = new LogEntryCache(); 365 RemoteLogOperation operation = new RemoteLogOperation(null, new ICVSRemoteResource[] { asRemoteResource(folder) }, null, null, logEntries) { 366 protected Command.LocalOption[] getLocalOptions(CVSTag tag1,CVSTag tag2) { 367 Command.LocalOption[] options = new Command.LocalOption[] {}; 368 if (recurse) 369 return options; 370 Command.LocalOption[] newOptions = new Command.LocalOption[options.length + 1]; 371 System.arraycopy(options, 0, newOptions, 0, options.length); 372 newOptions[options.length] = Command.DO_NOT_RECURSE; 373 return newOptions; 374 } 375 }; 376 try { 377 operation.run(monitor); 378 } catch (InvocationTargetException e) { 379 throw CVSException.wrapException(e); 380 } catch (InterruptedException e) { 381 } 383 String [] keys = logEntries.getCachedFilePaths(); 384 Set tags = new HashSet (); 385 for (int i = 0; i < keys.length; i++) { 386 String key = keys[i]; 387 ILogEntry[] entries = logEntries.getLogEntries(key); 388 for (int j = 0; j < entries.length; j++) { 389 ILogEntry entry = entries[j]; 390 tags.addAll(Arrays.asList(entry.getTags())); 391 } 392 } 393 return (CVSTag[]) tags.toArray(new CVSTag[tags.size()]); 394 } 395 396 private ICVSRemoteResource asRemoteResource(ICVSFolder folder) throws CVSException { 397 if (folder instanceof ICVSRemoteResource) { 398 return (ICVSRemoteResource)folder; 399 } 400 return CVSWorkspaceRoot.getRemoteResourceFor(folder); 401 } 402 403 406 private CVSTag[] fetchTagsUsingAutoRefreshFiles(ICVSFolder folder, IProgressMonitor monitor) throws TeamException { 407 String remotePath = getRemotePathFor(folder); 408 String [] filesToRefresh = getAutoRefreshFiles(remotePath); 409 try { 410 monitor.beginTask(null, filesToRefresh.length * 10); 411 List tags = new ArrayList (); 412 for (int i = 0; i < filesToRefresh.length; i++) { 413 ICVSRemoteFile file = root.getRemoteFile(filesToRefresh[i], CVSTag.DEFAULT); 414 try { 415 tags.addAll(Arrays.asList(fetchTags(file, Policy.subMonitorFor(monitor, 5)))); 416 } catch (TeamException e) { 417 IStatus status = e.getStatus(); 418 boolean doesNotExist = false; 419 if (status.getCode() == CVSStatus.SERVER_ERROR && status.isMultiStatus()) { 420 IStatus[] children = status.getChildren(); 421 if (children.length == 1 && children[0].getCode() == CVSStatus.DOES_NOT_EXIST) { 422 doesNotExist = true; 424 } 425 } 426 if (!doesNotExist) { 427 throw e; 428 } 429 } 430 } 431 return (CVSTag[]) tags.toArray(new CVSTag[tags.size()]); 432 } finally { 433 monitor.done(); 434 } 435 } 436 437 440 private CVSTag[] fetchTags(ICVSRemoteFile file, IProgressMonitor monitor) throws TeamException { 441 Set tagSet = new HashSet (); 442 ILogEntry[] entries = file.getLogEntries(monitor); 443 for (int j = 0; j < entries.length; j++) { 444 CVSTag[] tags = entries[j].getTags(); 445 for (int k = 0; k < tags.length; k++) { 446 tagSet.add(tags[k]); 447 } 448 } 449 return (CVSTag[])tagSet.toArray(new CVSTag[0]); 450 } 451 452 459 private String getCachePathFor(String remotePath) { 460 return remotePath; 461 } 462 463 469 public void writeState(XMLWriter writer) { 470 471 HashMap attributes = new HashMap (); 472 473 attributes.clear(); 474 attributes.put(RepositoriesViewContentHandler.ID_ATTRIBUTE, root.getLocation(false)); 475 if (name != null) { 476 attributes.put(RepositoriesViewContentHandler.NAME_ATTRIBUTE, name); 477 } 478 479 writer.startTag(RepositoriesViewContentHandler.REPOSITORY_TAG, attributes, true); 480 481 if(!dateTags.isEmpty()){ 483 writer.startTag(RepositoriesViewContentHandler.DATE_TAGS_TAG, attributes, true); 484 Iterator iter = dateTags.iterator(); 485 while(iter.hasNext()){ 486 CVSTag tag = (CVSTag)iter.next(); 487 writeATag(writer, attributes, tag, RepositoriesViewContentHandler.DATE_TAG_TAG); 488 } 489 writer.endTag(RepositoriesViewContentHandler.DATE_TAGS_TAG); 490 } 491 492 String [] paths = getKnownRemotePaths(); 495 for (int i = 0; i < paths.length; i++) { 496 String path = paths[i]; 497 attributes.clear(); 498 String name = path; 499 if (isDefinedModuleName(path)) { 500 name = getDefinedModuleName(path); 501 502 attributes.put(RepositoriesViewContentHandler.TYPE_ATTRIBUTE, RepositoriesViewContentHandler.DEFINED_MODULE_TYPE); 503 } 504 attributes.put(RepositoriesViewContentHandler.PATH_ATTRIBUTE, name); 505 TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(path); 506 boolean writeOutTags = entry != null && !entry.isExpired(); 507 if (writeOutTags) 508 attributes.put(RepositoriesViewContentHandler.LAST_ACCESS_TIME_ATTRIBUTE, Long.toString(entry.lastAccessTime)); 509 writer.startTag(RepositoriesViewContentHandler.MODULE_TAG, attributes, true); 510 if (writeOutTags) { 511 Iterator tagIt = entry.tags.iterator(); 512 while (tagIt.hasNext()) { 513 CVSTag tag = (CVSTag)tagIt.next(); 514 writeATag(writer, attributes, tag, RepositoriesViewContentHandler.TAG_TAG); 515 } 516 } 517 Set refreshSet = (Set )autoRefreshFiles.get(path); 518 if (refreshSet != null) { 519 Iterator filenameIt = refreshSet.iterator(); 520 while (filenameIt.hasNext()) { 521 String filename = (String )filenameIt.next(); 522 attributes.clear(); 523 attributes.put(RepositoriesViewContentHandler.FULL_PATH_ATTRIBUTE, filename); 524 writer.startAndEndTag(RepositoriesViewContentHandler.AUTO_REFRESH_FILE_TAG, attributes, true); 525 } 526 } 527 writer.endTag(RepositoriesViewContentHandler.MODULE_TAG); 528 } 529 writer.endTag(RepositoriesViewContentHandler.REPOSITORY_TAG); 530 } 531 532 private void writeATag(XMLWriter writer, HashMap attributes, CVSTag tag, String s) { 533 attributes.clear(); 534 attributes.put(RepositoriesViewContentHandler.NAME_ATTRIBUTE, tag.getName()); 535 attributes.put(RepositoriesViewContentHandler.TYPE_ATTRIBUTE, RepositoriesViewContentHandler.TAG_TYPES[tag.getType()]); 536 writer.startAndEndTag(s, attributes, true); 537 } 538 539 544 public CVSTag[] getAllKnownTags(String remotePath) { 545 TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(getCachePathFor(remotePath)); 546 if(entry != null){ 547 entry.accessed(); 548 CVSTag [] tags1 = (CVSTag[]) entry.tags.toArray(new CVSTag[entry.tags.size()]); 549 CVSTag[] tags2 = getDateTags(); 550 int len = tags1.length + tags2.length; 551 CVSTag[] tags = new CVSTag[len]; 552 for(int i = 0; i < len; i++){ 553 if(i < tags1.length){ 554 tags[i] = tags1[i]; 555 }else{ 556 tags[i] = tags2[i-tags1.length]; 557 } 558 } 559 return tags; 560 } 561 return getDateTags(); 562 } 563 564 public String [] getKnownRemotePaths() { 565 Set paths = new HashSet (); 566 paths.addAll(versionAndBranchTags.keySet()); 567 paths.addAll(autoRefreshFiles.keySet()); 568 return (String []) paths.toArray(new String [paths.size()]); 569 } 570 573 public Object getAdapter(Class adapter) { 574 if (ICVSRepositoryLocation.class.equals(adapter)) return getRoot(); 575 return super.getAdapter(adapter); 576 } 577 578 583 public boolean tagIsKnown(ICVSRemoteResource remoteResource) { 584 if (remoteResource instanceof ICVSRemoteFolder) { 585 ICVSRemoteFolder folder = (ICVSRemoteFolder) remoteResource; 586 String path = getCachePathFor(folder.getRepositoryRelativePath()); 587 CVSTag[] tags = getAllKnownTags(path); 588 CVSTag tag = folder.getTag(); 589 for (int i = 0; i < tags.length; i++) { 590 CVSTag knownTag = tags[i]; 591 if (knownTag.equals(tag)) return true; 592 } 593 } 594 return false; 595 } 596 597 601 void clearCache() { 602 synchronized(modulesCacheLock) { 603 if (modulesCache != null) 604 modulesCache = null; 605 } 606 } 607 608 612 void setRepositoryLocation(ICVSRepositoryLocation root) { 613 this.root = root; 614 } 615 616 620 void setLastAccessedTime(String remotePath, long lastAccessTime) { 621 TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(getCachePathFor(remotePath)); 622 if(entry != null){ 623 entry.lastAccessTime = lastAccessTime; 624 } 625 } 626 627 } 628 | Popular Tags |