View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.blobstore.service.filesystem;
35  
36  import java.io.File;
37  import java.io.IOException;
38  import java.io.InputStream;
39  
40  import fr.paris.lutece.plugins.blobstore.business.BytesBlobStore;
41  import fr.paris.lutece.plugins.blobstore.business.InputStreamBlobStore;
42  import fr.paris.lutece.plugins.blobstore.business.filesystem.FileAlreadyExistsException;
43  import fr.paris.lutece.plugins.blobstore.business.filesystem.FileSystemBlobStoreHome;
44  import fr.paris.lutece.plugins.blobstore.business.filesystem.IFileSystemBlobStoreHome;
45  import fr.paris.lutece.plugins.blobstore.service.BlobStoreFileItem;
46  import fr.paris.lutece.plugins.blobstore.service.IBlobStoreService;
47  import fr.paris.lutece.plugins.blobstore.service.download.IBlobStoreDownloadUrlService;
48  import fr.paris.lutece.plugins.blobstore.service.download.JSPBlobStoreDownloadUrlService;
49  import fr.paris.lutece.plugins.blobstore.util.BlobStoreUtils;
50  import fr.paris.lutece.portal.service.spring.SpringContextService;
51  import fr.paris.lutece.portal.service.util.AppException;
52  import fr.paris.lutece.portal.service.util.AppLogService;
53  import fr.paris.lutece.portal.service.util.AppPropertiesService;
54  
55  import org.apache.commons.fileupload.FileItem;
56  
57  /**
58   * FileSystemBlobStoreService.
59   */
60  public class FileSystemBlobStoreService implements IBlobStoreService
61  {
62      /** The Constant serialVersionUID. */
63      private static final long serialVersionUID = 1L;
64  
65      /** The base path. */
66      private String _strBasePath;
67  
68      /** The name. */
69      private String _strName;
70  
71      /** The depth. */
72      private Integer _intDepth = 0;
73  
74      /** Uses {@link JSPBlobStoreDownloadUrlService} as default one. */
75      private IBlobStoreDownloadUrlService _downloadUrlService = new JSPBlobStoreDownloadUrlService( );
76  
77      /**
78       * Gets the downloadService.
79       * 
80       * @return the downloadService
81       */
82      public IBlobStoreDownloadUrlService getDownloadUrlService( )
83      {
84          return _downloadUrlService;
85      }
86  
87      /**
88       * Sets the downloadService
89       * 
90       * @param downloadUrlService
91       *            downloadService
92       */
93      public void setDownloadUrlService( final IBlobStoreDownloadUrlService downloadUrlService )
94      {
95          _downloadUrlService = downloadUrlService;
96      }
97  
98      /*
99       * (non-Javadoc)
100      * 
101      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#setName(java .lang.String)
102      */
103     @Override
104     public void setName( final String strName )
105     {
106         _strName = strName;
107     }
108 
109     /*
110      * (non-Javadoc)
111      * 
112      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#getName()
113      */
114     @Override
115     public String getName( )
116     {
117         return _strName;
118     }
119 
120     /**
121      * Sets the base directory.
122      * 
123      * @param strBasePath
124      *            base path
125      */
126     public void setBasePath( final String strBasePath )
127     {
128         if ( strBasePath == null )
129         {
130             AppLogService.error( "Base path is not configured for FileSystemBlobStoreService" );
131         }
132 
133         _strBasePath = strBasePath;
134 
135         if ( !strBasePath.endsWith( "/" ) )
136         {
137             _strBasePath += File.separator;
138         }
139     }
140 
141     /**
142      * Gets the base directory.
143      * 
144      * @return the base directory
145      */
146     public String getBasePath( )
147     {
148         return _strBasePath;
149     }
150 
151     /*
152      * (non-Javadoc)
153      * 
154      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#delete(java .lang.String)
155      */
156     @Override
157     public void delete( final String strKey )
158     {
159         try
160         {
161             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
162             fileSystemBlobStoreHome.remove( strKey, getBasePath( ), getDepth( ) );
163         }
164         catch( final IOException e )
165         {
166             throw new AppException( e.getMessage( ), e );
167         }
168     }
169 
170     /*
171      * (non-Javadoc)
172      * 
173      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#getBlob(java .lang.String)
174      */
175     @Override
176     public byte [ ] getBlob( final String strKey )
177     {
178         final BytesBlobStore blob;
179 
180         try
181         {
182             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
183             blob = fileSystemBlobStoreHome.findByPrimaryKey( strKey, getBasePath( ), getDepth( ) );
184         }
185         catch( final IOException e )
186         {
187             AppLogService.error( e.getMessage( ), e );
188 
189             return null;
190         }
191 
192         return ( blob == null ) ? null : blob.getValue( );
193     }
194 
195     /*
196      * (non-Javadoc)
197      * 
198      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#getBlobInputStream (java.lang.String)
199      */
200     @Override
201     public InputStream getBlobInputStream( final String strKey )
202     {
203         try
204         {
205             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
206 
207             return fileSystemBlobStoreHome.findByPrimaryKeyInputStream( strKey, getBasePath( ), getDepth( ) );
208         }
209         catch( final IOException ioe )
210         {
211             AppLogService.error( ioe.getMessage( ), ioe );
212 
213             return null;
214         }
215     }
216 
217     /*
218      * (non-Javadoc)
219      * 
220      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#store(byte[])
221      */
222     @Override
223     public String store( final byte [ ] blob )
224     {
225         final String strKey = BlobStoreUtils.generateNewIdBlob( );
226         final BytesBlobStore blobStore = new BytesBlobStore( );
227         blobStore.setId( strKey );
228         blobStore.setValue( blob );
229 
230         try
231         {
232             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
233             fileSystemBlobStoreHome.create( blobStore, getBasePath( ), getDepth( ) );
234         }
235         catch( final IOException e )
236         {
237             throw new AppException( e.getMessage( ), e );
238         }
239         catch( final FileAlreadyExistsException fe )
240         {
241             throw new AppException( fe.getMessage( ), fe );
242         }
243 
244         return strKey;
245     }
246 
247     /*
248      * (non-Javadoc)
249      * 
250      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#storeInputStream (java.io.InputStream)
251      */
252     @Override
253     public String storeInputStream( final InputStream inputStream )
254     {
255         final String strKey = BlobStoreUtils.generateNewIdBlob( );
256         final InputStreamBlobStore blob = new InputStreamBlobStore( );
257         blob.setId( strKey );
258         blob.setInputStream( inputStream );
259 
260         try
261         {
262             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
263             fileSystemBlobStoreHome.createInputStream( blob, getBasePath( ), getDepth( ) );
264         }
265         catch( final IOException e )
266         {
267             throw new AppException( e.getMessage( ), e );
268         }
269         catch( final FileAlreadyExistsException fe )
270         {
271             throw new AppException( fe.getMessage( ), fe );
272         }
273 
274         return strKey;
275     }
276 
277     /*
278      * (non-Javadoc)
279      * 
280      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#storeFileItem (java.io.InputStream)
281      */
282     @Override
283     public String storeFileItem( FileItem fileItem )
284     {
285         try
286         {
287             // store the file content
288             String strBlobContentKey = storeInputStream( fileItem.getInputStream( ) );
289 
290             // build metadata as json file and store it
291             String strMetadata = BlobStoreFileItem.buildFileMetadata( fileItem.getName( ), fileItem.getSize( ), strBlobContentKey, fileItem.getContentType( ) );
292             String strMetadataKey = store( strMetadata.getBytes( ) );
293 
294             return strMetadataKey;
295         }
296         catch( final IOException e )
297         {
298             throw new AppException( e.getMessage( ), e );
299         }
300     }
301 
302     /*
303      * (non-Javadoc)
304      * 
305      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#update(java .lang.String, byte[])
306      */
307     @Override
308     public void update( final String strKey, final byte [ ] blob )
309     {
310         final BytesBlobStore blobStore = new BytesBlobStore( );
311         blobStore.setId( strKey );
312         blobStore.setValue( blob );
313 
314         try
315         {
316             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
317             fileSystemBlobStoreHome.update( blobStore, getBasePath( ), getDepth( ) );
318         }
319         catch( final IOException e )
320         {
321             throw new AppException( e.getMessage( ), e );
322         }
323     }
324 
325     /*
326      * (non-Javadoc)
327      * 
328      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#updateInputStream (java.lang.String, java.io.InputStream)
329      */
330     @Override
331     public void updateInputStream( final String strKey, final InputStream inputStream )
332     {
333         final InputStreamBlobStore blob = new InputStreamBlobStore( );
334         blob.setId( strKey );
335         blob.setInputStream( inputStream );
336 
337         try
338         {
339             IFileSystemBlobStoreHome fileSystemBlobStoreHome = SpringContextService.getBean( FileSystemBlobStoreHome.BEAN_SERVICE );
340             fileSystemBlobStoreHome.updateInputStream( blob, getBasePath( ), getDepth( ) );
341         }
342         catch( final IOException e )
343         {
344             throw new AppException( e.getMessage( ), e );
345         }
346     }
347 
348     /*
349      * (non-Javadoc)
350      * 
351      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#getBlobUrl( java.lang.String)
352      */
353     @Override
354     public String getBlobUrl( final String strKey )
355     {
356         return _downloadUrlService.getDownloadUrl( getName( ), strKey );
357     }
358 
359     /*
360      * (non-Javadoc)
361      * 
362      * @see fr.paris.lutece.portal.service.blobstore.BlobStoreService#getFileUrl( java.lang.String)
363      */
364     @Override
365     public String getFileUrl( final String strKey )
366     {
367         return _downloadUrlService.getFileUrl( getName( ), strKey );
368     }
369 
370     /**
371      * Gets the depth.
372      * 
373      * @return the depth
374      */
375     public Integer getDepth( )
376     {
377         return _intDepth;
378     }
379 
380     /**
381      * Sets the depth.
382      * 
383      * @param depth
384      *            the new depth
385      */
386     public void setDepth( final Integer depth )
387     {
388         if ( depth != null )
389         {
390             this._intDepth = depth;
391         }
392     }
393 
394     public void setBasePathKey( String key )
395     {
396         setBasePath( AppPropertiesService.getProperty( "blobstore.file.system.path", "/var/blobs/" ) );
397     }
398 
399     public void setDepthKey( String key )
400     {
401         setDepth( AppPropertiesService.getPropertyInt( "blobstore.file.system.depth", 1 ) );
402     }
403 }