├── README.txt ├── .gitignore ├── src ├── main │ └── java │ │ └── bbejeck │ │ └── nio │ │ ├── files │ │ ├── event │ │ │ ├── PathEventSubscriber.java │ │ │ └── PathEventContext.java │ │ ├── directory │ │ │ ├── event │ │ │ │ ├── DirectoryEventWatcher.java │ │ │ │ ├── PathEvent.java │ │ │ │ ├── DirectoryEventModule.java │ │ │ │ ├── DirectoryEventWatcherProvider.java │ │ │ │ ├── PathEvents.java │ │ │ │ └── DirectoryEventWatcherImpl.java │ │ │ ├── AsynchronousRecursiveDirectoryStream.java │ │ │ └── FileDirectoryStream.java │ │ └── visitor │ │ │ ├── CleanDirVisitor.java │ │ │ ├── DirFunctionVisitor.java │ │ │ ├── FunctionVisitor.java │ │ │ ├── DeleteDirVisitor.java │ │ │ ├── CopyDirVisitor.java │ │ │ └── CopyPredicateVisitor.java │ │ ├── channels │ │ ├── AsyncServerTestModule.java │ │ ├── guice │ │ │ ├── CustomCompletionHandler.java │ │ │ ├── EchoServer.java │ │ │ ├── GuiceAsyncDriver.java │ │ │ ├── AsynchronousServerModule.java │ │ │ ├── AsyncSocketServerGuiceExample.java │ │ │ └── EchoServerCompletionHandler.java │ │ ├── AsyncServerSocketNoCompletionHander.java │ │ ├── AsyncServerSocket.java │ │ └── AsyncSocketMessageSender.java │ │ ├── sockets │ │ ├── PlainSocketModule.java │ │ ├── PlainSocket.java │ │ ├── PlainSocketMessageSender.java │ │ └── PlainServerSocket.java │ │ ├── SocketModule.java │ │ ├── Host.java │ │ ├── Port.java │ │ ├── MessageCount.java │ │ ├── util │ │ ├── FilterBuilder.java │ │ ├── FileGenerator.java │ │ └── DirUtils.java │ │ ├── AsyncSocketTestDriver.java │ │ └── PlainSocketTestDriver.java └── test │ └── java │ └── bbejeck │ └── nio │ ├── files │ ├── directory │ │ ├── FileDirectoryStreamTest.java │ │ ├── AsynchronousRecursiveDirectoryStreamTest.java │ │ └── event │ │ │ ├── DirectoryEventWatcherGuiceTest.java │ │ │ └── DirectoryEventWatcherImplTest.java │ ├── FilesCopyMoveTest.java │ ├── BaseFileTest.java │ ├── watch │ │ └── WatchDirectoryTest.java │ ├── DirectoryStreamTest.java │ └── PathsTest.java │ ├── channels │ └── AsyncSocketServerComparisonTest.java │ └── util │ └── DirUtilsTest.java ├── License.txt └── pom.xml /README.txt: -------------------------------------------------------------------------------- 1 | Source code for the Java 7 java.nio.file blog series. 2 | Please note that the pom file needs to have the the property set for the path to Java 7 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/* 3 | *.iml 4 | *.ipr 5 | *.iws 6 | .idea/libraries 7 | test-files 8 | test-source-dir 9 | test-target-dir 10 | test.txt 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/event/PathEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.event; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 2/20/12 7 | * Time: 12:44 PM 8 | */ 9 | 10 | 11 | public interface PathEventSubscriber { 12 | 13 | void handlePathEvents(PathEventContext pathEventContext); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/DirectoryEventWatcher.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 2/15/12 9 | * Time: 10:29 PM 10 | */ 11 | 12 | public interface DirectoryEventWatcher { 13 | void start() throws IOException; 14 | 15 | boolean isRunning(); 16 | 17 | void stop(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/AsyncServerTestModule.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels; 2 | 3 | import com.google.inject.AbstractModule; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 3/15/12 9 | * Time: 10:35 PM 10 | */ 11 | 12 | public class AsyncServerTestModule extends AbstractModule { 13 | 14 | @Override 15 | protected void configure() { 16 | bind(AsyncServerSocket.class); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/sockets/PlainSocketModule.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.sockets; 2 | 3 | import com.google.inject.AbstractModule; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 3/10/12 9 | * Time: 12:57 PM 10 | */ 11 | public class PlainSocketModule extends AbstractModule { 12 | 13 | @Override 14 | protected void configure() { 15 | bind(PlainServerSocket.class); 16 | bind(PlainSocketMessageSender.class); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/event/PathEventContext.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.event; 2 | 3 | import bbejeck.nio.files.directory.event.PathEvent; 4 | 5 | import java.nio.file.Path; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * User: bbejeck 11 | * Date: 2/20/12 12 | * Time: 10:00 PM 13 | */ 14 | 15 | public interface PathEventContext { 16 | 17 | boolean isValid(); 18 | 19 | Path getWatchedDirectory(); 20 | 21 | List getEvents(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/CustomCompletionHandler.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import java.nio.channels.AsynchronousServerSocketChannel; 4 | import java.nio.channels.AsynchronousSocketChannel; 5 | import java.nio.channels.CompletionHandler; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * User: bbejeck 10 | * Date: 3/9/12 11 | * Time: 10:46 PM 12 | */ 13 | 14 | public interface CustomCompletionHandler extends CompletionHandler { 15 | void setSocketChannel(AsynchronousServerSocketChannel serverChannel); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/SocketModule.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import com.google.inject.AbstractModule; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 3/14/12 9 | * Time: 9:40 PM 10 | */ 11 | public class SocketModule extends AbstractModule { 12 | 13 | @Override 14 | protected void configure() { 15 | bind(String.class).annotatedWith(Host.class).toInstance("localhost"); 16 | bind(int.class).annotatedWith(MessageCount.class).toInstance(10000); 17 | bind(int.class).annotatedWith(Port.class).toInstance(8080); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/Host.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import com.google.inject.BindingAnnotation; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.ElementType.FIELD; 9 | import static java.lang.annotation.ElementType.METHOD; 10 | import static java.lang.annotation.ElementType.PARAMETER; 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/14/12 17 | * Time: 9:44 PM 18 | */ 19 | @BindingAnnotation 20 | @Target({ FIELD, PARAMETER, METHOD }) 21 | @Retention(RUNTIME) 22 | public @interface Host { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/Port.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import com.google.inject.BindingAnnotation; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.ElementType.FIELD; 9 | import static java.lang.annotation.ElementType.METHOD; 10 | import static java.lang.annotation.ElementType.PARAMETER; 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/14/12 17 | * Time: 9:41 PM 18 | */ 19 | @BindingAnnotation 20 | @Target({ FIELD, PARAMETER, METHOD }) 21 | @Retention(RUNTIME) 22 | public @interface Port { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/MessageCount.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import com.google.inject.BindingAnnotation; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.ElementType.FIELD; 9 | import static java.lang.annotation.ElementType.METHOD; 10 | import static java.lang.annotation.ElementType.PARAMETER; 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/14/12 17 | * Time: 9:43 PM 18 | */ 19 | @BindingAnnotation 20 | @Target({ FIELD, PARAMETER, METHOD }) 21 | @Retention(RUNTIME) 22 | public @interface MessageCount { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/EchoServer.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import com.google.inject.BindingAnnotation; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | import static java.lang.annotation.ElementType.PARAMETER; 6 | import static java.lang.annotation.ElementType.FIELD; 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 3/8/12 15 | * Time: 10:19 PM 16 | */ 17 | @BindingAnnotation 18 | @Target({ FIELD, PARAMETER, METHOD }) 19 | @Retention(RUNTIME) 20 | public @interface EchoServer { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/sockets/PlainSocket.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.sockets; 2 | 3 | import com.google.inject.BindingAnnotation; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.ElementType.FIELD; 9 | import static java.lang.annotation.ElementType.METHOD; 10 | import static java.lang.annotation.ElementType.PARAMETER; 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/10/12 17 | * Time: 12:58 PM 18 | */ 19 | @BindingAnnotation 20 | @Target({ FIELD, PARAMETER, METHOD }) 21 | @Retention(RUNTIME) 22 | public @interface PlainSocket { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/PathEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import java.nio.file.Path; 4 | import java.nio.file.WatchEvent; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * User: bbejeck 9 | * Date: 2/20/12 10 | * Time: 12:44 PM 11 | */ 12 | 13 | public class PathEvent { 14 | private final Path eventTarget; 15 | private final WatchEvent.Kind type; 16 | 17 | PathEvent(Path eventTarget, WatchEvent.Kind type) { 18 | this.eventTarget = eventTarget; 19 | this.type = type; 20 | } 21 | 22 | public Path getEventTarget() { 23 | return eventTarget; 24 | } 25 | 26 | public WatchEvent.Kind getType() { 27 | return type; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/CleanDirVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.FileVisitResult; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.SimpleFileVisitor; 8 | import java.nio.file.attribute.BasicFileAttributes; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * User: bbejeck 13 | * Date: 1/22/12 14 | * Time: 12:48 PM 15 | */ 16 | 17 | public class CleanDirVisitor extends SimpleFileVisitor { 18 | @Override 19 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 20 | Files.delete(file); 21 | return FileVisitResult.CONTINUE; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/DirectoryEventModule.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | import com.google.inject.AbstractModule; 5 | import com.google.inject.Singleton; 6 | import com.google.inject.matcher.Matchers; 7 | import com.google.inject.name.Names; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * User: bbejeck 12 | * Date: 2/25/12 13 | * Time: 9:30 PM 14 | */ 15 | 16 | public class DirectoryEventModule extends AbstractModule { 17 | 18 | @Override 19 | protected void configure() { 20 | bind(EventBus.class).in(Singleton.class); 21 | bind(String.class).annotatedWith(Names.named("START_PATH")).toInstance("test-files"); 22 | bind(DirectoryEventWatcher.class).toProvider(DirectoryEventWatcherProvider.class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/GuiceAsyncDriver.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import com.google.common.base.Stopwatch; 4 | import com.google.inject.Guice; 5 | import com.google.inject.Injector; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * User: bbejeck 10 | * Date: 3/9/12 11 | * Time: 10:01 PM 12 | */ 13 | public class GuiceAsyncDriver { 14 | 15 | public static void main(String[] args) throws Exception { 16 | Injector injector = Guice.createInjector(new AsynchronousServerModule()); 17 | AsyncSocketServerGuiceExample socketServer = injector.getInstance(AsyncSocketServerGuiceExample.class); 18 | System.out.println("Starting the EchoSever"); 19 | Stopwatch stopwatch = new Stopwatch().start(); 20 | socketServer.runServer(); 21 | stopwatch.stop(); 22 | System.out.println("EchoServer is done in "+stopwatch.elapsedMillis()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/DirFunctionVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | import com.google.common.base.Function; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.FileVisitResult; 7 | import java.nio.file.Path; 8 | import java.nio.file.SimpleFileVisitor; 9 | import java.nio.file.attribute.BasicFileAttributes; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 2/15/12 15 | * Time: 10:47 PM 16 | */ 17 | 18 | public class DirFunctionVisitor extends SimpleFileVisitor { 19 | 20 | private Function directoryFunction; 21 | 22 | public DirFunctionVisitor(Function directoryFunction) { 23 | this.directoryFunction = directoryFunction; 24 | } 25 | 26 | @Override 27 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 28 | return directoryFunction.apply(dir); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/FunctionVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | 4 | import com.google.common.base.Function; 5 | 6 | import java.io.IOException; 7 | import java.nio.file.FileVisitOption; 8 | import java.nio.file.FileVisitResult; 9 | import java.nio.file.Path; 10 | import java.nio.file.SimpleFileVisitor; 11 | import java.nio.file.attribute.BasicFileAttributes; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 1/28/12 17 | * Time: 9:07 PM 18 | */ 19 | 20 | public class FunctionVisitor extends SimpleFileVisitor { 21 | 22 | Function pathFunction; 23 | 24 | public FunctionVisitor(Function pathFunction) { 25 | this.pathFunction = pathFunction; 26 | } 27 | 28 | @Override 29 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 30 | return pathFunction.apply(file); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/DirectoryEventWatcherProvider.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | import com.google.inject.Inject; 5 | import com.google.inject.Provider; 6 | import com.google.inject.name.Named; 7 | 8 | import java.nio.file.Paths; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * User: bbejeck 13 | * Date: 2/25/12 14 | * Time: 9:19 PM 15 | */ 16 | 17 | public class DirectoryEventWatcherProvider implements Provider { 18 | 19 | private EventBus eventBus; 20 | private String startPath; 21 | 22 | 23 | @Inject 24 | public DirectoryEventWatcherProvider(EventBus eventBus, @Named("START_PATH") String startPath) { 25 | this.eventBus = eventBus; 26 | this.startPath = startPath; 27 | } 28 | 29 | @Override 30 | public DirectoryEventWatcher get() { 31 | return new DirectoryEventWatcherImpl(eventBus, Paths.get(startPath)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/DeleteDirVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.FileVisitResult; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.SimpleFileVisitor; 8 | import java.nio.file.attribute.BasicFileAttributes; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * User: bbejeck 13 | * Date: 1/23/12 14 | * Time: 10:16 PM 15 | */ 16 | 17 | public class DeleteDirVisitor extends SimpleFileVisitor { 18 | 19 | @Override 20 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 21 | Files.delete(file); 22 | return FileVisitResult.CONTINUE; 23 | } 24 | 25 | @Override 26 | public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { 27 | if(exc == null){ 28 | Files.delete(dir); 29 | return FileVisitResult.CONTINUE; 30 | } 31 | throw exc; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/AsynchronousServerModule.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import com.google.inject.AbstractModule; 4 | 5 | import java.util.concurrent.CountDownLatch; 6 | import java.util.concurrent.ExecutorService; 7 | import java.util.concurrent.Executors; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * User: bbejeck 12 | * Date: 3/6/12 13 | * Time: 10:24 PM 14 | */ 15 | public class AsynchronousServerModule extends AbstractModule { 16 | private CountDownLatch doneSignal = new CountDownLatch(1); 17 | private ExecutorService executorService = Executors.newFixedThreadPool(25); 18 | 19 | @Override 20 | protected void configure() { 21 | bind(CountDownLatch.class).annotatedWith(EchoServer.class).toInstance(doneSignal); 22 | bind(int.class).annotatedWith(EchoServer.class).toInstance(5000); 23 | bind(ExecutorService.class).annotatedWith(EchoServer.class).toInstance(executorService); 24 | bind(CustomCompletionHandler.class).annotatedWith(EchoServer.class).to(EchoServerCompletionHandler.class); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Bill Bejeck 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/PathEvents.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import bbejeck.nio.files.directory.event.PathEvent; 4 | import bbejeck.nio.files.event.PathEventContext; 5 | 6 | import java.nio.file.Path; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 2/20/12 15 | * Time: 2:05 PM 16 | */ 17 | public class PathEvents implements PathEventContext { 18 | 19 | private final List pathEvents = new ArrayList<>(); 20 | private final Path watchedDirectory; 21 | private final boolean isValid; 22 | 23 | PathEvents(boolean valid, Path watchedDirectory) { 24 | isValid = valid; 25 | this.watchedDirectory = watchedDirectory; 26 | } 27 | 28 | @Override 29 | public boolean isValid(){ 30 | return isValid; 31 | } 32 | 33 | @Override 34 | public Path getWatchedDirectory(){ 35 | return watchedDirectory; 36 | } 37 | 38 | @Override 39 | public List getEvents() { 40 | return Collections.unmodifiableList(pathEvents); 41 | } 42 | 43 | public void add(PathEvent pathEvent) { 44 | pathEvents.add(pathEvent); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/util/FilterBuilder.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.util; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.DirectoryStream; 5 | import java.nio.file.FileSystems; 6 | import java.nio.file.Path; 7 | import java.nio.file.PathMatcher; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * User: bbejeck 12 | * Date: 2/2/12 13 | * Time: 11:46 PM 14 | */ 15 | 16 | public class FilterBuilder { 17 | 18 | private FilterBuilder() {} 19 | 20 | public static DirectoryStream.Filter buildGlobFilter(String pattern) { 21 | final PathMatcher pathMatcher = getPathMatcher("glob:"+pattern); 22 | return new DirectoryStream.Filter() { 23 | @Override 24 | public boolean accept(Path entry) throws IOException { 25 | return pathMatcher.matches(entry); 26 | } 27 | }; 28 | } 29 | 30 | public static DirectoryStream.Filter buildRegexFilter(String pattern) { 31 | final PathMatcher pathMatcher = getPathMatcher("regex:"+pattern); 32 | return new DirectoryStream.Filter() { 33 | @Override 34 | public boolean accept(Path entry) throws IOException { 35 | return pathMatcher.matches(entry); 36 | } 37 | }; 38 | } 39 | 40 | 41 | private static PathMatcher getPathMatcher(String pattern) { 42 | return FileSystems.getDefault().getPathMatcher(pattern); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/CopyDirVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.*; 5 | import java.nio.file.attribute.BasicFileAttributes; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * User: bbejeck 10 | * Date: 1/23/12 11 | * Time: 10:29 PM 12 | */ 13 | public class CopyDirVisitor extends SimpleFileVisitor { 14 | 15 | private Path fromPath; 16 | private Path toPath; 17 | private StandardCopyOption copyOption; 18 | 19 | 20 | public CopyDirVisitor(Path fromPath, Path toPath, StandardCopyOption copyOption) { 21 | this.fromPath = fromPath; 22 | this.toPath = toPath; 23 | this.copyOption = copyOption; 24 | } 25 | 26 | public CopyDirVisitor(Path fromPath, Path toPath) { 27 | this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING); 28 | } 29 | 30 | @Override 31 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 32 | 33 | Path targetPath = toPath.resolve(fromPath.relativize(dir)); 34 | if(!Files.exists(targetPath)){ 35 | Files.createDirectory(targetPath); 36 | } 37 | return FileVisitResult.CONTINUE; 38 | } 39 | 40 | @Override 41 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 42 | 43 | Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption); 44 | return FileVisitResult.CONTINUE; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/util/FileGenerator.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.util; 2 | 3 | import java.io.PrintWriter; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * User: bbejeck 11 | * Date: 1/14/12 12 | * Time: 12:27 PM 13 | */ 14 | 15 | public class FileGenerator { 16 | private static final String LINE_OF_TEXT = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do " + 17 | "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad " + 18 | "minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + 19 | "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit" + 20 | " esse cillum dolore eu fugiat nulla pariatur. " + 21 | "Excepteur sint occaecat cupidatat non proident, sunt " + 22 | "in culpa qui officia deserunt mollit anim id est laborum."; 23 | 24 | private FileGenerator(){} 25 | 26 | 27 | public static void generate(Path path, int lines) throws Exception { 28 | try(PrintWriter printWriter = new PrintWriter(Files.newBufferedWriter(path, Charset.defaultCharset()))){ 29 | for(int i = 0; i< lines; i++){ 30 | printWriter.println(LINE_OF_TEXT); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/visitor/CopyPredicateVisitor.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.visitor; 2 | 3 | import com.google.common.base.Predicate; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.FileVisitResult; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.SimpleFileVisitor; 10 | import java.nio.file.attribute.BasicFileAttributes; 11 | 12 | /** 13 | * Created by IntelliJ IDEA. 14 | * User: bbejeck 15 | * Date: 1/29/12 16 | * Time: 10:11 PM 17 | */ 18 | public class CopyPredicateVisitor extends SimpleFileVisitor { 19 | 20 | private Path fromPath; 21 | private Path toPath; 22 | private Predicate copyPredicate; 23 | 24 | public CopyPredicateVisitor(Path fromPath, Path toPath, Predicate copyPredicate) { 25 | this.fromPath = fromPath; 26 | this.toPath = toPath; 27 | this.copyPredicate = copyPredicate; 28 | } 29 | 30 | @Override 31 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 32 | if (copyPredicate.apply(dir)) { 33 | Path targetPath = toPath.resolve(fromPath.relativize(dir)); 34 | if (!Files.exists(targetPath)) { 35 | Files.createDirectory(targetPath); 36 | } 37 | return FileVisitResult.CONTINUE; 38 | } 39 | return FileVisitResult.SKIP_SUBTREE; 40 | } 41 | 42 | @Override 43 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 44 | Files.copy(file, toPath.resolve(fromPath.relativize(file))); 45 | return FileVisitResult.CONTINUE; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/AsyncSocketTestDriver.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import bbejeck.nio.channels.AsyncServerSocket; 4 | import bbejeck.nio.channels.AsyncServerTestModule; 5 | import bbejeck.nio.sockets.PlainSocketMessageSender; 6 | import bbejeck.nio.sockets.PlainSocketModule; 7 | import com.google.common.base.Stopwatch; 8 | import com.google.inject.Guice; 9 | import com.google.inject.Injector; 10 | 11 | import java.util.concurrent.Callable; 12 | import java.util.concurrent.FutureTask; 13 | 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 3/14/12 19 | * Time: 9:48 PM 20 | */ 21 | public class AsyncSocketTestDriver { 22 | 23 | 24 | public static void main(String[] args) throws Exception { 25 | Injector injector = Guice.createInjector(new SocketModule(), new PlainSocketModule(), new AsyncServerTestModule()); 26 | PlainSocketMessageSender messageSender = injector.getInstance(PlainSocketMessageSender.class); 27 | final AsyncServerSocket asyncServerSocket = injector.getInstance(AsyncServerSocket.class); 28 | FutureTask asyncFutureTask = new FutureTask<>(new Callable() { 29 | @Override 30 | public Long call() throws Exception { 31 | Stopwatch stopwatch = new Stopwatch(); 32 | stopwatch.start(); 33 | asyncServerSocket.startServer(); 34 | stopwatch.stop(); 35 | return stopwatch.elapsedMillis(); 36 | } 37 | }); 38 | System.out.println("Starting the AsyncSocketServer Test"); 39 | new Thread(asyncFutureTask).start(); 40 | long sleepTime = 50; 41 | Thread.sleep(sleepTime); 42 | messageSender.sendMessages(); 43 | Long time = asyncFutureTask.get(); 44 | System.out.println("AsyncServer processed [10000] messages in " + (time - sleepTime) + " millis"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/PlainSocketTestDriver.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio; 2 | 3 | import bbejeck.nio.channels.AsyncServerTestModule; 4 | import bbejeck.nio.sockets.PlainServerSocket; 5 | import bbejeck.nio.sockets.PlainSocketMessageSender; 6 | import bbejeck.nio.sockets.PlainSocketModule; 7 | import com.google.common.base.Stopwatch; 8 | import com.google.inject.Guice; 9 | import com.google.inject.Injector; 10 | 11 | import java.util.concurrent.Callable; 12 | import java.util.concurrent.FutureTask; 13 | 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 3/14/12 19 | * Time: 9:48 PM 20 | */ 21 | public class PlainSocketTestDriver { 22 | 23 | 24 | public static void main(String[] args) throws Exception { 25 | Injector injector = Guice.createInjector(new SocketModule(), new PlainSocketModule(), new AsyncServerTestModule()); 26 | PlainSocketMessageSender messageSender = injector.getInstance(PlainSocketMessageSender.class); 27 | System.out.println("Starting the PlainSocketServer Test"); 28 | final PlainServerSocket plainServerSocket = injector.getInstance(PlainServerSocket.class); 29 | FutureTask plainFutureTask = new FutureTask<>(new Callable() { 30 | @Override 31 | public Long call() throws Exception { 32 | Stopwatch stopwatch = new Stopwatch(); 33 | stopwatch.start(); 34 | plainServerSocket.startServer(); 35 | stopwatch.stop(); 36 | return stopwatch.elapsedMillis(); 37 | } 38 | }); 39 | 40 | new Thread(plainFutureTask).start(); 41 | long sleepTime = 50; 42 | Thread.sleep(sleepTime); 43 | messageSender.sendMessages(); 44 | Long time = plainFutureTask.get(); 45 | System.out.println("PlainSocketServer processed [10000] messages in " + (time - sleepTime) + " millis"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/sockets/PlainSocketMessageSender.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.sockets; 2 | 3 | import bbejeck.nio.Host; 4 | import bbejeck.nio.MessageCount; 5 | import bbejeck.nio.Port; 6 | import com.google.inject.Inject; 7 | 8 | import java.io.BufferedReader; 9 | import java.io.BufferedWriter; 10 | import java.io.InputStreamReader; 11 | import java.io.OutputStreamWriter; 12 | import java.net.InetSocketAddress; 13 | import java.net.Socket; 14 | import java.nio.CharBuffer; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * User: bbejeck 19 | * Date: 3/10/12 20 | * Time: 1:18 PM 21 | */ 22 | public class PlainSocketMessageSender { 23 | 24 | private Socket socket; 25 | private int port; 26 | private InetSocketAddress socketAddress; 27 | private int messageCount; 28 | 29 | @Inject 30 | public PlainSocketMessageSender(@Port int port, @MessageCount int messageCount, @Host String host) { 31 | this.port = port; 32 | socketAddress = new InetSocketAddress(host, port); 33 | this.messageCount = messageCount; 34 | } 35 | 36 | public void sendMessages() throws Exception { 37 | for (int i = 0; i < messageCount; i++) { 38 | sendTextMessage("Plain text message from socket"); 39 | } 40 | sendTextMessage("quit"); 41 | } 42 | 43 | private void sendTextMessage(String message) throws Exception { 44 | socket = new Socket(); 45 | socket.connect(socketAddress); 46 | BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 47 | bufferedWriter.write(message); 48 | bufferedWriter.flush(); 49 | BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 50 | CharBuffer charBuffer = CharBuffer.allocate(1000); 51 | reader.read(charBuffer); 52 | charBuffer.flip(); 53 | // System.out.println("Reply from server "+charBuffer.toString()); 54 | reader.close(); 55 | bufferedWriter.close(); 56 | socket.close(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/directory/FileDirectoryStreamTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory; 2 | 3 | import bbejeck.nio.files.BaseFileTest; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.util.Iterator; 9 | 10 | import static org.hamcrest.CoreMatchers.is; 11 | import static org.junit.Assert.assertThat; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 2/12/12 17 | * Time: 10:38 PM 18 | */ 19 | 20 | 21 | public class FileDirectoryStreamTest extends BaseFileTest { 22 | private int expectedJavaFileCount; 23 | private int expectedTotalFileCount; 24 | 25 | @Before 26 | public void setUp() throws Exception { 27 | super.setUp(); 28 | expectedJavaFileCount = fakeJavaFiles.length * 3; 29 | expectedTotalFileCount = expectedJavaFileCount + textFileNames.length + 1; 30 | } 31 | 32 | @Test 33 | public void testGlob() throws Exception { 34 | File baseDir = basePath.toFile(); 35 | FileDirectoryStream directoryStream = new FileDirectoryStream(".*", baseDir); 36 | Iterator fileIterator = directoryStream.glob(); 37 | int fileCount = 0; 38 | while (fileIterator.hasNext()) { 39 | File f = fileIterator.next(); 40 | if (f.isFile()) { 41 | fileCount++; 42 | } 43 | } 44 | directoryStream.close(); 45 | assertThat(fileCount, is(expectedTotalFileCount)); 46 | } 47 | 48 | @Test 49 | public void testGlobJavaFiles() throws Exception { 50 | File baseDir = basePath.toFile(); 51 | FileDirectoryStream directoryStream = new FileDirectoryStream(".*\\.java$", baseDir); 52 | Iterator fileIterator = directoryStream.glob(); 53 | int fileCount = 0; 54 | while (fileIterator.hasNext()) { 55 | File f = fileIterator.next(); 56 | if (f.isFile()) { 57 | fileCount++; 58 | } 59 | } 60 | directoryStream.close(); 61 | assertThat(fileCount, is(expectedJavaFileCount)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/AsyncSocketServerGuiceExample.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import com.google.inject.Inject; 4 | 5 | import java.io.IOException; 6 | import java.net.InetSocketAddress; 7 | import java.nio.channels.AsynchronousChannelGroup; 8 | import java.nio.channels.AsynchronousServerSocketChannel; 9 | import java.util.Objects; 10 | import java.util.concurrent.CountDownLatch; 11 | import java.util.concurrent.ExecutorService; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/8/12 17 | * Time: 10:16 PM 18 | */ 19 | public class AsyncSocketServerGuiceExample { 20 | 21 | private CustomCompletionHandler completionHandler; 22 | private InetSocketAddress inetSocketAddress; 23 | private CountDownLatch doneSignal; 24 | private AsynchronousChannelGroup channelGroup; 25 | private AsynchronousServerSocketChannel server; 26 | private ExecutorService executorService; 27 | 28 | @Inject 29 | public AsyncSocketServerGuiceExample(@EchoServer CustomCompletionHandler completionHandler, 30 | @EchoServer int socketAddressPort, 31 | @EchoServer CountDownLatch doneSignal, 32 | @EchoServer ExecutorService executorService) throws IOException { 33 | 34 | this.completionHandler = Objects.requireNonNull(completionHandler); 35 | this.inetSocketAddress = new InetSocketAddress(socketAddressPort); 36 | this.doneSignal = Objects.requireNonNull(doneSignal); 37 | this.executorService = executorService; 38 | this.channelGroup = AsynchronousChannelGroup.withThreadPool(Objects.requireNonNull(executorService)); 39 | } 40 | 41 | public void runServer() throws Exception { 42 | server = AsynchronousServerSocketChannel.open(channelGroup); 43 | completionHandler.setSocketChannel(server); 44 | server.bind(inetSocketAddress); 45 | server.accept("AsyncServer", completionHandler); 46 | waitForQuit(); 47 | } 48 | 49 | private void waitForQuit() { 50 | try { 51 | doneSignal.await(); 52 | System.out.println("DoneSignal called"); 53 | channelGroup.shutdown(); 54 | executorService.shutdownNow(); 55 | } catch (InterruptedException e) { 56 | Thread.currentThread().interrupt(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/AsyncServerSocketNoCompletionHander.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels; 2 | 3 | import com.google.common.base.Stopwatch; 4 | 5 | import java.net.InetSocketAddress; 6 | import java.nio.ByteBuffer; 7 | import java.nio.channels.AsynchronousChannelGroup; 8 | import java.nio.channels.AsynchronousServerSocketChannel; 9 | import java.nio.channels.AsynchronousSocketChannel; 10 | import java.util.concurrent.ExecutionException; 11 | import java.util.concurrent.Executors; 12 | import java.util.concurrent.Future; 13 | 14 | /** 15 | * Created by IntelliJ IDEA. 16 | * User: bbejeck 17 | * Date: 3/4/12 18 | * Time: 10:25 PM 19 | */ 20 | public class AsyncServerSocketNoCompletionHander { 21 | 22 | static int count = 0; 23 | static AsynchronousChannelGroup channelGroup; 24 | 25 | public static void main(String[] args) throws Exception { 26 | channelGroup = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(5)); 27 | final AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(channelGroup); 28 | server.bind(new InetSocketAddress(5000)); 29 | Stopwatch stopwatch = new Stopwatch().start(); 30 | while (!channelGroup.isShutdown()) { 31 | AsynchronousSocketChannel socket = server.accept().get(); 32 | processConnection(socket); 33 | } 34 | stopwatch.stop(); 35 | System.out.println("EchoServer is done in " + stopwatch.elapsedMillis()); 36 | } 37 | 38 | private static void processConnection(AsynchronousSocketChannel socket) { 39 | ByteBuffer byteBuffer = ByteBuffer.allocate(1000); 40 | Future read = socket.read(byteBuffer); 41 | int totalBytes = 0; 42 | try { 43 | totalBytes = read.get(); 44 | } catch (InterruptedException | ExecutionException e) { 45 | e.printStackTrace(); 46 | } 47 | //TODO use charset encoders here USE UTF8 48 | byteBuffer.flip(); 49 | byte[] bytes = new byte[totalBytes]; 50 | if (bytes.length > 0) { 51 | byteBuffer.get(bytes, 0, totalBytes); 52 | String message = new String(bytes); 53 | System.out.println(Thread.currentThread().getName()); 54 | System.out.println("Message " + message); 55 | if (message.equals("quit")) { 56 | quit(); 57 | } 58 | } 59 | } 60 | 61 | private static void quit() { 62 | channelGroup.shutdown(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/channels/AsyncSocketServerComparisonTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels; 2 | 3 | import bbejeck.nio.sockets.PlainServerSocket; 4 | import bbejeck.nio.sockets.PlainSocketMessageSender; 5 | import com.google.common.base.Stopwatch; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | 9 | import java.util.concurrent.Callable; 10 | import java.util.concurrent.FutureTask; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 3/15/12 17 | * Time: 11:27 PM 18 | */ 19 | @Ignore 20 | public class AsyncSocketServerComparisonTest { 21 | 22 | 23 | @Test 24 | public void testAsyncSocketServer() throws Exception { 25 | PlainSocketMessageSender messageSender = new PlainSocketMessageSender(5000,10000,"localhost"); 26 | final AsyncServerSocket serverSocket = new AsyncServerSocket(5000,"localhost"); 27 | FutureTask asyncFutureTask = new FutureTask<>(new Callable() { 28 | @Override 29 | public Long call() throws Exception { 30 | Stopwatch stopwatch = new Stopwatch(); 31 | stopwatch.start(); 32 | serverSocket.startServer(); 33 | stopwatch.stop(); 34 | return stopwatch.elapsedTime(TimeUnit.SECONDS); 35 | } 36 | }); 37 | System.out.println("Starting the AsyncSocketServer Test"); 38 | new Thread(asyncFutureTask).start(); 39 | Thread.sleep(1000); 40 | messageSender.sendMessages(); 41 | Long time = asyncFutureTask.get(); 42 | System.out.println("AsyncServer processed [10000] messages in " + time+" seconds"); 43 | } 44 | 45 | @Test 46 | @Ignore 47 | public void testPlainSocketServer() throws Exception { 48 | PlainSocketMessageSender messageSender = new PlainSocketMessageSender(5001,10000,"localhost"); 49 | final PlainServerSocket serverSocket = new PlainServerSocket(5001,"localhost"); 50 | FutureTask plainFutureTask = new FutureTask<>(new Callable() { 51 | @Override 52 | public Long call() throws Exception { 53 | Stopwatch stopwatch = new Stopwatch(); 54 | stopwatch.start(); 55 | serverSocket.startServer(); 56 | stopwatch.stop(); 57 | return stopwatch.elapsedTime(TimeUnit.SECONDS); 58 | } 59 | }); 60 | 61 | new Thread(plainFutureTask).start(); 62 | Thread.sleep(1000); 63 | messageSender.sendMessages(); 64 | Long time = plainFutureTask.get(); 65 | System.out.println("PlainSocketServer processed [10000] messages in " + time +" seconds"); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/FilesCopyMoveTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 1/10/12 7 | * Time: 11:07 PM 8 | */ 9 | 10 | import bbejeck.nio.util.DirUtils; 11 | import bbejeck.nio.util.FileGenerator; 12 | import org.junit.Before; 13 | import org.junit.Test; 14 | 15 | import java.nio.file.*; 16 | 17 | import static org.hamcrest.CoreMatchers.is; 18 | import static org.junit.Assert.assertThat; 19 | 20 | public class FilesCopyMoveTest extends BaseFileTest { 21 | 22 | 23 | @Test 24 | public void testCopyFile() throws Exception { 25 | Path targetPath = dir1Path.resolve(basePath.relativize(sourcePath)); 26 | Files.copy(sourcePath,targetPath); 27 | assertThat(Files.size(targetPath), is(Files.size(sourcePath))); 28 | assertThat(Files.exists(sourcePath), is(true)); 29 | assertThat(Files.exists(targetPath), is(true)); 30 | } 31 | 32 | @Test 33 | public void testMoveFile() throws Exception { 34 | Path targetPath = dir1Path.resolve(basePath.relativize(sourcePath)); 35 | Files.move(sourcePath, targetPath); 36 | assertThat(Files.exists(sourcePath), is(false)); 37 | assertThat(Files.exists(targetPath), is(true)); 38 | } 39 | 40 | @Test (expected = UnsupportedOperationException.class) 41 | public void testMoveFileNoFollowLinksInvalid() throws Exception { 42 | Path targetPath = dir1Path.resolve(basePath.relativize(sourcePath)); 43 | Files.move(sourcePath, targetPath, StandardCopyOption.COPY_ATTRIBUTES); 44 | } 45 | 46 | 47 | @Test (expected = UnsupportedOperationException.class) 48 | public void testCopyInvalidOption() throws Exception{ 49 | Path targetPath = dir1Path.resolve(basePath.relativize(sourcePath)); 50 | Files.copy(sourcePath, targetPath, StandardCopyOption.ATOMIC_MOVE); 51 | } 52 | 53 | 54 | @Test 55 | public void testCopyDirectory() throws Exception { 56 | Path target = basePath.resolve(copyDir); 57 | Path targetDir = target.resolve(basePath.relativize(fooPath)); 58 | Files.copy(fooPath, targetDir); 59 | Path expectedPath = Paths.get(baseDir, copyDir, fooDir); 60 | assertThat(Files.exists(expectedPath), is(true)); 61 | } 62 | 63 | @Test 64 | public void testMoveDirectory() throws Exception { 65 | Path tempPath = basePath.resolve(tempDir); 66 | Files.createDirectory(tempPath); 67 | Path target = basePath.resolve(Paths.get(copyDir)); 68 | Path targetDir = target.resolve(basePath.relativize(tempPath)); 69 | Files.move(tempPath, targetDir); 70 | assertThat(Files.notExists(tempPath), is(true)); 71 | assertThat(Files.exists(basePath.resolve(Paths.get(copyDir, tempDir))), is(true)); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | bbejeck.coin 5 | java7_blog 6 | jar 7 | 1.0-SNAPSHOT 8 | java7_blog 9 | http://maven.apache.org 10 | 11 | 12 | com.google.guava 13 | guava 14 | 11.0.1 15 | 16 | 17 | com.google.inject 18 | guice 19 | 3.0 20 | 21 | 22 | org.apache.lucene 23 | lucene-core 24 | 3.6.0 25 | 26 | 27 | junit 28 | junit 29 | 4.10 30 | test 31 | 32 | 33 | org.apache.tika 34 | tika-core 35 | 1.0 36 | 37 | 38 | org.apache.tika 39 | tika-parsers 40 | 1.0 41 | 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-compiler-plugin 48 | 2.3.2 49 | 50 | true 51 | true 52 | ${java.7.home}/bin/javac 53 | 1.7 54 | 1.7 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-surefire-plugin 60 | 2.9 61 | 62 | ${java.7.home}/bin/java 63 | once 64 | 65 | 66 | 67 | 68 | 69 | 70 | /usr/share/java/java7/Contents/Home 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/BaseFileTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files; 2 | 3 | import bbejeck.nio.util.DirUtils; 4 | import bbejeck.nio.util.FileGenerator; 5 | import org.junit.Before; 6 | 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 1/31/12 15 | * Time: 9:31 PM 16 | */ 17 | 18 | public class BaseFileTest { 19 | protected String baseDir = "test-files"; 20 | protected String dir1 = "dir1"; 21 | protected String dir2 = "dir2"; 22 | protected String fileName; 23 | protected String fooDir = "foo"; 24 | protected String copyDir = "copy"; 25 | protected String tempDir = "temp"; 26 | protected Path basePath; 27 | protected Path dir1Path; 28 | protected Path dir2Path; 29 | protected Path fooPath; 30 | protected Path sourcePath; 31 | protected Path copyPath; 32 | protected String[] fakeJavaFiles = new String[]{"Code.java", "Foo.java", "Bar.java", "Baz.java"}; 33 | protected String[] textFileNames = new String[]{"persons.csv", "counts.csv", "CountyTaxes.csv"}; 34 | 35 | 36 | @Before 37 | public void setUp() throws Exception { 38 | createPaths(); 39 | cleanUp(); 40 | createDirectories(); 41 | generateFile(Paths.get(baseDir, fileName), 500); 42 | generateFiles(basePath, fakeJavaFiles, textFileNames); 43 | generateFiles(dir1Path, fakeJavaFiles); 44 | generateFiles(dir2Path, fakeJavaFiles); 45 | } 46 | 47 | protected void createPaths() { 48 | basePath = Paths.get(baseDir); 49 | dir1Path = basePath.resolve(dir1); 50 | dir2Path = basePath.resolve(dir2); 51 | fileName = "test.txt"; 52 | sourcePath = basePath.resolve(fileName); 53 | copyPath = basePath.resolve(copyDir); 54 | fooPath = basePath.resolve(fooDir); 55 | } 56 | 57 | protected void cleanUp() throws Exception { 58 | DirUtils.deleteIfExists(basePath); 59 | Files.deleteIfExists(basePath.resolve(Paths.get(copyDir, fooDir))); 60 | Files.deleteIfExists(basePath.resolve(Paths.get(copyDir, tempDir))); 61 | Files.deleteIfExists(basePath.resolve(tempDir)); 62 | Files.deleteIfExists(basePath.resolve("tempII")); 63 | } 64 | 65 | protected void createDirectories() throws Exception { 66 | Files.createDirectories(dir1Path); 67 | Files.createDirectories(dir2Path); 68 | Files.createDirectories(copyPath); 69 | Files.createDirectories(fooPath); 70 | } 71 | 72 | protected void generateFile(Path path, int numberLines) throws Exception { 73 | FileGenerator.generate(path, numberLines); 74 | } 75 | 76 | protected void generateFiles(Path path, String[]... fileNames) throws Exception { 77 | for (String[] fileNamesArray : fileNames) { 78 | for (String fileName : fileNamesArray) { 79 | generateFile(path.resolve(fileName), 10); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/directory/AsynchronousRecursiveDirectoryStreamTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory; 2 | 3 | import bbejeck.nio.files.BaseFileTest; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.nio.file.DirectoryStream; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.util.Iterator; 11 | 12 | import static org.hamcrest.CoreMatchers.is; 13 | import static org.junit.Assert.assertThat; 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 2/10/12 19 | * Time: 12:54 AM 20 | */ 21 | 22 | public class AsynchronousRecursiveDirectoryStreamTest extends BaseFileTest { 23 | private int expectedJavaFileCount; 24 | private int expectedTotalFileCount; 25 | 26 | @Before 27 | public void setUp() throws Exception { 28 | super.setUp(); 29 | expectedJavaFileCount = fakeJavaFiles.length * 3; 30 | expectedTotalFileCount = expectedJavaFileCount + textFileNames.length + 1; 31 | } 32 | 33 | @Test 34 | public void testRecursiveDirectoryStream() throws Exception { 35 | int fileCount = 0; 36 | try (DirectoryStream directoryStream = new AsynchronousRecursiveDirectoryStream(basePath, "*")) { 37 | for (Path path : directoryStream) { 38 | if (Files.isRegularFile(path)) { 39 | fileCount++; 40 | } 41 | } 42 | } 43 | assertThat(fileCount, is(expectedTotalFileCount)); 44 | } 45 | 46 | @Test 47 | public void testRecursiveDirectoryStreamJavaFiles() throws Exception { 48 | int fileCount = 0; 49 | try (DirectoryStream directoryStream = new AsynchronousRecursiveDirectoryStream(basePath, "*.java")) { 50 | for (Path path : directoryStream) { 51 | if (Files.isRegularFile(path)) { 52 | fileCount++; 53 | } 54 | } 55 | } 56 | assertThat(fileCount, is(expectedJavaFileCount)); 57 | } 58 | 59 | @Test (expected = IllegalStateException.class) 60 | public void testErrorWhenIteratorCalledAfterClose() throws Exception { 61 | DirectoryStream directoryStream = new AsynchronousRecursiveDirectoryStream(basePath,"*"); 62 | directoryStream.close(); 63 | directoryStream.iterator(); 64 | } 65 | 66 | @Test (expected = IllegalStateException.class) 67 | public void testErrorWhenIteratorCalledTwice() throws Exception { 68 | DirectoryStream directoryStream = new AsynchronousRecursiveDirectoryStream(basePath,"*"); 69 | directoryStream.iterator(); 70 | directoryStream.close(); 71 | directoryStream.iterator(); 72 | } 73 | 74 | @Test(expected = UnsupportedOperationException.class) 75 | public void testErrorOnRemove() throws Exception{ 76 | try(DirectoryStream directoryStream = new AsynchronousRecursiveDirectoryStream(basePath,"*")){ 77 | Iterator it = directoryStream.iterator(); 78 | while(it.hasNext()){ 79 | it.remove(); 80 | } 81 | } 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/sockets/PlainServerSocket.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.sockets; 2 | 3 | import bbejeck.nio.Host; 4 | import bbejeck.nio.Port; 5 | import com.google.inject.Inject; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.BufferedWriter; 9 | import java.io.InputStreamReader; 10 | import java.io.OutputStreamWriter; 11 | import java.net.ServerSocket; 12 | import java.net.Socket; 13 | import java.nio.CharBuffer; 14 | import java.util.concurrent.Callable; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | 18 | /** 19 | * Created by IntelliJ IDEA. 20 | * User: bbejeck 21 | * Date: 3/10/12 22 | * Time: 12:47 PM 23 | */ 24 | public class PlainServerSocket { 25 | 26 | private ExecutorService executorService; 27 | private java.net.ServerSocket server; 28 | private int port; 29 | private String host; 30 | 31 | 32 | @Inject 33 | public PlainServerSocket(@Port int port, @Host String host) { 34 | this.port = port; 35 | this.host = host; 36 | } 37 | 38 | 39 | public void startServer() { 40 | try { 41 | initServerSocket(); 42 | this.executorService = Executors.newCachedThreadPool(); 43 | while (!executorService.isShutdown()) { 44 | Socket socket = server.accept(); 45 | executorService.submit(handleSocketRequest(socket)); 46 | } 47 | } catch (Exception e) { 48 | if (!executorService.isShutdown()) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | } 53 | 54 | private Callable handleSocketRequest(final Socket socket) { 55 | return new Callable() { 56 | @Override 57 | public Void call() throws Exception { 58 | BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 59 | CharBuffer charBuffer = CharBuffer.allocate(1000); 60 | reader.read(charBuffer); 61 | charBuffer.flip(); 62 | StringBuilder builder = new StringBuilder("You Said >> \""); 63 | String message = charBuffer.toString(); 64 | // System.out.println("Plain Socket Message[" + message + "] received @" + new Date()); 65 | builder.append(message).append("\""); 66 | BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 67 | bufferedWriter.write(builder.toString()); 68 | bufferedWriter.flush(); 69 | if (message.equalsIgnoreCase("quit")) { 70 | stopServer(); 71 | } 72 | reader.close(); 73 | bufferedWriter.close(); 74 | socket.close(); 75 | return null; 76 | } 77 | }; 78 | } 79 | 80 | public void stopServer() throws Exception { 81 | executorService.shutdownNow(); 82 | server.close(); 83 | } 84 | 85 | 86 | private void initServerSocket() throws Exception { 87 | server = new ServerSocket(port); 88 | } 89 | 90 | } 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/guice/EchoServerCompletionHandler.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels.guice; 2 | 3 | import com.google.inject.Inject; 4 | 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.AsynchronousServerSocketChannel; 7 | import java.nio.channels.AsynchronousSocketChannel; 8 | import java.util.concurrent.CountDownLatch; 9 | import java.util.concurrent.ExecutionException; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 3/8/12 15 | * Time: 10:49 PM 16 | */ 17 | 18 | public class EchoServerCompletionHandler implements CustomCompletionHandler { 19 | 20 | private CountDownLatch doneSignal; 21 | private AsynchronousServerSocketChannel socketChannel; 22 | //TODO reuse byte buffers and pass around for lifecycle of request/response 23 | //TODO use in conjunction with charset encoders/decoders 24 | //TODO 25 | @Inject 26 | public EchoServerCompletionHandler(@EchoServer CountDownLatch doneSignal) { 27 | this.doneSignal = doneSignal; 28 | } 29 | 30 | @Override 31 | public void completed(AsynchronousSocketChannel result, Object attachment) { 32 | socketChannel.accept(null, this); 33 | StringBuilder messageBuilder = new StringBuilder("You Said >> "); 34 | String receivedMessage = readMessage(result); 35 | System.out.println(Thread.currentThread().getName()); 36 | 37 | System.out.println("Received message "+receivedMessage+" sending reply"); 38 | messageBuilder.append(receivedMessage); 39 | writeEchoMessage(result, messageBuilder.toString()); 40 | if(receivedMessage.equalsIgnoreCase("quit")){ 41 | sendShutdownSignal(); 42 | } 43 | } 44 | 45 | @Override 46 | public void failed(Throwable exc, Object attachment) { 47 | exc.printStackTrace(); 48 | } 49 | 50 | @Override 51 | public void setSocketChannel(AsynchronousServerSocketChannel socketChannel) { 52 | this.socketChannel = socketChannel; 53 | } 54 | 55 | private void writeEchoMessage(AsynchronousSocketChannel socket, String message) { 56 | ByteBuffer byteBuffer = getByteBuffer(); 57 | byteBuffer.put(message.getBytes()); 58 | byteBuffer.flip(); 59 | socket.write(byteBuffer); 60 | } 61 | 62 | private String readMessage(AsynchronousSocketChannel socket) { 63 | ByteBuffer byteBuffer = getByteBuffer(); 64 | int totalBytes = 0; 65 | String message = null; 66 | //TODO use charset encoders here 67 | //TODO reuse byteBuffers for lifecycle of entire call 68 | try { 69 | totalBytes = socket.read(byteBuffer).get(); 70 | } catch (InterruptedException | ExecutionException e) { 71 | e.printStackTrace(); 72 | } 73 | byteBuffer.flip(); 74 | if (totalBytes > 0) { 75 | byte[] bytes = new byte[totalBytes]; 76 | byteBuffer.get(bytes); 77 | message = new String(bytes); 78 | } 79 | return message; 80 | } 81 | 82 | private ByteBuffer getByteBuffer() { 83 | return ByteBuffer.allocate(1000); 84 | } 85 | 86 | private void sendShutdownSignal() { 87 | doneSignal.countDown(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/directory/event/DirectoryEventWatcherGuiceTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import bbejeck.nio.files.BaseFileTest; 4 | import bbejeck.nio.files.event.PathEventContext; 5 | import bbejeck.nio.files.event.PathEventSubscriber; 6 | import com.google.common.eventbus.EventBus; 7 | import com.google.common.eventbus.Subscribe; 8 | import com.google.inject.Guice; 9 | import com.google.inject.Injector; 10 | import org.junit.After; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | import java.nio.file.Path; 15 | import java.util.*; 16 | import java.util.concurrent.CountDownLatch; 17 | 18 | import static org.hamcrest.CoreMatchers.is; 19 | import static org.junit.Assert.assertThat; 20 | 21 | /** 22 | * Created by IntelliJ IDEA. 23 | * User: bbejeck 24 | * Date: 2/25/12 25 | */ 26 | public class DirectoryEventWatcherGuiceTest extends BaseFileTest { 27 | 28 | private DirectoryEventWatcher directoryEventWatcher; 29 | private CountDownLatch latch; 30 | private TestSubscriber subscriber; 31 | 32 | @Before 33 | public void setUp() throws Exception { 34 | createPaths(); 35 | cleanUp(); 36 | createDirectories(); 37 | latch = new CountDownLatch(3); 38 | Injector injector = Guice.createInjector(new DirectoryEventModule()); 39 | directoryEventWatcher = injector.getInstance(DirectoryEventWatcher.class); 40 | EventBus eventBus = injector.getInstance(EventBus.class); 41 | subscriber = new TestSubscriber(); 42 | eventBus.register(subscriber); 43 | directoryEventWatcher.start(); 44 | } 45 | 46 | @Test 47 | public void testDirectoryForWrittenEvents() throws Exception { 48 | Map eventResultsMap = new HashMap<>(); 49 | assertThat(directoryEventWatcher.isRunning(), is(true)); 50 | generateFile(dir1Path.resolve("newTextFile.txt"), 10); 51 | generateFile(basePath.resolve("newTextFileII.txt"), 10); 52 | generateFile(dir2Path.resolve("newTextFileIII.txt"), 10); 53 | latch.await(); 54 | 55 | assertThat(subscriber.pathEvents.size(), is(3)); 56 | List eventContexts = subscriber.pathEvents; 57 | 58 | for (PathEventContext eventContext : eventContexts) { 59 | Path dir = eventContext.getWatchedDirectory(); 60 | assertThat(eventContext.getEvents().size(), is(1)); 61 | Path target = eventContext.getEvents().get(0).getEventTarget(); 62 | eventResultsMap.put(dir, target.toString()); 63 | } 64 | 65 | Set watchedDirs = eventResultsMap.keySet(); 66 | assertThat(watchedDirs.size(), is(3)); 67 | assertThat(watchedDirs.contains(dir1Path), is(true)); 68 | assertThat(watchedDirs.contains(basePath), is(true)); 69 | assertThat(watchedDirs.contains(dir2Path), is(true)); 70 | 71 | assertThat(eventResultsMap.get(dir1Path), is("newTextFile.txt")); 72 | assertThat(eventResultsMap.get(basePath), is("newTextFileII.txt")); 73 | assertThat(eventResultsMap.get(dir2Path), is("newTextFileIII.txt")); 74 | 75 | } 76 | 77 | @After 78 | public void tearDown() { 79 | directoryEventWatcher.stop(); 80 | } 81 | 82 | 83 | private class TestSubscriber implements PathEventSubscriber { 84 | List pathEvents = new ArrayList<>(); 85 | 86 | @Override 87 | @Subscribe 88 | public void handlePathEvents(PathEventContext pathEventContext) { 89 | pathEvents.add(pathEventContext); 90 | latch.countDown(); 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/AsyncServerSocket.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels; 2 | 3 | import bbejeck.nio.Host; 4 | import bbejeck.nio.Port; 5 | import com.google.inject.Inject; 6 | 7 | import java.net.InetSocketAddress; 8 | import java.nio.ByteBuffer; 9 | import java.nio.channels.AsynchronousChannelGroup; 10 | import java.nio.channels.AsynchronousServerSocketChannel; 11 | import java.nio.channels.AsynchronousSocketChannel; 12 | import java.nio.channels.CompletionHandler; 13 | import java.nio.charset.Charset; 14 | import java.util.concurrent.*; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * User: bbejeck 19 | * Date: 3/4/12 20 | * Time: 10:25 PM 21 | */ 22 | 23 | public class AsyncServerSocket { 24 | 25 | private int count = 0; 26 | private CountDownLatch latch = new CountDownLatch(1); 27 | private int port; 28 | private String host; 29 | private AsynchronousChannelGroup channelGroup; 30 | private AsynchronousServerSocketChannel server; 31 | 32 | @Inject 33 | public AsyncServerSocket(@Port int port, @Host String host) throws Exception { 34 | this.port = port; 35 | this.host = host; 36 | } 37 | 38 | public void startServer() throws Exception { 39 | ExecutorService executorService = Executors.newCachedThreadPool(); 40 | channelGroup = AsynchronousChannelGroup.withThreadPool(executorService); 41 | server = AsynchronousServerSocketChannel.open(channelGroup); 42 | server.bind(new InetSocketAddress(host, port)); 43 | server.accept(null, new CompletionHandler() { 44 | @Override 45 | public void completed(AsynchronousSocketChannel result, Object attachment) { 46 | server.accept(null, this); 47 | processConnection(result); 48 | } 49 | 50 | @Override 51 | public void failed(Throwable exc, Object attachment) { 52 | exc.printStackTrace(); 53 | } 54 | }); 55 | latch.await(); 56 | channelGroup.shutdown(); 57 | executorService.shutdownNow(); 58 | System.out.println("AsyncServer shutting down"); 59 | } 60 | 61 | private void processConnection(AsynchronousSocketChannel socket) { 62 | ByteBuffer byteBuffer = ByteBuffer.allocate(1000); 63 | Future read = socket.read(byteBuffer); 64 | try { 65 | int totalBytes = read.get(); 66 | String message = getMessageFromBuffer(byteBuffer, totalBytes); 67 | // System.out.println("Message[" + message + "] received @" + new Date()); 68 | sendEchoResponse(byteBuffer, socket, message); 69 | if (message.equals("quit")) { 70 | quit(); 71 | } 72 | } catch (InterruptedException | ExecutionException e) { 73 | quit(); 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | private void sendEchoResponse(ByteBuffer byteBuffer, AsynchronousSocketChannel socket, String originalMessage) { 79 | StringBuilder builder = new StringBuilder("You Said >> \""); 80 | builder.append(originalMessage).append("\""); 81 | byteBuffer.clear(); 82 | byteBuffer.put(builder.toString().getBytes(Charset.forName("UTF-8"))); 83 | byteBuffer.flip(); 84 | socket.write(byteBuffer); 85 | } 86 | 87 | 88 | private String getMessageFromBuffer(ByteBuffer byteBuffer, int size) { 89 | byte[] bytes = new byte[size]; 90 | byteBuffer.flip(); 91 | byteBuffer.get(bytes, 0, size); 92 | return new String(bytes, Charset.forName("UTF-8")); 93 | } 94 | 95 | private void quit() { 96 | latch.countDown(); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/directory/event/DirectoryEventWatcherImplTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import bbejeck.nio.files.BaseFileTest; 4 | import bbejeck.nio.files.event.PathEventContext; 5 | import bbejeck.nio.files.event.PathEventSubscriber; 6 | import com.google.common.eventbus.EventBus; 7 | import com.google.common.eventbus.Subscribe; 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | 12 | import java.nio.file.Path; 13 | import java.util.*; 14 | import java.util.concurrent.CountDownLatch; 15 | 16 | import static org.hamcrest.CoreMatchers.is; 17 | import static org.junit.Assert.assertThat; 18 | 19 | /** 20 | * Created by IntelliJ IDEA. 21 | * User: bbejeck 22 | * Date: 2/20/12 23 | * Time: 10:32 PM 24 | */ 25 | //TODO add Test with Phaser to test adding deleting and updating 26 | //TODO add directory on the fly then start watching and add file confirm added to new dir 27 | public class DirectoryEventWatcherImplTest extends BaseFileTest { 28 | 29 | private EventBus eventBus; 30 | private DirectoryEventWatcherImpl dirWatcher; 31 | private CountDownLatch doneSignal; 32 | private TestSubscriber subscriber; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | createPaths(); 37 | cleanUp(); 38 | createDirectories(); 39 | eventBus = new EventBus(); 40 | dirWatcher = new DirectoryEventWatcherImpl(eventBus, basePath); 41 | dirWatcher.start(); 42 | subscriber = new TestSubscriber(); 43 | eventBus.register(subscriber); 44 | doneSignal = new CountDownLatch(3); 45 | } 46 | 47 | @Test 48 | public void testDirectoryForWrittenEvents() throws Exception { 49 | Map eventResultsMap = new HashMap<>(); 50 | assertThat(dirWatcher.isRunning(), is(true)); 51 | generateFile(dir1Path.resolve("newTextFile.txt"), 10); 52 | generateFile(basePath.resolve("newTextFileII.txt"), 10); 53 | generateFile(dir2Path.resolve("newTextFileIII.txt"), 10); 54 | doneSignal.await(); 55 | 56 | assertThat(subscriber.pathEvents.size(), is(3)); 57 | List eventContexts = subscriber.pathEvents; 58 | 59 | for (PathEventContext eventContext : eventContexts) { 60 | Path dir = eventContext.getWatchedDirectory(); 61 | assertThat(eventContext.getEvents().size(),is(1)); 62 | Path target = eventContext.getEvents().get(0).getEventTarget(); 63 | eventResultsMap.put(dir,target.toString()); 64 | 65 | } 66 | 67 | Set watchedDirs = eventResultsMap.keySet(); 68 | assertThat(watchedDirs.size(),is(3)); 69 | assertThat(watchedDirs.contains(dir1Path), is(true)); 70 | assertThat(watchedDirs.contains(basePath), is(true)); 71 | assertThat(watchedDirs.contains(dir2Path), is(true)); 72 | 73 | assertThat(eventResultsMap.get(dir1Path), is("newTextFile.txt")); 74 | assertThat(eventResultsMap.get(basePath), is("newTextFileII.txt")); 75 | assertThat(eventResultsMap.get(dir2Path), is("newTextFileIII.txt")); 76 | 77 | } 78 | 79 | @Test 80 | public void testStop() { 81 | dirWatcher.stop(); 82 | Integer count = dirWatcher.getEventCount(); 83 | assertThat(count,is(0)); 84 | assertThat(dirWatcher.isRunning(),is(false)); 85 | } 86 | 87 | 88 | @After 89 | public void tearDown() throws Exception { 90 | dirWatcher.stop(); 91 | } 92 | 93 | 94 | private class TestSubscriber implements PathEventSubscriber { 95 | List pathEvents = new ArrayList<>(); 96 | 97 | @Override 98 | @Subscribe 99 | public void handlePathEvents(PathEventContext pathEventContext) { 100 | pathEvents.add(pathEventContext); 101 | doneSignal.countDown(); 102 | } 103 | 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/channels/AsyncSocketMessageSender.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.channels; 2 | 3 | import bbejeck.nio.Host; 4 | import bbejeck.nio.MessageCount; 5 | import bbejeck.nio.Port; 6 | import com.google.common.base.Stopwatch; 7 | 8 | import java.net.InetSocketAddress; 9 | import java.nio.ByteBuffer; 10 | import java.nio.channels.AsynchronousChannelGroup; 11 | import java.nio.channels.AsynchronousSocketChannel; 12 | import java.nio.channels.CompletionHandler; 13 | import java.nio.charset.Charset; 14 | import java.util.concurrent.Executors; 15 | import java.util.concurrent.Future; 16 | import java.util.concurrent.TimeUnit; 17 | 18 | /** 19 | * Created by IntelliJ IDEA. 20 | * User: bbejeck 21 | * Date: 3/4/12 22 | * Time: 11:01 PM 23 | */ 24 | public class AsyncSocketMessageSender { 25 | 26 | private int port; 27 | private int numberMessages; 28 | private String host; 29 | private AsynchronousChannelGroup channelGroup; 30 | 31 | public AsyncSocketMessageSender(@Port int port, @MessageCount int numberMessages, @Host String host) { 32 | this.port = port; 33 | this.numberMessages = numberMessages; 34 | this.host = host; 35 | 36 | } 37 | 38 | public void sendMessages() throws Exception { 39 | channelGroup = AsynchronousChannelGroup.withThreadPool(Executors.newCachedThreadPool()); 40 | String sampleMessage = "Text message sent from socket"; 41 | AsynchronousSocketChannel socketChannel = null; 42 | for (int i = 0; i < numberMessages; i++) { 43 | Thread.sleep(1); 44 | socketChannel = AsynchronousSocketChannel.open(channelGroup); 45 | socketChannel.connect(new InetSocketAddress(host, port), null, getHandler(getByteBuffer(sampleMessage), socketChannel)); 46 | } 47 | 48 | socketChannel = AsynchronousSocketChannel.open(channelGroup); 49 | socketChannel.connect(new InetSocketAddress(port), null, getHandler(getByteBuffer("quit"), socketChannel)); 50 | channelGroup.shutdown(); 51 | } 52 | 53 | private ByteBuffer getByteBuffer(String message) { 54 | ByteBuffer buffer = ByteBuffer.allocate(1000); 55 | buffer.put(message.getBytes(Charset.forName("UTF-8"))); 56 | buffer.flip(); 57 | return buffer; 58 | } 59 | 60 | 61 | private CompletionHandler getHandler(final ByteBuffer messageBuffer, final AsynchronousSocketChannel socketChannel) { 62 | return new CompletionHandler() { 63 | @Override 64 | public void completed(AsynchronousSocketChannel result, Object attachment) { 65 | socketChannel.write(messageBuffer); 66 | messageBuffer.clear(); 67 | Future bytesRead = socketChannel.read(messageBuffer); 68 | try { 69 | int numBytes = bytesRead.get(); 70 | byte[] bytes = new byte[numBytes]; 71 | messageBuffer.flip(); 72 | messageBuffer.get(bytes, 0, numBytes); 73 | String reply = new String(bytes,Charset.forName("UTF-8")); 74 | System.out.println("Server Reply " + reply); 75 | socketChannel.close(); 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | 81 | @Override 82 | public void failed(Throwable exc, Object attachment) { 83 | System.out.println("FAILED"); 84 | exc.printStackTrace(); 85 | } 86 | }; 87 | } 88 | 89 | public static void main(String[] args) throws Exception { 90 | AsyncSocketMessageSender messageSender = new AsyncSocketMessageSender(5000, 1000, "localhost"); 91 | Stopwatch stopwatch = new Stopwatch(); 92 | stopwatch.start(); 93 | messageSender.sendMessages(); 94 | stopwatch.stop(); 95 | System.out.println("Done sending messages in " + stopwatch.elapsedTime(TimeUnit.SECONDS)); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/event/DirectoryEventWatcherImpl.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory.event; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.*; 7 | import java.nio.file.attribute.BasicFileAttributes; 8 | import java.util.List; 9 | import java.util.Objects; 10 | import java.util.concurrent.Callable; 11 | import java.util.concurrent.ExecutionException; 12 | import java.util.concurrent.FutureTask; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | import static java.nio.file.StandardWatchEventKinds.*; 16 | 17 | /** 18 | * Created by IntelliJ IDEA. 19 | * User: bbejeck 20 | * Date: 2/15/12 21 | * Time: 10:56 PM 22 | */ 23 | 24 | public class DirectoryEventWatcherImpl implements DirectoryEventWatcher { 25 | 26 | private FutureTask watchTask; 27 | private EventBus eventBus; 28 | private WatchService watchService; 29 | private volatile boolean keepWatching = true; 30 | private Path startPath; 31 | 32 | 33 | DirectoryEventWatcherImpl(EventBus eventBus, Path startPath) { 34 | this.eventBus = Objects.requireNonNull(eventBus); 35 | this.startPath = Objects.requireNonNull(startPath); 36 | } 37 | 38 | @Override 39 | public void start() throws IOException { 40 | initWatchService(); 41 | registerDirectories(); 42 | createWatchTask(); 43 | startWatching(); 44 | } 45 | 46 | @Override 47 | public boolean isRunning() { 48 | return watchTask != null && !watchTask.isDone(); 49 | } 50 | 51 | @Override 52 | public void stop() { 53 | keepWatching = false; 54 | } 55 | 56 | //Used for testing purposes 57 | Integer getEventCount() { 58 | try { 59 | return watchTask.get(); 60 | } catch (InterruptedException | ExecutionException e) { 61 | throw new RuntimeException(e); 62 | } 63 | } 64 | 65 | 66 | private void createWatchTask() { 67 | watchTask = new FutureTask<>(new Callable() { 68 | private int totalEventCount; 69 | 70 | @Override 71 | public Integer call() throws Exception { 72 | while (keepWatching) { 73 | WatchKey watchKey = watchService.poll(10, TimeUnit.SECONDS); 74 | if (watchKey != null) { 75 | List> events = watchKey.pollEvents(); 76 | Path watched = (Path) watchKey.watchable(); 77 | PathEvents pathEvents = new PathEvents(watchKey.isValid(), watched); 78 | for (WatchEvent event : events) { 79 | pathEvents.add(new PathEvent((Path) event.context(), event.kind())); 80 | totalEventCount++; 81 | } 82 | watchKey.reset(); 83 | eventBus.post(pathEvents); 84 | } 85 | } 86 | return totalEventCount; 87 | } 88 | }); 89 | } 90 | 91 | private void startWatching() { 92 | new Thread(watchTask).start(); 93 | } 94 | 95 | private void registerDirectories() throws IOException { 96 | Files.walkFileTree(startPath, new WatchServiceRegisteringVisitor()); 97 | } 98 | 99 | private WatchService initWatchService() throws IOException { 100 | if (watchService == null) { 101 | watchService = FileSystems.getDefault().newWatchService(); 102 | } 103 | return watchService; 104 | } 105 | 106 | private class WatchServiceRegisteringVisitor extends SimpleFileVisitor { 107 | @Override 108 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 109 | dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); 110 | return FileVisitResult.CONTINUE; 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/AsynchronousRecursiveDirectoryStream.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory; 2 | 3 | import bbejeck.nio.files.visitor.FunctionVisitor; 4 | import bbejeck.nio.util.FilterBuilder; 5 | import com.google.common.base.Function; 6 | 7 | import java.io.IOException; 8 | import java.nio.file.DirectoryStream; 9 | import java.nio.file.FileVisitResult; 10 | import java.nio.file.Files; 11 | import java.nio.file.Path; 12 | import java.util.Iterator; 13 | import java.util.Objects; 14 | import java.util.concurrent.*; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * User: bbejeck 19 | * Date: 2/5/12 20 | * Time: 1:05 PM 21 | */ 22 | public class AsynchronousRecursiveDirectoryStream implements DirectoryStream { 23 | 24 | private LinkedBlockingQueue pathsBlockingQueue = new LinkedBlockingQueue<>(); 25 | private boolean closed = false; 26 | private FutureTask pathTask; 27 | private Path startPath; 28 | private Filter filter; 29 | 30 | public AsynchronousRecursiveDirectoryStream(Path startPath, String pattern) throws IOException { 31 | this.filter = FilterBuilder.buildGlobFilter(Objects.requireNonNull(pattern)); 32 | this.startPath = Objects.requireNonNull(startPath); 33 | } 34 | 35 | @Override 36 | public Iterator iterator() { 37 | confirmNotClosed(); 38 | findFiles(startPath, filter); 39 | return new Iterator() { 40 | Path path; 41 | @Override 42 | public boolean hasNext() { 43 | try { 44 | path = pathsBlockingQueue.poll(); 45 | while (!pathTask.isDone() && path == null) { 46 | path = pathsBlockingQueue.poll(5, TimeUnit.MILLISECONDS); 47 | } 48 | return (path != null); 49 | } catch (InterruptedException e) { 50 | Thread.currentThread().interrupt(); 51 | } 52 | return false; 53 | } 54 | 55 | @Override 56 | public Path next() { 57 | return path; 58 | } 59 | 60 | @Override 61 | public void remove() { 62 | throw new UnsupportedOperationException("Removal not supported"); 63 | } 64 | }; 65 | } 66 | 67 | private void findFiles(final Path startPath, final Filter filter) { 68 | pathTask = new FutureTask<>(new Callable() { 69 | @Override 70 | public Void call() throws Exception { 71 | Files.walkFileTree(startPath, new FunctionVisitor(getFunction(filter))); 72 | return null; 73 | } 74 | }); 75 | start(pathTask); 76 | } 77 | 78 | private Function getFunction(final Filter filter) { 79 | return new Function() { 80 | @Override 81 | public FileVisitResult apply(Path input) { 82 | try { 83 | if (filter.accept(input.getFileName())) { 84 | pathsBlockingQueue.offer(input); 85 | } 86 | } catch (IOException e) { 87 | throw new RuntimeException(e.getMessage()); 88 | } 89 | return (pathTask.isCancelled()) ? FileVisitResult.TERMINATE : FileVisitResult.CONTINUE; 90 | } 91 | }; 92 | } 93 | 94 | 95 | @Override 96 | public void close() throws IOException { 97 | if(pathTask !=null){ 98 | pathTask.cancel(true); 99 | } 100 | pathsBlockingQueue.clear(); 101 | pathsBlockingQueue = null; 102 | pathTask = null; 103 | filter = null; 104 | closed = true; 105 | } 106 | 107 | private void start(FutureTask futureTask) { 108 | new Thread(futureTask).start(); 109 | } 110 | 111 | private void confirmNotClosed() { 112 | if (closed) { 113 | throw new IllegalStateException("DirectoryStream has already been closed"); 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/files/directory/FileDirectoryStream.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.directory; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | import java.io.IOException; 6 | import java.util.Iterator; 7 | import java.util.concurrent.Callable; 8 | import java.util.concurrent.FutureTask; 9 | import java.util.concurrent.LinkedBlockingQueue; 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.regex.Pattern; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 2/12/12 17 | * Time: 9:59 PM 18 | */ 19 | public class FileDirectoryStream { 20 | File startDirectory; 21 | String pattern; 22 | private LinkedBlockingQueue fileLinkedBlockingQueue = new LinkedBlockingQueue<>(); 23 | private boolean closed = false; 24 | private FutureTask fileTask; 25 | private FilenameFilter filenameFilter; 26 | 27 | 28 | public FileDirectoryStream(String pattern, File startDirectory) { 29 | this.pattern = pattern; 30 | this.startDirectory = startDirectory; 31 | this.filenameFilter = getFileNameFilter(pattern); 32 | } 33 | 34 | public Iterator glob() throws IOException { 35 | confirmNotClosed(); 36 | startFileSearch(startDirectory, filenameFilter); 37 | return new Iterator() { 38 | File file = null; 39 | 40 | @Override 41 | public boolean hasNext() { 42 | try { 43 | file = fileLinkedBlockingQueue.poll(); 44 | while (!fileTask.isDone() && file == null) { 45 | file = fileLinkedBlockingQueue.poll(5, TimeUnit.MILLISECONDS); 46 | } 47 | return file != null; 48 | } catch (InterruptedException e) { 49 | Thread.currentThread().interrupt(); 50 | } 51 | return false; 52 | } 53 | 54 | @Override 55 | public File next() { 56 | return file; 57 | } 58 | 59 | @Override 60 | public void remove() { 61 | throw new UnsupportedOperationException("Remove not supported"); 62 | } 63 | }; 64 | } 65 | 66 | private void startFileSearch(final File startDirectory, final FilenameFilter filenameFilter) { 67 | fileTask = new FutureTask(new Callable() { 68 | @Override 69 | public Void call() throws Exception { 70 | findFiles(startDirectory, filenameFilter); 71 | return null; 72 | } 73 | }); 74 | start(fileTask); 75 | } 76 | 77 | private void findFiles(final File startDirectory, final FilenameFilter filenameFilter) { 78 | File[] files = startDirectory.listFiles(filenameFilter); 79 | for (File file : files) { 80 | if (!fileTask.isCancelled()) { 81 | if (file.isDirectory()) { 82 | findFiles(file, filenameFilter); 83 | } 84 | fileLinkedBlockingQueue.offer(file); 85 | } 86 | } 87 | } 88 | 89 | private FilenameFilter getFileNameFilter(final String pattern) { 90 | return new FilenameFilter() { 91 | Pattern regexPattern = Pattern.compile(pattern); 92 | 93 | @Override 94 | public boolean accept(File dir, String name) { 95 | return new File(dir, name).isDirectory() || regexPattern.matcher(name).matches(); 96 | } 97 | }; 98 | } 99 | 100 | 101 | public void close() throws IOException { 102 | if (fileTask != null) { 103 | fileTask.cancel(true); 104 | } 105 | fileLinkedBlockingQueue.clear(); 106 | fileLinkedBlockingQueue = null; 107 | fileTask = null; 108 | closed = true; 109 | } 110 | 111 | private void start(FutureTask futureTask) { 112 | new Thread(futureTask).start(); 113 | } 114 | 115 | private void confirmNotClosed() { 116 | if (closed) { 117 | throw new IllegalStateException("File Iterator has already been closed"); 118 | } 119 | } 120 | 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/watch/WatchDirectoryTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files.watch; 2 | 3 | import bbejeck.nio.files.BaseFileTest; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.nio.file.*; 8 | import java.util.List; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | import static org.hamcrest.CoreMatchers.is; 12 | import static org.junit.Assert.*; 13 | import static java.nio.file.StandardWatchEventKinds.*; 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 2/13/12 19 | * Time: 9:47 PM 20 | */ 21 | 22 | public class WatchDirectoryTest extends BaseFileTest { 23 | private WatchService watchService; 24 | private WatchKey basePathWatchKey; 25 | 26 | @Before 27 | public void setUo() throws Exception { 28 | super.setUp(); 29 | watchService = FileSystems.getDefault().newWatchService(); 30 | basePathWatchKey = basePath.register(watchService,ENTRY_CREATE); 31 | } 32 | 33 | @Test 34 | public void testEventForDirectory() throws Exception { 35 | generateFile(basePath.resolve("newTextFile.txt"), 10); 36 | generateFile(basePath.resolve("newTextFileII.txt"), 10); 37 | generateFile(basePath.resolve("newTextFileIII.txt"), 10); 38 | WatchKey watchKey = watchService.poll(20, TimeUnit.SECONDS); 39 | assertNotNull(watchKey); 40 | assertThat(watchKey,is(basePathWatchKey)); 41 | List> eventList = watchKey.pollEvents(); 42 | assertThat(eventList.size(), is(3)); 43 | for (WatchEvent event : eventList) { 44 | assertThat(event.kind() == StandardWatchEventKinds.ENTRY_CREATE, is(true)); 45 | assertThat(event.count(),is(1)); 46 | } 47 | Path eventPath = (Path) eventList.get(0).context(); 48 | assertThat(Files.isSameFile(eventPath, Paths.get("newTextFile.txt")), is(true)); 49 | Path watchedPath = (Path) watchKey.watchable(); 50 | assertThat(Files.isSameFile(watchedPath, basePath), is(true)); 51 | } 52 | 53 | @Test 54 | public void testEventForDirectoryWatchKey() throws Exception { 55 | generateFile(basePath.resolve("newTextFile.txt"), 10); 56 | List> eventList = basePathWatchKey.pollEvents(); 57 | while (eventList.size() == 0 ){ 58 | eventList = basePathWatchKey.pollEvents(); 59 | Thread.sleep(10000); 60 | } 61 | assertThat(eventList.size(), is(1)); 62 | for (WatchEvent event : eventList) { 63 | assertThat(event.kind() == StandardWatchEventKinds.ENTRY_CREATE, is(true)); 64 | } 65 | basePathWatchKey.reset(); 66 | generateFile(basePath.resolve("newTextFileII.txt"), 10); 67 | generateFile(basePath.resolve("newTextFileIII.txt"), 10); 68 | while (eventList.size() == 0 ){ 69 | eventList = basePathWatchKey.pollEvents(); 70 | Thread.sleep(10000); 71 | } 72 | Path eventPath = (Path) eventList.get(0).context(); 73 | assertThat(Files.isSameFile(eventPath, Paths.get("newTextFile.txt")), is(true)); 74 | Path watchedPath = (Path) basePathWatchKey.watchable(); 75 | assertThat(Files.isSameFile(watchedPath, basePath), is(true)); 76 | } 77 | 78 | 79 | 80 | @Test 81 | public void testEventForSubDirectory() throws Exception { 82 | dir1Path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); 83 | generateFile(basePath.resolve("newTextFile.txt"), 10); 84 | generateFile(dir1Path.resolve("newTextFile.txt"), 10); 85 | int count = 0; 86 | while (count < 2) { 87 | WatchKey watchKey = watchService.poll(20, TimeUnit.SECONDS); 88 | Path watchedPath = (Path) watchKey.watchable(); 89 | assertNotNull(watchKey); 90 | List> eventList = watchKey.pollEvents(); 91 | WatchEvent event = eventList.get(0); 92 | assertThat(event.count(), is(1)); 93 | assertThat(event.kind() == StandardWatchEventKinds.ENTRY_CREATE, is(true)); 94 | assertTrue(Files.isSameFile((Path) event.context(), Paths.get("newTextFile.txt"))); 95 | count++; 96 | } 97 | } 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/DirectoryStreamTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files; 2 | 3 | import bbejeck.nio.files.directory.AsynchronousRecursiveDirectoryStream; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | import java.nio.file.*; 9 | 10 | import static org.hamcrest.CoreMatchers.is; 11 | import static org.junit.Assert.assertThat; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 1/31/12 17 | * Time: 9:18 PM 18 | */ 19 | public class DirectoryStreamTest extends BaseFileTest { 20 | private int expectedDirectoryCount; 21 | private int expectedFileCount; 22 | @Before 23 | public void setUp() throws Exception { 24 | super.setUp(); 25 | expectedDirectoryCount = 4; 26 | expectedFileCount = fakeJavaFiles.length + textFileNames.length + 1; 27 | } 28 | 29 | @Test 30 | public void testDirectoryStream() throws Exception { 31 | int directoryCount = 0; 32 | int fileCount = 0; 33 | try (DirectoryStream directoryStream = Files.newDirectoryStream(basePath)) { 34 | for (Path path : directoryStream) { 35 | if (Files.isDirectory(path)) { 36 | directoryCount++; 37 | } else if (Files.isRegularFile(path)) { 38 | fileCount++; 39 | } 40 | } 41 | } 42 | assertThat(expectedDirectoryCount, is(directoryCount)); 43 | assertThat(expectedFileCount, is(fileCount)); 44 | } 45 | 46 | @Test 47 | public void testDirectoryStreamGlobAll() throws Exception { 48 | int directoryCount = 0; 49 | int fileCount = 0; 50 | try (DirectoryStream directoryStream = Files.newDirectoryStream(basePath, "*")) { 51 | for (Path path : directoryStream) { 52 | if (Files.isDirectory(path)) { 53 | directoryCount++; 54 | } else if (Files.isRegularFile(path)) { 55 | fileCount++; 56 | } 57 | } 58 | } 59 | assertThat(expectedDirectoryCount, is(directoryCount)); 60 | assertThat(expectedFileCount, is(fileCount)); 61 | } 62 | 63 | @Test 64 | public void testDirectoryStreamGlobPattern() throws Exception { 65 | int directoryCount = 0; 66 | int fileCount = 0; 67 | try (DirectoryStream directoryStream = Files.newDirectoryStream(basePath, "Co*")) { 68 | for (Path path : directoryStream) { 69 | if (Files.isDirectory(path)) { 70 | directoryCount++; 71 | } else if (Files.isRegularFile(path)) { 72 | fileCount++; 73 | } 74 | } 75 | } 76 | assertThat(directoryCount, is(0)); 77 | assertThat(fileCount, is(2)); 78 | } 79 | 80 | @Test 81 | public void testDirectoryStreamGlobRegexPattern() throws Exception { 82 | int directoryCount = 0; 83 | int fileCount = 0; 84 | final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("regex:.*/[^ C d f t].*\\.\\w{3,4}"); 85 | DirectoryStream.Filter filter = new DirectoryStream.Filter() { 86 | @Override 87 | public boolean accept(Path entry) throws IOException { 88 | return pathMatcher.matches(entry); 89 | } 90 | }; 91 | try (DirectoryStream directoryStream = Files.newDirectoryStream(basePath, filter)) { 92 | for (Path path : directoryStream) { 93 | if (Files.isDirectory(path)) { 94 | directoryCount++; 95 | } else if (Files.isRegularFile(path)) { 96 | fileCount++; 97 | } 98 | } 99 | } 100 | assertThat(directoryCount, is(0)); 101 | assertThat(fileCount, is(5)); 102 | } 103 | 104 | @Test 105 | public void testDirectoryStreamGlobMultipleFileExtensions() throws Exception { 106 | int directoryCount = 0; 107 | int fileCount = 0; 108 | try (DirectoryStream directoryStream = Files.newDirectoryStream(basePath, "*.{java,txt}")) { 109 | for (Path path : directoryStream) { 110 | if (Files.isDirectory(path)) { 111 | directoryCount++; 112 | } else if (Files.isRegularFile(path)) { 113 | fileCount++; 114 | } 115 | } 116 | } 117 | assertThat(directoryCount, is(0)); 118 | assertThat(fileCount, is(5)); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/nio/util/DirUtils.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.util; 2 | 3 | import bbejeck.nio.files.directory.AsynchronousRecursiveDirectoryStream; 4 | import bbejeck.nio.files.visitor.*; 5 | import com.google.common.base.Function; 6 | import com.google.common.base.Predicate; 7 | 8 | import java.io.IOException; 9 | import java.nio.file.*; 10 | import java.util.EnumSet; 11 | import java.util.Objects; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 1/22/12 17 | * Time: 12:46 PM 18 | */ 19 | 20 | public class DirUtils { 21 | 22 | private DirUtils() { 23 | } 24 | 25 | /** 26 | * Walks file tree starting at the given path and deletes all files 27 | * but leaves the directory structure intact. 28 | * 29 | * @param path Base path to start from 30 | * @throws IOException 31 | */ 32 | public static void clean(Path path) throws IOException { 33 | validate(path); 34 | Files.walkFileTree(path, new CleanDirVisitor()); 35 | } 36 | 37 | /** 38 | * Walks file tree starting at the given path and deletes all files 39 | * but leaves the directory structure intact. If the given Path does not exist nothing 40 | * is done. 41 | * 42 | * @param path 43 | * @throws IOException 44 | */ 45 | public static void cleanIfExists(Path path) throws IOException { 46 | if (Files.exists(path)) { 47 | validate(path); 48 | Files.walkFileTree(path, new CleanDirVisitor()); 49 | } 50 | } 51 | 52 | 53 | /** 54 | * Completely removes given file tree starting at and including the given path. 55 | * 56 | * @param path 57 | * @throws IOException 58 | */ 59 | public static void delete(Path path) throws IOException { 60 | validate(path); 61 | Files.walkFileTree(path, new DeleteDirVisitor()); 62 | } 63 | 64 | 65 | /** 66 | * If the path exists, completely removes given file tree starting at and including the given path. 67 | * 68 | * @param path 69 | * @throws IOException 70 | */ 71 | public static void deleteIfExists(Path path) throws IOException { 72 | if (Files.exists(path)) { 73 | validate(path); 74 | Files.walkFileTree(path, new DeleteDirVisitor()); 75 | } 76 | } 77 | 78 | /** 79 | * Copies a directory tree 80 | * 81 | * @param from 82 | * @param to 83 | * @throws IOException 84 | */ 85 | public static void copy(Path from, Path to) throws IOException { 86 | validate(from); 87 | Files.walkFileTree(from, EnumSet.of(FileVisitOption.FOLLOW_LINKS),Integer.MAX_VALUE,new CopyDirVisitor(from, to)); 88 | } 89 | 90 | /** 91 | * Moves one directory tree to another. Not a true move operation in that the 92 | * directory tree is copied, then the original directory tree is deleted. 93 | * 94 | * @param from 95 | * @param to 96 | * @throws IOException 97 | */ 98 | public static void move(Path from, Path to) throws IOException { 99 | validate(from); 100 | Files.walkFileTree(from, new CopyDirVisitor(from, to)); 101 | Files.walkFileTree(from, new DeleteDirVisitor()); 102 | } 103 | 104 | /** 105 | * Traverses the directory structure and applies the given function to each file 106 | * @param target 107 | * @param function 108 | * @throws IOException 109 | */ 110 | public static void apply(Path target, Function function) throws IOException{ 111 | validate(target); 112 | Files.walkFileTree(target,new FunctionVisitor(function)); 113 | } 114 | 115 | /** 116 | * Traverses the directory structure and will only copy sub-tree structures where the provided predicate is true 117 | * @param from 118 | * @param to 119 | * @param predicate 120 | * @throws IOException 121 | */ 122 | 123 | public static void copyWithPredicate(Path from, Path to, Predicate predicate) throws IOException{ 124 | validate(from); 125 | Files.walkFileTree(from, new CopyPredicateVisitor(from,to,predicate)); 126 | } 127 | 128 | /** 129 | * Returns a DirectoryStream that can iterate over files found recursively based on the pattern provided 130 | * @param startPath the Directory to start from 131 | * @param pattern the glob to match against files 132 | * @return DirectoryStream 133 | * @throws IOException 134 | */ 135 | public static DirectoryStream glob(Path startPath, String pattern) throws IOException{ 136 | validate(startPath); 137 | return new AsynchronousRecursiveDirectoryStream(startPath,pattern); 138 | } 139 | 140 | 141 | 142 | private static void validate(Path... paths) { 143 | for (Path path : paths) { 144 | Objects.requireNonNull(path); 145 | if (!Files.isDirectory(path)) { 146 | throw new IllegalArgumentException(String.format("%s is not a directory", path.toString())); 147 | } 148 | } 149 | } 150 | 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/files/PathsTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.files; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 1/10/12 7 | * Time: 10:18 PM 8 | */ 9 | import org.junit.Test; 10 | 11 | import java.io.File; 12 | import java.nio.file.*; 13 | 14 | import static org.junit.Assert.*; 15 | import static org.hamcrest.CoreMatchers.*; 16 | 17 | 18 | public class PathsTest { 19 | 20 | @Test 21 | public void testPathsMultipleArgsOnePath() throws Exception{ 22 | String expected = "src/test/resources/test.txt"; 23 | Path path = Paths.get("src/","test/","resources/","test.txt"); 24 | assertThat(expected,is(path.toString())); 25 | } 26 | 27 | @Test 28 | public void testUsrLocalIsAbsoluteTest() throws Exception { 29 | Path path = Paths.get("/usr/local"); 30 | assertThat(path.resolve("/usr/local"),is(path)); 31 | assertThat(path.isAbsolute(),is(true)); 32 | Path resolved = path.resolve("/usr/local"); 33 | assertThat(resolved.isAbsolute(),is(true)); 34 | assertThat(Paths.get("/usr/local").isAbsolute(),is(true)); 35 | } 36 | 37 | @Test 38 | public void testPathsComparedToFileSystemPath() throws Exception { 39 | String expected = "src/test/resources/test.txt"; 40 | Path path = Paths.get("src/","test/","resources/","test.txt"); 41 | Path fsPath = FileSystems.getDefault().getPath("src/","test/","resources/","test.txt"); 42 | assertThat(Files.isSameFile(path,fsPath),is(true)); 43 | } 44 | 45 | @Test 46 | public void testPathsMultipleArgsOnePathFirstAbsolute(){ 47 | String expected = "/src/test/resources/test.txt"; 48 | Path path = Paths.get("/src/","/test/","//resources////","/test.txt"); 49 | assertThat(path.toString(),is(expected)); 50 | } 51 | 52 | @Test 53 | public void testPathsMultipleArgsOnePathNotFirstAbsolute(){ 54 | String expected = "src/test/resources/test.txt"; 55 | Path path = Paths.get("src/","test/","/resources/","/test.txt"); 56 | assertThat(expected,is(path.toString())); 57 | } 58 | 59 | @Test 60 | public void testRelativizeFromLongBasePath() { 61 | Path longParentPath = Paths.get("/usr/local/lib/foo"); 62 | Path path1 = Paths.get("bar/baz"); 63 | Path resolved = longParentPath.resolve(path1); 64 | Path relative = longParentPath.relativize(resolved); 65 | assertThat(resolved.toString(),is("/usr/local/lib/foo/bar/baz")); 66 | assertThat(relative.toString(),is("bar/baz")); 67 | } 68 | 69 | @Test 70 | public void testPathGetFileName(){ 71 | Path path = Paths.get("src/test/resources/test.txt"); 72 | assertThat("test.txt",is(path.getFileName().toString())); 73 | } 74 | 75 | @Test 76 | public void testResolveRelativePath() { 77 | Path basePath = Paths.get("/usr/local"); 78 | String relativePath = "lib/hadoop"; 79 | Path resolved = basePath.resolve(relativePath); 80 | assertThat(resolved.toString(),is("/usr/local/lib/hadoop")); 81 | } 82 | 83 | @Test 84 | public void testRelativizePathFromAbsolute() { 85 | Path basePath = Paths.get("/usr/local"); 86 | Path relativePath = Paths.get("/lib/hadoop"); 87 | Path resolved = basePath.relativize(relativePath); 88 | assertThat(resolved.toString(),is("../../lib/hadoop")); 89 | } 90 | 91 | @Test 92 | public void testRelativizePathFromParent() { 93 | Path p = Paths.get("/usr"); 94 | Path p2 = Paths.get("/usr/local/lib"); 95 | Path p3 = Paths.get("/Users"); 96 | Path p4 = p.relativize(p2); 97 | Path p5 = p3.resolve(p.relativize(p2)); 98 | assertThat(p5.toString(),is("/Users/local/lib")); 99 | } 100 | 101 | 102 | @Test 103 | public void testResolveSibling() { 104 | /* 105 | Directory structure 106 | /parent 107 | child1 108 | child2 109 | */ 110 | Path path = Paths.get("/parent/child1"); 111 | Path sibling = Paths.get("child2"); 112 | Path resolved = path.resolveSibling(sibling); 113 | assertThat(resolved.toString(),is("/parent/child2")); 114 | } 115 | 116 | @Test 117 | public void testResolveSilblingDirAndFileName(){ 118 | Path base = Paths.get("/parent/foo"); 119 | Path sibling = Paths.get("bar"); 120 | Path resolvedSibling = base.resolveSibling(sibling); 121 | assertThat(resolvedSibling.toString(),is("/parent/bar")); 122 | } 123 | 124 | @Test 125 | public void testPathHasRootElement() { 126 | Path path = Paths.get("/Users/bbejeck"); 127 | Path root = path.getRoot(); 128 | assertNotNull(root); 129 | assertThat(root.toString(),is("/")); 130 | } 131 | 132 | @Test 133 | public void testRelativizeWithLongPath(){ 134 | Path base = Paths.get("/usr"); 135 | Path foo = base.resolve("foo"); 136 | Path bar = foo.resolve("bar"); 137 | Path baz = bar.resolve("baz"); 138 | assertThat(baz.toString(),is("/usr/foo/bar/baz")); 139 | Path relative1 = base.relativize(baz); 140 | assertThat(relative1.toString(),is("foo/bar/baz")); 141 | } 142 | 143 | @Test 144 | public void testPathHasNoRootElement() { 145 | Path path = Paths.get("Users/bbejeck"); 146 | Path root = path.getRoot(); 147 | assertNull(root); 148 | } 149 | 150 | 151 | @Test 152 | public void testResolvePathAbsolute(){ 153 | Path path = Paths.get("/Users/bbejeck"); 154 | Path resolved = path.resolve("/dev"); 155 | assertThat(resolved.isAbsolute(),is(true)); 156 | assertThat(resolved.toString(),is("/dev")); 157 | } 158 | 159 | @Test 160 | public void testConvertPathToFile(){ 161 | File file = Paths.get("/Users","bbejeck","dev").toFile(); 162 | assertThat(file.getAbsolutePath(),is("/Users/bbejeck/dev")); 163 | } 164 | 165 | @Test 166 | public void testPathIsDirectory(){ 167 | Path path = Paths.get("src/test/resources/"); 168 | assertThat("resources",is(path.getFileName().toString())); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/nio/util/DirUtilsTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.nio.util; 2 | 3 | import com.google.common.base.Function; 4 | import com.google.common.base.Predicate; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.nio.file.*; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | import static org.hamcrest.CoreMatchers.is; 13 | import static org.junit.Assert.assertThat; 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 1/22/12 19 | * Time: 1:01 PM 20 | */ 21 | 22 | public class DirUtilsTest { 23 | 24 | private Path sourcePath; 25 | private Path targetPath; 26 | private Path fooPath; 27 | private Path barPath; 28 | private Path bazPath; 29 | private Path file1; 30 | private Path file2; 31 | private Path file3; 32 | private Path file4; 33 | private Path fooPathTarget; 34 | private Path barPathTarget; 35 | private Path bazPathTarget; 36 | private Path file1Target; 37 | private Path file2Target; 38 | private Path file3Target; 39 | private Path file4Target; 40 | private int numLines; 41 | private Path[] filePaths; 42 | 43 | @Before 44 | public void setUp() throws Exception { 45 | sourcePath = Paths.get("test-source-dir"); 46 | targetPath = Paths.get("test-target-dir"); 47 | setUpSourcePaths(); 48 | setUpTargetPaths(); 49 | filePaths = new Path[]{file1, file2, file3, file4}; 50 | numLines = 5000; 51 | deleteTestDirsAndFiles(); 52 | createTestDirectoryStructure(); 53 | } 54 | 55 | @Test 56 | public void testDirUtilsClean() throws Exception { 57 | assertAllSourceFilesExistIs(true); 58 | assertAllSourceDirsExistIs(true); 59 | 60 | DirUtils.clean(sourcePath); 61 | assertAllSourceFilesExistIs(false); 62 | assertAllSourceDirsExistIs(true); 63 | } 64 | 65 | @Test 66 | public void testDirUtilsDelete() throws Exception { 67 | assertAllSourceFilesExistIs(true); 68 | assertAllSourceDirsExistIs(true); 69 | 70 | DirUtils.delete(sourcePath); 71 | assertAllSourceFilesExistIs(false); 72 | assertAllSourceDirsExistIs(false); 73 | } 74 | 75 | @Test 76 | public void testDirUtilsCopy() throws Exception { 77 | assertAllSourceDirsExistIs(true); 78 | assertAllSourceFilesExistIs(true); 79 | assertAllTargetDirsExistIs(false); 80 | assertAllTargetFilesExistIs(false); 81 | 82 | DirUtils.copy(sourcePath, targetPath); 83 | 84 | assertAllSourceDirsExistIs(true); 85 | assertAllSourceFilesExistIs(true); 86 | assertAllTargetDirsExistIs(true); 87 | assertAllTargetFilesExistIs(true); 88 | } 89 | 90 | @Test 91 | public void testDirUtilsMove() throws Exception { 92 | assertAllSourceDirsExistIs(true); 93 | assertAllSourceFilesExistIs(true); 94 | assertAllTargetDirsExistIs(false); 95 | assertAllTargetFilesExistIs(false); 96 | 97 | DirUtils.move(sourcePath, targetPath); 98 | 99 | assertAllSourceDirsExistIs(false); 100 | assertAllSourceFilesExistIs(false); 101 | assertAllTargetDirsExistIs(true); 102 | assertAllTargetFilesExistIs(true); 103 | } 104 | 105 | @Test 106 | public void testApply() throws Exception { 107 | final List names = new ArrayList<>(); 108 | Function function = new Function() { 109 | @Override 110 | public FileVisitResult apply(Path path) { 111 | names.add(path.getFileName().toString()); 112 | return FileVisitResult.CONTINUE; 113 | } 114 | }; 115 | DirUtils.apply(sourcePath, function); 116 | assertThat(names.size(), is(4)); 117 | assertThat(names.contains("file1.txt"), is(true)); 118 | assertThat(names.contains("file2.txt"), is(true)); 119 | assertThat(names.contains("file3.txt"), is(true)); 120 | assertThat(names.contains("file4.txt"), is(true)); 121 | } 122 | 123 | @Test 124 | public void testCopyPredicate() throws Exception { 125 | Predicate copyPredicate = new Predicate() { 126 | @Override 127 | public boolean apply(Path input) { 128 | return (Files.isDirectory(input) && !input.getFileName().toString().equals("foo")); 129 | } 130 | }; 131 | DirUtils.copyWithPredicate(sourcePath, targetPath, copyPredicate); 132 | assertThat(Files.exists(targetPath), is(true)); 133 | assertThat(Files.exists(fooPathTarget), is(false)); 134 | assertThat(Files.exists(barPathTarget), is(false)); 135 | assertThat(Files.exists(bazPathTarget), is(true)); 136 | } 137 | 138 | @Test 139 | public void testDirectoryStream() throws Exception { 140 | int expectedCount = 4; 141 | int fileCount = 0; 142 | try (DirectoryStream directoryStream = DirUtils.glob(sourcePath, "*.txt")) { 143 | for (Path path : directoryStream) { 144 | if (Files.isRegularFile(path)) { 145 | fileCount++; 146 | } 147 | } 148 | } 149 | assertThat(expectedCount, is(fileCount)); 150 | } 151 | 152 | 153 | //TODO add method to assert all files sizes are same 154 | 155 | private void assertAllSourceFilesExistIs(boolean flag) { 156 | assertThat(Files.exists(file1), is(flag)); 157 | assertThat(Files.exists(file2), is(flag)); 158 | assertThat(Files.exists(file3), is(flag)); 159 | assertThat(Files.exists(file4), is(flag)); 160 | } 161 | 162 | private void assertAllSourceDirsExistIs(boolean flag) { 163 | assertThat(Files.exists(sourcePath), is(flag)); 164 | assertThat(Files.exists(fooPath), is(flag)); 165 | assertThat(Files.exists(barPath), is(flag)); 166 | assertThat(Files.exists(bazPath), is(flag)); 167 | } 168 | 169 | private void assertAllTargetFilesExistIs(boolean flag) { 170 | assertThat(Files.exists(file1Target), is(flag)); 171 | assertThat(Files.exists(file2Target), is(flag)); 172 | assertThat(Files.exists(file3Target), is(flag)); 173 | assertThat(Files.exists(file4Target), is(flag)); 174 | } 175 | 176 | private void assertAllTargetDirsExistIs(boolean flag) { 177 | assertThat(Files.exists(targetPath), is(flag)); 178 | assertThat(Files.exists(fooPathTarget), is(flag)); 179 | assertThat(Files.exists(barPathTarget), is(flag)); 180 | assertThat(Files.exists(bazPathTarget), is(flag)); 181 | } 182 | 183 | private void createTestDirectoryStructure() throws Exception { 184 | Files.createDirectories(barPath); 185 | Files.createDirectories(bazPath); 186 | for (Path filePath : filePaths) { 187 | generateFiles(filePath, numLines); 188 | } 189 | } 190 | 191 | private void deleteTestDirsAndFiles() throws Exception { 192 | if (Files.exists(sourcePath)) { 193 | DirUtils.delete(sourcePath); 194 | } 195 | 196 | if (Files.exists(targetPath)) { 197 | DirUtils.delete(targetPath); 198 | } 199 | } 200 | 201 | 202 | private void generateFiles(Path path, int numberLines) throws Exception { 203 | FileGenerator.generate(path, numberLines); 204 | } 205 | 206 | private void setUpTargetPaths() { 207 | fooPathTarget = targetPath.resolve("foo"); 208 | barPathTarget = fooPathTarget.resolve("bar"); 209 | bazPathTarget = targetPath.resolve("baz"); 210 | file1Target = fooPathTarget.resolve("file1.txt"); 211 | file2Target = barPathTarget.resolve("file2.txt"); 212 | file3Target = barPathTarget.resolve("file3.txt"); 213 | file4Target = bazPathTarget.resolve("file4.txt"); 214 | } 215 | 216 | private void setUpSourcePaths() { 217 | fooPath = sourcePath.resolve("foo"); 218 | barPath = fooPath.resolve("bar"); 219 | bazPath = sourcePath.resolve("baz"); 220 | file1 = fooPath.resolve("file1.txt"); 221 | file2 = barPath.resolve("file2.txt"); 222 | file3 = barPath.resolve("file3.txt"); 223 | file4 = bazPath.resolve("file4.txt"); 224 | } 225 | } 226 | --------------------------------------------------------------------------------