untested vamsasArchive class with additional method for transferring data between...
[vamsas.git] / src / org / vamsas / client / simpleclient / SessionFile.java
1 package org.vamsas.client.simpleclient;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.apache.commons.logging.impl.Log4jFactory;
11
12 /**
13  * Basic methods for classes handling locked IO on files 
14  * monitored by all (simpleclient) clients in a vamsas session.
15  * @author jimp
16  *
17  */
18 public class SessionFile {
19   private static Log log = LogFactory.getLog(SessionFile.class);
20   protected File sessionFile;
21   protected Lock fileLock = null;
22
23   protected SessionFile(File file) {
24     super();
25     sessionFile = file;
26   }
27
28   protected boolean lockFile(Lock extantlock) {
29     if (fileLock!=null && !fileLock.isLocked()) {
30       fileLock.release();// tidy up invalid lock
31     }
32     fileLock=extantlock;
33     return lockFile();
34   }
35
36   /**
37    * Get a lock for the SessionFile
38    * 
39    * @return true if lock was made
40    */
41   protected boolean lockFile() {
42     if (fileLock != null)
43       if (fileLock.isLocked())
44         return true;
45       else 
46         // lock failed for some reason.
47         fileLock.release();
48     fileLock = null;
49     if (sessionFile != null) {
50       if (sessionFile.exists()) {
51         // TODO: see if we need to loop-wait for locks or they just block until
52         // lock is made...
53         do {
54           if (fileLock!=null)
55             fileLock.release();
56           fileLock = new Lock(sessionFile); // TODO: wait around if we can't get the lock.
57         } while (!fileLock.isLocked());
58         // fileLock = new Lock(sessionFile);
59         return fileLock.isLocked();
60       }
61     } else
62       log.error("lockFile called for non-initialised SessionFile!");
63   
64     // no lock possible
65     return false;
66   }
67
68   /**
69    * Explicitly release the SessionFile's lock.
70    * 
71    * @return true if lock was released.
72    */
73   protected void unlockFile() {
74     if (fileLock != null) {
75       fileLock.release();    
76       fileLock = null;
77     }
78   }
79
80   /**
81    * Makes a backup of the sessionFile.
82    * @return Backed up SessionFile or null if failed to make backup.
83    */
84   protected File backupSessionFile() {
85     return backupSessionFile(null, sessionFile.getName(),".old", sessionFile.getParentFile());
86   }
87
88   protected File backupSessionFile(Lock extantLock, String backupPrefix, String backupSuffix, File backupDir) {
89     File tempfile=null;
90     if (lockFile(extantLock)) {
91       try {
92         tempfile = File.createTempFile(backupPrefix, backupSuffix, backupDir);
93         FileOutputStream tos = new FileOutputStream(tempfile);
94         tos.getChannel().transferFrom(fileLock.rafile.getChannel(), 0,
95             fileLock.rafile.length());
96         tos.close();
97       } catch (FileNotFoundException e1) {
98         log.warn("Can't create temp file for "+sessionFile.getName(),e1);
99         tempfile=null;
100       } catch (IOException e1) {
101         log.warn("Error when copying content to temp file for "+sessionFile.getName(),e1);
102         tempfile=null;
103       }
104     }
105     return tempfile;
106   }
107   /**
108    * Replaces data in sessionFile with data from file handled by another sessionFile
109    * passes up any exceptions.
110    * @param newData source for new data
111    */
112   protected void updateFrom(Lock extantLock, SessionFile newData) throws IOException {
113     log.debug("Updating "+sessionFile.getAbsolutePath()+" from "+newData.sessionFile.getAbsolutePath());
114     if (newData==null)
115       throw new IOException("Null newData object.");
116     if (newData.sessionFile!=null)
117       throw new IOException("Null SessionFile in newData.");
118       
119     lockFile(extantLock);  
120     newData.lockFile();
121     fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0, 
122         newData.fileLock.rafile.length());
123   }
124 }