View Javadoc

1   package twcsckernel.serverKernel.impl;
2   
3   import java.io.IOException;
4   import java.rmi.RemoteException;
5   import java.util.Collection;
6   import java.util.HashMap;
7   import java.util.Map;
8   
9   import twcsckernel.projectbase.common.FsChangeListener;
10  import twcsckernel.projectbase.common.RemoteAgent;
11  import twcsckernel.projectbase.common.RemoteFileSystem;
12  import twcsckernel.projectbase.common.User;
13  import twcsckernel.projectbase.io.FileSecurityManager;
14  import twcsckernel.projectbase.io.RemoteFileSystemImpl;
15  import twcsckernel.projectbase.plugins.PluginDescriptor;
16  import twcsckernel.serverKernel.io.LogWriter;
17  import twcsckernel.serverKernel.io.SharedFsChangeListener;
18  import twcsckernel.serverKernel.plugins.PluginHandle;
19  import twcsckernel.serverKernel.plugins.ServerPlugin;
20  import twcsckernel.serverKernel.usr.LoginException;
21  import twcsckernel.serverKernel.utils.RmiManager;
22  import twcsckernel.serverKernel.utils.ServerGlobalState;
23  import twcsckernel.serverKernel.utils.UserData;
24  
25  /***
26   * Implementacja interfejsu użytkownika.
27   * 
28   * @author VMD Group
29   * 
30   */
31  public class UserImpl implements User {
32  
33  	private UserData userData = null;
34  
35  	private ServerGlobalState globalState;
36  
37  	private Map<String, ServerPlugin> loggedPlugins;
38  
39  	private Map<String, RemoteAgent> registeredAgents;
40  
41  	private SharedFsChangeListener sharedFsChangeListener;
42  
43  	private FsChangeListener currentRemoteFsListener = null;
44  
45  	private long timeStamp;
46  
47  	private RmiManager rmiManager;
48  
49  	private RemoteFileSystemImpl remoteFileSystem;
50  
51  	private FileSecurityManager secManager;
52  
53  	private String userHost;
54  
55  	public UserImpl(UserData myself, ServerGlobalState globalState,
56  			RmiManager rmiMan, String userHost) throws IOException {
57  		userData = myself;
58  		rmiManager = rmiMan;
59  		this.userHost = userHost;
60  		try {
61  			this.secManager = globalState.loggedUsers.login(this);
62  		} catch (LoginException e) {
63  			// w konstruktorze MULTIPLE_LOGIN nie wystapi;)
64  			throw new IOException(
65  					"An error occured while creating security manager");
66  		}
67  		remoteFileSystem=new RemoteFileSystemImpl(secManager);
68  
69  		rmiManager.exportObject(remoteFileSystem.writerFactory);
70  		try {
71  			rmiManager.exportObject(remoteFileSystem.readerFactory);
72  		} catch (RemoteException re) {
73  			globalState.loggedUsers.logout(this);
74  			rmiManager.unexportObject(remoteFileSystem.writerFactory, true);
75  			throw re;
76  		}
77  		try {
78  			rmiManager.exportObject(remoteFileSystem.fileFactory);
79  		} catch (RemoteException re) {
80  			globalState.loggedUsers.logout(this);
81  			rmiManager.unexportObject(remoteFileSystem.writerFactory, true);
82  			rmiManager.unexportObject(remoteFileSystem.readerFactory, true);
83  			throw re;
84  		}
85  		try {
86  			rmiManager.exportObject(remoteFileSystem);
87  		} catch (RemoteException re) {
88  			globalState.loggedUsers.logout(this);
89  			rmiManager.unexportObject(remoteFileSystem.writerFactory, true);
90  			rmiManager.unexportObject(remoteFileSystem.readerFactory, true);
91  			rmiManager.unexportObject(remoteFileSystem.fileFactory, true);
92  			throw re;
93  		}
94  		sharedFsChangeListener = globalState.loggedUsers
95  				.getSharedUserListener(this);
96  		remoteFileSystem.addFilesystemChangeListener(sharedFsChangeListener);
97  		this.globalState = globalState;
98  		loggedPlugins = new HashMap<String, ServerPlugin>();
99  		registeredAgents = new HashMap<String, RemoteAgent>();
100 		timeStamp = System.currentTimeMillis();
101 	}
102 
103 	// Metody zdalne
104 
105 	public PluginDescriptor[] listClientPlugins() throws RemoteException {
106 		ping();
107 		return globalState.pluginHandleContainer
108 				.getUserPluginsDescriptors(userData.getType());
109 	}
110 
111 	public byte[] downloadClientPlugin(String clientPackagePath)
112 			throws RemoteException, IOException {
113 		ping();
114 		PluginHandle pHandle = globalState.pluginHandleContainer
115 				.getUserPluginByClientPackagePath(userData.getType(),
116 						clientPackagePath);
117 		if (pHandle == null)
118 			return null;
119 		return pHandle.getClientPluginData();
120 	}
121 
122 	public RemoteAgent getRemotePluginAgent(String clientPackagePath,
123 			RemoteAgent clientCallback) throws RemoteException {
124 		ping();
125 		RemoteAgent agent;
126 		synchronized (registeredAgents) {
127 			agent = registeredAgents.get(clientPackagePath);
128 			if (agent == null) {
129 				PluginHandle plugin = globalState.pluginHandleContainer
130 						.getUserPluginByClientPackagePath(userData.getType(),
131 								clientPackagePath);
132 				if (plugin == null)
133 					throw new RemoteException("No such plugin: "
134 							+ clientPackagePath);
135 				ServerPlugin pluginInstance;
136 				try {
137 					pluginInstance = plugin.serverPluginBuilder.getInstance(
138 							this, clientCallback, globalState);
139 				} catch (Exception e) {
140 					throw new RemoteException("exception: "
141 							+ e.getClass().getName() + " message: "
142 							+ e.getMessage(), e.getCause());
143 				}
144 				agent = pluginInstance.getOwnAgent(this);
145 				loggedPlugins.put(clientPackagePath, pluginInstance);
146 				rmiManager.exportObject(agent);
147 				registeredAgents.put(clientPackagePath, agent);
148 			}
149 		}
150 		return agent;
151 	}
152 
153 	public void logout() throws RemoteException {
154 		try {
155 			logout0();
156 		} catch (RemoteException re) {
157 			globalState.logWriter.writeUserLog(
158 					"Error while invoking remote logout of user: \""
159 							+ userData.getLogin() + "\" (" + userHost + ")",
160 					LogWriter.ERROR_OTHER);
161 			throw re;
162 		}
163 		globalState.logWriter.writeUserLog("User \"" + userData.getLogin()
164 				+ "\" (" + userHost + ") has successfully logged out.",
165 				LogWriter.USER_REMOTE_LOGOUT);
166 	}
167 
168 	public RemoteFileSystem getUserFileSystem() throws RemoteException {
169 		return remoteFileSystem;
170 	}
171 
172 	public void setFsChangeListener(FsChangeListener fsChangeListener)
173 			throws RemoteException {
174 		ping();
175 		// pewne implementacje mogą nie obsługiwać nasłuchiwania plików
176 		if (sharedFsChangeListener == null)
177 			return;
178 		synchronized (sharedFsChangeListener) {
179 			if (currentRemoteFsListener != null)
180 				sharedFsChangeListener.removeFsChangeListener(
181 						currentRemoteFsListener, this);
182 			if (fsChangeListener != null)
183 				sharedFsChangeListener.addFsChangeListener(fsChangeListener,
184 						this, secManager.getUserRootPathManager());
185 			currentRemoteFsListener = fsChangeListener;
186 		}
187 	}
188 
189 	public void ping() throws RemoteException {
190 		timeStamp = System.currentTimeMillis();
191 	}
192 
193 	public long getActivityTimeout() throws RemoteException {
194 		return rmiManager.getUserCollectorInterval();
195 	}
196 
197 	// Metody lokalne
198 
199 	private void logout0() throws RemoteException {
200 		/*
201 		 * synchronizacje na agentach i pluginach zapewnia unexportObject(this)
202 		 * odcinajac zdalny dostep do obiektu, a przy powtornym wylogowaniu w
203 		 * przypadku garbage collecora wyrzucony zostanie wyjatek
204 		 * NoSuchObjectException, ktrory takze w tym przypadku zapewni
205 		 * synchronizacje
206 		 */
207 
208 		rmiManager.unexportObject(this, true);
209 		rmiManager.unexportObject(remoteFileSystem, true);
210 		rmiManager.unexportObject(remoteFileSystem.fileFactory, true);
211 		rmiManager.unexportObject(remoteFileSystem.readerFactory, true);
212 		rmiManager.unexportObject(remoteFileSystem.writerFactory, true);
213 		globalState.loggedUsers.logout(this);
214 		Collection<ServerPlugin> loggedPluginsCollection = loggedPlugins
215 				.values();
216 		for (ServerPlugin srvPlugin : loggedPluginsCollection)
217 			srvPlugin.logoutUser(this);
218 		Collection<RemoteAgent> registeredAgentsCollection = registeredAgents
219 				.values();
220 		for (RemoteAgent agent : registeredAgentsCollection)
221 			rmiManager.unexportObject(agent, true);
222 
223 		remoteFileSystem.releaseAllResources();
224 
225 	}
226 
227 	/***
228 	 * Metoda lokalnego wylogowania użytkownika.
229 	 */
230 	public void kickUser() {
231 		try {
232 			logout0();
233 		} catch (RemoteException re) {
234 			globalState.logWriter.writeUserLog(
235 					"Error while invoking local logout [kick] of user: \""
236 							+ userData.getLogin() + "\" (owner: " + userHost
237 							+ ")", LogWriter.ERROR_OTHER);
238 		}
239 		globalState.logWriter.writeUserLog("User \"" + userData.getLogin()
240 				+ "\" (owner: " + userHost
241 				+ ") has been successfully kicked out.",
242 				LogWriter.USER_KICK_LOGOUT);
243 	}
244 
245 	/***
246 	 * @return - login użytkownika
247 	 */
248 	public String getUserLogin() {
249 		return userData.getLogin();
250 	}
251 
252 	/***
253 	 * @return - wartość znacznika czasowego ostatniej operacji jakiej dokonal
254 	 *         użytkownik (<i>System.currentTimeMilis()</i>)
255 	 */
256 	public long getTimeStamp() {
257 		return timeStamp;
258 	}
259 
260 	/***
261 	 * @return - ścieżka root użytkownika
262 	 */
263 	public String getUserRootPath() {
264 		return userData.getRoot();
265 	}
266 
267 	/***
268 	 * @return - typ użytkownika
269 	 */
270 	public String getUserType() {
271 		return userData.getType();
272 	}
273 
274 	/***
275 	 * @return - pełne dane użytkownika
276 	 */
277 	public UserData getFullUserData() {
278 		return userData;
279 	}
280 
281 }