View Javadoc

1   package twcsckernel.clientKernel.io;
2   
3   import java.io.IOException;
4   import java.rmi.RemoteException;
5   import java.util.ArrayList;
6   import java.util.Collections;
7   import java.util.HashMap;
8   import java.util.Map;
9   
10  import twcsckernel.clientKernel.io.fsChangeListenerClasses.RegisteredListenersListElem;
11  import twcsckernel.clientKernel.utils.CommonVariablesContainer;
12  import twcsckernel.projectbase.common.FsChangeListener;
13  import twcsckernel.projectbase.io.FileDescriptor;
14  import twcsckernel.projectbase.io.FsChangeDescriptor;
15  import twcsckernel.projectbase.io.LocalFsChangeListener;
16  import twcsckernel.projectbase.io.RemoteFile;
17  
18  public class FsChangeListenerServer implements FsChangeListener{
19  	/***
20  	 * 
21  	 */
22  	private static final long serialVersionUID = -2004662961257233974L;
23  
24  	private Map<String, ArrayList<RegisteredListenersListElem>> registeredListings;
25  
26  	private Map<LocalFsChangeListener, ArrayList<String>> registeredListeners;
27  
28  	public void fsChangeNotify(FsChangeDescriptor fsDescriptor)
29  			throws RemoteException {
30  
31  		// TODO: dla katalogów informowanie o zmianach w nich zawartych. Po
32  		// uzgodnieniu z bogiem listenerow
33  
34  		String path;
35  		if (fsDescriptor.getChangeType() == FsChangeDescriptor.FILE_RENAME
36  				|| fsDescriptor.getChangeType() == FsChangeDescriptor.FILE_DELETE) {
37  			path = fsDescriptor.getSource();
38  		} else {
39  
40  			path = fsDescriptor.getChangeInfo().getPath();
41  			if (path.length() == 0 || path.charAt(path.length()-1)!='/')
42  				path.concat("/");
43  			
44  			path = path + fsDescriptor.getChangeInfo().getName();
45  			
46  		}
47  //		System.out.println("Odebrano notify  type: "+fsDescriptor.getChangeType()+" na sciezke: "+path);
48  		
49  		synchronized (registeredListings) {
50  			ArrayList<RegisteredListenersListElem> tempElemList = registeredListings
51  					.get(path);
52  			if (tempElemList == null)
53  				return;
54  			for (RegisteredListenersListElem le : tempElemList) {
55  				if (le.typeListen(fsDescriptor.getChangeType())) {
56  					le.getListener().fsChangeNotify(fsDescriptor);
57  				}
58  			}
59  		}
60  		
61  		if (fsDescriptor.getChangeType()==FsChangeDescriptor.FILE_CREATE || fsDescriptor.getChangeType()==FsChangeDescriptor.FILE_DELETE){
62  			FsChangeDescriptor newDesc = new FsChangeDescriptor(FsChangeDescriptor.FILE_REFRESH);
63  			RemoteFile rf;
64  			FileDescriptor fd;
65  			try {
66  				rf = CommonVariablesContainer.rff.newRemoteFile(path);
67  				String parent  = rf.getParent();
68  				rf.disposeFileHandle();
69  				rf = CommonVariablesContainer.rff.newRemoteFile(parent);
70  				fd=rf.getDescriptor();
71  				rf.disposeFileHandle();
72  			} catch (RemoteException e) {
73  				// TODO Auto-generated catch block
74  				return;
75  			} catch (SecurityException e) {
76  				// TODO Auto-generated catch block
77  				return;
78  			} catch (IOException e) {
79  				// TODO Auto-generated catch block
80  				return;
81  			}
82  			
83  			newDesc.setChangeInfo(fd);
84  			fsChangeNotify(newDesc);
85  		}
86  
87  	}
88  
89  	public FsChangeListenerServer() {
90  		registeredListings = Collections
91  				.synchronizedMap(new HashMap<String, ArrayList<RegisteredListenersListElem>>());
92  		;
93  		registeredListeners = Collections
94  				.synchronizedMap(new HashMap<LocalFsChangeListener, ArrayList<String>>());
95  	}
96  
97  	/***
98  	 * Metoda rejestruje obiekt mający otrzymywać informacje o zmianach pliku
99  	 * wskazanego przez <code>path</code> o typach wskazanych przez
100 	 * <code>changeTypes</code>. Zmienna <code>changeTypes</code> jest
101 	 * tablicą zmiennej długości typu integer, wartości dopuszczalne to
102 	 * statyczne pola klasy <i>FsChangeDescriptor</i>. Użycie innych wartości
103 	 * całkowitoliczbowych może spowodować nieprzewidywalne zachowanie.
104 	 * 
105 	 * @param lfsl
106 	 *            obiekt implementujący interfejs LocalFsChangeListener
107 	 * @param path
108 	 *            sciezka do monitorowanego pliku
109 	 * @param changeTypes
110 	 *            typy śledzonych zmian
111 	 */
112 	public void registerLocalListener(LocalFsChangeListener lfsl, String path,
113 			int... changeTypes) {
114 		synchronized (registeredListings) {
115 			synchronized (registeredListeners) {
116 				RegisteredListenersListElem newElem = new RegisteredListenersListElem(
117 						lfsl, changeTypes);
118 				ArrayList<RegisteredListenersListElem> tempList;
119 				if ((tempList = registeredListings.get(path)) != null) {
120 					int index;
121 
122 					if ((index = tempList.indexOf(newElem)) >= 0) {
123 						tempList.get(index).addNewTypes(changeTypes);
124 					} else {
125 						tempList.add(newElem);
126 					}
127 				} else {
128 					tempList = new ArrayList<RegisteredListenersListElem>();
129 					tempList.add(newElem);
130 					registeredListings.put(path, tempList);
131 
132 				}
133 			}
134 			ArrayList<String> tempPathList;
135 			if ((tempPathList = registeredListeners.get(lfsl)) != null) {
136 				if (tempPathList.indexOf(path) == -1) {
137 					tempPathList.add(path);
138 				} else
139 					;
140 			} else {
141 				tempPathList = new ArrayList<String>();
142 				tempPathList.add(path);
143 				registeredListeners.put(lfsl, tempPathList);
144 			}
145 		}
146 	}
147 
148 	/***
149 	 * Usuwanie odbiorcy z listy obslugiwanych obiektów
150 	 * 
151 	 * @param lfscl
152 	 *            Odbiorca, który ma zostać usunięty
153 	 */
154 
155 	public void unregisterLocalListener(LocalFsChangeListener lfscl) {
156 		Object[] pathTable = new Object[0];
157 		synchronized (registeredListeners) {
158 			//TODO null pointer exception jak sie 
159 			//probuje wtyrejestrowac nieisrniejacy
160 			pathTable = registeredListeners.get(lfscl).toArray();
161 			if (pathTable ==null)
162 				return;
163 		}
164 		for (Object s : pathTable) {
165 			unregisterLocalListener(lfscl, (String)s, 0xFFFFFFFF);
166 		}
167 	}
168 
169 	/***
170 	 * Wyłączenie nasłuchu danego pliku
171 	 * 
172 	 * @param lfscl
173 	 *            Lokalny odbiorca zdarzen systemu plików
174 	 * @param path
175 	 *            Ścieżka na której odbiorca nasłuchuje
176 	 */
177 
178 	public void unregisterLocalListener(LocalFsChangeListener lfscl, String path) {
179 		unregisterLocalListener(lfscl, path, 0xFFFFFFFF);
180 	}
181 
182 	/***
183 	 * Wyłączanie poszczególnych typów nasłuchów.
184 	 * 
185 	 * @param lfscl
186 	 *            Lokalny odbiorca zdarzen systemu plików
187 	 * @param path
188 	 *            Ścieżka na której odbiorca nasłuchuje
189 	 * @param changeTypes
190 	 *            Typy zmian jakie mają zostać usunięte z listy nasłuchu -
191 	 *            informajce o tych zdarzeniach nie będą już więcej przekazywane
192 	 *            do odbiorcy.
193 	 */
194 
195 	public void unregisterLocalListener(LocalFsChangeListener lfscl,
196 			String path, int... changeTypes) {
197 		synchronized (registeredListings) {
198 			ArrayList<RegisteredListenersListElem> tempRListenersList;
199 			if ((tempRListenersList = registeredListings.get(path)) != null) {
200 				RegisteredListenersListElem tempElem = new RegisteredListenersListElem(
201 						lfscl, 0);
202 				if (tempRListenersList.contains(tempElem)) {
203 					int index = tempRListenersList.indexOf(tempElem);
204 					if (tempRListenersList.get(index).constraintListening(
205 							changeTypes) == 0) {
206 						tempRListenersList.remove(index);
207 						if (tempRListenersList.size() == 0) {
208 							registeredListings.remove(path);
209 						}
210 						synchronized (registeredListeners) {
211 							registeredListeners.get(lfscl).remove(path);
212 							if (registeredListeners.get(lfscl).size() == 0) {
213 								registeredListeners.remove(lfscl);
214 							}
215 						}
216 					}
217 				}
218 			}
219 
220 		}
221 
222 	}
223 
224 }