View Javadoc

1   /*
2    *
3    * <cvs:source>$Source: /devel/astrogrid/filestore/server/src/java/org/astrogrid/filestore/server/repository/RepositoryImpl.java,v $</cvs:source>
4    * <cvs:author>$Author: clq2 $</cvs:author>
5    * <cvs:date>$Date: 2005/01/28 10:43:58 $</cvs:date>
6    * <cvs:version>$Revision: 1.15 $</cvs:version>
7    * <cvs:log>
8    *   $Log: RepositoryImpl.java,v $
9    *   Revision 1.15  2005/01/28 10:43:58  clq2
10   *   dave_dev_200501141257 (filemanager)
11   *
12   *   Revision 1.14.6.1  2005/01/15 04:50:58  dave
13   *   Added created and modified dates to server ....
14   *   Removed log debug messages from JUnit tests ...
15   *
16   *   Revision 1.14  2004/12/16 17:25:49  jdt
17   *   merge from dave-dev-200410061224-200412161312
18   *
19   *   Revision 1.11.10.3  2004/12/08 17:54:55  dave
20   *   Added update to FileManager client and server side ...
21   *
22   *   Revision 1.11.10.2  2004/11/09 17:41:36  dave
23   *   Added file:// URL handling to allow server URLs to be tested.
24   *   Added importInit and exportInit to server implementation.
25   *   Moved remaining tests out of extended test abd removed it.
26   *
27   *   Revision 1.11.10.1  2004/10/19 14:56:16  dave
28   *   Refactored config and resolver to enable multiple instances of mock implementation.
29   *   Required to implement handling of multiple FileStore(s) in FileManager.
30   *
31   *   Revision 1.11  2004/09/17 16:46:14  dave
32   *   Fixed servlet deployment in FileStore ...
33   *   Changed tabs to spaces in source code ...
34   *
35   *   Revision 1.10.4.1  2004/09/17 15:10:32  dave
36   *   Uncommented the call to servlet deploy in the build script.
37   *   Replaced tabs with spaces in source code.
38   *
39   *   Revision 1.10  2004/09/17 06:57:10  dave
40   *   Added commons logging to FileStore.
41   *   Updated logging properties in Community.
42   *   Fixed bug in AGINAB deployment.
43   *   Removed MySpace tests with hard coded grendel address.
44   *
45   *   Revision 1.9.2.1  2004/09/17 01:08:36  dave
46   *   Updated debug to use commons logging API ....
47   *
48   *   Revision 1.9  2004/09/16 23:18:08  dave
49   *   Replaced debug logging in Community.
50   *   Added stream close() to FileStore.
51   *
52   *   Revision 1.8.14.3  2004/09/16 13:22:38  dave
53   *   Fixed typo ..
54   *
55   *   Revision 1.8.14.2  2004/09/16 13:19:00  dave
56   *   Refactored the stream close() into try catch finally blocks ....
57   *
58   *   Revision 1.8.14.1  2004/09/16 11:45:35  dave
59   *   Added close() to output streams ....
60   *
61   *   Revision 1.8  2004/09/02 10:25:41  dave
62   *   Updated FileStore and MySpace to handle mime type and file size.
63   *   Updated Community deployment script.
64   *
65   *   Revision 1.7.2.1  2004/09/01 23:05:16  dave
66   *   Updated filestore server to handle mime type correctly.
67   *
68   *   Revision 1.7  2004/08/27 22:43:15  dave
69   *   Updated filestore and myspace to report file size correctly.
70   *
71   *   Revision 1.6.12.1  2004/08/26 19:06:50  dave
72   *   Modified filestore to return file size in properties.
73   *
74   *   Revision 1.6  2004/08/18 19:00:01  dave
75   *   Myspace manager modified to use remote filestore.
76   *   Tested before checkin - integration tests at 91%.
77   *
78   *   Revision 1.5.10.4  2004/08/09 10:16:28  dave
79   *   Added resource URL to the properties.
80   *
81   *   Revision 1.5.10.3  2004/08/06 22:25:06  dave
82   *   Refactored bits and broke a few tests ...
83   *
84   *   Revision 1.5.10.2  2004/08/04 17:03:33  dave
85   *   Added container to servlet
86   *
87   *   Revision 1.5.10.1  2004/08/02 14:54:15  dave
88   *   Trying to get integration tests to run
89   *
90   *   Revision 1.5  2004/07/23 09:11:16  dave
91   *   Merged development branch, dave-dev-200407221513, into HEAD
92   *
93   *   Revision 1.4.6.1  2004/07/23 02:10:58  dave
94   *   Added IvornFactory and IvornParser
95   *
96   *   Revision 1.4  2004/07/21 18:11:55  dave
97   *   Merged development branch, dave-dev-200407201059, into HEAD
98   *
99   *   Revision 1.3.2.1  2004/07/21 16:28:16  dave
100  *   Added content properties and tests
101  *
102  *   Revision 1.3  2004/07/19 23:42:07  dave
103  *   Merged development branch, dave-dev-200407151443, into HEAD
104  *
105  *   Revision 1.2.4.1  2004/07/19 19:40:28  dave
106  *   Debugged and worked around Axis Exception handling
107  *
108  *   Revision 1.2  2004/07/14 13:50:29  dave
109  *   Merged development branch, dave-dev-200406301228, into HEAD
110  *
111  *   Revision 1.1.2.2  2004/07/14 10:34:08  dave
112  *   Reafctored server to use array of properties
113  *
114  *   Revision 1.1.2.1  2004/07/12 14:39:03  dave
115  *   Added server repository classes
116  *
117  *   Revision 1.1.2.1  2004/07/08 07:31:30  dave
118  *   Added container impl and tests
119  *
120  * </cvs:log>
121  *
122  */
123 package org.astrogrid.filestore.server.repository ;
124 
125 import org.apache.commons.logging.Log ;
126 import org.apache.commons.logging.LogFactory ;
127 
128 import java.net.URL ;
129 import java.net.URLConnection ;
130 import java.net.MalformedURLException ;
131 
132 import java.util.Date ;
133 
134 import java.io.File ;
135 import java.io.IOException ;
136 import java.io.InputStream ;
137 import java.io.OutputStream ;
138 import java.io.FileInputStream ;
139 import java.io.FileOutputStream ;
140 import java.io.FileNotFoundException ;
141 
142 import org.astrogrid.filestore.common.file.FileProperty ;
143 import org.astrogrid.filestore.common.file.FileProperties ;
144 import org.astrogrid.filestore.common.file.FileIdentifier ;
145 
146 import org.astrogrid.filestore.common.ivorn.FileStoreIvornFactory ;
147 
148 import org.astrogrid.filestore.common.transfer.TransferUtil ;
149 import org.astrogrid.filestore.common.exception.FileStoreException ;
150 import org.astrogrid.filestore.common.exception.FileStoreNotFoundException ;
151 import org.astrogrid.filestore.common.exception.FileStoreIdentifierException ;
152 import org.astrogrid.filestore.common.exception.FileStoreServiceException ;
153 import org.astrogrid.filestore.common.exception.FileStoreTransferException ;
154 
155 import org.astrogrid.filestore.common.FileStoreConfig ;
156 import org.astrogrid.filestore.common.FileStoreDateFormat;
157 
158 import org.astrogrid.filestore.server.FileStoreConfigImpl ;
159 
160 /***
161  * A factory class for creating and storing file containers.
162  *
163  */
164 public class RepositoryImpl
165     implements Repository
166     {
167     /***
168      * Our debug logger.
169      *
170      */
171     private static Log log = LogFactory.getLog(RepositoryImpl.class);
172 
173     /***
174      * The size of our copy buffer (8k bytes).
175      *
176      */
177     private static final int COPY_BUFFER_SIZE = 8 * 1024 ;
178 
179     /***
180      * Public constructor.
181      *
182      */
183     public RepositoryImpl(FileStoreConfig config)
184         {
185         if (null == config)
186             {
187             throw new IllegalArgumentException(
188                 "Null repository config"
189                 ) ;
190             }
191         this.config = config ;
192         }
193 
194     /***
195      * Reference to our repository config.
196      *
197      */
198     protected FileStoreConfig config ;
199 
200     /***
201      * Factory method to create a new container.
202      * @param properties An optional array of FileProperty(ies) describing the file contents.
203      * @return A new file container.
204      * @throws FileStoreServiceException if unable handle the request.
205      *
206      */
207     public RepositoryContainer create(FileProperty[] properties)
208         throws FileStoreServiceException
209         {
210         return create(
211             new FileProperties(
212                 properties
213                 )
214             ) ;
215         }
216 
217     /***
218      * Factory method to create a new container.
219      * @param properties An optional FileProperties describing the file contents.
220      * @return A new file container.
221      * @throws FileStoreServiceException if unable handle the request.
222      *
223      */
224     public RepositoryContainer create(FileProperties properties)
225         throws FileStoreServiceException
226         {
227         //
228         // Create the new container.
229         return new RepositoryContainerImpl(
230             properties
231             ) ;
232         }
233 
234     /***
235      * Locate an existing container.
236      * @param ident The identifier of the container.
237      * @return The file container, if it exists.
238      * @throws FileStoreIdentifierException if the identifier is null or not valid.
239      * @throws FileStoreNotFoundException if unable to locate the file.
240      * @throws FileStoreServiceException if unable handle the request.
241      * @todo Use FileIdentifier to ensure the ident is valid (which it don't yet).
242      *
243      */
244     public RepositoryContainer load(String ident)
245         throws FileStoreServiceException, FileStoreNotFoundException, FileStoreIdentifierException
246         {
247         //
248         // Check for null ident.
249         if (null == ident)
250             {
251             throw new FileStoreIdentifierException(
252                 FileStoreIdentifierException.NULL_IDENT_MESSAGE
253                 ) ;
254             }
255         //
256         // Return a container using the ident.
257         return new RepositoryContainerImpl(
258             ident
259             ) ;
260         }
261 
262     /***
263      * Copy an existing container.
264      * @param ident The identifier of the container.
265      * @return The new file container.
266      * @throws FileStoreIdentifierException if the identifier is null or not valid.
267      * @throws FileStoreTransferException If unable to transfer the data.
268      * @throws FileStoreNotFoundException if unable to locate the file.
269      * @throws FileStoreServiceException if unable handle the request.
270      *
271      */
272     public RepositoryContainer duplicate(String ident)
273         throws FileStoreServiceException, FileStoreNotFoundException, FileStoreIdentifierException, FileStoreTransferException
274         {
275         //
276         // Try to load the existing container.
277         RepositoryContainer original = new RepositoryContainerImpl(
278             ident
279             ) ;
280         //
281         // Create the new container with the same properties.
282         RepositoryContainer duplicate = new RepositoryContainerImpl(
283             original.properties()
284             ) ;
285         //
286         // Transfer the data.
287         duplicate.importData(
288             original.getDataInputStream()
289             ) ;
290         //
291         // Return the new container.
292         return duplicate ;
293         }
294 
295     /***
296      * Inner class to implement a container.
297      *
298      */
299     protected class RepositoryContainerImpl
300         implements RepositoryContainer
301         {
302         /***
303          * The file identifier.
304          *
305          */
306         private FileIdentifier ident ;
307 
308         /***
309          * Access to our identifier.
310          *
311          */
312         public FileIdentifier ident()
313             {
314             return this.ident ;
315             }
316 
317         /***
318          * The file properties.
319          *
320          */
321         private FileProperties properties ;
322 
323         /***
324          * Access to our properties.
325          *
326          */
327         public FileProperties properties()
328             {
329             return this.properties ;
330             }
331 
332         /***
333          * Constructor to create a new container.
334          * @param properties The file properties.
335          * @throws FileStoreServiceException If unable create the container.
336          *
337          */
338         public RepositoryContainerImpl(FileProperties properties)
339             throws FileStoreServiceException
340             {
341             //
342             // Create a copy of the properties.
343             this.properties = new FileProperties(
344                 properties
345                 ) ;
346             //
347             // Create a new identifier.
348             this.ident = new FileIdentifier() ;
349 			//
350 			// Create an ISO date formatter.
351 			FileStoreDateFormat formatter = new FileStoreDateFormat();
352             //
353             // Set the create date.
354 			this.properties.setProperty(
355 				FileProperties.FILE_CREATED_DATE_PROPERTY,
356 				formatter.format(
357 					new Date()
358 					)
359 				) ;
360             //
361             // Update and save the properties.
362             this.update() ;
363             }
364 
365         /***
366          * Constructor to load an existing container.
367          * @param ident The identifier of the container.
368          * @throws FileStoreIdentifierException if the identifier is null or not valid.
369          * @throws FileStoreNotFoundException if unable to locate the file.
370          * @throws FileStoreServiceException if unable handle the request.
371          *
372          */
373         public RepositoryContainerImpl(String ident)
374             throws FileStoreServiceException, FileStoreNotFoundException, FileStoreIdentifierException
375             {
376             //
377             // Create our identifier.
378             this.ident = new FileIdentifier(ident) ;
379             //
380             // Create a our properties.
381             this.properties = new FileProperties() ;
382             //
383             // Load the properties.
384             this.load() ;
385             }
386 
387         /***
388          * Generate the properties file path.
389          * @throws FileStoreServiceException if unable handle the request.
390          *
391          */
392         public File getInfoFile()
393             throws FileStoreServiceException
394             {
395             return new File(
396                 config.getInfoDirectory(),
397                 this.ident.toString() + ".inf"
398                 ) ;
399             }
400 
401         /***
402          * Generate the data file path.
403          * @throws FileStoreServiceException if unable handle the request.
404          *
405          */
406         public File getDataFile()
407             throws FileStoreServiceException
408             {
409             return new File(
410                 config.getDataDirectory(),
411                 this.ident.toString() + ".dat"
412                 ) ;
413             }
414 
415         /***
416          * Get the data file size.
417          *
418          */
419         public long getDataFileSize()
420             {
421             try {
422                 return getDataFile().length() ;
423                 }
424             catch (FileStoreServiceException ouch)
425                 {
426                 return 0L ;
427                 }
428             }
429 
430         /***
431          * Update the properties.
432          *
433          */
434         public void update()
435             throws FileStoreServiceException
436             {
437             //
438             // Create our properties.
439             if (null == this.properties)
440                 {
441                 this.properties = new FileProperties() ;
442                 }
443 			//
444 			// Set the resource properties.
445             try {
446 	            //
447 	            // Set the resource size.
448 	            this.properties.setProperty(
449 	                FileProperties.CONTENT_SIZE_PROPERTY,
450 	                String.valueOf(
451 	                    this.getDataFileSize()
452 	                    )
453 	                ) ;
454                 //
455                 // Set the resource ivorn.
456                 this.properties.setStoreResourceIvorn(
457                     config.getResourceIvorn(
458                         ident.toString()
459                         )
460                     ) ;
461                 //
462                 // Set the resource URL.
463                 this.properties.setProperty(
464                     FileProperties.STORE_RESOURCE_URL,
465                     config.getResourceUrl(
466                         ident.toString()
467                         ).toString()
468                     ) ;
469 				//
470 				// Create an ISO date formatter.
471 				FileStoreDateFormat formatter = new FileStoreDateFormat();
472 	            //
473 	            // Set the modified date.
474 				this.properties.setProperty(
475 					FileProperties.FILE_MODIFIED_DATE_PROPERTY,
476 					formatter.format(
477 						new Date()
478 						)
479 					) ;
480                 }
481             //
482             // Save the properties.
483             finally {
484                 this.save() ;
485                 }
486             }
487 
488         /***
489          * Load the file properties.
490          * @throws FileStoreServiceException If unable to load the info.
491          * @throws FileStoreNotFoundException If unable to locate the file.
492          *
493          */
494         protected void load()
495             throws FileStoreServiceException, FileStoreNotFoundException
496             {
497             InputStream input = null ;
498             try {
499                 input = new FileInputStream(
500                     this.getInfoFile()
501                     ) ;
502                 this.properties.load(
503                     input
504                     ) ;
505                 }
506             catch (FileNotFoundException ouch)
507                 {
508                 throw new FileStoreNotFoundException(
509                     this.ident.toString()
510                     ) ;
511                 }
512             catch (IOException ouch)
513                 {
514                 throw new FileStoreServiceException(
515                     "Unable to load info file",
516                     ouch
517                     ) ;
518                 }
519             finally
520                 {
521                 if (null != input)
522                     {
523                     try {
524                         input.close() ;
525                         }
526                     catch (IOException ouch)
527                         {
528                         log.warn("----") ;
529                         log.warn("RepositoryContainerImpl.load") ;
530                         log.warn("Failed to close input stream") ;
531                         log.warn("----") ;
532                         }
533                     }
534                 }
535             }
536 
537         /***
538          * Save the file properties.
539          * @throws FileStoreServiceException If unable to save the info.
540          *
541          */
542         protected void save()
543             throws FileStoreServiceException
544             {
545             OutputStream output = null ;
546             try {
547                 output = new FileOutputStream(
548                     this.getInfoFile()
549                     ) ;
550                 this.properties.save(
551                     output
552                     ) ;
553                 }
554             catch (IOException ouch)
555                 {
556                 throw new FileStoreServiceException(
557                     "Unable to save info file",
558                     ouch
559                     ) ;
560                 }
561             finally
562                 {
563                 if (null != output)
564                     {
565                     try {
566                         output.close() ;
567                         }
568                     catch (IOException ouch)
569                         {
570                         log.warn("----") ;
571                         log.warn("RepositoryContainerImpl.save") ;
572                         log.warn("Failed to close output stream") ;
573                         log.warn("----") ;
574                         }
575                     }
576                 }
577             }
578 
579         /***
580          * Delete the container file(s).
581          * @throws FileStoreNotFoundException If unable to locate the file.
582          * @throws FileStoreServiceException If unable to complete the action.
583          *
584          */
585         public void delete()
586             throws FileStoreServiceException
587             {
588             this.getDataFile().delete() ;
589             this.getInfoFile().delete() ;
590             }
591 
592         /***
593          * Import an array of bytes.
594          * @param bytes The array of bytes to import into the container.
595          * @throws FileStoreServiceException If unable to complete the action.
596          *
597          */
598         public void importBytes(byte[] bytes)
599             throws FileStoreServiceException
600             {
601             //
602             // Transfer the data.
603             OutputStream output = null ;
604             try {
605                 output = this.getDataOutputStream() ;
606                 output.write(bytes) ;
607                 }
608             catch (IOException ouch)
609                 {
610                 throw new FileStoreServiceException(
611                     "Unable to write to data file",
612                     ouch
613                     ) ;
614                 }
615             finally
616                 {
617                 //
618                 // Update our properties.
619                 this.update() ;
620                 //
621                 // Close our output stream.
622                 try {
623                     if (null != output)
624                         {
625                         output.close() ;
626                         }
627                     }
628                 catch (IOException ouch)
629                     {
630                     log.warn("----") ;
631                     log.warn("RepositoryContainerImpl.importBytes") ;
632                     log.warn("Failed to close output stream") ;
633                     log.warn("----") ;
634                     }
635                 }
636             }
637 
638         /***
639          * Export our contents as bytes.
640          * @return An array of bytes from the container contents.
641          * @throws FileStoreNotFoundException If unable to locate the file.
642          * @throws FileStoreServiceException If unable to complete the action.
643          * @todo Deprecate this soon, as it potentially allocates a HUGE buffer in memory.
644          *
645          */
646         public byte[] exportBytes()
647             throws FileStoreServiceException, FileStoreNotFoundException
648             {
649             int size = (int) this.getDataFile().length() ;
650             byte[] buffer = new byte[size] ;
651             InputStream input = null ;
652             try {
653                 input = this.getDataInputStream() ;
654                 input.read(buffer) ;
655                 }
656             catch (IOException ouch)
657                 {
658                 throw new FileStoreServiceException(
659                     "Unable to read file data",
660                     ouch
661                     ) ;
662                 }
663             finally
664                 {
665                 try {
666                     if (null != input)
667                         {
668                         input.close() ;
669                         }
670                     }
671                 catch (IOException ouch)
672                     {
673                     log.warn("----") ;
674                     log.warn("RepositoryContainerImpl.exportBytes") ;
675                     log.warn("Failed to close input stream") ;
676                     log.warn("----") ;
677                     }
678                 }
679             return buffer ;
680             }
681 
682         /***
683          * Append an array of bytes.
684          * @param bytes The array of bytes to append to the container.
685          * @throws FileStoreNotFoundException If unable to locate the file.
686          * @throws FileStoreServiceException If unable to complete the action.
687          *
688          */
689         public void appendBytes(byte[] bytes)
690             throws FileStoreServiceException, FileStoreNotFoundException
691             {
692             //
693             // Transfer the data.
694             OutputStream output = null ;
695             try {
696                 output = this.getDataOutputStream(true) ;
697                 output.write(bytes) ;
698                 output.close() ;
699                 }
700             catch (IOException ouch)
701                 {
702                 throw new FileStoreServiceException(
703                     "Unable to write data file",
704                     ouch
705                     ) ;
706                 }
707             finally
708                 {
709                 //
710                 // Update our properties.
711                 this.update() ;
712                 //
713                 // Close our output stream.
714                 try {
715                     if (null != output)
716                         {
717                         output.close() ;
718                         }
719                     }
720                 catch (IOException ouch)
721                     {
722                     log.warn("----") ;
723                     log.warn("RepositoryContainerImpl.appendBytes") ;
724                     log.warn("Failed to close output stream") ;
725                     log.warn("----") ;
726                     }
727                 }
728             }
729 
730         /***
731          * Get an input stream to the container contents.
732          * @throws FileStoreNotFoundException If unable to locate the file.
733          * @throws FileStoreServiceException If unable to open the file.
734          *
735          */
736         public InputStream getDataInputStream()
737             throws FileStoreServiceException, FileStoreNotFoundException
738             {
739             try {
740                 return new FileInputStream(
741                     this.getDataFile()
742                     ) ;
743                 }
744             catch (FileNotFoundException ouch)
745                 {
746                 throw new FileStoreNotFoundException(
747                     this.ident.toString()
748                     ) ;
749                 }
750             catch (IOException ouch)
751                 {
752                 throw new FileStoreServiceException(
753                     "Unable to open data file",
754                     ouch
755                     ) ;
756                 }
757             }
758 
759         /***
760          * Get an output stream to the container contents.
761          * @throws FileStoreServiceException If unable to open the file.
762          *
763          */
764         public OutputStream getDataOutputStream()
765             throws FileStoreServiceException
766             {
767             return getDataOutputStream(false) ;
768             }
769 
770         /***
771          * Get an output stream to the container contents.
772          * @param append True if the output stream should append to the end of the file.
773          * @throws FileStoreServiceException If unable to open the file.
774          *
775          */
776         public OutputStream getDataOutputStream(boolean append)
777             throws FileStoreServiceException
778             {
779             try {
780                 return new FileOutputStream(
781                     this.getDataFile(),
782                     append
783                     ) ;
784                 }
785             catch (IOException ouch)
786                 {
787                 throw new FileStoreServiceException(
788                     "Unable to open local data file",
789                     ouch
790                     ) ;
791                 }
792             }
793 
794         /***
795          * Import our data from a URL.
796          * @param url The URL to import the data from.
797          * @throws FileStoreTransferException If unable to complete the action.
798          * @throws FileStoreServiceException If unable to open the local file.
799          *
800          */
801         public void importData(URL url)
802             throws FileStoreServiceException, FileStoreTransferException
803             {
804             try {
805                 //
806                 // Open a connection to the URL.
807                 URLConnection connection = url.openConnection() ;
808                 //
809                 // Set the source URL.
810                 this.properties.setProperty(
811                     FileProperties.TRANSFER_SOURCE_URL,
812                     url.toString()
813                     ) ;
814                 //
815                 // If the content type type hasn't been set yet.
816                 // Set it from the URL connection.
817                 if (null == this.properties.getProperty(
818                     FileProperties.MIME_TYPE_PROPERTY)
819                     )
820                     {
821                     this.properties.setProperty(
822                         FileProperties.MIME_TYPE_PROPERTY,
823                         connection.getContentType()
824                         ) ;
825                     }
826                 //
827                 // If the content encoding hasn't been set yet.
828                 // Set it from the URL connection.
829                 if (null == this.properties.getProperty(
830                     FileProperties.MIME_ENCODING_PROPERTY)
831                     )
832                     {
833                     this.properties.setProperty(
834                         FileProperties.MIME_ENCODING_PROPERTY,
835                         connection.getContentEncoding()
836                         ) ;
837                     }
838                 //
839                 // Transfer the data from the URL.
840                 InputStream input = null ;
841                 try {
842                     input = connection.getInputStream() ;
843                     this.importData(
844                         input
845                         ) ;
846                     }
847                 finally
848                     {
849                     try {
850                         if (null != input)
851                             {
852                             input.close() ;
853                             }
854                         }
855                     catch (IOException ouch)
856                         {
857                         log.warn("----") ;
858                         log.warn("RepositoryContainerImpl.importData") ;
859                         log.warn("Failed to close input stream") ;
860                         log.warn("----") ;
861                         }
862                     }
863                 }
864             catch (IOException ouch)
865                 {
866                 throw new FileStoreTransferException(
867                     "Unable to open URL source",
868                     ouch
869                     ) ;
870                 }
871             }
872 
873         /***
874          * Import our data from an InputStream.
875          * @param stream The input stream to import the data from.
876          * @throws FileStoreTransferException If unable to complete the action.
877          * @throws FileStoreServiceException If unable to open the local file.
878          *
879          */
880         public void importData(InputStream input)
881             throws FileStoreServiceException, FileStoreTransferException
882             {
883             //
884             // Transfer the data.
885             OutputStream output = null ;
886             try {
887                 output = this.getDataOutputStream() ;
888                 TransferUtil trans = new TransferUtil(
889                     input,
890                     output
891                     ) ;
892                 trans.transfer() ;
893                 }
894             catch (IOException ouch)
895                 {
896                 throw new FileStoreTransferException(
897                     "Encountered error while transferring data",
898                     ouch
899                     ) ;
900                 }
901             finally
902                 {
903                 //
904                 // Close the output stream.
905                 try {
906                     if (null != output)
907                         {
908                         output.close() ;
909                         }
910                     }
911                 catch (IOException ouch)
912                     {
913                     log.warn("----") ;
914                     log.warn("RepositoryContainerImpl.importData") ;
915                     log.warn("Failed to close output stream") ;
916                     log.warn("----") ;
917                     }
918                 //
919                 // Update our properties.
920                 this.update() ;
921                 }
922             }
923 
924         /***
925          * Export our data to an OutputStream.
926          * @param stream The output stream to export the data to.
927          * @throws FileStoreTransferException If unable to complete the action.
928          * @throws FileStoreServiceException If unable to open the local file.
929          *
930          */
931         public void exportData(OutputStream output)
932             throws FileStoreServiceException, FileStoreNotFoundException, FileStoreTransferException
933             {
934             InputStream input = null ;
935             try {
936                 input = this.getDataInputStream() ;
937                 TransferUtil trans = new TransferUtil(
938                     input,
939                     output
940                     ) ;
941                 trans.transfer() ;
942                 }
943             catch (IOException ouch)
944                 {
945                 throw new FileStoreTransferException(
946                     "Encountered error while transferring data",
947                     ouch
948                     ) ;
949                 }
950             finally
951                 {
952                 //
953                 // Close our input stream.
954                 try {
955                     if (null != input)
956                         {
957                         input.close() ;
958                         }
959                     }
960                 catch (IOException ouch)
961                     {
962                     log.warn("----") ;
963                     log.warn("RepositoryContainerImpl.exportData") ;
964                     log.warn("Failed to close input stream") ;
965                     log.warn("----") ;
966                     }
967                 }
968             }
969         }
970     }