001 /*
002
003 $Id: CVSManager.java,v 1.12 2003/05/08 10:34:22 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.LocalFileManager;
012 import sharpster.daemon.filemanagement.FileMap;
013
014 import java.util.LinkedList;
015 import java.util.ListIterator;
016 import java.io.*;
017
018 /**
019 * Class which handles the local CVS and files stored in it.
020 * It should be used for executing commands to both manipulate and
021 * retrieve information, such as file logs, from the CVS.
022 * This class keeps the whole CVS database checked out under
023 * <code>m_tempDir</code>, where it puts recieved files before issuing an
024 * update, commit or a similar command.
025 * All methods use the method <code>localDoCVS</code> to perform CVS commands.
026 */
027
028 public class CVSManager {
029
030 /**
031 * Temporary directory which can be used by the class.
032 * Should be set up during the initialization of the class.
033 */
034 private String tempDir;
035
036 /**
037 * Holds the path to the CVS root directory. Should be set up during
038 * the initialization of the class.
039 */
040 private String CVSRoot;
041
042 /**
043 * This class keeps a reference to the <code>FileKeyManager</code>
044 * in order to be able to update it when files are added and
045 * removed from the CVS.
046 */
047 private FileMap fileMap;
048
049
050 /**
051 * Constructs an instance of the class and initializes the member
052 * attributes.
053 */
054 public CVSManager(FileMap fkm, String tempDir)
055 {
056 fileMap = fkm;
057 this.tempDir = tempDir;
058 this.CVSRoot = sharpster.daemon.SharpsterDaemon.getCVSRoot();
059 }
060
061 /**
062 * Executes a CVS command. The command attributes contains the
063 * CVS command and any arguments associated with it.
064 * If the command include adding or removing of files,
065 * this method is responsible for updating the <code>fkm</code>
066 * with the changes. The <code>ResponseCollection</code> returned
067 * by the method, holds an array of strings which contains output
068 * from the CVS command.
069 */
070 public ResponseCollection localDoCVS(String command,
071 String workingDirectory) {
072 Runtime runtime = Runtime.getRuntime();
073 String output = new String();
074 String s;
075
076 ResponseCollection responses = new ResponseCollection();
077 int returnValue=0;
078
079 try {
080 Process process = runtime.exec("cvs "+command,null,new File(workingDirectory));
081
082 BufferedReader inReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
083 BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
084
085 boolean stop = false;
086 boolean trackStdout = true;
087 boolean trackStderr = true;
088 String stdout = new String();
089 String stderr = new String();
090
091 while(!stop) {
092 if(trackStdout) {
093 String stdoutLine = inReader.readLine();
094 if(stdoutLine == null) trackStdout=false;
095 else stdout += stdoutLine + "\n";
096 }
097 if(trackStderr) {
098 String stderrLine = errReader.readLine();
099 if(stderrLine == null) trackStderr=false;
100 else stderr += stderrLine + "\n";
101 }
102 if(!trackStdout && !trackStderr) stop = true;
103 }
104
105 returnValue = process.waitFor();
106
107 CVSOutputResponse cvsResp = new CVSOutputResponse();
108 cvsResp.setOrigin("FileManager");
109 cvsResp.setUser(SharpsterDaemon.getPeerName());
110 cvsResp.setError(returnValue!=0);
111 cvsResp.setMessage(stdout + "\n" + stderr);
112 responses.addResponse(cvsResp);
113 }
114 catch(Exception e) {
115 e.printStackTrace();
116 }
117
118 return responses;
119 }
120
121 private void synchronizeRecusive(File root, String cvsLocalPath, FileMap oldFileMap, FileMap newFileMap) {
122 FileReader fr;
123 BufferedReader inFile;
124 String temp;
125 boolean binary = false;
126
127 try {
128 File[] fileList = root.listFiles();
129 for(int i=0;i<fileList.length;i++) {
130 String name = fileList[i].getName();
131 if(name.equals("CVSROOT")) continue;
132
133 if(name.endsWith(",v")) {
134 name = name.substring(0,name.length()-2);
135 if(oldFileMap.hasFile(cvsLocalPath+"/"+name)) {
136 net.jxta.id.ID id = oldFileMap.getID(cvsLocalPath+"/"+name);
137 newFileMap.addFile(cvsLocalPath+"/"+name,false,oldFileMap.isBinary(id));
138 }
139 else {
140 File file = new File(root.getAbsolutePath(),name+",v");
141 if(file != null) {
142 fr = new FileReader(file);
143 inFile = new BufferedReader(fr);
144 binary = false;
145 while((temp=inFile.readLine())!=null) {
146 if(temp.startsWith("\n") || temp.startsWith("\r") || temp.startsWith(" ") || temp.equals("")) {
147 break;
148 }
149 if(temp.matches("(expand).*(@b@;)\r?\n?")) {
150 binary = true;
151 break;
152 }
153 }
154 newFileMap.addFile(cvsLocalPath+"/"+name,false,binary);
155 }
156 }
157 }
158 else {
159 newFileMap.addFile(cvsLocalPath+"/"+name,true,false);
160 synchronizeRecusive(fileList[i],cvsLocalPath+"/"+name,oldFileMap,newFileMap);
161 }
162 }
163 }
164 catch(Exception e) {
165 }
166 }
167
168 /*private void synchronizeRecusive(File root, FileMap fileMap) {
169 FileReader fr;
170 BufferedReader inFile;
171 String temp;
172 String repository;
173 File tempFile;
174
175 try {
176 fr = new FileReader(root.getAbsolutePath()+
177 File.separator+"CVS"+
178 File.separator+"Repository");
179 inFile = new BufferedReader(fr);
180 temp = inFile.readLine();
181 inFile.close();
182
183 tempFile = new File(temp);
184 if(tempFile.isAbsolute()) {
185 String cvsRoot = sharpster.daemon.SharpsterDaemon.getCVSRoot();
186 repository = temp.substring(cvsRoot.length()+1);
187 }
188 else {
189 repository = temp;
190 }
191
192 fr = new FileReader(root.getAbsolutePath()+
193 File.separator+"CVS"+
194 File.separator+"Entries");
195 inFile = new BufferedReader(fr);
196
197 while((temp=inFile.readLine())!=null) {
198 String[] params = temp.split("(/)");
199 boolean dir = params[0].equals("D");
200 boolean bin = false;
201 if(params.length>4) bin = params[4].equals("-kb");
202 String path = repository + "/" + params[1];
203 fileMap.addFile(path,dir,bin);
204 }
205
206 inFile.close();
207 }
208 catch(Exception e) {
209 return;
210 }
211
212 File[] children = root.listFiles();
213 for(int i=0;i<children.length;i++) {
214 if(children[i].isDirectory()) {
215 synchronizeRecusive(children[i],fileMap);
216 }
217 }
218 }*/
219
220 public void synchronizeCVS(FileMap fileMap) {
221 File cvsRoot = new File(SharpsterDaemon.getCVSRoot());
222 File[] fileList = cvsRoot.listFiles();
223
224 FileMap newFileMap = new FileMap();
225
226 for(int i=0;i<fileList.length;i++) {
227 if(fileList[i].isDirectory()) {
228 if(fileList[i].isDirectory() && !fileList[i].getName().equals("CVSROOT")) {
229 newFileMap.addFile(fileList[i].getName(),true,false);
230 synchronizeRecusive(fileList[i],fileList[i].getName(),fileMap,newFileMap);
231 }
232 }
233 }
234 fileMap.merge(newFileMap);
235
236 /*FileMap newFileMap = new FileMap();
237 File rootPath = new File(workingDirectory);
238 File cvsFolderPath = new File(workingDirectory+File.separator+"CVS");
239 if(cvsFolder == null || !cvsFolder.isDirectory()) return;
240 newFileMap.addFile(rootPath.getName(),true,false);
241 synchronizeRecusive(rootPath,newFileMap);
242 fileMap.merge(newFileMap);*/
243 }
244
245 /**
246 * Checks out the latest version of the files in <code>files</code>
247 * and puts it in the <code>tempDir</code> directory tree.
248 * The <code>files</code> objects is then completed with the
249 * checked out files.
250 */
251 public ResponseCollection cvsRun(FileCollection files, String cmd, boolean doVersions) {
252 Runtime runtime = Runtime.getRuntime();
253 String cvsRoot = SharpsterDaemon.getCVSRoot();
254 File cvsTemp = new File(SharpsterDaemon.getCVSTemp());
255 String allFiles = new String();
256 String output = new String();
257 ResponseCollection responses = new ResponseCollection();
258 int returnValue=0;
259 String command;
260
261 try {
262 for(int i=0;i<files.getFileCount();i++) {
263
264 if(doVersions) {
265 command = "cvs -d " + cvsRoot + " " + cmd
266 + " -r" + files.getFile(i).getVersion()
267 + " " + files.getFile(i).getFullPath();
268 }
269 else {
270 command = "cvs -d " + cvsRoot + " " + cmd + " "
271 + files.getFile(i).getFullPath();
272 }
273 System.out.println(command);
274 Process process = runtime.exec(command,null,cvsTemp);
275
276 BufferedReader inReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
277 BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
278
279 boolean stop = false;
280 boolean trackStdout = true;
281 boolean trackStderr = true;
282 String stdout = new String();
283 String stderr = new String();
284
285 while(!stop) {
286 if(trackStdout) {
287 String stdoutLine = inReader.readLine();
288 if(stdoutLine == null) trackStdout=false;
289 else stdout += stdoutLine + "\n";
290 }
291 if(trackStderr) {
292 String stderrLine = errReader.readLine();
293 if(stderrLine == null) trackStderr=false;
294 else stderr += stderrLine + "\n";
295 }
296 if(!trackStdout && !trackStderr) stop = true;
297 }
298
299 returnValue = process.waitFor();
300 }
301
302 CVSOutputResponse cvsResp = new CVSOutputResponse();
303 cvsResp.setOrigin("FileManager");
304 cvsResp.setUser(SharpsterDaemon.getPeerName());
305 cvsResp.setError(returnValue!=0);
306 cvsResp.setMessage(output);
307 responses.addResponse(cvsResp);
308 }
309 catch(Exception e) {
310 e.printStackTrace();
311 }
312
313 return responses;
314 }
315
316 /**
317 * Updates the given files with possible new changes from the CVS.
318 * The files in <code>files</code> are first stored in the accurate
319 * position in the <code>tempDir</code> directory tree.
320 * Then an update command is issued to the CVS.
321 * <code>files</code> is then updated with the updated files.
322 */
323 public ResponseCollection updateFiles(FileCollection files) {
324 return new ResponseCollection();
325 }
326
327 /**
328 * Commits the files to the CVS.
329 * The files in <code>files</code> are first stored in the
330 * <code>tempDir</code> directory tree,
331 * from where they are commited to the CVS.
332 */
333 public ResponseCollection commitFiles(FileCollection files) {
334 return new ResponseCollection();
335 }
336
337 /**
338 * Adds the files to the CVS. This includes also a commit of the
339 * added files. The files in <code>files</code> are first stored in
340 * the accurate position in the <code>tempDir</code> directory tree,
341 * from where the add and the commit commands are issued.
342 */
343 public ResponseCollection addFiles(FileCollection files) {
344 return new ResponseCollection();
345 }
346
347 /**
348 * Removes the files from the CVS.
349 * The method is performed by removing the files specified in
350 * <code>files</code> in the <code>tempDir</code> directory tree,
351 * and then issuing CVS commands for removing the files and commiting
352 * the remove.
353 */
354 public ResponseCollection removeFiles(FileCollection files) {
355 return new ResponseCollection();
356 }
357
358 /**
359 * Translates a local file path to a path in CVS.
360 */
361 public SharedFile translatePath(String path) {
362 String repository, filename, temp, cvsroot;
363 SharedFile file = null;
364
365 File cvsFilePath = new File(path);
366 if(!cvsFilePath.exists()) return null;
367
368 try {
369 File cvsFileDir = cvsFilePath.getParentFile();
370
371 filename = cvsFilePath.getName();
372
373 FileReader fr = new FileReader(cvsFileDir.getAbsolutePath()+
374 File.separator+"CVS"+
375 File.separator+"Repository");
376 BufferedReader inFile = new BufferedReader(fr);
377
378 repository = inFile.readLine();
379
380 inFile.close();
381
382 fr = new FileReader(cvsFileDir.getAbsolutePath()+
383 File.separator+"CVS"+
384 File.separator+"Root");
385 inFile = new BufferedReader(fr);
386
387 cvsroot = inFile.readLine();
388
389 inFile.close();
390
391 if(repository.startsWith(cvsroot)) {
392 repository = repository.substring(cvsroot.length()+1);
393 }
394
395 fr = new FileReader(cvsFileDir.getAbsolutePath()+
396 File.separator+"CVS"+
397 File.separator+"Entries");
398 inFile = new BufferedReader(fr);
399
400 while((temp=inFile.readLine())!=null) {
401 String[] params = temp.split("(/)");
402 if(params[1].equals(filename)) {
403 file = new SharedFile();
404 file.setFileName(filename);
405 file.setPathInCVS(repository);
406 if(params.length>2) file.setVersion(params[2]);
407 Body body = new Body();
408 body.setBinary(false);
409 if(params.length>4) body.setBinary(params[4].equals("-kb"));
410 file.setBody(body);
411 break;
412 }
413 }
414
415 inFile.close();
416 }
417 catch(Exception e) {
418 e.printStackTrace();
419 return null;
420 }
421
422 return file;
423 }
424 }
425
426
427