1 19 package org.netbeans.modules.versioning.util; 20 21 import org.openide.util.RequestProcessor; 22 import org.openide.util.NbBundle; 23 import org.openide.util.actions.Presenter; 24 import org.openide.loaders.DataObject; 25 import org.openide.loaders.DataObjectNotFoundException; 26 import org.openide.loaders.DataShadow; 27 import org.openide.filesystems.FileObject; 28 import org.openide.filesystems.FileUtil; 29 import org.openide.awt.Actions; 30 import org.openide.nodes.Node; 31 import org.openide.text.CloneableEditorSupport; 32 import org.openide.windows.CloneableOpenSupport; 33 import org.netbeans.modules.versioning.spi.VCSContext; 34 import org.netbeans.api.project.Project; 35 import org.netbeans.api.project.ProjectUtils; 36 37 import javax.swing.text.Document ; 38 import javax.swing.*; 39 import java.io.*; 40 import java.util.prefs.Preferences ; 41 import java.util.prefs.BackingStoreException ; 42 import java.util.*; 43 import java.util.logging.Logger ; 44 import java.util.logging.Level ; 45 import java.awt.Rectangle ; 46 import java.awt.Point ; 47 import java.text.MessageFormat ; 48 import java.beans.PropertyChangeListener ; 49 import java.beans.VetoableChangeListener ; 50 51 56 public final class Utils { 57 58 61 private static final RequestProcessor vcsRequestProcessor = new RequestProcessor("Versioning", 1); 62 63 66 private static final RequestProcessor vcsBlockingRequestProcessor = new RequestProcessor("Versioning long tasks", 1); 67 68 private Utils() { 69 } 70 71 78 public static RequestProcessor.Task createTask(Runnable runnable) { 79 return vcsBlockingRequestProcessor.create(runnable); 80 } 81 82 88 public static void post(Runnable runnable) { 89 vcsRequestProcessor.post(runnable); 90 } 91 92 99 public static boolean isParentOrEqual(File parent, File file) { 100 if (parent instanceof FlatFolder) { 101 return parent.equals(file) || parent.equals(file.getParentFile()) && !file.isDirectory(); 102 } 103 for (; file != null; file = file.getParentFile()) { 104 if (file.equals(parent)) return true; 105 } 106 return false; 107 } 108 109 115 public static boolean shareCommonDataObject(File[] files) { 116 if (files == null || files.length < 2) return true; 117 DataObject common = findDataObject(files[0]); 118 for (int i = 1; i < files.length; i++) { 119 DataObject dao = findDataObject(files[i]); 120 if (dao != common && (dao == null || !dao.equals(common))) return false; 121 } 122 return true; 123 } 124 125 129 public static Set<File> getAllDataObjectFiles(File file) { 130 Set<File> filesToCheckout = new HashSet<File>(2); 131 filesToCheckout.add(file); 132 FileObject fo = FileUtil.toFileObject(file); 133 if (fo != null) { 134 try { 135 DataObject dao = DataObject.find(fo); 136 Set<FileObject> fileObjects = dao.files(); 137 for (FileObject fileObject : fileObjects) { 138 filesToCheckout.add(FileUtil.toFile(fileObject)); 139 } 140 } catch (DataObjectNotFoundException e) { 141 } 143 } 144 return filesToCheckout; 145 } 146 147 private static DataObject findDataObject(File file) { 148 FileObject fo = FileUtil.toFileObject(file); 149 if (fo != null) { 150 try { 151 return DataObject.find(fo); 152 } catch (DataObjectNotFoundException e) { 153 } 155 } 156 return null; 157 } 158 159 166 public static void copyStreamsCloseAll(OutputStream writer, InputStream reader) throws IOException { 167 byte [] buffer = new byte[4096]; 168 int n; 169 while ((n = reader.read(buffer)) != -1) { 170 writer.write(buffer, 0, n); 171 } 172 writer.close(); 173 reader.close(); 174 } 175 176 183 public static void copyStreamsCloseAll(Writer writer, Reader reader) throws IOException { 184 char [] buffer = new char[4096]; 185 int n; 186 while ((n = reader.read(buffer)) != -1) { 187 writer.write(buffer, 0, n); 188 } 189 writer.close(); 190 reader.close(); 191 } 192 193 200 public static List<String > getStringList(Preferences prefs, String key) { 201 List<String > retval = new ArrayList<String >(); 202 try { 203 String [] keys = prefs.keys(); 204 for (int i = 0; i < keys.length; i++) { 205 String k = keys[i]; 206 if (k != null && k.startsWith(key)) { 207 int idx = Integer.parseInt(k.substring(k.lastIndexOf('.') + 1)); 208 retval.add(idx + "." + prefs.get(k, null)); 209 } 210 } 211 List<String > rv = new ArrayList<String >(retval.size()); 212 rv.addAll(retval); 213 for (String s : retval) { 214 int pos = s.indexOf('.'); 215 int index = Integer.parseInt(s.substring(0, pos)); 216 rv.set(index, s.substring(pos + 1)); 217 } 218 return rv; 219 } catch (Exception ex) { 220 Logger.getLogger(Utils.class.getName()).log(Level.INFO, null, ex); 221 return new ArrayList<String >(0); 222 } 223 } 224 225 232 public static void put(Preferences prefs, String key, List<String > value) { 233 try { 234 String [] keys = prefs.keys(); 235 for (int i = 0; i < keys.length; i++) { 236 String k = keys[i]; 237 if (k != null && k.startsWith(key + ".")) { 238 prefs.remove(k); 239 } 240 } 241 int idx = 0; 242 for (String s : value) { 243 prefs.put(key + "." + idx++, s); 244 } 245 } catch (BackingStoreException ex) { 246 Logger.getLogger(Utils.class.getName()).log(Level.INFO, null, ex); 247 } 248 } 249 250 260 public static void insert(Preferences prefs, String key, String value, int maxLength) { 261 List<String > newValues = getStringList(prefs, key); 262 if(newValues.contains(value)) { 263 newValues.remove(value); 264 } 265 newValues.add(0, value); 266 if (maxLength > -1 && newValues.size() > maxLength) { 267 newValues.subList(maxLength, newValues.size()).clear(); 268 } 269 put(prefs, key, newValues); 270 } 271 272 279 public static void removeFromArray(Preferences prefs, String key, List<String > values) { 280 List<String > newValues = getStringList(prefs, key); 281 newValues.removeAll(values); 282 put(prefs, key, newValues); 283 } 284 285 292 public static void removeFromArray(Preferences prefs, String key, String value) { 293 List<String > newValues = getStringList(prefs, key); 294 newValues.remove(value); 295 put(prefs, key, newValues); 296 } 297 298 305 public static File[][] splitFlatOthers(File [] files) { 306 Set<File> flat = new HashSet<File>(1); 307 for (int i = 0; i < files.length; i++) { 308 if (files[i] instanceof FlatFolder) { 309 flat.add(files[i]); 310 } 311 } 312 if (flat.size() == 0) { 313 return new File[][] { new File[0], files }; 314 } else { 315 Set<File> allFiles = new HashSet<File>(Arrays.asList(files)); 316 allFiles.removeAll(flat); 317 return new File[][] { 318 flat.toArray(new File[flat.size()]), 319 allFiles.toArray(new File[allFiles.size()]) 320 }; 321 } 322 } 323 324 329 public static void deleteRecursively(File file) { 330 if (file.isDirectory()) { 331 File [] files = file.listFiles(); 332 for (int i = 0; i < files.length; i++) { 333 deleteRecursively(files[i]); 334 } 335 } 336 file.delete(); 337 } 338 339 347 public static File getCommonParent(File a, File b) { 348 for (;;) { 349 if (a.equals(b)) { 350 return a; 351 } else if (a.getAbsolutePath().length() > b.getAbsolutePath().length()) { 352 a = a.getParentFile(); 353 if (a == null) return null; 354 } else { 355 b = b.getParentFile(); 356 if (b == null) return null; 357 } 358 } 359 } 360 361 public static String getStackTrace() { 362 Exception e = new Exception (); 363 e.fillInStackTrace(); 364 StringWriter sw = new StringWriter(); 365 e.printStackTrace(new PrintWriter(sw)); 366 return sw.toString(); 367 } 368 369 375 public static Reader getDocumentReader(final Document doc) { 376 final String [] str = new String [1]; 377 Runnable run = new Runnable () { 378 public void run () { 379 try { 380 str[0] = doc.getText(0, doc.getLength()); 381 } catch (javax.swing.text.BadLocationException e) { 382 e.printStackTrace(); 384 } 385 } 386 }; 387 doc.render(run); 388 return new StringReader(str[0]); 389 } 390 391 397 public static Point getPositionForPopup(JTable table) { 398 int idx = table.getSelectedRow(); 399 if (idx == -1) idx = 0; 400 Rectangle rect = table.getCellRect(idx, 1, true); 401 return rect.getLocation(); 402 } 403 404 410 public static JMenuItem toMenuItem(Action action) { 411 JMenuItem item; 412 if (action instanceof Presenter.Menu) { 413 item = ((Presenter.Menu) action).getMenuPresenter(); 414 } else { 415 item = new JMenuItem(); 416 Actions.connect(item, action, false); 417 } 418 return item; 419 } 420 421 public static File getTempFolder() { 422 File tmpDir = new File(System.getProperty("java.io.tmpdir")); for (;;) { 424 File dir = new File(tmpDir, "vcs-" + Long.toString(System.currentTimeMillis())); if (!dir.exists() && dir.mkdirs()) { 426 dir.deleteOnExit(); 427 return FileUtil.normalizeFile(dir); 428 } 429 } 430 } 431 432 439 public static String wordWrap(String s, int maxLineLength) { 440 int n = s.length() - 1; 441 if (maxLineLength < 1 || n < maxLineLength) return s; 442 StringBuilder sb = new StringBuilder (); 443 444 int currentWrap = 0; 445 for (;;) { 446 int nextWrap = currentWrap + maxLineLength - 1; 447 if (nextWrap >= n) { 448 sb.append(s.substring(currentWrap)); 449 break; 450 } 451 int idx = s.lastIndexOf(' ', nextWrap + 1); 452 if (idx > currentWrap) { 453 sb.append(s.substring(currentWrap, idx).trim()); 454 currentWrap = idx + 1; 455 } else { 456 sb.append(s.substring(currentWrap, nextWrap + 1)); 457 currentWrap = nextWrap + 1; 458 } 459 sb.append('\n'); 460 } 461 return sb.toString(); 462 } 463 464 472 public static String getActionName(Class clazz, String baseName, VCSContext ctx) { 473 Set<File> nodes = ctx.getRootFiles(); 474 int objectCount = nodes.size(); 475 479 Node[] activatedNodes = ctx.getNodes(); 480 boolean projectsOnly = true; 481 for (int i = 0; i < activatedNodes.length; i++) { 482 Node activatedNode = activatedNodes[i]; 483 Project project = (Project) activatedNode.getLookup().lookup(Project.class); 484 if (project == null) { 485 projectsOnly = false; 486 break; 487 } 488 } 489 if (projectsOnly) objectCount = activatedNodes.length; 490 491 if (objectCount == 0) { 492 return NbBundle.getBundle(clazz).getString(baseName); 493 } else if (objectCount == 1) { 494 if (projectsOnly) { 495 String dispName = ProjectUtils.getInformation((Project) activatedNodes[0].getLookup().lookup(Project.class)).getDisplayName(); 496 return NbBundle.getMessage(clazz, baseName + "_Context", dispName); 498 } 499 String name; 500 FileObject fo = (FileObject) activatedNodes[0].getLookup().lookup(FileObject.class); 501 if (fo != null) { 502 name = fo.getNameExt(); 503 } else { 504 DataObject dao = (DataObject) activatedNodes[0].getLookup().lookup(DataObject.class); 505 if (dao instanceof DataShadow) { 506 dao = ((DataShadow) dao).getOriginal(); 507 } 508 if (dao != null) { 509 name = dao.getPrimaryFile().getNameExt(); 510 } else { 511 name = activatedNodes[0].getDisplayName(); 512 } 513 } 514 return MessageFormat.format(NbBundle.getBundle(clazz).getString(baseName + "_Context"), name); } else { 516 if (projectsOnly) { 517 try { 518 return MessageFormat.format(NbBundle.getBundle(clazz).getString(baseName + "_Projects"), objectCount); } catch (MissingResourceException ex) { 520 } 522 } 523 return MessageFormat.format(NbBundle.getBundle(clazz).getString(baseName + "_Context_Multiple"), objectCount); } 525 } 526 527 533 public static String getContextDisplayName(VCSContext ctx) { 534 Set<File> nodes = ctx.getRootFiles(); 536 int objectCount = nodes.size(); 537 541 Node[] activatedNodes = ctx.getNodes(); 542 boolean projectsOnly = true; 543 for (int i = 0; i < activatedNodes.length; i++) { 544 Node activatedNode = activatedNodes[i]; 545 Project project = (Project) activatedNode.getLookup().lookup(Project.class); 546 if (project == null) { 547 projectsOnly = false; 548 break; 549 } 550 } 551 if (projectsOnly) objectCount = activatedNodes.length; 552 553 if (objectCount == 0) { 554 return null; 555 } else if (objectCount == 1) { 556 if (projectsOnly) { 557 return ProjectUtils.getInformation((Project) activatedNodes[0].getLookup().lookup(Project.class)).getDisplayName(); 558 } 559 FileObject fo = (FileObject) activatedNodes[0].getLookup().lookup(FileObject.class); 560 if (fo != null) { 561 return fo.getNameExt(); 562 } else { 563 DataObject dao = (DataObject) activatedNodes[0].getLookup().lookup(DataObject.class); 564 if (dao instanceof DataShadow) { 565 dao = ((DataShadow) dao).getOriginal(); 566 } 567 if (dao != null) { 568 return dao.getPrimaryFile().getNameExt(); 569 } else { 570 return activatedNodes[0].getDisplayName(); 571 } 572 } 573 } else { 574 if (projectsOnly) { 575 try { 576 return MessageFormat.format(NbBundle.getBundle(Utils.class).getString("MSG_ActionContext_MultipleProjects"), objectCount); } catch (MissingResourceException ex) { 578 } 580 } 581 return MessageFormat.format(NbBundle.getBundle(Utils.class).getString("MSG_ActionContext_MultipleFiles"), objectCount); } 583 } 584 585 591 public static void openFile(FileObject fo, String revision) { 592 ViewEnv env = new ViewEnv(fo); 593 CloneableEditorSupport ces = new ViewCES(env, fo.getNameExt() + " @ " + revision); ces.view(); 595 } 596 597 private static class ViewEnv implements CloneableEditorSupport.Env { 598 599 private final FileObject file; 600 601 public ViewEnv(FileObject file) { 602 this.file = file; 603 } 604 605 public InputStream inputStream() throws IOException { 606 return file.getInputStream(); 607 } 608 609 public OutputStream outputStream() throws IOException { 610 throw new IOException(); 611 } 612 613 public Date getTime() { 614 return file.lastModified(); 615 } 616 617 public String getMimeType() { 618 return file.getMIMEType(); 619 } 620 621 public void addPropertyChangeListener(PropertyChangeListener l) { 622 } 623 624 public void removePropertyChangeListener(PropertyChangeListener l) { 625 } 626 627 public void addVetoableChangeListener(VetoableChangeListener l) { 628 } 629 630 public void removeVetoableChangeListener(VetoableChangeListener l) { 631 } 632 633 public boolean isValid() { 634 return file.isValid(); 635 } 636 637 public boolean isModified() { 638 return false; 639 } 640 641 public void markModified() throws IOException { 642 throw new IOException(); 643 } 644 645 public void unmarkModified() { 646 } 647 648 public CloneableOpenSupport findCloneableOpenSupport() { 649 return null; 650 } 651 } 652 653 private static class ViewCES extends CloneableEditorSupport { 654 655 private final String name; 656 657 public ViewCES(Env env, String name) { 658 super(env); 659 this.name = name; 660 } 661 662 protected String messageSave() { 663 return name; 664 } 665 666 protected String messageName() { 667 return name; 668 } 669 670 protected String messageToolTip() { 671 return name; 672 } 673 674 protected String messageOpening() { 675 return name; 676 } 677 678 protected String messageOpened() { 679 return name; 680 } 681 } 682 } 683 | Popular Tags |