1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.documentlibrary.util;
21  
22  import com.liferay.documentlibrary.DuplicateDirectoryException;
23  import com.liferay.documentlibrary.DuplicateFileException;
24  import com.liferay.documentlibrary.NoSuchDirectoryException;
25  import com.liferay.documentlibrary.NoSuchFileException;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.search.Document;
31  import com.liferay.portal.kernel.search.Field;
32  import com.liferay.portal.kernel.search.SearchEngineUtil;
33  import com.liferay.portal.kernel.search.SearchException;
34  import com.liferay.portal.kernel.util.FileUtil;
35  import com.liferay.portal.kernel.util.GetterUtil;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.util.PropsKeys;
38  import com.liferay.portal.util.PropsUtil;
39  
40  import java.io.File;
41  import java.io.FileInputStream;
42  import java.io.IOException;
43  import java.io.InputStream;
44  
45  import java.util.Arrays;
46  import java.util.Date;
47  
48  /**
49   * <a href="FileSystemHook.java.html"><b><i>View Source</i></b></a>
50   *
51   * @author Brian Wing Shun Chan
52   * @author Sten Martinez
53   *
54   */
55  public class FileSystemHook extends BaseHook {
56  
57      public FileSystemHook() {
58          _rootDir = new File(_ROOT_DIR);
59  
60          if (!_rootDir.exists()) {
61              _rootDir.mkdirs();
62          }
63      }
64  
65      public void addDirectory(long companyId, long repositoryId, String dirName)
66          throws PortalException {
67  
68          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
69  
70          if (dirNameDir.exists()) {
71              throw new DuplicateDirectoryException();
72          }
73  
74          dirNameDir.mkdirs();
75      }
76  
77      public void addFile(
78              long companyId, String portletId, long groupId, long repositoryId,
79              String fileName, long fileEntryId, String properties,
80              Date modifiedDate, String[] tagsCategories, String[] tagsEntries,
81              InputStream is)
82          throws PortalException, SystemException {
83  
84          try {
85              File fileNameVersionFile = getFileNameVersionFile(
86                  companyId, repositoryId, fileName, DEFAULT_VERSION);
87  
88              if (fileNameVersionFile.exists()) {
89                  throw new DuplicateFileException();
90              }
91  
92              FileUtil.write(fileNameVersionFile, is);
93  
94              Indexer.addFile(
95                  companyId, portletId, groupId, repositoryId, fileName,
96                  fileEntryId, properties, modifiedDate, tagsCategories,
97                  tagsEntries);
98          }
99          catch (IOException ioe) {
100             throw new SystemException();
101         }
102     }
103 
104     public void checkRoot(long companyId) {
105     }
106 
107     public void deleteDirectory(
108             long companyId, String portletId, long repositoryId, String dirName)
109         throws PortalException {
110 
111         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
112 
113         if (!dirNameDir.exists()) {
114             throw new NoSuchDirectoryException();
115         }
116 
117         FileUtil.deltree(dirNameDir);
118     }
119 
120     public void deleteFile(
121             long companyId, String portletId, long repositoryId,
122             String fileName)
123         throws PortalException, SystemException {
124 
125         try {
126             File fileNameDir = getFileNameDir(
127                 companyId, repositoryId, fileName);
128 
129             if (!fileNameDir.exists()) {
130                 throw new NoSuchFileException();
131             }
132 
133             FileUtil.deltree(fileNameDir);
134 
135             Indexer.deleteFile(companyId, portletId, repositoryId, fileName);
136         }
137         catch (SearchException se) {
138             throw new SystemException();
139         }
140     }
141 
142     public void deleteFile(
143             long companyId, String portletId, long repositoryId,
144             String fileName, double versionNumber)
145         throws PortalException {
146 
147         File fileNameVersionFile = getFileNameVersionFile(
148             companyId, repositoryId, fileName, versionNumber);
149 
150         if (!fileNameVersionFile.exists()) {
151             throw new NoSuchFileException();
152         }
153 
154         fileNameVersionFile.delete();
155     }
156 
157     public InputStream getFileAsStream(
158             long companyId, long repositoryId, String fileName,
159             double versionNumber)
160         throws PortalException, SystemException {
161 
162         try {
163             if (versionNumber == 0) {
164                 versionNumber = getHeadVersionNumber(
165                     companyId, repositoryId, fileName);
166             }
167 
168             File fileNameVersionFile = getFileNameVersionFile(
169                 companyId, repositoryId, fileName, versionNumber);
170 
171             if (!fileNameVersionFile.exists()) {
172                 throw new NoSuchFileException();
173             }
174 
175             return new FileInputStream(fileNameVersionFile);
176         }
177         catch (IOException ioe) {
178             throw new SystemException();
179         }
180     }
181 
182     public String[] getFileNames(
183             long companyId, long repositoryId, String dirName)
184         throws PortalException {
185 
186         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
187 
188         if (!dirNameDir.exists()) {
189             throw new NoSuchDirectoryException();
190         }
191 
192         String[] fileNames = FileUtil.listDirs(dirNameDir);
193 
194         Arrays.sort(fileNames);
195 
196         // Convert /${fileName} to /${dirName}/${fileName}
197 
198         for (int i = 0; i < fileNames.length; i++) {
199             fileNames[i] =
200                 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
201         }
202 
203         return fileNames;
204     }
205 
206     public long getFileSize(
207             long companyId, long repositoryId, String fileName)
208         throws PortalException {
209 
210         double versionNumber = getHeadVersionNumber(
211             companyId, repositoryId, fileName);
212 
213         File fileNameVersionFile = getFileNameVersionFile(
214             companyId, repositoryId, fileName, versionNumber);
215 
216         if (!fileNameVersionFile.exists()) {
217             throw new NoSuchFileException();
218         }
219 
220         return fileNameVersionFile.length();
221     }
222 
223     public boolean hasFile(
224         long companyId, long repositoryId, String fileName,
225         double versionNumber) {
226 
227         File fileNameVersionFile = getFileNameVersionFile(
228             companyId, repositoryId, fileName, versionNumber);
229 
230         if (fileNameVersionFile.exists()) {
231             return true;
232         }
233         else {
234             return false;
235         }
236     }
237 
238     public void move(String srcDir, String destDir) {
239     }
240 
241     public void reIndex(String[] ids) {
242         long companyId = GetterUtil.getLong(ids[0]);
243         String portletId = ids[1];
244         long groupId = GetterUtil.getLong(ids[2]);
245         long repositoryId = GetterUtil.getLong(ids[3]);
246 
247         File repistoryDir = getRepositoryDir(companyId, repositoryId);
248 
249         String[] fileNames = FileUtil.listDirs(repistoryDir);
250 
251         for (int i = 0; i < fileNames.length; i++) {
252             String fileName = fileNames[i];
253 
254             try {
255                 Document doc = Indexer.getFileDocument(
256                     companyId, portletId, groupId, repositoryId, fileName);
257 
258                 SearchEngineUtil.updateDocument(
259                     companyId, doc.get(Field.UID), doc);
260             }
261             catch (Exception e) {
262                 _log.error("Reindexing " + fileName, e);
263             }
264         }
265     }
266 
267     public void updateFile(
268             long companyId, String portletId, long groupId, long repositoryId,
269             String fileName, double versionNumber, String sourceFileName,
270             long fileEntryId, String properties, Date modifiedDate,
271             String[] tagsCategories, String[] tagsEntries, InputStream is)
272         throws PortalException, SystemException {
273 
274         try {
275             File fileNameVersionFile = getFileNameVersionFile(
276                 companyId, repositoryId, fileName, versionNumber);
277 
278             if (fileNameVersionFile.exists()) {
279                 throw new DuplicateFileException();
280             }
281 
282             FileUtil.write(fileNameVersionFile, is);
283 
284             Indexer.updateFile(
285                 companyId, portletId, groupId, repositoryId, fileName,
286                 fileEntryId, properties, modifiedDate, tagsCategories,
287                 tagsEntries);
288         }
289         catch (IOException ioe) {
290             throw new SystemException();
291         }
292     }
293 
294     public void updateFile(
295             long companyId, String portletId, long groupId, long repositoryId,
296             long newRepositoryId, String fileName, long fileEntryId)
297         throws SystemException {
298 
299         try {
300             File fileNameDir = getFileNameDir(
301                 companyId, repositoryId, fileName);
302             File newFileNameDir = getFileNameDir(
303                 companyId, newRepositoryId, fileName);
304 
305             FileUtil.copyDirectory(fileNameDir, newFileNameDir);
306 
307             FileUtil.deltree(fileNameDir);
308 
309             try {
310                 Indexer.deleteFile(
311                     companyId, portletId, repositoryId, fileName);
312             }
313             catch (SearchException se) {
314             }
315 
316             Indexer.addFile(
317                 companyId, portletId, groupId, newRepositoryId, fileName);
318         }
319         catch (SearchException se) {
320             throw new SystemException();
321         }
322     }
323 
324     protected File getCompanyDir(long companyId) {
325         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
326 
327         if (!companyDir.exists()) {
328             companyDir.mkdirs();
329         }
330 
331         return companyDir;
332     }
333 
334     protected File getDirNameDir(
335         long companyId, long repositoryId, String dirName) {
336 
337         return getFileNameDir(companyId, repositoryId, dirName);
338     }
339 
340     protected File getRepositoryDir(long companyId, long repositoryId) {
341         File companyDir = getCompanyDir(companyId);
342 
343         File repositoryDir = new File(
344             companyDir + StringPool.SLASH + repositoryId);
345 
346         if (!repositoryDir.exists()) {
347             repositoryDir.mkdirs();
348         }
349 
350         return repositoryDir;
351     }
352 
353     protected File getFileNameDir(
354         long companyId, long repositoryId, String fileName) {
355 
356         File repositoryDir = getRepositoryDir(companyId, repositoryId);
357 
358         File fileNameDir = new File(
359             repositoryDir + StringPool.SLASH + fileName);
360 
361         return fileNameDir;
362     }
363 
364     protected File getFileNameVersionFile(
365         long companyId, long repositoryId, String fileName, double version) {
366 
367         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
368 
369         File fileNameVersionFile = new File(
370             fileNameDir + StringPool.SLASH + version);
371 
372         return fileNameVersionFile;
373     }
374 
375     protected double getHeadVersionNumber(
376         long companyId, long repositoryId, String fileName) {
377 
378         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
379 
380         if (!fileNameDir.exists()) {
381             return DEFAULT_VERSION;
382         }
383 
384         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
385 
386         double headVersionNumber = DEFAULT_VERSION;
387 
388         for (int i = 0; i < versionNumbers.length; i++) {
389             double versionNumber = GetterUtil.getDouble(versionNumbers[i]);
390 
391             if (versionNumber > headVersionNumber) {
392                 headVersionNumber = versionNumber;
393             }
394         }
395 
396         return headVersionNumber;
397     }
398 
399     private static final String _ROOT_DIR = PropsUtil.get(
400         PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
401 
402     private static Log _log = LogFactoryUtil.getLog(FileSystemHook.class);
403 
404     private File _rootDir;
405 
406 }