1 19 20 package org.netbeans.modules.versioning.system.cvss.util; 21 22 import java.awt.Dialog ; 23 import java.awt.Frame ; 24 import java.awt.KeyboardFocusManager ; 25 import java.awt.Window ; 26 import java.io.BufferedReader ; 27 import java.io.File ; 28 import java.io.FileNotFoundException ; 29 import java.io.FileReader ; 30 import java.io.IOException ; 31 import java.lang.ref.Reference ; 32 import java.lang.ref.WeakReference ; 33 import java.util.*; 34 import java.util.regex.Pattern ; 35 36 import org.netbeans.api.fileinfo.NonRecursiveFolder; 37 import org.netbeans.api.project.FileOwnerQuery; 38 import org.netbeans.api.project.Project; 39 import org.netbeans.api.project.ProjectUtils; 40 import org.netbeans.api.project.SourceGroup; 41 import org.netbeans.api.project.Sources; 42 import org.netbeans.lib.cvsclient.admin.Entry; 43 import org.netbeans.lib.cvsclient.command.log.LogInformation; 44 import org.netbeans.modules.versioning.system.cvss.CvsFileNode; 45 import org.netbeans.modules.versioning.system.cvss.CvsVersioningSystem; 46 import org.netbeans.modules.versioning.system.cvss.FileInformation; 47 import org.netbeans.modules.versioning.system.cvss.FileStatusCache; 48 import org.netbeans.modules.versioning.util.FlatFolder; 49 import org.openide.filesystems.FileObject; 50 import org.openide.filesystems.FileUtil; 51 import org.openide.loaders.DataObject; 52 import org.openide.loaders.DataShadow; 53 import org.openide.nodes.Node; 54 import org.openide.util.Lookup; 55 import org.openide.windows.TopComponent; 56 import org.openide.windows.WindowManager; 57 58 63 public class Utils { 64 65 private static final Pattern metadataPattern = Pattern.compile(".*\\" + File.separatorChar + "CVS(\\" + File.separatorChar + ".*|$)"); 66 67 private static Reference contextNodesCached = new WeakReference (null); 68 private static Context contextCached; 69 70 79 public static Context getCurrentContext(Node[] nodes) { 80 if (nodes == null) { 81 nodes = TopComponent.getRegistry().getActivatedNodes(); 82 } 83 if (Arrays.equals((Node[]) contextNodesCached.get(), nodes)) return contextCached; 84 Set files = new HashSet(nodes.length); 85 Set rootFiles = new HashSet(nodes.length); 86 Set rootFileExclusions = new HashSet(5); 87 for (int i = 0; i < nodes.length; i++) { 88 Node node = nodes[i]; 89 CvsFileNode cvsNode = node.getLookup().lookup(CvsFileNode.class); 90 if (cvsNode != null) { 91 files.add(cvsNode.getFile()); 92 rootFiles.add(cvsNode.getFile()); 93 continue; 94 } 95 Project project = node.getLookup().lookup(Project.class); 96 if (project != null) { 97 addProjectFiles(files, rootFiles, rootFileExclusions, project); 98 continue; 99 } 100 addFileObjects(node, files, rootFiles); 101 } 102 103 contextCached = new Context(files, rootFiles, rootFileExclusions); 104 contextNodesCached = new WeakReference (nodes); 105 return contextCached; 106 } 107 108 109 120 public static Context getCurrentContext(Node[] nodes, int includingFileStatus, int includingFolderStatus) { 121 Context context = getCurrentContext(nodes); 122 FileStatusCache cache = CvsVersioningSystem.getInstance().getStatusCache(); 123 File [] files = context.getRootFiles(); 124 for (int i = 0; i < files.length; i++) { 125 File file = files[i]; 126 FileInformation fi = cache.getStatus(file); 127 if (file.isDirectory()) { 128 if ((fi.getStatus() & includingFolderStatus) == 0) return Context.Empty; 129 } else { 130 if ((fi.getStatus() & includingFileStatus) == 0) return Context.Empty; 131 } 132 } 133 if (context.getExclusions().size() == 0) return context; 135 136 Set<File > filteredFiles = new HashSet<File >(Arrays.asList(context.getFiles())); 140 Set<File > rootFiles = new HashSet<File >(Arrays.asList(context.getRootFiles())); 141 Set<File > rootFileExclusions = new HashSet<File >(context.getExclusions()); 142 143 for (Iterator<File > i = filteredFiles.iterator(); i.hasNext(); ) { 144 File file = i.next(); 145 if (file.isDirectory()) { 146 if ((cache.getStatus(file).getStatus() & includingFolderStatus) == 0) i.remove(); 147 } else { 148 if ((cache.getStatus(file).getStatus() & includingFileStatus) == 0) i.remove(); 149 } 150 } 151 return new Context(filteredFiles, rootFiles, rootFileExclusions); 152 } 153 154 162 public static boolean isVersionedProject(Node node) { 163 Lookup lookup = node.getLookup(); 164 Project project = lookup.lookup(Project.class); 165 return isVersionedProject(project); 166 } 167 168 176 public static boolean isVersionedProject(Project project) { 177 if (project != null) { 178 FileStatusCache cache = CvsVersioningSystem.getInstance().getStatusCache(); 179 Sources sources = ProjectUtils.getSources(project); 180 SourceGroup [] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC); 181 for (int j = 0; j < sourceGroups.length; j++) { 182 SourceGroup sourceGroup = sourceGroups[j]; 183 File f = FileUtil.toFile(sourceGroup.getRootFolder()); 184 if (f != null) { 185 if ((cache.getStatus(f).getStatus() & FileInformation.STATUS_MANAGED) != 0) return true; 186 } 187 } 188 } 189 return false; 190 } 191 192 private static void addFileObjects(Node node, Set files, Set rootFiles) { 193 Collection folders = node.getLookup().lookup(new Lookup.Template(NonRecursiveFolder.class)).allInstances(); 194 List nodeFiles = new ArrayList(); 195 if (folders.size() > 0) { 196 for (Iterator j = folders.iterator(); j.hasNext();) { 197 NonRecursiveFolder nonRecursiveFolder = (NonRecursiveFolder) j.next(); 198 nodeFiles.add(new FlatFolder(FileUtil.toFile(nonRecursiveFolder.getFolder()).getAbsolutePath())); 199 } 200 } else { 201 Collection fileObjects = node.getLookup().lookup(new Lookup.Template(FileObject.class)).allInstances(); 202 if (fileObjects.size() > 0) { 203 nodeFiles.addAll(toFileCollection(fileObjects)); 204 } else { 205 DataObject dataObject = node.getCookie(DataObject.class); 206 if (dataObject instanceof DataShadow) { 207 dataObject = ((DataShadow) dataObject).getOriginal(); 208 } 209 if (dataObject != null) { 210 Collection doFiles = toFileCollection(dataObject.files()); 211 nodeFiles.addAll(doFiles); 212 } 213 } 214 } 215 files.addAll(nodeFiles); 216 rootFiles.addAll(nodeFiles); 217 } 218 219 225 public static void addProjectFiles(Collection filteredFiles, Collection rootFiles, Collection rootFilesExclusions, Project project) { 226 FileStatusCache cache = CvsVersioningSystem.getInstance().getStatusCache(); 227 Sources sources = ProjectUtils.getSources(project); 228 SourceGroup [] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC); 229 for (int j = 0; j < sourceGroups.length; j++) { 230 SourceGroup sourceGroup = sourceGroups[j]; 231 FileObject srcRootFo = sourceGroup.getRootFolder(); 232 File rootFile = FileUtil.toFile(srcRootFo); 233 try { 234 getCVSRootFor(rootFile); 235 } catch (IOException e) { 236 continue; 238 } 239 rootFiles.add(rootFile); 240 boolean containsSubprojects = false; 241 FileObject [] rootChildren = srcRootFo.getChildren(); 242 Set projectFiles = new HashSet(rootChildren.length); 243 for (int i = 0; i < rootChildren.length; i++) { 244 FileObject rootChildFo = rootChildren[i]; 245 if (CvsVersioningSystem.FILENAME_CVS.equals(rootChildFo.getNameExt())) continue; 246 File child = FileUtil.toFile(rootChildFo); 247 if (sourceGroup.contains(rootChildFo) || CvsVersioningSystem.FILENAME_CVSIGNORE.equals(rootChildFo.getNameExt())) { 249 projectFiles.add(child); 251 } else { 252 int status = cache.getStatus(child).getStatus(); 253 if (status != FileInformation.STATUS_NOTVERSIONED_EXCLUDED) { 254 rootFilesExclusions.add(child); 255 containsSubprojects = true; 256 } 257 } 258 } 259 if (containsSubprojects) { 260 filteredFiles.addAll(projectFiles); 261 } else { 262 filteredFiles.add(rootFile); 263 } 264 } 265 } 266 267 273 public static Context getProjectsContext(Project [] projects) { 274 Set filtered = new HashSet(); 275 Set roots = new HashSet(); 276 Set exclusions = new HashSet(); 277 for (int i = 0; i < projects.length; i++) { 278 addProjectFiles(filtered, roots, exclusions, projects[i]); 279 } 280 return new Context(filtered, roots, exclusions); 281 } 282 283 private static Collection toFileCollection(Collection fileObjects) { 284 Set files = new HashSet(fileObjects.size()*4/3+1); 285 for (Iterator i = fileObjects.iterator(); i.hasNext();) { 286 files.add(FileUtil.toFile((FileObject) i.next())); 287 } 288 files.remove(null); 289 return files; 290 } 291 292 public static File [] toFileArray(Collection fileObjects) { 293 Set files = new HashSet(fileObjects.size()*4/3+1); 294 for (Iterator i = fileObjects.iterator(); i.hasNext();) { 295 files.add(FileUtil.toFile((FileObject) i.next())); 296 } 297 files.remove(null); 298 return (File []) files.toArray(new File [files.size()]); 299 } 300 301 309 public static String getCVSRootFor(File file) throws IOException { 310 if (file.isFile()) file = file.getParentFile(); 311 for (; file != null; file = file.getParentFile()) { 312 File rootFile = new File (file, "CVS/Root"); BufferedReader br = null; 314 try { 315 br = new BufferedReader (new FileReader (rootFile)); 316 return br.readLine(); 317 } catch (FileNotFoundException e) { 318 continue; 319 } finally { 320 if (br != null) br.close(); 321 } 322 } 323 throw new IOException ("CVS/Root not found"); } 325 326 public static Window getCurrentWindow() { 327 Window wnd = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); 328 if (wnd instanceof Dialog || wnd instanceof Frame ) { 329 return wnd; 330 } else { 331 return WindowManager.getDefault().getMainWindow(); 332 } 333 } 334 335 342 public static boolean isParentOrEqual(File parent, File file) { 343 for (; file != null; file = file.getParentFile()) { 344 if (file.equals(parent)) return true; 345 } 346 return false; 347 } 348 349 356 public static String getRelativePath(File file) { 357 try { 358 return CvsVersioningSystem.getInstance().getAdminHandler().getRepositoryForDirectory(file.getParent(), "").substring(1); } catch (IOException e) { 360 return ""; } 362 } 363 364 371 public static String getSticky(File file) { 372 if (file == null) return null; 373 FileInformation info = CvsVersioningSystem.getInstance().getStatusCache().getStatus(file); 374 if (info.getStatus() == FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY) { 375 return getSticky(file.getParentFile()); 376 } else if (info.getStatus() == FileInformation.STATUS_NOTVERSIONED_EXCLUDED) { 377 return null; 378 } 379 if (file.isDirectory()) { 380 return CvsVersioningSystem.getInstance().getAdminHandler().getStickyTagForDirectory(file); 381 } 382 Entry entry = info.getEntry(file); 383 if (entry != null) { 384 String stickyInfo = null; 385 if (entry.getTag() != null) stickyInfo = "T" + entry.getTag(); else if (entry.getDate() != null) stickyInfo = "D" + entry.getDateFormatted(); return stickyInfo; 388 } 389 return null; 390 } 391 392 398 public static String previousRevision(String revision) { 399 if (revision == null) return null; 400 String [] nums = revision.split("\\."); assert (nums.length % 2) == 0 : "File revisions must consist from even tokens: " + revision; 403 int lastIndex = nums.length -1; 405 boolean cutoff = false; 406 while (lastIndex>1 && "1".equals(nums[lastIndex])) { lastIndex -= 2; 408 cutoff = true; 409 } 410 if (lastIndex <= 0) { 411 return null; 412 } else if (lastIndex == 1 && "1".equals(nums[lastIndex])) { return null; 414 } else { 415 int rev = Integer.parseInt(nums[lastIndex]); 416 if (!cutoff) rev--; 417 StringBuffer sb = new StringBuffer (nums[0]); 418 for (int i = 1; i<lastIndex; i++) { 419 sb.append('.').append(nums[i]); } 421 sb.append('.').append(rev); return sb.toString(); 423 } 424 } 425 426 432 public static Project getProject(File file) { 433 if (file == null) return null; 434 FileObject fo = FileUtil.toFileObject(file); 435 if (fo == null) return getProject(file.getParentFile()); 436 return FileOwnerQuery.getOwner(fo); 437 } 438 439 public static String createBranchRevisionNumber(String branchNumber) { 440 StringBuilder sb = new StringBuilder (); 441 int idx = branchNumber.lastIndexOf('.'); sb.append(branchNumber.substring(0, idx)); 443 sb.append(".0"); sb.append(branchNumber.substring(idx)); 445 return sb.toString(); 446 } 447 448 public static String formatBranches(LogInformation.Revision revision, boolean useNumbersIfNamesNotAvailable) { 449 String branches = revision.getBranches(); 450 if (branches == null) return ""; 452 boolean branchNamesAvailable = true; 453 StringBuilder branchNames = new StringBuilder (); 454 StringTokenizer st = new StringTokenizer(branches, ";"); while (st.hasMoreTokens()) { 456 String branchNumber = st.nextToken().trim(); 457 List<LogInformation.SymName> names = revision.getLogInfoHeader().getSymNamesForRevision(createBranchRevisionNumber(branchNumber)); 458 if (names.size() > 0) { 459 branchNames.append(names.get(0).getName()); 460 } else { 461 branchNamesAvailable = false; 462 if (useNumbersIfNamesNotAvailable) { 463 branchNames.append(branchNumber); 464 } else { 465 break; 466 } 467 } 468 branchNames.append("; "); } 470 if (branchNamesAvailable || useNumbersIfNamesNotAvailable) { 471 branchNames.delete(branchNames.length() - 2, branchNames.length()); 472 } else { 473 branchNames.delete(0, branchNames.length()); 474 } 475 return branchNames.toString(); 476 } 477 478 481 public static class ByImportanceComparator implements Comparator { 482 public int compare(Object o1, Object o2) { 483 FileInformation i1 = (FileInformation) o1; 484 FileInformation i2 = (FileInformation) o2; 485 return getComparableStatus(i1.getStatus()) - getComparableStatus(i2.getStatus()); 486 } 487 } 488 489 495 public static int getComparableStatus(int status) { 496 switch (status) { 497 case FileInformation.STATUS_VERSIONED_CONFLICT: 498 return 0; 499 case FileInformation.STATUS_VERSIONED_MERGE: 500 return 1; 501 case FileInformation.STATUS_VERSIONED_DELETEDLOCALLY: 502 return 10; 503 case FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY: 504 return 11; 505 case FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY: 506 return 12; 507 case FileInformation.STATUS_VERSIONED_ADDEDLOCALLY: 508 return 13; 509 case FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY: 510 return 14; 511 case FileInformation.STATUS_VERSIONED_REMOVEDINREPOSITORY: 512 return 30; 513 case FileInformation.STATUS_VERSIONED_NEWINREPOSITORY: 514 return 31; 515 case FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY: 516 return 32; 517 case FileInformation.STATUS_VERSIONED_UPTODATE: 518 return 50; 519 case FileInformation.STATUS_NOTVERSIONED_EXCLUDED: 520 return 100; 521 case FileInformation.STATUS_NOTVERSIONED_NOTMANAGED: 522 return 101; 523 case FileInformation.STATUS_UNKNOWN: 524 return 102; 525 default: 526 throw new IllegalArgumentException ("Unknown status: " + status); } 528 } 529 530 public static boolean isPartOfCVSMetadata(File file) { 531 return metadataPattern.matcher(file.getAbsolutePath()).matches(); 532 } 533 534 535 public static FileObject mkfolders(File file) throws IOException { 536 if (file.isDirectory()) return FileUtil.toFileObject(file); 537 538 File parent = file.getParentFile(); 539 540 String path = file.getName(); 541 while (parent.isDirectory() == false) { 542 path = parent.getName() + "/" + path; parent = parent.getParentFile(); 544 } 545 546 FileObject fo = FileUtil.toFileObject(parent); 547 return FileUtil.createFolder(fo, path); 548 } 549 550 558 public static boolean isTagValid(String name) { 559 if (name == null || name.length() == 0) return false; 560 char c = name.charAt(0); 561 if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) return false; 562 for (int i = 1; i < name.length(); i++) { 563 c = name.charAt(i); 564 if (c == '$' || c == ',' || c=='.' || c == ':' || c == ';' || c =='@' || c == ' ' || c == '\t' || c == '\n') return false; 565 } 566 if (name.equals("HEAD") || name.equals("BASE")) return false; 567 return true; 568 } 569 } 570 | Popular Tags |