KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > system > cvss > ui > actions > update > UpdateExecutor


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.versioning.system.cvss.ui.actions.update;
21
22 import org.netbeans.modules.versioning.system.cvss.*;
23 import org.netbeans.modules.versioning.VersioningManager;
24 import org.netbeans.modules.versioning.VersioningOutputManager;
25 import org.netbeans.lib.cvsclient.command.update.UpdateCommand;
26 import org.netbeans.lib.cvsclient.command.GlobalOptions;
27 import org.netbeans.lib.cvsclient.command.DefaultFileInfoContainer;
28 import org.netbeans.lib.cvsclient.command.Command;
29 import org.netbeans.lib.cvsclient.event.*;
30 import org.openide.filesystems.*;
31 import org.openide.ErrorManager;
32 import org.openide.DialogDisplayer;
33 import org.openide.NotifyDescriptor;
34 import org.openide.util.NbBundle;
35
36 import javax.swing.*;
37 import java.io.File JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.util.*;
40 import java.util.logging.Logger JavaDoc;
41 import java.util.logging.Level JavaDoc;
42
43 /**
44  * Executes a given 'update' command and refreshes file statuses.
45  *
46  * @author Maros Sandor
47  */

48 public class UpdateExecutor extends ExecutorSupport {
49     
50     /**
51      * Contains all files that should NOT be set as up-to-date after Update finishes.
52      */

53     private Set<File JavaDoc> refreshedFiles = Collections.synchronizedSet(new HashSet<File JavaDoc>());
54     private boolean rwUpdate;
55     private boolean mergeUpdate;
56
57     /**
58      * Display name of the context on which update operates, eg "3 Projects".
59      */

60     private final String JavaDoc contextDisplayName;
61     
62     /**
63      * Files modified afterwards will not be cosidered up-to-date even if server says so.
64      */

65     private long updateStartTimestamp;
66
67     /**
68      * Splits the original command into more commands if the original
69      * command would execute on incompatible files.
70      * See {@link #prepareBasicCommand(org.netbeans.lib.cvsclient.command.BasicCommand)}
71      * for more information.
72      *
73      * @param cmd command to execute
74      * @param cvs CVS engine to use
75      * @param options global option for the command
76      * @param contextDisplayName context name for the Update Results output tab (eg. "3 Projects"). If null, the output tab
77      * will not open
78      * @return array of executors that will execute the command (or array of splitted commands)
79      */

80     public static UpdateExecutor [] splitCommand(UpdateCommand cmd, CvsVersioningSystem cvs, GlobalOptions options, String JavaDoc contextDisplayName) {
81         Command [] cmds = new org.netbeans.lib.cvsclient.command.Command[0];
82         if (cmd.getDisplayName() == null) cmd.setDisplayName(NbBundle.getMessage(UpdateExecutor.class, "MSG_UpdateExecutor_CmdDisplayName"));
83         try {
84             cmds = prepareBasicCommand(cmd);
85         } catch (IOException JavaDoc e) {
86             ErrorManager.getDefault().notify(e);
87             return null;
88         }
89         UpdateExecutor [] executors = new UpdateExecutor[cmds.length];
90         for (int i = 0; i < cmds.length; i++) {
91             Command command = cmds[i];
92             executors[i] = new UpdateExecutor(cvs, (UpdateCommand) command, options, contextDisplayName);
93         }
94         return executors;
95     }
96
97     private UpdateExecutor(CvsVersioningSystem cvs, UpdateCommand cmd, GlobalOptions options, String JavaDoc contextDisplayName) {
98         super(cvs, cmd, options);
99         this.contextDisplayName = contextDisplayName;
100         rwUpdate = options == null || !options.isDoNoChanges();
101         mergeUpdate = cmd.getMergeRevision1() != null;
102     }
103
104     protected void setup() {
105         super.setup();
106         updateStartTimestamp = System.currentTimeMillis();
107     }
108
109     public void fileInfoGenerated(FileInfoEvent e) {
110         super.fileInfoGenerated(e);
111     }
112     
113     /**
114      * Refreshes statuse of relevant files after this command terminates.
115      */

116     protected void commandFinished(ClientRuntime.Result result) {
117         
118         UpdateCommand ucmd = (UpdateCommand) cmd;
119
120         // Sometimes the commandFinished() may be called before command.execute() is called. In this case, global options
121
// are not set yet and also this postprocessing does not make sense, return here to prevent NPE later
122
// See ExecutorSupport.commandTerminated and CommandRunnable.run, there is no guarantee that client.execute() precedes commandFinished()
123
if (ucmd.getGlobalOptions() == null) {
124             if (!cmd.hasFailed()) {
125                 // this is somewhat unexpected, print a warning
126
Logger.getLogger("org.netbeans.modules.versioning.system.cvss").log(Level.INFO, "Warning: Update command did not fail but global options are null.");
127             }
128             return;
129         }
130         
131         cvs.setParameter(CvsVersioningSystem.PARAM_BATCH_REFRESH_RUNNING, Boolean.TRUE);
132         
133         File JavaDoc [] files = ucmd.getFiles();
134         
135         for (int i = 0; i < files.length; i++) {
136             cache.clearVirtualDirectoryContents(files[i], ucmd.isRecursive(), ucmd.getGlobalOptions().getExclusions());
137         }
138         
139         if (rwUpdate && contextDisplayName != null) {
140             openOutputResults();
141         }
142         
143         Set<FileSystem> filesystems = new HashSet<FileSystem>(2);
144         boolean hasConflict = false;
145         for (Iterator i = toRefresh.iterator(); i.hasNext();) {
146             DefaultFileInfoContainer info = (DefaultFileInfoContainer) i.next();
147             File JavaDoc file = info.getFile();
148             if (refreshedFiles.contains(file)) continue;
149             int c = info.getType().charAt(0);
150             if (c == 'P') c = 'U';
151             if (rwUpdate) {
152                 if (c == 'U') {
153                     if (mergeUpdate) {
154                         c = FileStatusCache.REPOSITORY_STATUS_MODIFIED;
155                     } else {
156                         c = FileStatusCache.REPOSITORY_STATUS_UPTODATE;
157                     }
158                 }
159                 if (c == 'G') c = FileStatusCache.REPOSITORY_STATUS_MODIFIED;
160                 if (c == 'C') hasConflict = true;
161             }
162             cache.refresh(file, c, true);
163             refreshedFiles.add(file);
164         }
165                 
166         // refresh all command roots
167
// assuming that command roots and updated files all belong to the same filesystem
168
for (int i = 0; i < files.length; i++) {
169             if (ucmd.isRecursive()) {
170                 refreshRecursively(files[i]);
171             } else {
172                 refreshFlat(files[i]);
173             }
174             addFileSystem(filesystems, files[i]);
175             if (files[i].isFile()) {
176                 cache.refreshCached(files[i].getParentFile(), FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
177             }
178         }
179         
180         cvs.setParameter(CvsVersioningSystem.PARAM_BATCH_REFRESH_RUNNING, null);
181         if (hasConflict) {
182             NotifyDescriptor nd = new NotifyDescriptor.Message(
183                     NbBundle.getMessage(UpdateExecutor.class, "MSG_UpdateGeneratedConflicts_Prompt"),
184                     NotifyDescriptor.WARNING_MESSAGE);
185             DialogDisplayer.getDefault().notify(nd);
186         }
187         
188         for (Iterator i = filesystems.iterator(); i.hasNext();) {
189             FileSystem fileSystem = (FileSystem) i.next();
190             try {
191                 CvsVersioningSystem.ignoreFilesystemEvents(true);
192                 fileSystem.refresh(true); // fires fileChanged
193
} finally {
194                 CvsVersioningSystem.ignoreFilesystemEvents(false);
195             }
196         }
197
198         // special case: switching to a branch/tag changes textual annotations on nodes that are NOT changed during this operation, typically folders
199
if (ucmd.getUpdateByRevision() != null || ucmd.isResetStickyOnes()) {
200             CvsVersioningSystem.getInstance().refreshAllAnnotations();
201         }
202     }
203
204     private void openOutputResults() {
205         SwingUtilities.invokeLater(new Runnable JavaDoc() {
206             public void run() {
207                 UpdateResults results = new UpdateResults(toRefresh, cmd.getGlobalOptions().getCVSRoot(), contextDisplayName);
208                 VersioningOutputManager vom = VersioningManager.getInstance().getOutputManager();
209                 vom.addComponent(cmd.getGlobalOptions().getCVSRoot() + "-UpdateExecutor", results); // NOI18N
210
}
211         });
212     }
213
214     private void addFileSystem(Set<FileSystem> filesystems, File JavaDoc file) {
215         FileObject fo;
216         for (;;) {
217             fo = FileUtil.toFileObject(file);
218             if (fo != null) break;
219             file = file.getParentFile();
220             if (file == null) return;
221         }
222         try {
223             filesystems.add(fo.getFileSystem());
224         } catch (FileStateInvalidException e) {
225             // ignore invalid filesystems
226
}
227     }
228
229     private void refreshRecursively(File JavaDoc file) {
230         try {
231             if (cvs.isIgnoredFilename(file)) return;
232             if (cmd.getGlobalOptions().isExcluded(file)) return;
233             if (file.isDirectory()) {
234                 if (cache.getStatus(file).getStatus() == FileInformation.STATUS_NOTVERSIONED_EXCLUDED) return;
235                 File JavaDoc [] files = file.listFiles();
236                 for (int i = 0; i < files.length; i++) {
237                     refreshRecursively(files[i]);
238                 }
239                 if (!refreshedFiles.contains(file)) cache.refreshCached(file, FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
240             } else {
241                 if (!refreshedFiles.contains(file)) refreshFile(file);
242             }
243         } catch (Throwable JavaDoc e) {
244             // we catch exceptions here because we want to refresh statuses of all files regardless of any errors below
245
ErrorManager.getDefault().notify(e);
246         }
247     }
248     
249     private void refreshFlat(File JavaDoc file) {
250         if (cvs.isIgnoredFilename(file)) return;
251         if (cmd.getGlobalOptions().isExcluded(file)) return;
252         if (refreshedFiles.contains(file)) return;
253         if (file.isDirectory()) {
254             File JavaDoc [] files = file.listFiles();
255             for (int i = 0; i < files.length; i++) {
256                 if (cvs.isIgnoredFilename(files[i])) return;
257                 if (refreshedFiles.contains(files[i])) return;
258                 if (files[i].isDirectory()) continue;
259                 refreshFile(files[i]);
260             }
261             cache.refreshCached(file, FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
262         } else {
263             refreshFile(file);
264         }
265     }
266
267     private void refreshFile(File JavaDoc file) {
268         long lastModified = file.lastModified();
269         if (!cmd.hasFailed() && cache.getStatus(file.getParentFile()).getStatus() == FileInformation.STATUS_VERSIONED_UPTODATE &&
270                 lastModified > 0 && lastModified < updateStartTimestamp) {
271             cache.refreshCached(file, FileStatusCache.REPOSITORY_STATUS_UPTODATE);
272         } else {
273             cache.refreshCached(file, FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
274         }
275     }
276 }
277
Popular Tags