31 Temmuz 2018 Salı

WatchService Sınıfı - NIO

Giriş
Şu satırı dahil ederiz.
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
Bu sınıf yerine eskiden Apache Commons'tan VFS API kullanılırdı.

Kullanım
1. FileSystem sınıfının newWatchService() metodunu kullanarak bir WatchService yaratılır.

2. Daha sonra Path.register() metodu ile izlemek istediğimiz dizini ve olayları belirtiriz.

2.1 Dosya yaratılmayı yakalamak için StandardWatchEventKinds.ENTRY_CREATE kullanılır. Dosyanın yaratılmış olması diğer uygulamanın yazmayı bitirdiği anlamına gelmez.

2.2 Dosyanın değiştirildiğimi yakalamak için StandardWatchEventKinds.ENTRY_MODIFY kullanılır. Belli bir süre değiştirilmeyen dosyaya diğer uygulamanın yazmayı bitirdiği varsayabilir.

3. WatchService.take() veya WatchService.poll() ile sonsuz bir döngü kurarak dizini izlemeye başlarız. 
Sonsuz döngü bir ExecutorService ile de kurulabilir.

Kullanılan Thread
WatchService tek bir thread kullanır. Bu thread'in ismi şöyle
Thread[FileSystemWatcher]
constructor
Örnek
Şöyle yaparız.
WatchService watchService = FileSystems.getDefault().newWatchService();
register metodu
Örnek

Dosya yaratılmayı yakalamak için StandardWatchEventKinds.ENTRY_CREATE kullanılır. Şöyle yaparız.
Path faxFolder = Paths.get("./faxFolder/");
WatchService watchService = ...;
faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
Örnek
Şöyle yaparız. Burada bir dizin gözlemleniyor.
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

WatchService watcher = FileSystems.getDefault().newWatchService();

Path path = ...;
WatchKey watchKes = path.register(watcher,
  ENTRY_CREATE,
  ENTRY_DELETE,
  ENTRY_MODIFY);
poll metodu
Belirtilen süre kadar WatchKey nesnesinin gelmesini bekler.

take metodu
WatchKey nesnesi hazır oluncaya kadar bloke olur.

Örnek
Şöyle yaparız.
WatchKey watckKey = watcher.take();
Örnek
Açıklaması şöyle.
When an event occurs, the key is signaled and placed into the watcher's queue. After processing its events, we need to put it back into a ready state by invoking its reset() method. If it returns false, the key is no longer valid and the loop can exit.
Şöyle yaparız.
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get("c:\\directory");
path.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);

boolean poll = true;

while (poll) {

  WatchKey key = watchService.take();
  for (WatchEvent<?> event : key.pollEvents()) {
    System.out.println("Event kind : " + event.kind() + " - File : " + event.context());
  }

  poll = key.reset();

}
Örnek
Bazı kodlarda null kontrolü yapılıyor. Buna gerek yok.
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(dirLocation);
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
 StandardWatchEventKinds.ENTRY_MODIFY,
 StandardWatchEventKinds.ENTRY_DELETE);
WatchKey key;

while ((key = watchService.take()) != null) {
  for (WatchEvent<?> event : key.pollEvents()) {
    if ("ENTRY_CREATE".equalsIgnoreCase(event.kind().name())) {
      // File reading here
    }
  }
}

Jakarta EE WEB-INF Dizini - Jakarta XML'lerini İçeri

Giriş
Açıklaması şöyle. Jakarta XML'leri bu dizine konulur. Bazı projelerde JSP dosyaları da bu dizine konuluyor. Bu standart kullanım mı emin değilim
A special directory exists within the application hierarchy named WEB-INF. This directory contains all things related to the application that aren’t in the document root of the application. The WEB-INF node is not part of the public document tree of the application. No file contained in the WEB-INF directory may be served directly to a client by the container. However, the contents of the WEB-INF directory are visible to servlet code using the getResource and getResourceAsStream method calls on the ServletContext, and may be exposed using the RequestDispatcher calls.
Yapısı şöyle
ApplicationName
|
|--META-INF
|--WEB-INF
      |_web.xml       <-- configuration file of your web app
      |_classes       <--all the classes of your webapp, 
      |_lib           <--all the libraries (jars) your application need
Spring MVC ile yapısı şöyle. src/main/webapp/WEB_INF şeklinde
├── src
   └── main
       ├── java
          └── com
              └── hellokoding
                  └── hello
                      └── web
                          └── YourClass.java
       ├── resources
          ├── application.properties
          └── logback.xml
       └── webapp
           ├── resources
              ├── css
                 └── bootstrap.min.css
              ├── images
              └── js
                  └── bootstrap.min.js
           └── WEB-INF
               ├── views
                  └── hello.jsp
|               ├── appconfig-mvc.xml
               ├── appconfig-root.xml 
               └── web.xml 
└── pom.xml
Dosyalardan birisi web.xml

META-INF dizini
İçi şöyledir.
Apps
  --META-INF
     -maven
     -MANIFEST.MF
     -war-tracker
  --WEB-INF
      -classes
           -com
           -static
           -application.properties
      - lib-provided
      -lib
      - web.xml + audit-servlet.xml
  --org
  -- My JSP pages ..
classes dizini
Açıklaması şöyle
The WEB-INF/classes and WEB-INF/lib folders are examples of folders required by the Servlet specification at runtime.
Örnek
ClassLoader ile classes dizininden okumak için şöyle yaparız.
this.getClass().getClassLoader().getResourceAsStream("xyz");
Örnek
Elimizde şöyle bir yapı olsun. file.text classes dizini altında.
WEB-INF
    + classes
        + package
            + App.class
        + file.txt
Okumak için şöyle yaparız.
InputStream in = package.App.class.getClassloader().getResourceAsStream("file.txt");
Örnek
Bu sefer dll'leri classes dizinine ekliyoruz. Şöyle yaparız.
WEB-INF\classes\mylibrary.dll
Bu dll'i tomcat'e yükletip JNI ile kullanmak için şöyle yaparız.
${catalina.home}\webapps\ROOT\WEB-INF\classes\mylibrary.dll
lib dizini
lib dizininden okuma yapmak mümkün değil. Açıklaması şöyle
WEB-INF/lib is not in the classpath. It is supposed to contain jar files, that are in the classpath.