26package org.jau.pkg.cache;
29import java.io.FileOutputStream;
30import java.io.FilenameFilter;
31import java.io.IOException;
32import java.nio.channels.FileChannel;
33import java.nio.channels.FileLock;
35import org.jau.io.IOUtil;
36import org.jau.lang.InterruptSource;
37import org.jau.sys.Debug;
40 private static final boolean DEBUG =
Debug.
debug(
"TempFileCache");
43 private static boolean staticInitError =
false;
46 private static boolean staticTempIsExecutable =
true;
48 private static final String tmpDirPrefix =
"file_cache";
51 private static final File tmpBaseDir;
55 static final String tmpRootPropName =
"jnlp.jogamp.tmp.cache.root";
63 private static String tmpRootPropValue;
66 private static File tmpRootDir;
69 private boolean initError =
false;
71 private File individualTmpDir;
75 synchronized (System.out) {
79 File _tmpBaseDir =
null;
83 staticTempIsExecutable =
true;
84 }
catch (
final Exception ex) {
85 System.err.println(
"Warning: Caught Exception while retrieving executable temp base directory:");
87 staticTempIsExecutable =
false;
91 }
catch (
final Exception ex2) {
92 System.err.println(
"Warning: Caught Exception while retrieving non-executable temp base directory:");
93 ex2.printStackTrace();
94 staticInitError =
true;
97 tmpBaseDir = _tmpBaseDir;
100 final String tmpBaseDirAbsPath =
null != tmpBaseDir ? tmpBaseDir.getAbsolutePath() :
null;
101 System.err.println(
"TempFileCache: Static Initialization ---------------------------------------------- OK: "+(!staticInitError));
102 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
103 ", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
104 ", tempBaseDir "+tmpBaseDirAbsPath+
", executable "+staticTempIsExecutable);
107 if(!staticInitError) {
110 }
catch (
final Exception ex) {
111 System.err.println(
"Warning: Caught Exception due to initializing TmpRoot:");
112 ex.printStackTrace();
113 staticInitError =
true;
114 staticTempIsExecutable =
false;
118 System.err.println(
"------------------------------------------------------------------ OK: "+(!staticInitError));
128 return !staticInitError;
182 private static void initTmpRoot() throws IOException {
183 tmpRootPropValue = System.getProperty(tmpRootPropName);
185 if (tmpRootPropValue !=
null) {
187 if (tmpRootPropValue.indexOf(
'/') >= 0 ||
188 tmpRootPropValue.indexOf(File.separatorChar) >= 0) {
189 throw new IOException(
"Illegal value of: " + tmpRootPropName);
194 System.err.println(
"TempFileCache: Trying existing value of: " +
195 tmpRootPropName +
"=" + tmpRootPropValue);
197 tmpRootDir =
new File(tmpBaseDir, tmpRootPropValue);
199 System.err.println(
"TempFileCache: Trying tmpRootDir = " + tmpRootDir.getAbsolutePath());
201 if (tmpRootDir.isDirectory()) {
202 if (!tmpRootDir.canWrite()) {
203 throw new IOException(
"Temp root directory is not writable: " + tmpRootDir.getAbsolutePath());
208 System.err.println(
"TempFileCache: None existing tmpRootDir = " + tmpRootDir.getAbsolutePath()+
", assuming new path due to update");
209 tmpRootPropValue =
null;
211 System.clearProperty(tmpRootPropName);
215 if (tmpRootPropValue ==
null) {
217 final File tmpFile = File.createTempFile(
"jln",
".tmp", tmpBaseDir);
219 System.err.println(
"TempFileCache: tmpFile = " + tmpFile.getAbsolutePath());
221 final FileOutputStream tmpOut =
new FileOutputStream(tmpFile);
222 final FileChannel tmpChannel = tmpOut.getChannel();
223 final FileLock tmpLock = tmpChannel.lock();
226 final String tmpFileName = tmpFile.getAbsolutePath();
227 final String tmpRootName = tmpFileName.substring(0, tmpFileName.lastIndexOf(
".tmp"));
230 final String lckFileName = tmpRootName +
".lck";
231 final File lckFile =
new File(lckFileName);
233 System.err.println(
"TempFileCache: lckFile = " + lckFile.getAbsolutePath());
235 lckFile.createNewFile();
236 final FileOutputStream lckOut =
new FileOutputStream(lckFile);
237 final FileChannel lckChannel = lckOut.getChannel();
238 final FileLock lckLock = lckChannel.lock();
241 tmpRootDir =
new File(tmpRootName);
243 System.err.println(
"TempFileCache: tmpRootDir = " + tmpRootDir.getAbsolutePath());
245 if (!tmpRootDir.mkdir()) {
246 throw new IOException(
"Cannot create " + tmpRootDir);
252 Runtime.getRuntime().addShutdownHook(
new InterruptSource.Thread() {
265 } catch (final IOException ex) {
272 tmpRootPropValue = tmpRootName.substring(tmpRootName.lastIndexOf(File.separator) + 1);
273 System.setProperty(tmpRootPropName, tmpRootPropValue);
275 System.err.println(
"TempFileCache: Setting " + tmpRootPropName +
"=" + tmpRootPropValue);
279 final Thread reaperThread =
new InterruptSource.Thread() {
286 reaperThread.setName(
"TempFileCache-Reaper");
287 reaperThread.start();
295 private static void deleteOldTempDirs() {
297 System.err.println(
"TempFileCache: *** Reaper: deleteOldTempDirs in " +
298 tmpBaseDir.getAbsolutePath());
302 final String ourLockFile = tmpRootPropValue +
".lck";
303 final FilenameFilter lckFilter =
new FilenameFilter() {
306 public boolean accept(
final File dir,
final String name) {
307 return name.endsWith(
".lck") && !name.equals(ourLockFile);
316 final String[] fileNames = tmpBaseDir.list(lckFilter);
317 if (fileNames !=
null) {
318 for (
int i = 0; i < fileNames.length; i++) {
319 final String lckFileName = fileNames[i];
320 final String tmpDirName = lckFileName.substring(0, lckFileName.lastIndexOf(
".lck"));
321 final String tmpFileName = tmpDirName +
".tmp";
323 final File lckFile =
new File(tmpBaseDir, lckFileName);
324 final File tmpFile =
new File(tmpBaseDir, tmpFileName);
325 final File tmpDir =
new File(tmpBaseDir, tmpDirName);
327 if (lckFile.exists() && tmpFile.exists() && tmpDir.isDirectory()) {
328 FileOutputStream tmpOut =
null;
329 FileChannel tmpChannel =
null;
330 FileLock tmpLock =
null;
333 tmpOut =
new FileOutputStream(tmpFile);
334 tmpChannel = tmpOut.getChannel();
335 tmpLock = tmpChannel.tryLock();
336 }
catch (
final Exception ex) {
339 ex.printStackTrace();
343 if (tmpLock !=
null) {
344 FileOutputStream lckOut =
null;
345 FileChannel lckChannel =
null;
346 FileLock lckLock =
null;
349 lckOut =
new FileOutputStream(lckFile);
350 lckChannel = lckOut.getChannel();
351 lckLock = lckChannel.tryLock();
352 }
catch (
final Exception ex) {
354 ex.printStackTrace();
358 if (lckLock !=
null) {
372 }
catch (
final IOException ex) {
377 }
catch (
final IOException ex) {
383 if (lckOut !=
null) {
390 }
catch (
final IOException ex) {
392 ex.printStackTrace();
399 System.err.println(
"TempFileCache: Skipping: " + tmpDir.getAbsolutePath());
410 private static void removeAll(
final File path) {
412 System.err.println(
"TempFileCache: removeAll(" + path +
")");
415 if (path.isDirectory()) {
417 final File[] list = path.listFiles();
419 for (
int i = 0; i < list.length; i++) {
430 System.err.println(
"TempFileCache: new TempFileCache() --------------------- (static ok: "+(!staticInitError)+
")");
431 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
", this 0x"+Integer.toHexString(hashCode()));
433 if(!staticInitError) {
436 }
catch (
final Exception ex) {
437 ex.printStackTrace();
442 System.err.println(
"TempFileCache: tempDir "+individualTmpDir+
" (ok: "+(!initError)+
")");
443 System.err.println(
"----------------------------------------------------------");
450 System.err.println(
"TempFileCache: destroy() --------------------- (static ok: "+(!staticInitError)+
")");
451 System.err.println(
"TempFileCache: Thread: "+Thread.currentThread().getName()+
", CL 0x"+Integer.toHexString(
TempFileCache.class.getClassLoader().hashCode())+
", this 0x"+Integer.toHexString(hashCode()));
453 if(!staticInitError) {
455 removeAll(individualTmpDir);
456 }
catch (
final Exception ex) {
457 ex.printStackTrace();
460 individualTmpDir =
null;
462 System.err.println(
"TempFileCache: destroy() END");
472 public boolean isValid(
final boolean forExecutables) {
473 return !staticInitError && !initError && ( !forExecutables || staticTempIsExecutable );
553 private void createTmpDir() throws IOException {
554 final File tmpFile = File.createTempFile(
"jln",
".tmp", tmpRootDir);
555 final String tmpFileName = tmpFile.getAbsolutePath();
556 final String tmpDirName = tmpFileName.substring(0, tmpFileName.lastIndexOf(
".tmp"));
557 individualTmpDir =
new File(tmpDirName);
558 if (!individualTmpDir.mkdir()) {
559 throw new IOException(
"Cannot create " + individualTmpDir);
static File testDir(final File dir, final boolean create, final boolean executable)
Returns the directory dir, which is processed and tested as described below.
static File getTempDir(final boolean executable)
Returns a platform independent writable directory for temporary files consisting of the platform's te...
void destroy()
Delete the getTempDir() recursively and remove it's reference.
File getTempDir()
Temporary directory for individual files (eg.
static File getRootDir()
Root temp directory for this JVM instance.
TempFileCache()
Create the getTempDir().
boolean isValid(final boolean forExecutables)
static File getBaseDir()
Base temp directory used by TempFileCache.
static boolean initSingleton()
Documented way to kick off static initialization.
Helper routines for logging and debugging.
static final boolean debug(final String subcomponent)