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.log.Log;
25  import com.liferay.portal.kernel.log.LogFactoryUtil;
26  import com.liferay.portal.kernel.search.Document;
27  import com.liferay.portal.kernel.search.Field;
28  import com.liferay.portal.kernel.search.Indexer;
29  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
30  import com.liferay.portal.kernel.search.SearchEngineUtil;
31  import com.liferay.portal.kernel.util.FileUtil;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.kernel.util.PropsKeys;
34  import com.liferay.portal.kernel.util.StringPool;
35  import com.liferay.portal.kernel.util.Validator;
36  import com.liferay.portal.service.ServiceContext;
37  import com.liferay.portal.util.PropsUtil;
38  import com.liferay.portlet.documentlibrary.util.DLUtil;
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  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) {
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         File repistoryDir = getRepositoryDir(companyId, repositoryId);
263 
264         String[] fileNames = FileUtil.listDirs(repistoryDir);
265 
266         for (int i = 0; i < fileNames.length; i++) {
267             String fileName = fileNames[i];
268 
269             try {
270                 Indexer indexer = IndexerRegistryUtil.getIndexer(
271                     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                 SearchEngineUtil.updateDocument(
284                     companyId, document.get(Field.UID), document);
285             }
286             catch (Exception e) {
287                 _log.error("Reindexing " + fileName, e);
288             }
289         }
290     }
291 
292     public void updateFile(
293             long companyId, String portletId, long groupId, long repositoryId,
294             long newRepositoryId, String fileName, long fileEntryId)
295         throws PortalException {
296 
297         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
298         File newFileNameDir = getFileNameDir(
299             companyId, newRepositoryId, fileName);
300 
301         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
302 
303         FileUtil.deltree(fileNameDir);
304 
305         Indexer indexer = IndexerRegistryUtil.getIndexer(
306             FileModel.class);
307 
308         FileModel fileModel = new FileModel();
309 
310         fileModel.setCompanyId(companyId);
311         fileModel.setFileName(fileName);
312         fileModel.setPortletId(portletId);
313         fileModel.setRepositoryId(repositoryId);
314 
315         indexer.delete(fileModel);
316 
317         fileModel.setRepositoryId(newRepositoryId);
318         fileModel.setGroupId(groupId);
319 
320         indexer.reindex(fileModel);
321     }
322 
323     public void updateFile(
324             long companyId, String portletId, long groupId, long repositoryId,
325             String fileName, String versionNumber, String sourceFileName,
326             long fileEntryId, String properties, Date modifiedDate,
327             ServiceContext serviceContext, InputStream is)
328         throws PortalException, SystemException {
329 
330         try {
331             File fileNameVersionFile = getFileNameVersionFile(
332                 companyId, repositoryId, fileName, versionNumber);
333 
334             if (fileNameVersionFile.exists()) {
335                 throw new DuplicateFileException(fileNameVersionFile.getPath());
336             }
337 
338             FileUtil.write(fileNameVersionFile, is);
339 
340             Indexer indexer = IndexerRegistryUtil.getIndexer(
341                 FileModel.class);
342 
343             FileModel fileModel = new FileModel();
344 
345             fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
346             fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
347             fileModel.setCompanyId(companyId);
348             fileModel.setFileEntryId(fileEntryId);
349             fileModel.setFileName(fileName);
350             fileModel.setGroupId(groupId);
351             fileModel.setModifiedDate(modifiedDate);
352             fileModel.setPortletId(portletId);
353             fileModel.setProperties(properties);
354             fileModel.setRepositoryId(repositoryId);
355 
356             indexer.reindex(fileModel);
357         }
358         catch (IOException ioe) {
359             throw new SystemException(ioe);
360         }
361     }
362 
363     public void updateFile(
364             long companyId, String portletId, long groupId, long repositoryId,
365             String fileName, String newFileName, boolean reindex)
366         throws PortalException {
367 
368         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
369         File newFileNameDir = getFileNameDir(
370             companyId, repositoryId, newFileName);
371 
372         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
373 
374         FileUtil.deltree(fileNameDir);
375 
376         if (reindex) {
377             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
378 
379             FileModel fileModel = new FileModel();
380 
381             fileModel.setCompanyId(companyId);
382             fileModel.setFileName(fileName);
383             fileModel.setPortletId(portletId);
384             fileModel.setRepositoryId(repositoryId);
385 
386             indexer.delete(fileModel);
387 
388             fileModel.setFileName(newFileName);
389             fileModel.setGroupId(groupId);
390 
391             indexer.reindex(fileModel);
392         }
393     }
394 
395     protected File getCompanyDir(long companyId) {
396         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
397 
398         if (!companyDir.exists()) {
399             companyDir.mkdirs();
400         }
401 
402         return companyDir;
403     }
404 
405     protected File getDirNameDir(
406         long companyId, long repositoryId, String dirName) {
407 
408         return getFileNameDir(companyId, repositoryId, dirName);
409     }
410 
411     protected File getFileNameDir(
412         long companyId, long repositoryId, String fileName) {
413 
414         File repositoryDir = getRepositoryDir(companyId, repositoryId);
415 
416         File fileNameDir = new File(
417             repositoryDir + StringPool.SLASH + fileName);
418 
419         return fileNameDir;
420     }
421 
422     protected File getFileNameVersionFile(
423         long companyId, long repositoryId, String fileName, String version) {
424 
425         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
426 
427         File fileNameVersionFile = new File(
428             fileNameDir + StringPool.SLASH + version);
429 
430         return fileNameVersionFile;
431     }
432 
433     protected String getHeadVersionNumber(
434         long companyId, long repositoryId, String fileName) {
435 
436         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
437 
438         if (!fileNameDir.exists()) {
439             return DEFAULT_VERSION;
440         }
441 
442         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
443 
444         String headVersionNumber = DEFAULT_VERSION;
445 
446         for (String versionNumber : versionNumbers) {
447             if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
448                 headVersionNumber = versionNumber;
449             }
450         }
451 
452         return headVersionNumber;
453     }
454 
455     protected File getRepositoryDir(long companyId, long repositoryId) {
456         File companyDir = getCompanyDir(companyId);
457 
458         File repositoryDir = new File(
459             companyDir + StringPool.SLASH + repositoryId);
460 
461         if (!repositoryDir.exists()) {
462             repositoryDir.mkdirs();
463         }
464 
465         return repositoryDir;
466     }
467 
468     private static final String _ROOT_DIR = PropsUtil.get(
469         PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
470 
471     private static Log _log = LogFactoryUtil.getLog(FileSystemHook.class);
472 
473     private File _rootDir;
474 
475 }