View Javadoc

1   package org.treetank.filelistener.file;
2   
3   import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
4   import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
5   import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
6   
7   import java.io.File;
8   import java.nio.file.WatchEvent;
9   import java.util.Collection;
10  import java.util.HashSet;
11  import java.util.Objects;
12  import java.util.concurrent.Callable;
13  
14  import org.treetank.api.IFilelistenerWriteTrx;
15  
16  /**
17   * This class is used to safe notifications from the filesystem for later
18   * processing via the WorkingQueue.
19   * 
20   * @author Andreas Rain
21   * 
22   */
23  public class FilesystemNotification implements Callable<Void> {
24          
25  	/** The file that has been changed */
26  	private final File mFile;
27  
28  	/** Determine whether or not this fsn has finished. */
29  	private boolean mFinished;
30  
31  	/** The relative path as a String */
32  	private final String mRelativePath;
33  
34  	/** The root path of the listener folder */
35  	private final String mRootPath;
36  
37  	/** The event for this notification */
38  	private WatchEvent.Kind<?> mEvtType;
39  	
40  	/**
41  	 * Time this notification needed to be processed.
42  	 */
43  	private long mTimeTaken;
44  	
45  	/**
46  	 * Bucket amount
47  	 */
48  	private int mBuckets;
49  
50  	/** Transaction to use */
51  	private final IFilelistenerWriteTrx mWtx;
52  
53  	/**
54  	 * FilesystemNotificationObservers for this notification
55  	 */
56  	private Collection<FilesystemNotificationObserver> mObservers;
57  
58  	/**
59  	 * Create a FilesystemNotification that holds the File
60  	 * 
61  	 * @param pFile
62  	 * @param pRelativePath
63  	 * @param pRootPath
64  	 */
65  	public FilesystemNotification(File pFile, String pRelativePath,
66  			String pRootPath, WatchEvent.Kind<?> pEvtType,
67  			IFilelistenerWriteTrx pWtx) {
68  		super();
69  		mFile = pFile;
70  		mRelativePath = pRelativePath;
71  		mRootPath = pRootPath;
72  		mEvtType = pEvtType;
73  		mWtx = pWtx;
74  		mFinished = false;
75  		mObservers = new HashSet<>();
76  	}
77  
78  	public File getFile() {
79  		return mFile;
80  	}
81  
82  	public String getRelativePath() {
83  		return mRelativePath;
84  	}
85  
86  	public String getRootPath() {
87  		return mRootPath;
88  	}
89  
90  	public void setEvtType(WatchEvent.Kind<?> pEvtType) {
91  		mEvtType = pEvtType;
92  	}
93  
94  	public WatchEvent.Kind<?> getEvtType() {
95  		return mEvtType;
96  	}
97  
98  	public boolean isFinished() {
99  		return mFinished;
100 	}
101 
102 	@Override
103 	public int hashCode() {
104 		return Objects.hash(mEvtType, mRelativePath, mRootPath, mFile);
105 	}
106 
107 	@Override
108 	public boolean equals(Object o) {
109 		return this.hashCode() == o.hashCode();
110 	}
111 
112 	@Override
113 	public Void call() throws Exception {
114 	        mTimeTaken = System.currentTimeMillis();
115 
116 		if (this.getEvtType() == ENTRY_CREATE) {
117 			mWtx.addEmptyFile(this.getRelativePath());
118 		} else if (this.getEvtType() == ENTRY_MODIFY) {
119 			mWtx.removeFile(this.getRelativePath());
120 			if (this.getFile().exists()) {
121 				mWtx.addFile(this.getFile(), this.getRelativePath());
122 
123 				if (this.mObservers.size() > 0) {
124 					// For bench purposes
125 //				    System.out.println("Commiting blocked");
126 					mWtx.commitBlocked();
127 //				    System.out.println("Commit finsihed.");
128 				} else {
129 					// Non blocking
130 					mWtx.commit();
131 				}
132 			}
133 		} else if (this.getEvtType() == ENTRY_DELETE) {
134 			mWtx.removeFile(this.getRelativePath());
135 		}
136 
137 		mFinished = true;
138 		
139 		mTimeTaken = System.currentTimeMillis() - mTimeTaken;
140 
141 		// Notifying observers that a task has been finished.
142 		this.notifyObservers();
143 		return null;
144 	}
145 	
146 	/**
147 	 * Determine how long this notifcation was processed.
148 	 * @return time in form of a long in ms
149 	 */
150 	public long getTime(){
151 	    return mTimeTaken;
152 	}
153         
154         /**
155          * Determine how many buckets are in the storage after this notifcation was processed.
156          * @return amount of buckets
157          */
158         public int getBucketAmount(){
159             return mBuckets;
160         }
161 
162 	/**
163 	 * @throws InterruptedException
164 	 */
165 	public void notifyObservers() throws InterruptedException {
166 		synchronized (this) {
167 			for (FilesystemNotificationObserver o : mObservers) {
168 		                mBuckets = mWtx.getCount();
169 				o.addNotification(this);
170 			}
171 		}
172 	}
173 
174 	/**
175 	 * @param observer
176 	 */
177 	public void addObserver(FilesystemNotificationObserver observer) {
178 		this.mObservers.add(observer);
179 	}
180 
181 }