Skip to content

Commit

Permalink
trying a watcher service out
Browse files Browse the repository at this point in the history
  • Loading branch information
barmintor committed Apr 5, 2013
1 parent 6fe9331 commit a028cd0
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Expand Up @@ -76,6 +76,11 @@
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/fcrepo/federation/bagit/BagItConnector.java
Expand Up @@ -202,5 +202,9 @@ public void updateDocument(DocumentChanges documentChanges) {
// TODO Auto-generated method stub

}

File getBagItDirectory() {
return this.directory;
}

}
161 changes: 161 additions & 0 deletions src/main/java/org/fcrepo/federation/bagit/BagItWatchService.java
@@ -0,0 +1,161 @@
package org.fcrepo.federation.bagit;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;

public class BagItWatchService implements WatchService {

private static final Logger logger = LoggerFactory.getLogger(BagItWatchService.class);

static final Pattern MANIFEST = Pattern.compile("^manifest-([^\\.]+).txt$");
static final Pattern TAG_MANIFEST = Pattern.compile("^tagmanifest-([^\\.]+).txt$");

static GetFilesFromManifest getFilesFromManifest = new GetFilesFromManifest();

WatchService delegate;

Collection<Path> tagFiles = new ArrayList<Path>();

Collection<Path> manifests = new ArrayList<Path>();

BagItWatchService() throws IOException {
delegate = FileSystems.getDefault().newWatchService();
}

public BagItWatchService(File bagItDir) throws IOException {
this();
for (File file: bagItDir.listFiles()) {
if (isManifest(file)) {
monitorManifest(file);
} else if (isTagManifest(file)) {
for (File listedFile: getFilesFromManifest.apply(file)) monitorTagFile(listedFile);
}
}
}

@Override
public void close() throws IOException {
delegate.close();
}

@Override
public WatchKey poll() {
return delegate.poll();
}

@Override
public WatchKey poll(long timeout, TimeUnit unit)
throws InterruptedException {
return delegate.poll(timeout, unit);
}

@Override
public WatchKey take() throws InterruptedException {
return delegate.take();
}

public void monitorTagFile(File input) throws IOException {
Path path = Paths.get(input.toURI());
if (!tagFiles.contains(path)) tagFiles.add(path);
path.register(this, ENTRY_MODIFY);
}

public void monitorManifest(File input) throws IOException {
Path path = Paths.get(input.toURI());
if (!manifests.contains(path)) manifests.add(path);
path.register(this, ENTRY_MODIFY);
}

boolean isManifest(String fileName) {
Matcher m = MANIFEST.matcher(fileName);
if (m.find()) {
String csa = m.group(1);
try {
MessageDigest.getInstance(csa);
return true;
} catch (NoSuchAlgorithmException e) {
logger.warn("Ignoring potential manifest file {} because {} is not a supported checksum algorithm.", fileName, csa);
}
}
return false;
}

boolean isManifest(File file) {
if (file.isFile() && file.canRead() && !file.isHidden()) {
return(isManifest(file.getName()));
} else return false;
}

boolean isManifest(Path path) {
return isManifest(path.toFile());
}

boolean isTagManifest(String fileName) {
Matcher m = TAG_MANIFEST.matcher(fileName);
if (m.find()) {
String csa = m.group(1);
try {
MessageDigest.getInstance(csa);
return true;
} catch (NoSuchAlgorithmException e) {
logger.warn("Ignoring potential tag-manifest file {} because {} is not a supported checksum algorithm.", fileName, csa);
}
}
return false;
}

boolean isTagManifest(File file) {
if (file.isFile() && file.canRead() && !file.isHidden()) {
return isTagManifest(file.getName());
} else return false;
}

boolean isTagManifest(Path path) {
return isManifest(path.toFile());
}

static class GetFilesFromManifest implements Function<File, Collection<File>> {

@Override
public Collection<File> apply(File input) {
try {
ArrayList<File> result = new ArrayList<File>();
LineNumberReader lnr = new LineNumberReader(new FileReader(input));
String line = null;
while((line = lnr.readLine()) != null) {
File file = new File(input.getParentFile(), line);
result.add(file);
}
return result;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

}

}
48 changes: 48 additions & 0 deletions src/main/java/org/fcrepo/federation/bagit/ManifestMonitor.java
@@ -0,0 +1,48 @@
package org.fcrepo.federation.bagit;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.util.List;

public class ManifestMonitor implements Runnable {

private BagItConnector connector;

private BagItWatchService watchService;

private boolean run;

public ManifestMonitor(BagItConnector connector) throws IOException {
this.connector = connector;
this.watchService = new BagItWatchService(connector.getBagItDirectory());
}

@Override
public void run() {
while(!Thread.interrupted()) {
WatchKey key = watchService.poll();
List<WatchEvent<?>> events = key.pollEvents();
boolean manifest = false;
boolean tagManifest = false;
Path path;
for (WatchEvent<?> event: events) {
Path context = (Path)event.context();
if (watchService.isManifest(context)) {
manifest = true;
path= context;
} else if (watchService.isTagManifest(context)) {
tagManifest = true;
path= context;
}
}
if (manifest) {
//connector.manifestChanged(path.toFile());
} else if (tagManifest) {
//connector.tagFileChanged(path.toFile());
}
}
}

}
@@ -0,0 +1,50 @@
package org.fcrepo.federation.bagit;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class BagItWatchServiceTest {

@Test
public void testIsManifest() throws IOException {
File input = mock(File.class);
when(input.isFile()).thenReturn(true);
when(input.canRead()).thenReturn(true);

BagItWatchService test = new BagItWatchService();
String fname = "not-a-manifest.txt";
when(input.getName()).thenReturn(fname);
assertFalse("\"" + fname + "\" should not be a valid manifest file", test.isManifest(input));
fname = "manifest-md5.txt";
when(input.getName()).thenReturn(fname);
assertTrue("\"" + fname + "\" should be a valid manifest file", test.isManifest(input));
fname = "manifest-foobar.txt";
when(input.getName()).thenReturn(fname);
assertFalse("Unexpected checksum algorithm \"foobar\" returned valid manifest", test.isManifest(input));
}

@Test
public void testIsTagManifest() throws IOException {
File input = mock(File.class);
when(input.isFile()).thenReturn(true);
when(input.canRead()).thenReturn(true);

BagItWatchService test = new BagItWatchService();
String fname = "not-a-manifest.txt";
when(input.getName()).thenReturn(fname);
assertFalse("\"" + fname + "\" should not be a valid manifest file", test.isTagManifest(input));
fname = "tagmanifest-md5.txt";
when(input.getName()).thenReturn(fname);
assertTrue("\"" + fname + "\" should be a valid manifest file", test.isTagManifest(input));
fname = "tagmanifest-foobar.txt";
when(input.getName()).thenReturn(fname);
assertFalse("Unexpected checksum algorithm \"foobar\" returned valid manifest", test.isTagManifest(input));
}
}

0 comments on commit a028cd0

Please sign in to comment.