View Javadoc

1   /*
2    * <cvs:source>$Source: /devel/astrogrid/mySpace/client/src/java/org/astrogrid/store/tree/TreeClientMock.java,v $</cvs:source>
3    * <cvs:author>$Author: clq2 $</cvs:author>
4    * <cvs:date>$Date: 2004/11/17 16:22:53 $</cvs:date>
5    * <cvs:version>$Revision: 1.2 $</cvs:version>
6    * <cvs:log>
7    *   $Log: TreeClientMock.java,v $
8    *   Revision 1.2  2004/11/17 16:22:53  clq2
9    *   nww-itn07-704
10   *
11   *   Revision 1.1.2.2  2004/11/16 17:27:58  nw
12   *   tidied imports
13   *
14   *   Revision 1.1.2.1  2004/11/16 16:47:28  nw
15   *   copied aladinAdapter interfaces into a neutrally-named package.
16   *   deprecated original interfaces.
17   *   javadoc
18   *
19   *   Revision 1.3  2004/10/05 15:39:29  dave
20   *   Merged changes to AladinAdapter ...
21   *
22   *   Revision 1.2.4.1  2004/10/05 15:30:44  dave
23   *   Moved test base from test to src tree ....
24   *   Added MimeTypeUtil
25   *   Added getMimeType to the adapter API
26   *   Added logout to the adapter API
27   *
28   *   Revision 1.2  2004/09/28 10:24:19  dave
29   *   Added AladinAdapter interfaces and mock implementation.
30   *
31   *   Revision 1.1.2.8  2004/09/27 22:46:53  dave
32   *   Added AdapterFile interface, with input and output stream API.
33   *
34   *   Revision 1.1.2.7  2004/09/24 01:36:18  dave
35   *   Refactored File as Node and Container ...
36   *
37   *   Revision 1.1.2.6  2004/09/24 01:12:09  dave
38   *   Added initial test for child nodes.
39   *
40   *   Revision 1.1.2.5  2004/09/23 16:32:02  dave
41   *   Added better Exception handling ....
42   *   Added initial mock container ....
43   *   Added initial root container tests ...
44   *
45   *   Revision 1.1.2.4  2004/09/23 12:21:31  dave
46   *   Added mock security service and login test ...
47   *
48   *   Revision 1.1.2.3  2004/09/23 10:12:19  dave
49   *   Added config properties for JUnit tests ....
50   *   Added test for null password.
51   *
52   *   Revision 1.1.2.2  2004/09/23 09:18:13  dave
53   *   Renamed AbstractTest to TestBase to exclude it from batch test ....
54   *   Added first test for null account ....
55   *
56   *   Revision 1.1.2.1  2004/09/22 16:47:37  dave
57   *   Added initial classes and tests for AladinAdapter.
58   *
59   * </cvs:log>
60   *
61   */
62  package org.astrogrid.store.tree;
63  
64  import org.astrogrid.community.common.exception.CommunitySecurityException;
65  import org.astrogrid.community.common.ivorn.CommunityIvornParser;
66  import org.astrogrid.community.common.security.data.SecurityToken;
67  import org.astrogrid.community.common.security.service.SecurityServiceMock;
68  import org.astrogrid.store.Ivorn;
69  import org.astrogrid.store.util.MimeTypeUtil;
70  
71  import org.apache.commons.collections.collection.UnmodifiableCollection;
72  
73  import java.io.ByteArrayInputStream;
74  import java.io.ByteArrayOutputStream;
75  import java.io.InputStream;
76  import java.io.OutputStream;
77  import java.util.Collection;
78  import java.util.HashMap;
79  import java.util.Map;
80  
81  /***
82   * A mock implementation of the AladinAdapter interface.
83   *
84   */
85  public class TreeClientMock
86  	implements TreeClient
87  	{
88  
89  	/***
90  	 * Our test account identifier.
91  	 *
92  	 */
93  	private Ivorn account ;
94  
95  	/***
96  	 * Set the test account identifier.
97  	 * @param ivorn The test account identifier.
98  	 *
99  	 */
100 	public void setTestAccount(Ivorn ivorn)
101 		{
102 		this.account = ivorn ;
103 		}
104 
105 	/***
106 	 * Set the test account password.
107 	 *
108 	 */
109 	public void setTestPassword(String password)
110 		{
111 		//
112 		// Setup the security service password.
113 		security.setPassword(password) ;
114 		}
115 
116 	/***
117 	 * Our mock security service.
118 	 *
119 	 */
120 	SecurityServiceMock security = new SecurityServiceMock() ;
121 
122 	/***
123 	 * Public constructor.
124 	 *
125 	 */
126 	public TreeClientMock()
127 		{
128 		}
129 
130 	/***
131 	 * Our current secutiry token.
132 	 *
133 	 */
134 	private SecurityToken token ;
135 
136 	/***
137 	 * Login to the AstroGrid community.
138 	 * @param ivorn    The 'ivo://...' identifier for the AstroGrid account.
139 	 * @param password The account password.
140      * @throws TreeClientLoginException   If the login fails.
141      * @throws TreeClientServiceException If unable to handle the request.
142 	 *
143 	 */
144 	public void login(Ivorn ivorn, String password)
145 		throws TreeClientLoginException, TreeClientServiceException
146 		{
147 		if (null == ivorn)
148 			{
149 			throw new IllegalArgumentException(
150 				"Null account"
151 				) ;
152 			}
153 		if (null == password)
154 			{
155 			throw new IllegalArgumentException(
156 				"Null password"
157 				) ;
158 			}
159 		//
160 		// Check the password with our resolver.
161 		try {
162 			//
163 			// Try login to the account.
164 			this.token = null ;
165 			this.token = security.checkPassword(
166 				ivorn.toString(),
167 				password
168 				) ;
169 			//
170 			// Initialise our file system.
171 			this.init() ;
172 			}
173 		catch (CommunitySecurityException ouch)
174 			{
175 			throw new TreeClientLoginException(
176 				"Login failed",
177 				ouch
178 				) ;
179 			}
180 		catch (Throwable ouch)
181 			{
182 			throw new TreeClientServiceException(
183 				"Failed to perform request",
184 				ouch
185 				) ;
186 			}
187 		}
188 
189 	/***
190 	 * Access to the current security token.
191 	 * @return The current security token, or null if not logged in.
192 	 *
193 	 */
194 	public SecurityToken getToken()
195 		{
196 		return this.token ;
197 		}
198 
199 	/***
200 	 * Logout from the AstroGrid community.
201 	 *
202 	 */
203 	public void logout()
204 		{
205 		this.token = null ;
206 		}
207 
208 	/***
209 	 * Our fake myspace file system.
210 	 *
211 	 */
212 	private Map myspace = new HashMap() ;
213 
214 	/***
215 	 * Get the root node of the account home space.
216 	 * @return An AladinAdapterContainer representing the root of the account myspace.
217      * @throws TreeClientSecurityException If the adapter is not logged in.
218      * @throws TreeClientServiceException  If unable to handle the request.
219 	 *
220 	 */
221 	public Container getRoot()
222 		throws TreeClientSecurityException, TreeClientServiceException
223 		{
224 		//
225 		// Check we are logged in.
226 		if (null == this.token)
227 			{
228 			throw new TreeClientSecurityException(
229 				"Not logged in"
230 				) ;
231 			}
232 		//
233 		// If we are logged in.
234 		else {
235 			return (Container) myspace.get(
236 				this.token.getAccount()
237 				) ;
238 			}
239 		}
240 
241 	/***
242 	 * Initialise our mock myspace.
243 	 *
244 	 */
245 	private void init()
246 		throws TreeClientServiceException
247 		{
248 		//
249 		// If we have a valid token.
250 		if (null != this.token)
251 			{
252 			//
253 			// If we don't have a root node for the account.
254 			if (false == myspace.containsKey(this.token.getAccount()))
255 				{
256 				try {
257 					//
258 					// Parse current the account ivorn.
259 					CommunityIvornParser parser = new CommunityIvornParser(
260 						this.token.getAccount()
261 						) ;
262 					//
263 					// Create the root node for this account.
264 					MockContainer root = new MockContainer(
265 							parser.getAccountName()
266 							) ;
267 					//
268 					// Add the default child containers.
269 					root.addContainer(
270 						"workflow"
271 						) ;
272 					//
273 					// Add the root container to our map.
274 					myspace.put(
275 						this.token.getAccount(),
276 						root
277 						) ;
278 					}
279 				catch (Exception ouch)
280 					{
281 					throw new TreeClientServiceException(
282 						"Failed to initialise account space",
283 						ouch
284 						) ;
285 					}
286 				}
287 			}
288 		}
289 
290 	/***
291 	 * Inner class to represent a myspace container.
292 	 *
293 	 */
294 	public class MockContainer
295 		implements Container
296 		{
297 		/***
298 		 * Public constructor.
299 		 * @param name The container name.
300 		 *
301 		 */
302 		public MockContainer(String name)
303 			{
304 			if (null == name)
305 				{
306 				throw new IllegalArgumentException(
307 					"Null container name"
308 					) ;
309 				}
310 			this.name = name ;
311 			}
312 
313 		/***
314 		 * The name of this container.
315 		 *
316 		 */
317 		private String name ;
318 
319 		/***
320 		 * Access to the name.
321 		 *
322 		 */
323 		public String getName()
324 			{
325 			return this.name ;
326 			}
327 
328 		/***
329 		 * Check if this represents a file.
330 		 * @return true if this is a file.
331 		 *
332 		 */
333 		public boolean isFile()
334 			{
335 			return false ;
336 			}
337 
338 		/***
339 		 * Check if this represents a container.
340 		 * @return true if this is a container.
341 		 *
342 		 */
343 		public boolean isContainer()
344 			{
345 			return true ;
346 			}
347 
348 		/***
349 		 * A map of our child nodes.
350 		 *
351 		 */
352 		private Map nodes = new HashMap() ;
353 
354 		/***
355 		 * Get a list (collection) of the current child nodes.
356 		 * Note, you cannot add a child node by adding a node to the collection.
357 		 * @return An unmodifiable collection of AladinAdapterNode(s) for the child nodes.
358 		 *
359 		 */
360 		public Collection getChildNodes()
361 			{
362 			return UnmodifiableCollection.decorate(
363 				nodes.values()
364 				) ;
365 			}
366 
367 		/***
368 		 * Add a child container.
369 		 * @param name The container name.
370 	     * @throws TreeClientDuplicateException If the container already exists.
371 		 * @throws TreeClientServiceException   If the service is unable to handle the request.
372 		 *
373 		 */
374 		public Container addContainer(String name)
375 			throws TreeClientDuplicateException
376 			{
377 			if (nodes.containsKey(name))
378 				{
379 				throw new TreeClientDuplicateException() ;
380 				}
381 			else {
382 				Container node = new MockContainer(
383 					name
384 					) ;
385 				nodes.put(
386 					name,
387 					node
388 					) ;
389 				return node ;
390 				}
391 			}
392 
393 		/***
394 		 * Add a file to this container.
395 		 * @param name The container name.
396 	     * @throws TreeClientDuplicateException If the container already exists.
397 		 * @throws TreeClientServiceException   If the service is unable to handle the request.
398 		 *
399 		 */
400 		public File addFile(String name)
401 			throws TreeClientDuplicateException
402 			{
403 			if (nodes.containsKey(name))
404 				{
405 				throw new TreeClientDuplicateException() ;
406 				}
407 			else {
408 				File node = new MockFile(
409 					name
410 					) ;
411 				nodes.put(
412 					name,
413 					node
414 					) ;
415 				return node ;
416 				}
417 			}
418 		}
419 
420 	/***
421 	 * Inner class to represent a myspace file.
422 	 *
423 	 */
424 	public class MockFile
425 		implements File
426 		{
427 		/***
428 		 * Public constructor.
429 		 * @param name The file name.
430 		 *
431 		 */
432 		public MockFile(String name)
433 			{
434 			if (null == name)
435 				{
436 				throw new IllegalArgumentException(
437 					"Null file name"
438 					) ;
439 				}
440 			this.name = name ;
441 			}
442 
443 		/***
444 		 * The name of this file.
445 		 *
446 		 */
447 		private String name ;
448 
449 		/***
450 		 * Access to the name.
451 		 *
452 		 */
453 		public String getName()
454 			{
455 			return this.name ;
456 			}
457 
458 		/***
459 		 * Check if this represents a file.
460 		 * @return true if this is a file.
461 		 *
462 		 */
463 		public boolean isFile()
464 			{
465 			return true ;
466 			}
467 
468 		/***
469 		 * Check if this represents a container.
470 		 * @return true if this is a container.
471 		 *
472 		 */
473 		public boolean isContainer()
474 			{
475 			return false ;
476 			}
477 
478 		/***
479 		 * Get the mime type for the file.
480 		 * @return The mime type for the file contents, or null if is not set..
481 		 *
482 		 */
483 		public String getMimeType() {
484 			MimeTypeUtil util = new MimeTypeUtil() ;
485 			return util.resolve(
486 				this.getName()
487 				) ;
488 			}
489 
490 		/***
491 		 * Our internal byte array.
492 		 *
493 		 */
494 		private byte[] data = new byte[0] ;
495 
496 		/***
497 		 * Get an OutputStream to send data to the file.
498 		 * Openning a new stream to an existing file will over-write the file contents.
499 		 * The client MUST close the output stream to force the transfer to complete.
500 	     * @throws TreeClientServiceException If the service is unable to handle the request.
501 		 *
502 		 */
503 		public OutputStream getOutputStream()
504 			{
505 			return new ByteArrayOutputStream()
506 				{
507 				public void close()
508 					{
509 					data = this.toByteArray() ;
510 					}
511 				} ;
512 			}
513 
514 		/***
515 		 * Get an InputStream to read data from the file.
516 	     * @throws TreeClientServiceException If the service is unable to handle the request.
517 		 *
518 		 */
519 		public InputStream getInputStream()
520 			{
521 			return new ByteArrayInputStream(
522 				data
523 				) ;
524 			}
525 		}
526 	}