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.Indexer;
28  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
29  import com.liferay.portal.kernel.search.SearchEngineUtil;
30  import com.liferay.portal.kernel.search.SearchException;
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.ArrayList;
46  import java.util.Arrays;
47  import java.util.Collection;
48  import java.util.Date;
49  
50  /**
51   * <a href="FileSystemHook.java.html"><b><i>View Source</i></b></a>
52   *
53   * @author Brian Wing Shun Chan
54   * @author Sten Martinez
55   */
56  public class FileSystemHook extends BaseHook {
57  
58      public FileSystemHook() {
59          _rootDir = new File(_ROOT_DIR);
60  
61          if (!_rootDir.exists()) {
62              _rootDir.mkdirs();
63          }
64      }
65  
66      public void addDirectory(long companyId, long repositoryId, String dirName)
67          throws PortalException {
68  
69          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
70  
71          if (dirNameDir.exists()) {
72              throw new DuplicateDirectoryException(dirNameDir.getPath());
73          }
74  
75          dirNameDir.mkdirs();
76      }
77  
78      public void addFile(
79              long companyId, String portletId, long groupId, long repositoryId,
80              String fileName, long fileEntryId, String properties,
81              Date modifiedDate, ServiceContext serviceContext, 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(fileNameVersionFile.getPath());
90              }
91  
92              FileUtil.write(fileNameVersionFile, is);
93  
94              Indexer indexer = IndexerRegistryUtil.getIndexer(
95                  FileModel.class);
96  
97              FileModel fileModel = new FileModel();
98  
99              fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
100             fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
101             fileModel.setCompanyId(companyId);
102             fileModel.setFileEntryId(fileEntryId);
103             fileModel.setFileName(fileName);
104             fileModel.setGroupId(groupId);
105             fileModel.setModifiedDate(modifiedDate);
106             fileModel.setPortletId(portletId);
107             fileModel.setProperties(properties);
108             fileModel.setRepositoryId(repositoryId);
109 
110             indexer.reindex(fileModel);
111         }
112         catch (IOException ioe) {
113             throw new SystemException(ioe);
114         }
115     }
116 
117     public void checkRoot(long companyId) {
118     }
119 
120     public void deleteDirectory(
121             long companyId, String portletId, long repositoryId, String dirName)
122         throws PortalException {
123 
124         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
125 
126         if (!dirNameDir.exists()) {
127             throw new NoSuchDirectoryException(dirNameDir.getPath());
128         }
129 
130         FileUtil.deltree(dirNameDir);
131     }
132 
133     public void deleteFile(
134             long companyId, String portletId, long repositoryId,
135             String fileName)
136         throws PortalException {
137 
138         File fileNameDir = getFileNameDir(
139             companyId, repositoryId, fileName);
140 
141         if (!fileNameDir.exists()) {
142             throw new NoSuchFileException(fileNameDir.getPath());
143         }
144 
145         FileUtil.deltree(fileNameDir);
146 
147         FileModel fileModel = new FileModel();
148 
149         fileModel.setCompanyId(companyId);
150         fileModel.setFileName(fileName);
151         fileModel.setPortletId(portletId);
152         fileModel.setRepositoryId(repositoryId);
153 
154         Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
155 
156         indexer.delete(fileModel);
157     }
158 
159     public void deleteFile(
160             long companyId, String portletId, long repositoryId,
161             String fileName, String versionNumber)
162         throws PortalException {
163 
164         File fileNameVersionFile = getFileNameVersionFile(
165             companyId, repositoryId, fileName, versionNumber);
166 
167         if (!fileNameVersionFile.exists()) {
168             throw new NoSuchFileException(fileNameVersionFile.getPath());
169         }
170 
171         fileNameVersionFile.delete();
172     }
173 
174     public InputStream getFileAsStream(
175             long companyId, long repositoryId, String fileName,
176             String versionNumber)
177         throws PortalException, SystemException {
178 
179         try {
180             if (Validator.isNull(versionNumber)) {
181                 versionNumber = getHeadVersionNumber(
182                     companyId, repositoryId, fileName);
183             }
184 
185             File fileNameVersionFile = getFileNameVersionFile(
186                 companyId, repositoryId, fileName, versionNumber);
187 
188             if (!fileNameVersionFile.exists()) {
189                 throw new NoSuchFileException(fileNameVersionFile.getPath());
190             }
191 
192             return new FileInputStream(fileNameVersionFile);
193         }
194         catch (IOException ioe) {
195             throw new SystemException(ioe);
196         }
197     }
198 
199     public String[] getFileNames(
200             long companyId, long repositoryId, String dirName)
201         throws PortalException {
202 
203         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
204 
205         if (!dirNameDir.exists()) {
206             throw new NoSuchDirectoryException(dirNameDir.getPath());
207         }
208 
209         String[] fileNames = FileUtil.listDirs(dirNameDir);
210 
211         Arrays.sort(fileNames);
212 
213         // Convert /${fileName} to /${dirName}/${fileName}
214 
215         for (int i = 0; i < fileNames.length; i++) {
216             fileNames[i] =
217                 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
218         }
219 
220         return fileNames;
221     }
222 
223     public long getFileSize(
224             long companyId, long repositoryId, String fileName)
225         throws PortalException {
226 
227         String versionNumber = getHeadVersionNumber(
228             companyId, repositoryId, fileName);
229 
230         File fileNameVersionFile = getFileNameVersionFile(
231             companyId, repositoryId, fileName, versionNumber);
232 
233         if (!fileNameVersionFile.exists()) {
234             throw new NoSuchFileException(fileNameVersionFile.getPath());
235         }
236 
237         return fileNameVersionFile.length();
238     }
239 
240     public boolean hasFile(
241         long companyId, long repositoryId, String fileName,
242         String versionNumber) {
243 
244         File fileNameVersionFile = getFileNameVersionFile(
245             companyId, repositoryId, fileName, versionNumber);
246 
247         if (fileNameVersionFile.exists()) {
248             return true;
249         }
250         else {
251             return false;
252         }
253     }
254 
255     public void move(String srcDir, String destDir) {
256     }
257 
258     public void reindex(String[] ids) throws SearchException {
259         long companyId = GetterUtil.getLong(ids[0]);
260         String portletId = ids[1];
261         long groupId = GetterUtil.getLong(ids[2]);
262         long repositoryId = GetterUtil.getLong(ids[3]);
263 
264         Collection<Document> documents = new ArrayList<Document>();
265 
266         File repistoryDir = getRepositoryDir(companyId, repositoryId);
267 
268         String[] fileNames = FileUtil.listDirs(repistoryDir);
269 
270         for (int i = 0; i < fileNames.length; i++) {
271             String fileName = fileNames[i];
272 
273             try {
274                 Indexer indexer = IndexerRegistryUtil.getIndexer(
275                     FileModel.class);
276 
277                 FileModel fileModel = new FileModel();
278 
279                 fileModel.setCompanyId(companyId);
280                 fileModel.setFileName(fileName);
281                 fileModel.setGroupId(groupId);
282                 fileModel.setPortletId(portletId);
283                 fileModel.setRepositoryId(repositoryId);
284 
285                 Document document = indexer.getDocument(fileModel);
286 
287                 if (document == null) {
288                     continue;
289                 }
290 
291                 documents.add(document);
292             }
293             catch (Exception e) {
294                 _log.error("Reindexing " + fileName, e);
295             }
296         }
297 
298         SearchEngineUtil.updateDocuments(companyId, documents);
299     }
300 
301     public void updateFile(
302             long companyId, String portletId, long groupId, long repositoryId,
303             long newRepositoryId, String fileName, long fileEntryId)
304         throws PortalException {
305 
306         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
307         File newFileNameDir = getFileNameDir(
308             companyId, newRepositoryId, fileName);
309 
310         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
311 
312         FileUtil.deltree(fileNameDir);
313 
314         Indexer indexer = IndexerRegistryUtil.getIndexer(
315             FileModel.class);
316 
317         FileModel fileModel = new FileModel();
318 
319         fileModel.setCompanyId(companyId);
320         fileModel.setFileName(fileName);
321         fileModel.setPortletId(portletId);
322         fileModel.setRepositoryId(repositoryId);
323 
324         indexer.delete(fileModel);
325 
326         fileModel.setRepositoryId(newRepositoryId);
327         fileModel.setGroupId(groupId);
328 
329         indexer.reindex(fileModel);
330     }
331 
332     public void updateFile(
333             long companyId, String portletId, long groupId, long repositoryId,
334             String fileName, String newFileName, boolean reindex)
335         throws PortalException {
336 
337         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
338         File newFileNameDir = getFileNameDir(
339             companyId, repositoryId, newFileName);
340 
341         FileUtil.copyDirectory(fileNameDir, newFileNameDir);
342 
343         FileUtil.deltree(fileNameDir);
344 
345         if (reindex) {
346             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
347 
348             FileModel fileModel = new FileModel();
349 
350             fileModel.setCompanyId(companyId);
351             fileModel.setFileName(fileName);
352             fileModel.setPortletId(portletId);
353             fileModel.setRepositoryId(repositoryId);
354 
355             indexer.delete(fileModel);
356 
357             fileModel.setFileName(newFileName);
358             fileModel.setGroupId(groupId);
359 
360             indexer.reindex(fileModel);
361         }
362     }
363 
364     public void updateFile(
365             long companyId, String portletId, long groupId, long repositoryId,
366             String fileName, String versionNumber, String sourceFileName,
367             long fileEntryId, String properties, Date modifiedDate,
368             ServiceContext serviceContext, InputStream is)
369         throws PortalException, SystemException {
370 
371         try {
372             File fileNameVersionFile = getFileNameVersionFile(
373                 companyId, repositoryId, fileName, versionNumber);
374 
375             if (fileNameVersionFile.exists()) {
376                 throw new DuplicateFileException(fileNameVersionFile.getPath());
377             }
378 
379             FileUtil.write(fileNameVersionFile, is);
380 
381             Indexer indexer = IndexerRegistryUtil.getIndexer(
382                 FileModel.class);
383 
384             FileModel fileModel = new FileModel();
385 
386             fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
387             fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
388             fileModel.setCompanyId(companyId);
389             fileModel.setFileEntryId(fileEntryId);
390             fileModel.setFileName(fileName);
391             fileModel.setGroupId(groupId);
392             fileModel.setModifiedDate(modifiedDate);
393             fileModel.setPortletId(portletId);
394             fileModel.setProperties(properties);
395             fileModel.setRepositoryId(repositoryId);
396 
397             indexer.reindex(fileModel);
398         }
399         catch (IOException ioe) {
400             throw new SystemException(ioe);
401         }
402     }
403 
404     protected File getCompanyDir(long companyId) {
405         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
406 
407         if (!companyDir.exists()) {
408             companyDir.mkdirs();
409         }
410 
411         return companyDir;
412     }
413 
414     protected File getDirNameDir(
415         long companyId, long repositoryId, String dirName) {
416 
417         return getFileNameDir(companyId, repositoryId, dirName);
418     }
419 
420     protected File getFileNameDir(
421         long companyId, long repositoryId, String fileName) {
422 
423         File repositoryDir = getRepositoryDir(companyId, repositoryId);
424 
425         File fileNameDir = new File(
426             repositoryDir + StringPool.SLASH + fileName);
427 
428         return fileNameDir;
429     }
430 
431     protected File getFileNameVersionFile(
432         long companyId, long repositoryId, String fileName, String version) {
433 
434         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
435 
436         File fileNameVersionFile = new File(
437             fileNameDir + StringPool.SLASH + version);
438 
439         return fileNameVersionFile;
440     }
441 
442     protected String getHeadVersionNumber(
443         long companyId, long repositoryId, String fileName) {
444 
445         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
446 
447         if (!fileNameDir.exists()) {
448             return DEFAULT_VERSION;
449         }
450 
451         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
452 
453         String headVersionNumber = DEFAULT_VERSION;
454 
455         for (String versionNumber : versionNumbers) {
456             if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
457                 headVersionNumber = versionNumber;
458             }
459         }
460 
461         return headVersionNumber;
462     }
463 
464     protected File getRepositoryDir(long companyId, long repositoryId) {
465         File companyDir = getCompanyDir(companyId);
466 
467         File repositoryDir = new File(
468             companyDir + StringPool.SLASH + repositoryId);
469 
470         if (!repositoryDir.exists()) {
471             repositoryDir.mkdirs();
472         }
473 
474         return repositoryDir;
475     }
476 
477     private static final String _ROOT_DIR = PropsUtil.get(
478         PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
479 
480     private static Log _log = LogFactoryUtil.getLog(FileSystemHook.class);
481 
482     private File _rootDir;
483 
484 }