1 28 29 package org.apache.commons.transaction.file; 30 31 import java.io.BufferedReader ; 32 import java.io.BufferedWriter ; 33 import java.io.File ; 34 import java.io.FileInputStream ; 35 import java.io.FileNotFoundException ; 36 import java.io.FileOutputStream ; 37 import java.io.IOException ; 38 import java.io.InputStream ; 39 import java.io.InputStreamReader ; 40 import java.io.OutputStream ; 41 import java.io.OutputStreamWriter ; 42 import java.io.UnsupportedEncodingException ; 43 44 import org.apache.commons.transaction.util.FileHelper; 45 import org.apache.commons.transaction.util.LoggerFacade; 46 47 53 public class FileSequence { 54 55 protected final String storeDir; 56 protected final LoggerFacade logger; 57 58 64 public FileSequence(String storeDir, LoggerFacade logger) throws ResourceManagerException { 65 this.storeDir = storeDir; 66 this.logger = logger; 67 File file = new File (storeDir); 68 file.mkdirs(); 69 if (!file.exists()) { 70 throw new ResourceManagerException("Can not create working directory " + storeDir); 71 } 72 } 73 74 80 public synchronized boolean exists(String sequenceName) { 81 String pathI = getPathI(sequenceName); 82 String pathII = getPathII(sequenceName); 83 84 return (FileHelper.fileExists(pathI) || FileHelper.fileExists(pathII)); 85 } 86 87 94 public synchronized boolean create(String sequenceName, long initialValue) throws ResourceManagerException { 95 if (exists(sequenceName)) 96 return false; 97 write(sequenceName, initialValue); 98 return true; 99 } 100 101 107 public synchronized boolean delete(String sequenceName) { 108 if (!exists(sequenceName)) 109 return false; 110 String pathI = getPathI(sequenceName); 111 String pathII = getPathII(sequenceName); 112 113 boolean res1 = FileHelper.deleteFile(pathI); 115 boolean res2 = FileHelper.deleteFile(pathII); 116 117 return (res1 || res2); 118 } 119 120 129 public synchronized long nextSequenceValueBottom(String sequenceName, long increment) 130 throws ResourceManagerException { 131 if (!exists(sequenceName)) { 132 throw new ResourceManagerException("Sequence " + sequenceName + " does not exist"); 133 } 134 if (increment <= 0) { 135 throw new IllegalArgumentException ("Increment must be greater than 0, was " + increment); 136 } 137 long value = read(sequenceName); 138 long newValue = value + increment; 139 write(sequenceName, newValue); 140 return value; 141 } 142 143 protected long read(String sequenceName) throws ResourceManagerException { 144 String pathI = getPathI(sequenceName); 145 String pathII = getPathII(sequenceName); 146 147 long returnValue = -1; 148 149 long valueI = -1; 150 if (FileHelper.fileExists(pathI)) { 151 try { 152 valueI = readFromPath(pathI); 153 } catch (NumberFormatException e) { 154 throw new ResourceManagerException("Fatal internal error: Backup sequence value corrupted"); 155 } catch (FileNotFoundException e) { 156 throw new ResourceManagerException("Fatal internal error: Backup sequence vanished"); 157 } catch (IOException e) { 158 throw new ResourceManagerException("Fatal internal error: Backup sequence value corrupted"); 159 } 160 } 161 162 long valueII = -1; 163 if (FileHelper.fileExists(pathII)) { 164 try { 165 valueII = readFromPath(pathII); 166 if (valueII > valueI) { 167 returnValue = valueII; 168 } else { 169 logger.logWarning("Latest sequence value smaller than previous, reverting to previous"); 171 FileHelper.deleteFile(pathII); 172 returnValue = valueI; 173 } 174 } catch (NumberFormatException e) { 175 logger.logWarning("Latest sequence value corrupted, reverting to previous"); 176 FileHelper.deleteFile(pathII); 177 returnValue = valueI; 178 } catch (FileNotFoundException e) { 179 logger.logWarning("Can not find latest sequence value, reverting to previous"); 180 FileHelper.deleteFile(pathII); 181 returnValue = valueI; 182 } catch (IOException e) { 183 logger.logWarning("Can not read latest sequence value, reverting to previous"); 184 FileHelper.deleteFile(pathII); 185 returnValue = valueI; 186 } 187 } else { 188 logger.logWarning("Can not read latest sequence value, reverting to previous"); 189 returnValue = valueI; 190 } 191 192 if (returnValue != -1) { 193 return returnValue; 194 } else { 195 throw new ResourceManagerException("Fatal internal error: Could not compute valid sequence value"); 196 } 197 } 198 199 protected void write(String sequenceName, long value) throws ResourceManagerException { 200 String pathII = getPathII(sequenceName); 201 202 File f2 = new File (pathII); 203 if (f2.exists()) { 205 String pathI = getPathI(sequenceName); 207 File f1 = new File (pathI); 208 f1.delete(); 209 if (!f2.renameTo(f1)) { 210 throw new ResourceManagerException("Fatal internal error: Can not create backup value at" + pathI); 211 } 212 } 213 try { 214 if (!f2.createNewFile()) { 215 throw new ResourceManagerException("Fatal internal error: Can not create new value at" + pathII); 216 } 217 } catch (IOException e) { 218 throw new ResourceManagerException("Fatal internal error: Can not create new value at" + pathII, e); 219 } 220 writeToPath(pathII, value); 221 } 222 223 protected String getPathI(String sequenceName) { 224 return storeDir + "/" + sequenceName + "_1.seq"; 225 } 226 227 protected String getPathII(String sequenceName) { 228 return storeDir + "/" + sequenceName + "_2.seq"; 229 } 230 231 protected long readFromPath(String path) 232 throws ResourceManagerException, NumberFormatException , FileNotFoundException , IOException { 233 File file = new File (path); 234 BufferedReader reader = null; 235 try { 236 InputStream is = new FileInputStream (file); 237 238 reader = new BufferedReader (new InputStreamReader (is, "UTF-8")); 240 String valueString = reader.readLine(); 241 long value = Long.parseLong(valueString); 242 return value; 243 } catch (UnsupportedEncodingException e) { 244 throw new ResourceManagerException("Fatal internal error, encoding UTF-8 unknown"); 245 } finally { 246 if (reader != null) { 247 try { 248 reader.close(); 249 } catch (IOException e) { 250 } 251 252 } 253 } 254 } 255 256 protected void writeToPath(String path, long value) throws ResourceManagerException { 257 File file = new File (path); 258 BufferedWriter writer = null; 259 try { 260 OutputStream os = new FileOutputStream (file); 261 writer = new BufferedWriter (new OutputStreamWriter (os, "UTF-8")); 262 String valueString = Long.toString(value); 263 writer.write(valueString); 264 writer.write('\n'); 265 } catch (FileNotFoundException e) { 266 throw new ResourceManagerException("Fatal internal error: Can not find sequence at " + path); 267 } catch (IOException e) { 268 throw new ResourceManagerException("Fatal internal error: Can not write to sequence at " + path); 269 } finally { 270 if (writer != null) { 271 try { 272 writer.close(); 273 } catch (IOException e) { 274 } 275 276 } 277 } 278 } 279 } 280 | Popular Tags |