more fixes for clientdocument/simpleclient. Testign the vamsasArchive reader and...
[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
11 /**
12  * Basic methods for classes handling locked IO on files 
13  * monitored by all (simpleclient) clients in a vamsas session.
14  * @author jimp
15  *TODO: support non nio file locking capable systems
16  */
17 public class SessionFile {
18   private static Log log = LogFactory.getLog(SessionFile.class);
19   protected File sessionFile;
20   protected Lock fileLock = null;
21
22   protected SessionFile(File file) {
23     super();
24     sessionFile = file;
25   }
26
27   protected boolean lockFile(Lock extantlock) {
28     if (fileLock!=null && !fileLock.isLocked()) {
29       fileLock.release();// tidy up invalid lock
30     }
31     fileLock=extantlock;
32     return lockFile();
33   }
34
35   /**
36    * Get a lock for the SessionFile
37    * 
38    * @return true if lock was made
39    */
40   protected boolean lockFile() {
41     if (fileLock != null)
42       if (fileLock.isLocked())
43         return true;
44       else 
45         // lock failed for some reason.
46         fileLock.release();
47     fileLock = null;
48     if (sessionFile != null) {
49       if (!sessionFile.exists()) {
50         // create new file
51         try {
52           if (!sessionFile.createNewFile()) {
53             log.error("Failed to create file prior to locking: "+sessionFile);
54             return false;
55           }
56         } catch (IOException e) {
57           log.error("Exception when trying to create file "+sessionFile, e);
58           return false;
59         }
60       }
61       // TODO: see if we need to loop-wait for locks or they just block until
62       // lock is made...
63       do {
64         if (fileLock!=null)
65           fileLock.release();
66           fileLock = new Lock(sessionFile); // TODO: wait around if we can't get the lock.
67       } while (!fileLock.isLocked());
68       // fileLock = new Lock(sessionFile);
69       return fileLock.isLocked();    
70     } else
71       log.error("lockFile called for non-initialised SessionFile!");
72   
73     // no lock possible
74     return false;
75   }
76
77   /**
78    * Explicitly release the SessionFile's lock.
79    * 
80    * @return true if lock was released.
81    */
82   protected void unlockFile() {
83     if (fileLock != null) {
84       fileLock.release();    
85       fileLock = null;
86     }
87   }
88
89   /**
90    * Makes a backup of the sessionFile.
91    * @return Backed up SessionFile or null if failed to make backup.
92    */
93   protected File backupSessionFile() {
94     return backupSessionFile(null, sessionFile.getName(),".old", sessionFile.getParentFile());
95   }
96
97   protected File backupSessionFile(Lock extantLock, String backupPrefix, String backupSuffix, File backupDir) {
98     File tempfile=null;
99     if (lockFile(extantLock)) {
100       try {
101         tempfile = File.createTempFile(backupPrefix, backupSuffix, backupDir);
102         FileOutputStream tos = new FileOutputStream(tempfile);
103         tos.getChannel().transferFrom(fileLock.rafile.getChannel(), 0,
104             fileLock.rafile.length());
105         tos.close();
106       } catch (FileNotFoundException e1) {
107         log.warn("Can't create temp file for "+sessionFile.getName(),e1);
108         tempfile=null;
109       } catch (IOException e1) {
110         log.warn("Error when copying content to temp file for "+sessionFile.getName(),e1);
111         tempfile=null;
112       }
113     }
114     return tempfile;
115   }
116   /**
117    * Replaces data in sessionFile with data from file handled by another sessionFile
118    * passes up any exceptions.
119    * @param newData source for new data
120    */
121   protected void updateFrom(Lock extantLock, SessionFile newData) throws IOException {
122     log.debug("Updating "+sessionFile.getAbsolutePath()+" from "+newData.sessionFile.getAbsolutePath());
123     if (newData==null)
124       throw new IOException("Null newData object.");
125     if (newData.sessionFile==null)
126       throw new IOException("Null SessionFile in newData.");
127       
128     lockFile(extantLock);  
129     newData.lockFile();
130     fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0, 
131         newData.fileLock.rafile.length());
132   }
133   /**
134    * remove all trace of the sessionFile file
135    *
136    */
137   protected void eraseExistence() {
138     unlockFile();
139     if (sessionFile!=null) {
140       sessionFile.delete();
141       sessionFile = null;
142     }
143   }
144 }