1   /*
2    * Copyright 2003 - 2013 The eFaps Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.admin.program.bundle;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileNotFoundException;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.util.List;
30  import java.util.zip.GZIPOutputStream;
31  
32  import org.apache.commons.io.FileUtils;
33  import org.efaps.admin.AbstractAdminObject;
34  import org.efaps.admin.AppConfigHandler;
35  import org.efaps.db.Checkout;
36  import org.efaps.util.EFapsException;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  /**
41   * Makes a bundle of files and zipps them.
42   *
43   * @author The eFaps Team
44   * @version $Id$
45   */
46  public class TempFileBundle
47      implements BundleInterface
48  {
49  
50      /**
51       * Name of the folder inside the "official" temporary folder.
52       */
53      public static final String TMPFOLDERNAME = "eFapsFileBundles";
54  
55      /**
56       * Logging instance used in this class.
57       */
58      private static final Logger LOG = LoggerFactory.getLogger(AbstractAdminObject.class);
59  
60      /**
61       * Temporary folder.
62       */
63      private static File TMPFOLDER = new File("");
64      static {
65          File tmpfld = AppConfigHandler.get().getTempFolder();
66          if (tmpfld == null) {
67              File temp;
68              try {
69                  temp = File.createTempFile("eFaps", ".tmp");
70                  tmpfld = temp.getParentFile();
71                  temp.delete();
72              } catch (final IOException e) {
73                  TempFileBundle.LOG.error("Cannot create temp file", e);
74              }
75  
76          }
77          TempFileBundle.TMPFOLDER = new File(tmpfld, TempFileBundle.TMPFOLDERNAME);
78          if (!TempFileBundle.TMPFOLDER.exists()) {
79              final boolean mkdir = TempFileBundle.TMPFOLDER.mkdir();
80              if (!mkdir) {
81                  TempFileBundle.LOG.error("Temp folder was not created");
82              }
83          }
84      }
85  
86      /**
87       * File.
88       */
89      private File file = null;
90  
91      /**
92       * zipped file.
93       */
94      private File gzipFile = null;
95  
96      /**
97       * Time in miliseconds when this file was created.
98       */
99      private final long created;
100 
101     /**
102      * TYpe of the content.
103      */
104     private String contentType = "text/plain";
105 
106     /**
107      * List of oids included in this bundle.
108      */
109     private List<String> oids;
110 
111     /**
112      * Key to this bundle.
113      */
114     private String key;
115 
116     /**
117      * Constructor.
118      */
119     public TempFileBundle()
120     {
121         this.created = System.currentTimeMillis();
122     }
123 
124     /**
125      * {@inheritDoc}
126      */
127     @Override
128     public synchronized InputStream getInputStream(final boolean _gziped)
129         throws EFapsException
130     {
131         InputStream ret = null;
132         try {
133             if (_gziped) {
134                 if (this.gzipFile == null  || !this.gzipFile.exists()) {
135                     this.gzipFile = setFile(true);
136                 }
137                 ret = new FileInputStream(this.gzipFile);
138             } else {
139                 if (this.file == null || !this.file.exists()) {
140                     this.file = setFile(false);
141                 }
142                 ret = new FileInputStream(this.file);
143             }
144         } catch (final FileNotFoundException e) {
145             throw new EFapsException(this.getClass(), "getInputStream", e);
146         }
147         return ret;
148     }
149 
150     /**
151      * {@inheritDoc}
152      */
153     @Override
154     public long getCreationTime()
155     {
156         return this.created;
157     }
158 
159     /**
160      * This is the getter method for the instance variable {@link #contentType}.
161      *
162      * @return value of instance variable {@link #contentType}
163      */
164     @Override
165     public String getContentType()
166     {
167         return this.contentType;
168     }
169 
170     /**
171      * This is the setter method for the instance variable {@link #contentType}.
172      *
173      * @param _contentType the contentType to set
174      */
175     public void setContentType(final String _contentType)
176     {
177         this.contentType = _contentType;
178     }
179 
180     /**
181      * This is the getter method for the instance variable {@link #oids}.
182      *
183      * @return value of instance variable {@link #oids}
184      */
185     public List<String> getOids()
186     {
187         return this.oids;
188     }
189 
190     /**
191      * @param _gziped zip the file
192      * @return File
193      * @throws EFapsException on error
194      */
195     private File setFile(final boolean _gziped)
196         throws EFapsException
197     {
198         final String filename = _gziped ? this.key + "GZIP" : this.key;
199         final File ret = FileUtils.getFile(TempFileBundle.getTempFolder(), filename);
200         try {
201             final FileOutputStream out = new FileOutputStream(ret);
202             final byte[] buffer = new byte[1024];
203             int bytesRead;
204             if (_gziped) {
205                 final GZIPOutputStream zout = new GZIPOutputStream(out);
206                 for (final String oid : this.oids) {
207                     final Checkout checkout = new Checkout(oid);
208                     final InputStream bis = checkout.execute();
209                     while ((bytesRead = bis.read(buffer)) != -1) {
210                         zout.write(buffer, 0, bytesRead);
211                     }
212                 }
213                 zout.close();
214             } else {
215                 for (final String oid : this.oids) {
216                     final Checkout checkout = new Checkout(oid);
217                     final InputStream bis = checkout.execute();
218                     while ((bytesRead = bis.read(buffer)) != -1) {
219                         out.write(buffer, 0, bytesRead);
220                     }
221                 }
222             }
223             out.close();
224         } catch (final IOException e) {
225             throw new EFapsException(this.getClass(), "setFile", e, filename);
226         }
227         return ret;
228     }
229 
230     /**
231      * @return the temporary folder
232      * @throws EFapsException on error
233      */
234     public static File getTempFolder()
235         throws EFapsException
236     {
237         return TempFileBundle.TMPFOLDER;
238     }
239 
240     /**
241      * {@inheritDoc}
242      */
243     @Override
244     public void setKey(final String _key,
245                        final List<String> _oids)
246     {
247         this.key = _key;
248         this.oids = _oids;
249     }
250 }