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    }