forked from ebean-orm/ebean
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
9 changed files
with
438 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
ebean-api/src/main/java/io/ebean/config/DeleteOnShutdownTempFileProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package io.ebean.config; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* TempFileProvider implementation, which deletes all temp files on shutdown. | ||
* | ||
* @author Roland Praml, FOCONIS AG | ||
* | ||
*/ | ||
public class DeleteOnShutdownTempFileProvider implements TempFileProvider { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(DeleteOnShutdownTempFileProvider.class); | ||
|
||
List<String> tempFiles = new ArrayList<>(); | ||
private final String prefix; | ||
private final String suffix; | ||
private final File directory; | ||
|
||
/** | ||
* Creates the TempFileProvider with default prefix "db-". | ||
*/ | ||
public DeleteOnShutdownTempFileProvider() { | ||
this("db-", null, null); | ||
} | ||
|
||
/** | ||
* Creates the TempFileProvider. | ||
*/ | ||
public DeleteOnShutdownTempFileProvider(String prefix, String suffix, File directory) { | ||
this.prefix = prefix; | ||
this.suffix = suffix; | ||
this.directory = directory; | ||
} | ||
|
||
@Override | ||
public File createTempFile() throws IOException { | ||
File file = File.createTempFile(prefix, suffix, directory); | ||
synchronized (tempFiles) { | ||
tempFiles.add(file.getAbsolutePath()); | ||
} | ||
return file; | ||
} | ||
|
||
/** | ||
* Deletes all created files on shutdown. | ||
*/ | ||
@Override | ||
public void shutdown() { | ||
synchronized (tempFiles) { | ||
for (String path : tempFiles) { | ||
if (new File(path).delete()) { | ||
logger.trace("deleted {}", path); | ||
} else { | ||
logger.warn("could not delete {}", path); | ||
} | ||
} | ||
tempFiles.clear(); | ||
} | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
ebean-api/src/main/java/io/ebean/config/TempFileProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package io.ebean.config; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Creates a temp file for the ScalarTypeFile datatype. | ||
* | ||
* @author Roland Praml, FOCONIS AG | ||
* | ||
*/ | ||
public interface TempFileProvider { | ||
|
||
/** | ||
* Creates a tempFile. | ||
*/ | ||
File createTempFile() throws IOException; | ||
|
||
/** | ||
* Shutdown the tempFileProvider. | ||
*/ | ||
void shutdown(); | ||
} |
145 changes: 145 additions & 0 deletions
145
ebean-api/src/main/java/io/ebean/config/WeakRefTempFileProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package io.ebean.config; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.lang.ref.ReferenceQueue; | ||
import java.lang.ref.WeakReference; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* WeakRefTempFileProvider will delete the tempFile if all references to the returned File | ||
* object are collected by the garbage collection. | ||
* | ||
* @author Roland Praml, FOCONIS AG | ||
* | ||
*/ | ||
public class WeakRefTempFileProvider implements TempFileProvider { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(WeakRefTempFileProvider.class); | ||
|
||
private final ReferenceQueue<File> tempFiles = new ReferenceQueue<>(); | ||
|
||
private WeakFileReference root; | ||
|
||
private final String prefix; | ||
private final String suffix; | ||
private final File directory; | ||
|
||
/** | ||
* We hold a linkedList of weak references. So we can remove stale files in O(1) | ||
* | ||
* @author Roland Praml, FOCONIS AG | ||
*/ | ||
private static class WeakFileReference extends WeakReference<File> { | ||
|
||
String path; | ||
WeakFileReference prev; | ||
WeakFileReference next; | ||
|
||
WeakFileReference(File referent, ReferenceQueue<? super File> q) { | ||
super(referent, q); | ||
path = referent.getAbsolutePath(); | ||
} | ||
|
||
boolean delete(boolean shutdown) { | ||
File file = new File(path); | ||
if (!file.exists()) { | ||
logger.trace("already deleted {}", path); | ||
return true; | ||
} else if (file.delete()) { | ||
logger.trace("deleted {}", path); | ||
return true; | ||
} else { | ||
if (shutdown) { | ||
logger.warn("could not delete {}", path); | ||
} else { | ||
logger.info("could not delete {} - will delete on shutdown", path); | ||
} | ||
return false; | ||
} | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Creates the TempFileProvider with default prefix "db-". | ||
*/ | ||
public WeakRefTempFileProvider() { | ||
this("db-", null, null); | ||
} | ||
|
||
/** | ||
* Creates the TempFileProvider. | ||
*/ | ||
public WeakRefTempFileProvider(String prefix, String suffix, File directory) { | ||
this.prefix = prefix; | ||
this.suffix = suffix; | ||
this.directory = directory; | ||
} | ||
|
||
@Override | ||
public File createTempFile() throws IOException { | ||
File tempFile = File.createTempFile(prefix, suffix, directory); | ||
logger.trace("createTempFile: {}", tempFile); | ||
synchronized (this) { | ||
add(new WeakFileReference(tempFile, tempFiles)); | ||
} | ||
return tempFile; | ||
} | ||
|
||
/** | ||
* Will delete stale files. | ||
* This is public to use in tests. | ||
*/ | ||
public void deleteStaleTempFiles() { | ||
synchronized (this) { | ||
deleteStaleTempFilesInternal(); | ||
} | ||
} | ||
|
||
private void deleteStaleTempFilesInternal() { | ||
WeakFileReference ref; | ||
while ((ref = (WeakFileReference) tempFiles.poll()) != null) { | ||
if (ref.delete(false)) { | ||
remove(ref); // remove from linkedList only, if delete was successful. | ||
} | ||
} | ||
} | ||
|
||
private void add(WeakFileReference ref) { | ||
deleteStaleTempFilesInternal(); | ||
|
||
if (root == null) { | ||
root = ref; | ||
} else { | ||
ref.next = root; | ||
root.prev = ref; | ||
root = ref; | ||
} | ||
} | ||
|
||
private void remove(WeakFileReference ref) { | ||
if (ref.next != null) { | ||
ref.next.prev = ref.prev; | ||
} | ||
if (ref.prev != null) { | ||
ref.prev.next = ref.next; | ||
} else { | ||
root = ref.next; | ||
} | ||
} | ||
|
||
/** | ||
* Deletes all created files on shutdown. | ||
*/ | ||
@Override | ||
public void shutdown() { | ||
while (root != null) { | ||
root.delete(true); | ||
root = root.next; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.