28package com.jogamp.common.util.cache;
31import java.io.FileOutputStream;
32import java.io.FilenameFilter;
33import java.io.IOException;
34import java.nio.channels.FileChannel;
35import java.nio.channels.FileLock;
37import com.jogamp.common.util.IOUtil;
38import com.jogamp.common.util.InterruptSource;
40import jogamp.common.Debug;
43 private static final boolean DEBUG = Debug.debug(
"TempFileCache");
46 private static boolean staticInitError =
false;
49 private static boolean staticTempIsExecutable =
true;
51 private static final String tmpDirPrefix =
"file_cache";
54 private static final File tmpBaseDir;
58 static final String tmpRootPropName =
"jnlp.jogamp.tmp.cache.root";
66 private static String tmpRootPropValue;
69 private static File tmpRootDir;
72 private boolean initError =
false;
74 private File individualTmpDir;
78 synchronized (System.out) {
82 File _tmpBaseDir =
null;
86 staticTempIsExecutable =
true;
87 }
catch (
final Exception ex) {
88 System.err.println(
"Warning: Caught Exception while retrieving executable temp base directory:");
90 staticTempIsExecutable =
false;
94 }
catch (
final Exception ex2) {
95 System.err.println(
"Warning: Caught Exception while retrieving non-executable temp base directory:");
96 ex2.printStackTrace();
97 staticInitError =
true;
100 tmpBaseDir = _tmpBaseDir;
103 final String tmpBaseDirAbsPath =
null != tmpBaseDir ? tmpBaseDir.getAbsolutePath() :
null;
104 System.err.println(
"TempFileCache: Static Initialization ---------------------------------------------- OK: "+(!staticInitError));
105 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
106 ", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
107 ", tempBaseDir "+tmpBaseDirAbsPath+
", executable "+staticTempIsExecutable);
110 if(!staticInitError) {
113 }
catch (
final Exception ex) {
114 System.err.println(
"Warning: Caught Exception due to initializing TmpRoot:");
115 ex.printStackTrace();
116 staticInitError =
true;
117 staticTempIsExecutable =
false;
121 System.err.println(
"------------------------------------------------------------------ OK: "+(!staticInitError));
131 return !staticInitError;
185 private static void initTmpRoot() throws IOException {
186 tmpRootPropValue = System.getProperty(tmpRootPropName);
188 if (tmpRootPropValue !=
null) {
190 if (tmpRootPropValue.indexOf(
'/') >= 0 ||
191 tmpRootPropValue.indexOf(File.separatorChar) >= 0) {
192 throw new IOException(
"Illegal value of: " + tmpRootPropName);
197 System.err.println(
"TempFileCache: Trying existing value of: " +
198 tmpRootPropName +
"=" + tmpRootPropValue);
200 tmpRootDir =
new File(tmpBaseDir, tmpRootPropValue);
202 System.err.println(
"TempFileCache: Trying tmpRootDir = " + tmpRootDir.getAbsolutePath());
204 if (tmpRootDir.isDirectory()) {
205 if (!tmpRootDir.canWrite()) {
206 throw new IOException(
"Temp root directory is not writable: " + tmpRootDir.getAbsolutePath());
211 System.err.println(
"TempFileCache: None existing tmpRootDir = " + tmpRootDir.getAbsolutePath()+
", assuming new path due to update");
212 tmpRootPropValue =
null;
214 System.clearProperty(tmpRootPropName);
218 if (tmpRootPropValue ==
null) {
220 final File tmpFile = File.createTempFile(
"jln",
".tmp", tmpBaseDir);
222 System.err.println(
"TempFileCache: tmpFile = " + tmpFile.getAbsolutePath());
224 final FileOutputStream tmpOut =
new FileOutputStream(tmpFile);
225 final FileChannel tmpChannel = tmpOut.getChannel();
226 final FileLock tmpLock = tmpChannel.lock();
229 final String tmpFileName = tmpFile.getAbsolutePath();
230 final String tmpRootName = tmpFileName.substring(0, tmpFileName.lastIndexOf(
".tmp"));
233 final String lckFileName = tmpRootName +
".lck";
234 final File lckFile =
new File(lckFileName);
236 System.err.println(
"TempFileCache: lckFile = " + lckFile.getAbsolutePath());
238 lckFile.createNewFile();
239 final FileOutputStream lckOut =
new FileOutputStream(lckFile);
240 final FileChannel lckChannel = lckOut.getChannel();
241 final FileLock lckLock = lckChannel.lock();
244 tmpRootDir =
new File(tmpRootName);
246 System.err.println(
"TempFileCache: tmpRootDir = " + tmpRootDir.getAbsolutePath());
248 if (!tmpRootDir.mkdir()) {
249 throw new IOException(
"Cannot create " + tmpRootDir);
255 Runtime.getRuntime().addShutdownHook(
new InterruptSource.Thread() {
268 } catch (final IOException ex) {
275 tmpRootPropValue = tmpRootName.substring(tmpRootName.lastIndexOf(File.separator) + 1);
276 System.setProperty(tmpRootPropName, tmpRootPropValue);
278 System.err.println(
"TempFileCache: Setting " + tmpRootPropName +
"=" + tmpRootPropValue);
282 final Thread reaperThread =
new InterruptSource.Thread() {
289 reaperThread.setName(
"TempFileCache-Reaper");
290 reaperThread.start();
298 private static void deleteOldTempDirs() {
300 System.err.println(
"TempFileCache: *** Reaper: deleteOldTempDirs in " +
301 tmpBaseDir.getAbsolutePath());
305 final String ourLockFile = tmpRootPropValue +
".lck";
306 final FilenameFilter lckFilter =
new FilenameFilter() {
309 public boolean accept(
final File dir,
final String name) {
310 return name.endsWith(
".lck") && !name.equals(ourLockFile);
319 final String[] fileNames = tmpBaseDir.list(lckFilter);
320 if (fileNames !=
null) {
321 for (
int i = 0; i < fileNames.length; i++) {
322 final String lckFileName = fileNames[i];
323 final String tmpDirName = lckFileName.substring(0, lckFileName.lastIndexOf(
".lck"));
324 final String tmpFileName = tmpDirName +
".tmp";
326 final File lckFile =
new File(tmpBaseDir, lckFileName);
327 final File tmpFile =
new File(tmpBaseDir, tmpFileName);
328 final File tmpDir =
new File(tmpBaseDir, tmpDirName);
330 if (lckFile.exists() && tmpFile.exists() && tmpDir.isDirectory()) {
331 FileOutputStream tmpOut =
null;
332 FileChannel tmpChannel =
null;
333 FileLock tmpLock =
null;
336 tmpOut =
new FileOutputStream(tmpFile);
337 tmpChannel = tmpOut.getChannel();
338 tmpLock = tmpChannel.tryLock();
339 }
catch (
final Exception ex) {
342 ex.printStackTrace();
346 if (tmpLock !=
null) {
347 FileOutputStream lckOut =
null;
348 FileChannel lckChannel =
null;
349 FileLock lckLock =
null;
352 lckOut =
new FileOutputStream(lckFile);
353 lckChannel = lckOut.getChannel();
354 lckLock = lckChannel.tryLock();
355 }
catch (
final Exception ex) {
357 ex.printStackTrace();
361 if (lckLock !=
null) {
375 }
catch (
final IOException ex) {
380 }
catch (
final IOException ex) {
386 if (lckOut !=
null) {
393 }
catch (
final IOException ex) {
395 ex.printStackTrace();
402 System.err.println(
"TempFileCache: Skipping: " + tmpDir.getAbsolutePath());
413 private static void removeAll(
final File path) {
415 System.err.println(
"TempFileCache: removeAll(" + path +
")");
418 if (path.isDirectory()) {
420 final File[] list = path.listFiles();
422 for (
int i = 0; i < list.length; i++) {
433 System.err.println(
"TempFileCache: new TempFileCache() --------------------- (static ok: "+(!staticInitError)+
")");
434 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
", this 0x"+Integer.toHexString(hashCode()));
436 if(!staticInitError) {
439 }
catch (
final Exception ex) {
440 ex.printStackTrace();
445 System.err.println(
"TempFileCache: tempDir "+individualTmpDir+
" (ok: "+(!initError)+
")");
446 System.err.println(
"----------------------------------------------------------");
453 System.err.println(
"TempFileCache: destroy() --------------------- (static ok: "+(!staticInitError)+
")");
454 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
", this 0x"+Integer.toHexString(hashCode()));
456 if(!staticInitError) {
458 removeAll(individualTmpDir);
459 }
catch (
final Exception ex) {
460 ex.printStackTrace();
463 individualTmpDir =
null;
465 System.err.println(
"TempFileCache: destroy() END");
475 public boolean isValid(
final boolean forExecutables) {
476 return !staticInitError && !initError && ( !forExecutables || staticTempIsExecutable );
556 private void createTmpDir() throws IOException {
557 final File tmpFile = File.createTempFile(
"jln",
".tmp", tmpRootDir);
558 final String tmpFileName = tmpFile.getAbsolutePath();
559 final String tmpDirName = tmpFileName.substring(0, tmpFileName.lastIndexOf(
".tmp"));
560 individualTmpDir =
new File(tmpDirName);
561 if (!individualTmpDir.mkdir()) {
562 throw new IOException(
"Cannot create " + individualTmpDir);
static File getTempDir(final boolean executable)
Returns a platform independent writable directory for temporary files consisting of the platform's te...
static File testDir(final File dir, final boolean create, final boolean executable)
Returns the directory dir, which is processed and tested as described below.
File getTempDir()
Temporary directory for individual files (eg.
boolean isValid(final boolean forExecutables)
TempFileCache()
Create the getTempDir().
static boolean initSingleton()
Documented way to kick off static initialization.
static File getRootDir()
Root temp directory for this JVM instance.
void destroy()
Delete the getTempDir() recursively and remove it's reference.
static File getBaseDir()
Base temp directory used by TempFileCache.