still dealing with JarInputStream issues.
[vamsas.git] / src / org / vamsas / client / simpleclient / SessionFile.java
1 package org.vamsas.client.simpleclient;
2
3 import java.io.BufferedInputStream;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13
14 /**
15  * Basic methods for classes handling locked IO on files 
16  * monitored by all (simpleclient) clients in a vamsas session.
17  * @author jimp
18  *TODO: support non nio file locking capable systems
19  */
20 public class SessionFile {
21   private static Log log = LogFactory.getLog(SessionFile.class);
22   protected File sessionFile;
23   protected Lock fileLock = null;
24
25   protected SessionFile(File file) {
26     super();
27     sessionFile = file;
28   }
29
30   protected boolean lockFile(Lock extantlock) {
31     if (fileLock!=null && !fileLock.isLocked()) {
32       fileLock.release();// tidy up invalid lock
33       fileLock=null;
34     }
35     if (extantlock!=null)
36       fileLock=extantlock;
37     return lockFile();
38   }
39
40   /**
41    * Get a lock for the SessionFile
42    * 
43    * @return true if lock was made
44    */
45   protected boolean lockFile() {
46     if (fileLock != null)
47       if (fileLock.isLocked())
48         return true;
49       else 
50         // lock failed for some reason.
51         fileLock.release();
52     fileLock = null;
53     if (sessionFile != null) {
54       if (!sessionFile.exists()) {
55         // create new file
56         try {
57           if (!sessionFile.createNewFile()) {
58             log.error("Failed to create file prior to locking: "+sessionFile);
59             return false;
60           }
61         } catch (IOException e) {
62           log.error("Exception when trying to create file "+sessionFile, e);
63           return false;
64         }
65       }
66       // TODO: see if we need to loop-wait for locks or they just block until
67       // lock is made...
68       long tries=500;
69       do {
70         tries--;
71         if (fileLock!=null && !fileLock.isLocked())
72           fileLock.release();
73           fileLock = new Lock(sessionFile); // TODO: wait around if we can't get the lock.
74       } while (tries>0 && !fileLock.isLocked());
75       if (!fileLock.isLocked())
76         log.error("Failed to get lock for "+sessionFile);
77       // fileLock = new Lock(sessionFile);
78       return fileLock.isLocked();    
79     } else
80       log.error("lockFile called for non-initialised SessionFile!");
81   
82     // no lock possible
83     return false;
84   }
85
86   /**
87    * Explicitly release the SessionFile's lock.
88    * 
89    * @return true if lock was released.
90    */
91   protected void unlockFile() {
92     if (fileLock != null) {
93       fileLock.release();    
94       fileLock = null;
95     }
96   }
97
98   /**
99    * Makes a backup of the sessionFile.
100    * @return Backed up SessionFile or null if failed to make backup.
101    */
102   protected File backupSessionFile() {
103     return backupSessionFile(null, sessionFile.getName(),".old", sessionFile.getParentFile());
104   }
105
106   protected File backupSessionFile(Lock extantLock, String backupPrefix, String backupSuffix, File backupDir) {
107     File tempfile=null;
108     if (lockFile(extantLock)) {
109       try {
110         tempfile = File.createTempFile(backupPrefix, backupSuffix, backupDir);
111         FileOutputStream tos = new FileOutputStream(tempfile);
112         tos.getChannel().transferFrom(fileLock.rafile.getChannel(), 0,
113             fileLock.rafile.length());
114         tos.close();
115       } catch (FileNotFoundException e1) {
116         log.warn("Can't create temp file for "+sessionFile.getName(),e1);
117         tempfile=null;
118       } catch (IOException e1) {
119         log.warn("Error when copying content to temp file for "+sessionFile.getName(),e1);
120         tempfile=null;
121       }
122     }
123     return tempfile;
124   }
125   /**
126    * Replaces data in sessionFile with data from file handled by another sessionFile
127    * passes up any exceptions.
128    * @param newData source for new data
129    */
130   protected void updateFrom(Lock extantLock, SessionFile newData) throws IOException {
131     log.debug("Updating "+sessionFile.getAbsolutePath()+" from "+newData.sessionFile.getAbsolutePath());
132     if (newData==null)
133       throw new IOException("Null newData object.");
134     if (newData.sessionFile==null)
135       throw new IOException("Null SessionFile in newData.");
136       
137     lockFile(extantLock);  
138     newData.lockFile();
139     fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0, 
140         newData.fileLock.rafile.length());
141   }
142   /**
143    * remove all trace of the sessionFile file
144    *
145    */
146   protected void eraseExistence() {
147     unlockFile();
148     if (sessionFile!=null) {
149       sessionFile.delete();
150       sessionFile = null;
151     }
152   }
153   /* (non-Javadoc)
154    * @see org.vamsas.client.simpleclient.Lock#getBufferedInputStream(boolean)
155    */
156   public BufferedInputStream getBufferedInputStream(boolean atStart) throws IOException {
157     lockFile();
158     return fileLock.getBufferedInputStream(atStart);
159   }
160
161   /* (non-Javadoc)
162    * @see org.vamsas.client.simpleclient.Lock#getBufferedOutputStream(boolean)
163    */
164   public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
165     lockFile();
166     return fileLock.getBufferedOutputStream(clear);
167   }
168
169   /* (non-Javadoc)
170    * @see org.vamsas.client.simpleclient.Lock#getFileInputStream(boolean)
171    */
172   public FileInputStream getFileInputStream(boolean atStart) throws IOException {
173     lockFile();
174     return fileLock.getFileInputStream(atStart);
175   }
176
177   /* (non-Javadoc)
178    * @see org.vamsas.client.simpleclient.Lock#getFileOutputStream(boolean)
179    */
180   public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
181     lockFile();
182     return fileLock.getFileOutputStream(clear);
183   }
184   
185 }