001 /*
002
003 $Id: FileManager.java,v 1.13 2003/05/02 20:29:48 culdesac Exp $
004
005 */
006
007 package sharpster.daemon.filemanagement;
008
009 import sharpster.common.*;
010 import sharpster.daemon.SharpsterDaemon;
011 import sharpster.daemon.filemanagement.WildcardFilter;
012 import sharpster.daemon.daemonplugin.*;
013 import net.jxta.id.*;
014 import net.jxta.document.*;
015 import java.io.FileInputStream;
016 import java.io.FileOutputStream;
017 import java.io.StringWriter;
018 import java.util.Enumeration;
019 import java.util.LinkedList;
020 import java.util.ListIterator;
021
022 /**
023 * Class responsible for the overall management of files, both local files
024 * and files stored in the local CVS.
025 * Most of its work is delegated to the classes of the
026 * <code>CVSManager</code>, the <code>LocalFileManager</code> or the
027 * <code>FileKeyManager.</code>
028 */
029 public class FileManager {
030
031 /**
032 *
033 */
034 private DaemonPluginManager pluginManager;
035
036 /**
037 * A class used to contain cross references between users name and id.
038 */
039 private FileMap fileMap;
040
041 /**
042 * A class used to manage cvs.
043 */
044 private CVSManager cvsManager;
045
046 /**
047 * A class used to to operations on the local harddrive.
048 */
049 private LocalFileManager localFileManager;
050
051 /**
052 * A string containing the path to the configuration file (used in
053 * saveToFile and loadFromFile).
054 */
055 private String configFile;
056
057 /**
058 * Constructs an instance of the FileManager object.
059 * Creates the <code>FileKeyManager</code>, a <code>CVSManager</code>,
060 * and a <code>LocalFileManager</code>, and initializes the
061 * member attributes.
062 */
063 public FileManager() {
064 fileMap = new FileMap();
065 cvsManager = new CVSManager(fileMap,"");
066 localFileManager = new LocalFileManager(cvsManager);
067 configFile = new String();
068 }
069
070 /**
071 * Perform eventual initializations.
072 */
073 public void initialize(DaemonPluginManager pm) {
074 pluginManager = pm;
075 }
076
077 /**
078 * Returns a unique key value for a given filename and CVS path.
079 * Uses the fkm.
080 */
081 public ID getFileID(String filePath) {
082 return fileMap.getID(filePath);
083 }
084
085 /**
086 * Returns a filename, including the CVS path of the file,
087 * for a given key. Uses the fkm.
088 */
089 public String getFilePath(ID id) {
090 return fileMap.getPath(id);
091 }
092
093 /**
094 * If the command specifies a file remove, it returns the files
095 * which have been removed, otherwise null is returned.
096 */
097 public FileCollection getRemovedFiles(String command) {
098 return null;
099 }
100
101 /**
102 * Executes a CVS command requested by the user of the local client.
103 * The command attribute contains the CVS command and arguments
104 * associated with it. Uses the cvsm.
105 */
106 public ResponseCollection localDoCVS(String command,
107 String workingDirectory) {
108 ResponseCollection resp = cvsManager.localDoCVS(command, workingDirectory);
109
110 cvsManager.synchronizeCVS(fileMap);
111 saveToFile(null);
112
113 return resp;
114 }
115
116 /**
117 * Saves the specified files in the given working directory.
118 * Returns information about the result of the operation.
119 * Uses the cvsm.
120 */
121 public ResponseCollection localSaveFiles(FileCollection files,
122 String workingDirectory) {
123 return localFileManager.localSaveFiles(files,workingDirectory);
124 }
125
126 public ResponseCollection localLoadFiles(FileCollection files,
127 String workingDirectory) {
128 return localFileManager.localLoadFiles(files,workingDirectory,false);
129 }
130
131 /**
132 * Updates the <code>files</code> object. For each file which is
133 * specified, it insert a <code>File</code> object, containing the name
134 * and the path in the local CVS of the file. This method is used
135 * for commands which operate on the local CVS.
136 * Uses the <code>cvsm.</code>
137 */
138 public ResponseCollection translateLocalPaths(FileCollection files,
139 String workingDirectory,
140 boolean cvs) {
141 return localFileManager.translateLocalPaths(files,
142 workingDirectory,
143 cvs);
144 }
145
146 /**
147 * Updates the <code>files</code> object. For each file which is
148 * specified, it insert a <code>File</code> object, containing the name,
149 * the remote owning user and the path to the remote CVS of the file.
150 * This method is used for commands which operate on the remote CVS.
151 * Uses the <code>cvsm.</code>
152 */
153 public ResponseCollection translateRemotePaths(FileCollection files,
154 boolean recursive) {
155 return localFileManager.translateRemotePaths(files,
156 fileMap,
157 recursive);
158 }
159
160 /**
161 * Verifies that the given <code>files</code> exist.
162 */
163 public ResponseCollection checkFilesExistance(FileCollection files) {
164 ResponseCollection responses = new ResponseCollection();
165 FileCollection missingFiles = new FileCollection();
166
167 for(int i=0;i<files.getFileCount();i++) {
168 SharedFile file = files.getFile(i);
169 ID id = fileMap.getID(file.getFullPath());
170 if(id == null) {
171 missingFiles.addFile(file);
172 }
173 }
174
175 if(missingFiles.getFileCount()!=0) {
176 MissingFilesResponse missing = new MissingFilesResponse();
177 missing.setOrigin("FileManager");
178 missing.setUser(sharpster.daemon.SharpsterDaemon.getPeerName());
179 missing.setError(true);
180 missing.setLocation(FileLocation.LOCAL_MEMORY);
181 missing.setFiles(missingFiles);
182 responses.addResponse(missing);
183 }
184
185 return responses;
186 }
187
188 /**
189 * Synchronizes the file database with the specified directory.
190 */
191 public ResponseCollection synchronizeCVS(String workingDirectory) {
192 cvsManager.synchronizeCVS(fileMap);
193 saveToFile(null);
194
195 MessageResponse message = new MessageResponse();
196 ResponseCollection resp = new ResponseCollection();
197
198 message.setOrigin("FileManager");
199 message.setUser(sharpster.daemon.SharpsterDaemon.getPeerName());
200 message.setError(false);
201 message.setMessage("Synchronization was successful");
202 resp.addResponse(message);
203
204 return resp;
205 }
206
207 public void clearTemporaryFiles() {
208 boolean res = localFileManager.localClearDirectory(SharpsterDaemon.getCVSTemp());
209 if(!res) {
210 System.out.println("FM::Warning, unable to clear temporary directory");
211 }
212 }
213
214 /**
215 * Update the <code>files</code> argument by adding the specified
216 * files and information about their versions.
217 * The updated collection is then returned by a <code>ResponseCollection.</code>
218 * Uses the <code>fkm</code>.
219 */
220 public ResponseCollection remoteCheckoutFiles(FileCollection files, String role) {
221 ResponseCollection responses = cvsManager.cvsRun(files,"checkout",false);
222 if(responses.hasError()) return responses;
223
224 ResponseCollection resp =
225 localFileManager.localLoadFiles(files,
226 SharpsterDaemon.getCVSTemp(),
227 true);
228
229 ResponseCollection respFiles = pluginManager.extractParts(files, role);
230
231 files.removeAllFiles();
232
233 for (int i=0; i < respFiles.getResponseCount(); i++) {
234 FileResponse fileResp = (FileResponse)respFiles.getResponse(i);
235 files.appendCollection(fileResp.getFiles());
236 }
237
238 responses.appendCollection(resp);
239 responses.appendCollection(respFiles);
240
241 return responses;
242 }
243
244 /**
245 * Updates the given <code>files</code> with possible changes from the
246 * CVS. The changes are specified in conflict files, files created to
247 * provide information about conflicting changes. Information
248 * about the result of the operation is returned.
249 * Uses the <code>fkm</code>.
250 */
251 public ResponseCollection remoteUpdateFiles(FileCollection files) {
252 ResponseCollection responses = new ResponseCollection();
253 ResponseCollection resp;
254
255 System.out.println("FM::Checkout");
256 resp = cvsManager.cvsRun(files,"checkout",true);
257 responses.appendCollection(resp);
258 if(responses.hasError()) return responses;
259
260 //load and merge
261 FileCollection origFiles = files.createDuplicate();
262 System.out.println("FM::Local load original files");
263 resp = localFileManager.localLoadFiles(origFiles,SharpsterDaemon.getCVSTemp(),true);
264 responses.appendCollection(resp);
265 if(responses.hasError()) return responses;
266
267 ResponseCollection respFiles = pluginManager.mergeParts(origFiles,files,null);
268
269 files.removeAllFiles();
270
271 for (int i=0; i < respFiles.getResponseCount(); i++) {
272 FileResponse fileResp = (FileResponse)respFiles.getResponse(i);
273 files.appendCollection(fileResp.getFiles());
274 }
275
276 responses.appendCollection(respFiles);
277
278 ///
279
280 System.out.println("FM::Local save");
281 resp = localFileManager.localSaveFiles(files,SharpsterDaemon.getCVSTemp());
282 responses.appendCollection(resp);
283 if(responses.hasError()) return responses;
284
285 System.out.println("FM::Update");
286 resp = cvsManager.cvsRun(files,"update -A",false);
287 responses.appendCollection(resp);
288 if(responses.hasError()) return responses;
289
290 System.out.println("FM::Local load");
291 resp = localFileManager.localLoadFiles(files,SharpsterDaemon.getCVSTemp(),true);
292 responses.appendCollection(resp);
293 if(responses.hasError()) return responses;
294
295 ResponseCollection respFiles2 = pluginManager.extractParts(files,null);
296
297 files.removeAllFiles();
298
299 for (int i=0; i < respFiles2.getResponseCount(); i++) {
300 FileResponse fileResp = (FileResponse)respFiles2.getResponse(i);
301 files.appendCollection(fileResp.getFiles());
302 }
303
304 responses.appendCollection(respFiles2);
305
306
307 return responses;
308 }
309
310 /**
311 * Commits the specified <code>files</code> to the CVS. Returns
312 * information about the result of the operation.
313 * Uses the <code>fkm</code>.
314 */
315 public ResponseCollection remoteCommitFiles(FileCollection files, String role) {
316 ResponseCollection responses = new ResponseCollection();
317 ResponseCollection resp;
318
319 System.out.println("FM::Checkout");
320 resp = cvsManager.cvsRun(files,"checkout",true);
321 responses.appendCollection(resp);
322 if(responses.hasError()) return responses;
323
324 //load and merge
325 FileCollection origFiles = files.createDuplicate();
326 System.out.println("FM::Local load original files");
327 resp = localFileManager.localLoadFiles(origFiles,SharpsterDaemon.getCVSTemp(),true);
328 responses.appendCollection(resp);
329 if(responses.hasError()) return responses;
330
331 ResponseCollection respFiles = pluginManager.mergeParts(origFiles,files,role);
332
333 files.removeAllFiles();
334
335 for (int i=0; i < respFiles.getResponseCount(); i++) {
336 FileResponse fileResp = (FileResponse)respFiles.getResponse(i);
337 files.appendCollection(fileResp.getFiles());
338 }
339
340 responses.appendCollection(respFiles);
341
342 ///
343
344 System.out.println("FM::Local save");
345 resp = localFileManager.localSaveFiles(files,SharpsterDaemon.getCVSTemp());
346 responses.appendCollection(resp);
347 if(responses.hasError()) return responses;
348
349 System.out.println("FM::Update");
350 resp = cvsManager.cvsRun(files,"update -A",false);
351 responses.appendCollection(resp);
352
353 if(!responses.hasError()) {
354 System.out.println("FM::Commit");
355 resp = cvsManager.cvsRun(files,"commit -m \"\"",false);
356 responses.appendCollection(resp);
357 }
358
359 System.out.println("FM::Local load");
360 resp = localFileManager.localLoadFiles(files,SharpsterDaemon.getCVSTemp(),true);
361 responses.appendCollection(resp);
362 if(responses.hasError()) return responses;
363
364 ResponseCollection respFiles2 = pluginManager.extractParts(files,null);
365
366 files.removeAllFiles();
367
368 for (int i=0; i < respFiles2.getResponseCount(); i++) {
369 FileResponse fileResp = (FileResponse)respFiles2.getResponse(i);
370 files.appendCollection(fileResp.getFiles());
371 }
372
373 responses.appendCollection(respFiles2);
374
375
376 return responses;
377 }
378
379 /**
380 * Adds the specified <code>files</code> to the CVS. Returns
381 * information about the result of the operation.
382 * Uses the <code>fkm</code>.
383 */
384 public ResponseCollection remoteAddFiles(FileCollection files) {
385 return new ResponseCollection();
386 }
387
388 /**
389 * Removes the specified <code>files</code> to the CVS. Returns
390 * information about the result of the operation.
391 * Uses the <code>fkm</code>.
392 */
393 public ResponseCollection remoteRemoveFiles(FileCollection files) {
394 return new ResponseCollection();
395 }
396
397 /**
398 * Save the file database to a configuration file.
399 */
400 public boolean saveToFile(String file) {
401 if(file == null) {
402 file = configFile;
403 }
404 else {
405 configFile = new String(file);
406 }
407
408 return fileMap.saveToFile(configFile);
409 }
410
411 /**
412 * Load the file database from a configuration file.
413 */
414 public boolean loadFromFile(String file) {
415 if(file == null) {
416 file = configFile;
417 }
418 else {
419 configFile = new String(file);
420 }
421
422 return fileMap.loadFromFile(configFile);
423 }
424 }