KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > system > cvss > CvsVersioningSystem


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.versioning.system.cvss;
21
22 import org.netbeans.modules.versioning.util.ListenersSupport;
23 import org.netbeans.modules.versioning.util.VersioningListener;
24 import org.netbeans.modules.versioning.util.VersioningEvent;
25 import org.netbeans.lib.cvsclient.admin.AdminHandler;
26 import org.netbeans.lib.cvsclient.admin.Entry;
27 import org.netbeans.lib.cvsclient.command.*;
28 import org.netbeans.lib.cvsclient.command.add.AddCommand;
29 import org.netbeans.lib.cvsclient.connection.AuthenticationException;
30 import org.netbeans.lib.cvsclient.file.FileHandler;
31 import org.netbeans.modules.versioning.system.cvss.util.Utils;
32 import org.netbeans.modules.versioning.system.cvss.util.Context;
33 import org.netbeans.modules.versioning.system.cvss.ui.syncview.CvsSynchronizeTopComponent;
34 import org.netbeans.modules.versioning.spi.VCSAnnotator;
35 import org.netbeans.modules.versioning.spi.VCSInterceptor;
36 import org.netbeans.modules.versioning.spi.OriginalContent;
37 import org.netbeans.modules.versioning.VersioningManager;
38 import org.netbeans.api.queries.SharabilityQuery;
39 import org.openide.ErrorManager;
40 import org.openide.cookies.EditorCookie;
41 import org.openide.loaders.DataObject;
42 import org.openide.loaders.DataObjectNotFoundException;
43 import org.openide.util.RequestProcessor;
44 import org.openide.filesystems.*;
45
46 import javax.swing.*;
47 import java.io.*;
48 import java.util.*;
49 import java.util.regex.Pattern JavaDoc;
50 import java.util.regex.PatternSyntaxException JavaDoc;
51 import java.beans.PropertyChangeListener JavaDoc;
52
53 /**
54  * A singleton CVS manager class, center of CVS module. Use {@link #getInstance()} to get access
55  * to CVS module functionality.
56  *
57  * @author Maros Sandor
58  */

59 public class CvsVersioningSystem {
60
61     private static CvsVersioningSystem instance;
62     
63     public static final String JavaDoc FILENAME_CVSIGNORE = ".cvsignore"; // NOI18N
64
public static final String JavaDoc FILENAME_CVS = "CVS"; // NOI18N
65

66     public static final Object JavaDoc EVENT_PARAM_CHANGED = new Object JavaDoc();
67     public static final Object JavaDoc PARAM_BATCH_REFRESH_RUNNING = new Object JavaDoc();
68     public static final Object JavaDoc EVENT_VERSIONED_FILES_CHANGED = new Object JavaDoc();
69
70     public static final Object JavaDoc EVENT_REFRESH_ANNOTATIONS = new Object JavaDoc();
71
72     private static final String JavaDoc FILENAME_CVS_REPOSITORY = FILENAME_CVS + "/Repository"; // NOI18N
73
private static final String JavaDoc FILENAME_CVS_ENTRIES = FILENAME_CVS + "/Entries"; // NOI18N
74

75     /**
76      * Extensions to be treated as text although MIME type may suggest otherwise.
77      */

78     private static final Set textExtensions = new HashSet(Arrays.asList(new String JavaDoc [] { "txt", "xml", "html", "properties", "mf", "jhm", "hs", "form" })); // NOI18N
79

80     private final Map clientsCache = new HashMap();
81     private final Map params = new HashMap();
82
83     private GlobalOptions defaultGlobalOptions;
84     private FileStatusCache fileStatusCache;
85
86     private CvsLiteAdminHandler sah;
87     private CvsLiteFileHandler workdirFileHandler;
88     private CvsLiteGzippedFileHandler workdirGzippedFileHandler;
89     private FilesystemHandler filesystemHandler;
90     private VCSAnnotator fileStatusProvider;
91
92     private Annotator annotator;
93
94     private final Set userIgnorePatterns = new HashSet();
95     private boolean userIgnorePatternsReset;
96     private long userIgnorePatternsTimestamp;
97
98     private final Set<File> alreadyGeneratedFiles = new HashSet<File>(5);
99
100     public static synchronized CvsVersioningSystem getInstance() {
101         if (instance == null) {
102             instance = new CvsVersioningSystem();
103             instance.init();
104         }
105         return instance;
106     }
107
108     private void init() {
109         defaultGlobalOptions = CvsVersioningSystem.createGlobalOptions();
110         sah = new CvsLiteAdminHandler();
111         workdirFileHandler = new CvsLiteFileHandler();
112         workdirGzippedFileHandler = new CvsLiteGzippedFileHandler();
113         fileStatusCache = new FileStatusCache(this);
114         filesystemHandler = new FilesystemHandler(this);
115         annotator = new Annotator(this);
116         fileStatusProvider = new FileStatusProvider();
117         cleanup();
118     }
119
120     private void cleanup() {
121         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
122             public void run() {
123                 fileStatusCache.cleanUp();
124             }
125         }, 3000);
126     }
127
128     void shutdown() {
129         SwingUtilities.invokeLater(new Runnable JavaDoc() {
130             public void run() {
131                 try {
132                     CvsSynchronizeTopComponent.getInstance().close();
133                 } catch (Throwable JavaDoc e) {
134                     // ignore, this component is already invalid
135
}
136             }
137         });
138     }
139     
140     private CvsVersioningSystem() {
141     }
142
143     public CvsFileTableModel getFileTableModel(Context context, int displayStatuses) {
144         return new CvsFileTableModel(context, displayStatuses);
145     }
146     
147     /**
148      * Determines correct CVS client from the given cvs root.
149      *
150      * @param cvsRoot root never <code>null</code>
151      * @return
152      */

153     public ClientRuntime getClientRuntime(String JavaDoc cvsRoot) {
154  
155             cvsRoot.length(); // rise NPE
156

157             ClientRuntime clientRuntime;
158             synchronized(clientsCache) {
159                 clientRuntime = (ClientRuntime) clientsCache.get(cvsRoot);
160                 if (clientRuntime == null) {
161                     clientRuntime = new ClientRuntime(cvsRoot);
162                     clientsCache.put(cvsRoot, clientRuntime);
163                 }
164             }
165             return clientRuntime;
166     }
167
168     /**
169      * Determines CVS root for the given command.
170      *
171      * @param cmd a CVS command
172      * @return CVSRoot the command will execute in
173      * @throws NotVersionedException if the root cannot be determined (no CVS/Root file or unsupported command)
174      */

175     String JavaDoc detectCvsRoot(Command cmd) throws NotVersionedException {
176         File [] files;
177
178         if (cmd instanceof AddCommand) {
179             AddCommand c = (AddCommand) cmd;
180             files = c.getFiles();
181         } else if (cmd instanceof BasicCommand) {
182             BasicCommand c = (BasicCommand) cmd;
183             files = c.getFiles();
184         } else {
185             throw new NotVersionedException("Cannot determine CVSRoot for command: " + cmd); // NOI18N
186
}
187
188         File oneFile = files[0];
189         try {
190             String JavaDoc cvsRoot = Utils.getCVSRootFor(oneFile);
191             return cvsRoot;
192         } catch (IOException e) {
193             throw new NotVersionedException("Cannot determine CVSRoot for: " + oneFile); // NOI18N
194
}
195
196     }
197
198     /**
199      * Executes this command asynchronously, in a separate thread, and returns immediately. The command may
200      * or may not execute immediately, depending on previous commands sent to the CVS client that may be
201      * still waiting for execution.
202      *
203      * @param cmd command to execute
204      * @param mgr listener for events the command produces
205      * @throws CommandException
206      * @throws AuthenticationException
207      */

208     public RequestProcessor.Task post(Command cmd, ExecutorSupport mgr) throws CommandException,
209             AuthenticationException, NotVersionedException, IllegalCommandException,
210             IOException {
211         return post(cmd, defaultGlobalOptions, mgr);
212     }
213
214     /**
215      * Schedules given command for execution.
216      * @param cmd
217      * @param options Global options to use, may be set to null to use default options
218      * @param mgr
219      * @return already scheduled task
220      * @throws IllegalCommandException if the command is not valid, e.g. it contains files that cannot be
221      * processed by a single command (they do not have a common filesystem root OR their CVS Roots differ)
222      */

223     public RequestProcessor.Task post(Command cmd, GlobalOptions options, ExecutorSupport mgr) throws IllegalCommandException {
224         ClientRuntime clientRuntime = getClientRuntime(cmd, options);
225         RequestProcessor.Task task = clientRuntime.createTask(cmd, options != null ? options : defaultGlobalOptions, mgr);
226         task.schedule(0);
227         return task;
228     }
229
230     /**
231      * Gets client runtime (a repository session).
232      *
233      * @return runtime never <code>null</code>
234      */

235     public ClientRuntime getClientRuntime(Command cmd, GlobalOptions options) {
236         String JavaDoc root;
237         if (options != null && options.getCVSRoot() != null) {
238             root = options.getCVSRoot();
239         } else {
240             try {
241                 root = detectCvsRoot(cmd);
242             } catch (NotVersionedException e) {
243                 if (options == null) return null;
244                 root = options.getCVSRoot();
245             }
246         }
247         return getClientRuntime(root);
248     }
249
250     public FileStatusCache getStatusCache() {
251         return fileStatusCache;
252     }
253     
254     ListenersSupport listenerSupport = new ListenersSupport(this);
255     public void addVersioningListener(VersioningListener listener) {
256         listenerSupport.addListener(listener);
257     }
258
259     public void removeVersioningListener(VersioningListener listener) {
260         listenerSupport.removeListener(listener);
261     }
262     
263     /**
264      * Checks if the file is ignored by CVS module. This method assumes that the file is managed so
265      * if you do not know this beforehand, you have to call isManaged() first.
266      *
267      * @param file file to be tested
268      * @return true, if the file is ignored by CVS, false otherwise.
269      */

270     boolean isIgnored(final File file) {
271         if (file.isDirectory()) {
272             File cvsRepository = new File(file, FILENAME_CVS_REPOSITORY);
273             if (cvsRepository.canRead()) return false;
274         }
275         String JavaDoc name = file.getName();
276
277         // #67900 global sharability query will report .cvsignore as not sharable
278
if (FILENAME_CVSIGNORE.equals(name)) return false;
279         // backward compatability #68124
280
if (".nbintdb".equals(name)) { // NOI18N
281
return true;
282         }
283
284         Set patterns = new HashSet(Arrays.asList(CvsModuleConfig.getDefault().getIgnoredFilePatterns()));
285         addUserPatterns(patterns);
286         addCvsIgnorePatterns(patterns, file.getParentFile());
287
288         for (Iterator i = patterns.iterator(); i.hasNext();) {
289             Pattern JavaDoc pattern = (Pattern JavaDoc) i.next();
290             if (pattern.matcher(name).matches()) return true;
291         }
292         
293         int sharability = SharabilityQuery.getSharability(file);
294         if (sharability == SharabilityQuery.NOT_SHARABLE) {
295             // BEWARE: In NetBeans VISIBILTY == SHARABILITY ... and we hide Locally Removed folders => we must not Ignore them by mistake
296
if (CvsVisibilityQuery.isHiddenFolder(file)) {
297                 return false;
298             }
299             // #90564: make sure that we only try to generate the .cvsignore file ONCE and if the user deletes it
300
// the file will NOT be re-generated. Do this only for auto-generated .cvsignore files.
301
File cvsIgnoreFile = new File(file.getParentFile(), FILENAME_CVSIGNORE);
302             if (file.exists() && !cvsIgnoreFile.exists()) {
303                 if (!alreadyGeneratedFiles.add(cvsIgnoreFile)) return true;
304             }
305             try {
306                 setIgnored(file);
307             } catch (IOException e) {
308                 // strange, but does no harm
309
}
310             return true;
311         } else {
312             return false;
313         }
314     }
315     
316     private void addUserPatterns(Set patterns) {
317         File userIgnores = new File(System.getProperty("user.home"), FILENAME_CVSIGNORE); // NOI18N
318
long lm = userIgnores.lastModified();
319         if (lm > userIgnorePatternsTimestamp || lm == 0 && userIgnorePatternsTimestamp > 0) {
320             userIgnorePatternsTimestamp = lm;
321             parseUserPatterns(userIgnores);
322         }
323         if (userIgnorePatternsReset) {
324             patterns.clear();
325         }
326         patterns.addAll(userIgnorePatterns);
327     }
328
329     private void parseUserPatterns(File userIgnores) {
330         userIgnorePatternsReset = false;
331         userIgnorePatterns.clear();
332         BufferedReader r = null;
333         try {
334             r = new BufferedReader(new FileReader(userIgnores));
335             String JavaDoc s;
336             while ((s = r.readLine()) != null) {
337                 if ("!".equals(s)) { // NOI18N
338
userIgnorePatternsReset = true;
339                     userIgnorePatterns.clear();
340                 } else {
341                     try {
342                         userIgnorePatterns.add(sh2regex(s));
343                     } catch (IOException e) {
344                         // unsupported pattern
345
}
346                 }
347             }
348         } catch (IOException e) {
349             // user has invalid ignore list, ignore it
350
} finally {
351             if (r != null) try { r.close(); } catch (IOException e) {}
352         }
353     }
354
355     /**
356      * Converts shell file pattern to regex pattern.
357      *
358      * @param s unix shell pattern
359      * @return regex patterm
360      * @throws IOException if this shell pattern is not supported
361      */

362     private static Pattern JavaDoc sh2regex(String JavaDoc s) throws IOException {
363         // TODO: implement full SH->REGEX convertor
364
s = s.replaceAll("\\.", "\\\\."); // NOI18N
365
s = s.replaceAll("\\*", ".*"); // NOI18N
366
s = s.replaceAll("\\?", "."); // NOI18N
367
try {
368             return Pattern.compile(s);
369         } catch (PatternSyntaxException JavaDoc e) {
370             throw new IOException(e.getMessage());
371         }
372     }
373
374     /**
375      * Tests whether a file or directory should receive the STATUS_NOTVERSIONED_NOTMANAGED status.
376      * All files and folders that have a parent with CVS/Repository file are considered versioned.
377      *
378      * @param file a file or directory
379      * @return false if the file should receive the STATUS_NOTVERSIONED_NOTMANAGED status, true otherwise
380      */

381     boolean isManaged(File file) {
382         return VersioningManager.getInstance().getOwner(file) instanceof CVS && !Utils.isPartOfCVSMetadata(file);
383     }
384
385     public void versionedFilesChanged() {
386         listenerSupport.fireVersioningEvent(EVENT_VERSIONED_FILES_CHANGED);
387     }
388         
389     /**
390      * Tests whether the file is managed by this versioning system. If it is, the method should return the topmost
391      * parent of the file that is still versioned.
392      *
393      * @param file a file
394      * @return File the file itself or one of its parents or null if the supplied file is NOT managed by this versioning system
395      */

396     File getTopmostManagedParent(File file) {
397         if (Utils.isPartOfCVSMetadata(file)) {
398             for (;file != null; file = file.getParentFile()) {
399                 if (file.isDirectory() && file.getName().equals(FILENAME_CVS)) {
400                     file = file.getParentFile();
401                     break;
402                 }
403             }
404         }
405         File topmost = null;
406         for (; file != null; file = file.getParentFile()) {
407             File repository = new File(file, FILENAME_CVS_REPOSITORY);
408             File entries = new File(file, FILENAME_CVS_ENTRIES);
409             if (repository.canRead() && entries.canRead()) {
410                 topmost = file;
411             }
412         }
413         return topmost;
414     }
415
416     private void addCvsIgnorePatterns(Set patterns, File file) {
417         Set shPatterns;
418         try {
419             shPatterns = readCvsIgnoreEntries(file);
420         } catch (IOException e) {
421             // ignore invalid entries
422
return;
423         }
424         for (Iterator i = shPatterns.iterator(); i.hasNext();) {
425             String JavaDoc shPattern = (String JavaDoc) i.next();
426             if ("!".equals(shPattern)) { // NOI18N
427
patterns.clear();
428             } else {
429                 try {
430                     patterns.add(sh2regex(shPattern));
431                 } catch (IOException e) {
432                     // unsupported pattern
433
}
434             }
435         }
436     }
437     
438      public boolean isInCvsIgnore(File file) {
439         try {
440             return readCvsIgnoreEntries(file.getParentFile()).contains(file.getName());
441         } catch (IOException e) {
442             ErrorManager.getDefault().notify(e);
443             return false;
444         }
445     }
446     
447     public boolean isIgnoredFilename(File file) {
448         if (FILENAME_CVS.equals(file.getName())) return true;
449         return false;
450     }
451     
452
453     public AdminHandler getAdminHandler() {
454         return sah;
455     }
456
457     public FileHandler getFileHandler() {
458         return workdirFileHandler;
459     }
460
461     public FileHandler getGzippedFileHandler() {
462         return workdirGzippedFileHandler;
463     }
464
465     public Annotator getAnnotator() {
466         return annotator;
467     }
468     
469     public Object JavaDoc getParameter(Object JavaDoc key) {
470         synchronized(params) {
471             return params.get(key);
472         }
473     }
474
475     public KeywordSubstitutionOptions getDefaultKeywordSubstitution(File file) {
476         // TODO: Let user configure defaults
477
return isText(file) || isBinary(file) == false ?
478                 KeywordSubstitutionOptions.DEFAULT :
479                 KeywordSubstitutionOptions.BINARY;
480     }
481
482     /**
483      * @return true if the file is almost certainly textual.
484      */

485     public boolean isText(File file) {
486         if (FILENAME_CVSIGNORE.equals(file.getName())) {
487             return true;
488         }
489         // honor Entries, only if this fails use MIME type, etc.
490
try {
491             Entry entry = sah.getEntry(file);
492             if (entry != null) {
493                 return !entry.isBinary();
494             }
495         } catch (IOException e) {
496             // ignore, probably new or nonexistent file
497
}
498         FileObject fo = FileUtil.toFileObject(file);
499         if (fo == null) return false;
500         try {
501             DataObject dao = DataObject.find(fo);
502             return dao.getCookie(EditorCookie.class) != null;
503         } catch (DataObjectNotFoundException e) {
504             // not found, continue
505
}
506         if (fo.getMIMEType().startsWith("text")) { // NOI18N
507
return true;
508         }
509         // TODO: HACKS begin, still needed?
510
return textExtensions.contains(fo.getExt());
511     }
512
513     /**
514      * Uses first 1024 bytes test. A control byte means binary.
515      * @return true if the file is almost certainly binary.
516      */

517     public boolean isBinary(File file) {
518         InputStream in = null;
519         try {
520             in = new FileInputStream(file);
521             in = new BufferedInputStream(in);
522             for (int i = 0; i<1024; i++) {
523                 int ch = in.read();
524                 if (ch == -1) break;
525                 if (ch < 32 && ch != '\t' && ch != '\n' && ch != '\r') {
526                     return true;
527                 }
528             }
529         } catch (IOException e) {
530             ErrorManager err = ErrorManager.getDefault();
531             err.notify(ErrorManager.INFORMATIONAL, e);
532         } finally {
533             if (in != null) {
534                 try {
535                     in.close();
536                 } catch (IOException alreadyClosed) {
537                 }
538             }
539         }
540         return false;
541     }
542
543     public void setParameter(Object JavaDoc key, Object JavaDoc value) {
544         Object JavaDoc old;
545         synchronized(params) {
546             old = params.put(key, value);
547         }
548         if (old != value) listenerSupport.fireVersioningEvent(EVENT_PARAM_CHANGED, key);
549     }
550
551     /**
552      * Adds all supplied files to 'cvsignore' file. They need not reside in the same folder.
553      *
554      * @param files files to ignore
555      */

556     public void setIgnored(File[] files) {
557         for (int i = 0; i < files.length; i++) {
558             try {
559                 setIgnored(files[i]);
560             } catch (IOException e) {
561                 ErrorManager.getDefault().notify(e);
562             }
563         }
564     }
565
566     /**
567      * Adds supplied file to 'cvsignore' file.
568      *
569      * @param file file to ignore
570      */

571     private void setIgnored(File file) throws IOException {
572         if (file.exists()) {
573             addToCvsIgnore(file);
574         }
575     }
576     
577     public void setNotignored(File[] files) {
578         for (int i = 0; i < files.length; i++) {
579             try {
580                 removeFromCvsIgnore(files[i]);
581             } catch (IOException e) {
582                 ErrorManager.getDefault().notify(e);
583             }
584         }
585     }
586         
587     private void addToCvsIgnore(File file) throws IOException {
588         
589         Set entries = readCvsIgnoreEntries(file.getParentFile());
590         if (entries.add(file.getName())) {
591             writeCvsIgnoreEntries(file.getParentFile(), entries);
592         }
593     }
594     
595     private void removeFromCvsIgnore(File file) throws IOException {
596         Set entries = readCvsIgnoreEntries(file.getParentFile());
597         if (entries.remove(file.getName())) {
598             writeCvsIgnoreEntries(file.getParentFile(), entries);
599         }
600     }
601     
602     private Set<String JavaDoc> readCvsIgnoreEntries(File directory) throws IOException {
603         File cvsIgnore = new File(directory, FILENAME_CVSIGNORE);
604         
605         Set<String JavaDoc> entries = new HashSet<String JavaDoc>(5);
606         if (!cvsIgnore.canRead()) return entries;
607         
608         String JavaDoc s;
609         BufferedReader r = null;
610         try {
611             r = new BufferedReader(new FileReader(cvsIgnore));
612             while ((s = r.readLine()) != null) {
613                 entries.addAll(Arrays.asList(s.trim().split(" ")));
614             }
615         } finally {
616             if (r != null) try { r.close(); } catch (IOException e) {}
617         }
618         return entries;
619     }
620     
621     private void writeCvsIgnoreEntries(File directory, Set entries) throws IOException {
622         File cvsIgnore = new File(directory, FILENAME_CVSIGNORE);
623         FileObject fo = FileUtil.toFileObject(cvsIgnore);
624
625         if (entries.size() == 0) {
626             if (fo != null) fo.delete();
627             return;
628         }
629         
630         if (fo == null || !fo.isValid()) {
631             fo = FileUtil.toFileObject(directory);
632             fo = fo.createData(FILENAME_CVSIGNORE);
633         }
634         FileLock lock = fo.lock();
635         PrintWriter w = null;
636         try {
637             w = new PrintWriter(fo.getOutputStream(lock));
638             for (Iterator i = entries.iterator(); i.hasNext();) {
639                 w.println(i.next());
640             }
641         } finally {
642             lock.releaseLock();
643             if (w != null) w.close();
644         }
645     }
646
647     /** @see FilesystemHandler#ignoreEvents */
648     public static void ignoreFilesystemEvents(boolean ignore) {
649         FilesystemHandler.ignoreEvents(ignore);
650     }
651
652     /**
653      * Creates new GlobalOptions prefilled with default options:
654      * <ul>
655      * <li>compression level 3 if not enabled logging
656      * </ul>
657      */

658     public static GlobalOptions createGlobalOptions() {
659         GlobalOptions globalOptions = new GlobalOptions();
660         if (System.getProperty("cvsClientLog") == null) { // NOI18N
661
int gzipLevel = 4;
662             String JavaDoc level = System.getProperty("netbeans.experimental.cvs.io.compressionLevel"); // NOI18N
663
if (level != null) {
664                 try {
665                     int candidate = Integer.parseInt(level);
666                     if (0 <= candidate && candidate < 10) {
667                         gzipLevel = candidate;
668                     }
669                 } catch (NumberFormatException JavaDoc ex) {
670                     // default level
671
}
672             }
673             if (gzipLevel > 0) {
674                 globalOptions.setCompressionLevel(gzipLevel);
675             }
676         }
677         return globalOptions;
678     }
679
680     public VCSAnnotator getVCSAnnotator() {
681         return fileStatusProvider;
682     }
683
684     public VCSInterceptor getVCSInterceptor() {
685         return filesystemHandler;
686     }
687
688     private static final int STATUS_DIFFABLE =
689             FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY |
690             FileInformation.STATUS_VERSIONED_ADDEDLOCALLY |
691             FileInformation.STATUS_VERSIONED_UPTODATE |
692             FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY |
693             FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
694             FileInformation.STATUS_VERSIONED_CONFLICT |
695             FileInformation.STATUS_VERSIONED_MERGE |
696             FileInformation.STATUS_VERSIONED_REMOVEDINREPOSITORY |
697             FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
698             FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY;
699     
700     
701     public OriginalContent getVCSOriginalContent(File file) {
702         FileInformation info = fileStatusCache.getStatus(file);
703         if ((info.getStatus() & STATUS_DIFFABLE) == 0) return null;
704         return new CvsOriginalContent(file);
705     }
706
707     public void refreshAllAnnotations() {
708         listenerSupport.fireVersioningEvent(EVENT_REFRESH_ANNOTATIONS);
709     }
710
711     private class CvsOriginalContent extends OriginalContent implements VersioningListener {
712         
713         public CvsOriginalContent(File working) {
714             super(working);
715         }
716
717         protected void getOriginalFiles(File destination, Set<File> files) throws Exception JavaDoc {
718             for (File file : files) {
719                 // TODO: it is not easy to tell whether the file is not yet versioned OR some real error occurred
720
File original = VersionsCache.getInstance().getRemoteFile(file, VersionsCache.REVISION_BASE, null, true);
721                 if (original == null) throw new IOException("Unable to get BASE revision of " + file);
722
723                 File daoFile = new File(destination, file.getName());
724                 org.netbeans.modules.versioning.util.Utils.copyStreamsCloseAll(new FileOutputStream(daoFile), new FileInputStream(original));
725                 daoFile.deleteOnExit();
726             }
727         }
728
729         public void versioningEvent(VersioningEvent event) {
730             if (FileStatusCache.EVENT_FILE_STATUS_CHANGED == event.getId()) {
731                 File eventFile = (File) event.getParams()[0];
732                 if (eventFile.equals(workingCopy)) {
733                     support.firePropertyChange(PROP_CONTENT_CHANGED, null, null);
734                 }
735             }
736         }
737         
738         public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
739             if (!support.hasListeners(null)) {
740                 fileStatusCache.addVersioningListener(this);
741             }
742             super.addPropertyChangeListener(listener);
743         }
744
745         public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
746             super.removePropertyChangeListener(listener);
747             if (!support.hasListeners(null)) {
748                 fileStatusCache.removeVersioningListener(this);
749             }
750         }
751     }
752 }
Popular Tags