Symlinker.java
package doss.local;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import doss.NoSuchBlobException;
class Symlinker {
final private Path linkRoot;
final private boolean enabled;
Symlinker(final Path indexStorage) {
this.linkRoot = indexStorage;
enabled = !System.getProperty("os.name").startsWith("Windows");
}
public void link(long blobId, DirectoryContainer container, long offset) {
if (!enabled)
return;
Path link = resolveLinkPath(blobId);
Path target = container.dataPathFor(offset);
Path relativeTarget = link.getParent().relativize(target);
try {
Files.createSymbolicLink(link, relativeTarget);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void unlink(long blobId) throws NoSuchBlobException {
if (!enabled)
return;
Path link = resolveLinkPath(blobId);
// 8/8/13: check for any sym link created as blobId and/or
// blobId with an file extension
try (DirectoryStream<Path> matches = Files.newDirectoryStream(linkRoot,
"" + blobId + ".*")) {
boolean hasMatches = false;
for (Path entry : matches) {
hasMatches = true;
Files.delete(entry);
}
if (!hasMatches && !Files.exists(link)) {
throw new NoSuchBlobException(blobId);
}
if (Files.exists(link)) {
Files.delete(link);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void updateLinkPath(long blobId, String mimeExt) {
Path fromLinkPath = linkRoot.resolve(Long.toString(blobId) + ".jp2");
Path toLinkPath = linkRoot.resolve(Long.toString(blobId) + mimeExt);
fromLinkPath.toFile().renameTo(toLinkPath.toFile());
}
private Path resolveLinkPath(long blobId) {
// 8/8/13: a hack to enable iip srv to read jp2 image from Doss
// which require a file extension to be added to the sym link
// this will need be refactored later for the permanent solution
// for serving files to 3rd party apps from Doss
return linkRoot.resolve(Long.toString(blobId) + ".jp2");
}
}