1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.documentlibrary.util;
16  
17  import com.liferay.documentlibrary.DuplicateDirectoryException;
18  import com.liferay.documentlibrary.DuplicateFileException;
19  import com.liferay.documentlibrary.NoSuchDirectoryException;
20  import com.liferay.documentlibrary.NoSuchFileException;
21  import com.liferay.documentlibrary.model.FileModel;
22  import com.liferay.portal.kernel.exception.PortalException;
23  import com.liferay.portal.kernel.exception.SystemException;
24  import com.liferay.portal.kernel.search.Document;
25  import com.liferay.portal.kernel.search.Indexer;
26  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
27  import com.liferay.portal.kernel.search.SearchEngineUtil;
28  import com.liferay.portal.kernel.search.SearchException;
29  import com.liferay.portal.kernel.util.FileUtil;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.PropsKeys;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.service.ServiceContext;
35  import com.liferay.portal.util.PropsUtil;
36  import com.liferay.portlet.documentlibrary.util.DLUtil;
37  
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.IOException;
41  import java.io.InputStream;
42  
43  import java.util.ArrayList;
44  import java.util.Arrays;
45  import java.util.Collection;
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  public class FileSystemHook extends BaseHook {
55  
56      public FileSystemHook() {
57          _rootDir = new File(_ROOT_DIR);
58  
59          if (!_rootDir.exists()) {
60              _rootDir.mkdirs();
61          }
62      }
63  
64      public void addDirectory(long companyId, long repositoryId, String dirName)
65          throws PortalException {
66  
67          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
68  
69          if (dirNameDir.exists()) {
70              throw new DuplicateDirectoryException(dirNameDir.getPath());
71          }
72  
73          dirNameDir.mkdirs();
74      }
75  
76      public void addFile(
77              long companyId, String portletId, long groupId, long repositoryId,
78              String fileName, long fileEntryId, String properties,
79              Date modifiedDate, ServiceContext serviceContext, InputStream is)
80          throws PortalException, SystemException {
81  
82          try {
83              File fileNameVersionFile = getFileNameVersionFile(
84                  companyId, repositoryId, fileName, DEFAULT_VERSION);
85  
86              if (fileNameVersionFile.exists()) {
87                  throw new DuplicateFileException(fileNameVersionFile.getPath());
88              }
89  
90              FileUtil.write(fileNameVersionFile, is);
91  
92              Indexer indexer = IndexerRegistryUtil.getIndexer(
93                  FileModel.class);
94  
95              FileModel fileModel = new FileModel();
96  
97              fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
98              fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
99              fileModel.setCompanyId(companyId);
100             fileModel.setFileEntryId(fileEntryId);
101             fileModel.setFileName(fileName);
102             fileModel.setGroupId(groupId);
103             fileModel.setModifiedDate(modifiedDate);
104             fileModel.setPortletId(portletId);
105             fileModel.setProperties(properties);
106             fileModel.setRepositoryId(repositoryId);
107 
108             indexer.reindex(fileModel);
109         }
110         catch (IOException ioe) {
111             throw new SystemException(ioe);
112         }
113     }
114 
115     public void checkRoot(long companyId) {
116     }
117 
118     public void deleteDirectory(
119             long companyId, String portletId, long repositoryId, String dirName)
120         throws PortalException {
121 
122         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
123 
124         if (!dirNameDir.exists()) {
125             throw new NoSuchDirectoryException(dirNameDir.getPath());
126         }
127 
128         FileUtil.deltree(dirNameDir);
129     }
130 
131     public void deleteFile(
132             long companyId, String portletId, long repositoryId,
133             String fileName)
134         throws PortalException {
135 
136         File fileNameDir = getFileNameDir(
137             companyId, repositoryId, fileName);
138 
139         if (!fileNameDir.exists()) {
140             throw new NoSuchFileException(fileNameDir.getPath());
141         }
142 
143         FileUtil.deltree(fileNameDir);
144 
145         FileModel fileModel = new FileModel();
146 
147         fileModel.setCompanyId(companyId);
148         fileModel.setFileName(fileName);
149         fileModel.setPortletId(portletId);
150         fileModel.setRepositoryId(repositoryId);
151 
152         Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
153 
154         indexer.delete(fileModel);
155     }
156 
157     public void deleteFile(
158             long companyId, String portletId, long repositoryId,
159             String fileName, String versionNumber)
160         throws PortalException {
161 
162         File fileNameVersionFile = getFileNameVersionFile(
163             companyId, repositoryId, fileName, versionNumber);
164 
165         if (!fileNameVersionFile.exists()) {
166             throw new NoSuchFileException(fileNameVersionFile.getPath());
167         }
168 
169         fileNameVersionFile.delete();
170     }
171 
172     public InputStream getFileAsStream(
173             long companyId, long repositoryId, String fileName,
174             String versionNumber)
175         throws PortalException, SystemException {
176 
177         try {
178             if (Validator.isNull(versionNumber)) {
179                 versionNumber = getHeadVersionNumber(
180                     companyId, repositoryId, fileName);
181             }
182 
183             File fileNameVersionFile = getFileNameVersionFile(
184                 companyId, repositoryId, fileName, versionNumber);
185 
186             if (!fileNameVersionFile.exists()) {
187                 throw new NoSuchFileException(fileNameVersionFile.getPath());
188             }
189 
190             return new FileInputStream(fileNameVersionFile);
191         }
192         catch (IOException ioe) {
193             throw new SystemException(ioe);
194         }
195     }
196 
197     public String[] getFileNames(
198             long companyId, long repositoryId, String dirName)
199         throws PortalException {
200 
201         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
202 
203         if (!dirNameDir.exists()) {
204             throw new NoSuchDirectoryException(dirNameDir.getPath());
205         }
206 
207         String[] fileNames = FileUtil.listDirs(dirNameDir);
208 
209         Arrays.sort(fileNames);
210 
211         // Convert /${fileName} to /${dirName}/${fileName}
212 
213         for (int i = 0; i < fileNames.length; i++) {
214             fileNames[i] =
215                 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
216         }
217 
218         return fileNames;
219     }
220 
221     public long getFileSize(
222             long companyId, long repositoryId, String fileName)
223         throws PortalException {
224 
225         String versionNumber = getHeadVersionNumber(
226             companyId, repositoryId, fileName);
227 
228         File fileNameVersionFile = getFileNameVersionFile(
229             companyId, repositoryId, fileName, versionNumber);
230 
231         if (!fileNameVersionFile.exists()) {
232             throw new NoSuchFileException(fileNameVersionFile.getPath());
233         }
234 
235         return fileNameVersionFile.length();
236     }
237 
238     public boolean hasFile(
239         long companyId, long repositoryId, String fileName,
240         String versionNumber) {
241 
242         File fileNameVersionFile = getFileNameVersionFile(
243             companyId, repositoryId, fileName, versionNumber);
244 
245         if (fileNameVersionFile.exists()) {
246             return true;
247         }
248         else {
249             return false;
250         }
251     }
252 
253     public void move(String srcDir, String destDir) {
254     }
255 
256     public void reindex(String[] ids) throws SearchException {
257         long companyId = GetterUtil.getLong(ids[0]);
258         String portletId = ids[1];
259         long groupId = GetterUtil.getLong(ids[2]);
260         long repositoryId = GetterUtil.getLong(ids[3]);
261 
262         Collection<Document> documents = new ArrayList<Document>();
263 
264         File repistoryDir = getRepositoryDir(companyId, repositoryId);
265 
266         String[] fileNames = FileUtil.listDirs(repistoryDir);
267 
268         for (int i = 0; i < fileNames.length; i++) {
269             String fileName = fileNames[i];
270 
271             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
272 
273             FileModel fileModel = new FileModel();
274 
275             fileModel.setCompanyId(companyId);
276             fileModel.setFileName(fileName);
277             fileModel.setGroupId(groupId);
278             fileModel.setPortletId(portletId);
279             fileModel.setRepositoryId(repositoryId);
280 
281             Document document = indexer.getDocument(fileModel);
282 
283             if (document == null) {
284                 continue;
285             }
286 
287             documents.add(document);
288         }
289 
290         SearchEngineUtil.updateDocuments(companyId, documents);
291     }
292 
293     public void updateFile(
294             long companyId, String portletId, long groupId, long repositoryId,
295             long newRepositoryId, String fileName, long fileEntryId)
296         throws PortalException {
297 
298         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
299         File newFileNameDir = getFileNameDir(
300             companyId, newRepositoryId, fileName);
301 
302         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
303 
304         FileUtil.deltree(fileNameDir);
305 
306         Indexer indexer = IndexerRegistryUtil.getIndexer(
307             FileModel.class);
308 
309         FileModel fileModel = new FileModel();
310 
311         fileModel.setCompanyId(companyId);
312         fileModel.setFileName(fileName);
313         fileModel.setPortletId(portletId);
314         fileModel.setRepositoryId(repositoryId);
315 
316         indexer.delete(fileModel);
317 
318         fileModel.setRepositoryId(newRepositoryId);
319         fileModel.setGroupId(groupId);
320 
321         indexer.reindex(fileModel);
322     }
323 
324     public void updateFile(
325             long companyId, String portletId, long groupId, long repositoryId,
326             String fileName, String newFileName, boolean reindex)
327         throws PortalException {
328 
329         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
330         File newFileNameDir = getFileNameDir(
331             companyId, repositoryId, newFileName);
332 
333         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
334 
335         FileUtil.deltree(fileNameDir);
336 
337         if (reindex) {
338             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
339 
340             FileModel fileModel = new FileModel();
341 
342             fileModel.setCompanyId(companyId);
343             fileModel.setFileName(fileName);
344             fileModel.setPortletId(portletId);
345             fileModel.setRepositoryId(repositoryId);
346 
347             indexer.delete(fileModel);
348 
349             fileModel.setFileName(newFileName);
350             fileModel.setGroupId(groupId);
351 
352             indexer.reindex(fileModel);
353         }
354     }
355 
356     public void updateFile(
357             long companyId, String portletId, long groupId, long repositoryId,
358             String fileName, String versionNumber, String sourceFileName,
359             long fileEntryId, String properties, Date modifiedDate,
360             ServiceContext serviceContext, InputStream is)
361         throws PortalException, SystemException {
362 
363         try {
364             File fileNameVersionFile = getFileNameVersionFile(
365                 companyId, repositoryId, fileName, versionNumber);
366 
367             if (fileNameVersionFile.exists()) {
368                 throw new DuplicateFileException(fileNameVersionFile.getPath());
369             }
370 
371             FileUtil.write(fileNameVersionFile, is);
372 
373             Indexer indexer = IndexerRegistryUtil.getIndexer(
374                 FileModel.class);
375 
376             FileModel fileModel = new FileModel();
377 
378             fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
379             fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
380             fileModel.setCompanyId(companyId);
381             fileModel.setFileEntryId(fileEntryId);
382             fileModel.setFileName(fileName);
383             fileModel.setGroupId(groupId);
384             fileModel.setModifiedDate(modifiedDate);
385             fileModel.setPortletId(portletId);
386             fileModel.setProperties(properties);
387             fileModel.setRepositoryId(repositoryId);
388 
389             indexer.reindex(fileModel);
390         }
391         catch (IOException ioe) {
392             throw new SystemException(ioe);
393         }
394     }
395 
396     protected File getCompanyDir(long companyId) {
397         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
398 
399         if (!companyDir.exists()) {
400             companyDir.mkdirs();
401         }
402 
403         return companyDir;
404     }
405 
406     protected File getDirNameDir(
407         long companyId, long repositoryId, String dirName) {
408 
409         return getFileNameDir(companyId, repositoryId, dirName);
410     }
411 
412     protected File getFileNameDir(
413         long companyId, long repositoryId, String fileName) {
414 
415         File repositoryDir = getRepositoryDir(companyId, repositoryId);
416 
417         File fileNameDir = new File(
418             repositoryDir + StringPool.SLASH + fileName);
419 
420         return fileNameDir;
421     }
422 
423     protected File getFileNameVersionFile(
424         long companyId, long repositoryId, String fileName, String version) {
425 
426         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
427 
428         File fileNameVersionFile = new File(
429             fileNameDir + StringPool.SLASH + version);
430 
431         return fileNameVersionFile;
432     }
433 
434     protected String getHeadVersionNumber(
435         long companyId, long repositoryId, String fileName) {
436 
437         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
438 
439         if (!fileNameDir.exists()) {
440             return DEFAULT_VERSION;
441         }
442 
443         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
444 
445         String headVersionNumber = DEFAULT_VERSION;
446 
447         for (String versionNumber : versionNumbers) {
448             if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
449                 headVersionNumber = versionNumber;
450             }
451         }
452 
453         return headVersionNumber;
454     }
455 
456     protected File getRepositoryDir(long companyId, long repositoryId) {
457         File companyDir = getCompanyDir(companyId);
458 
459         File repositoryDir = new File(
460             companyDir + StringPool.SLASH + repositoryId);
461 
462         if (!repositoryDir.exists()) {
463             repositoryDir.mkdirs();
464         }
465 
466         return repositoryDir;
467     }
468 
469     private static final String _ROOT_DIR = PropsUtil.get(
470         PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
471 
472     private File _rootDir;
473 
474 }