1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.documentlibrary.util;
24  
25  import com.liferay.documentlibrary.DuplicateDirectoryException;
26  import com.liferay.documentlibrary.DuplicateFileException;
27  import com.liferay.documentlibrary.NoSuchDirectoryException;
28  import com.liferay.documentlibrary.NoSuchFileException;
29  import com.liferay.portal.PortalException;
30  import com.liferay.portal.SystemException;
31  import com.liferay.portal.kernel.log.Log;
32  import com.liferay.portal.kernel.log.LogFactoryUtil;
33  import com.liferay.portal.kernel.search.Document;
34  import com.liferay.portal.kernel.search.Field;
35  import com.liferay.portal.kernel.search.SearchEngineUtil;
36  import com.liferay.portal.kernel.search.SearchException;
37  import com.liferay.portal.kernel.util.FileUtil;
38  import com.liferay.portal.kernel.util.GetterUtil;
39  import com.liferay.portal.kernel.util.StringPool;
40  import com.liferay.portal.util.PropsKeys;
41  import com.liferay.portal.util.PropsUtil;
42  
43  import java.io.File;
44  import java.io.FileInputStream;
45  import java.io.IOException;
46  import java.io.InputStream;
47  
48  import java.util.Arrays;
49  import java.util.Date;
50  
51  /**
52   * <a href="FileSystemHook.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Brian Wing Shun Chan
55   * @author Sten Martinez
56   *
57   */
58  public class FileSystemHook extends BaseHook {
59  
60      public FileSystemHook() {
61          _rootDir = new File(_ROOT_DIR);
62  
63          if (!_rootDir.exists()) {
64              _rootDir.mkdirs();
65          }
66      }
67  
68      public void addDirectory(long companyId, long repositoryId, String dirName)
69          throws PortalException {
70  
71          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
72  
73          if (dirNameDir.exists()) {
74              throw new DuplicateDirectoryException();
75          }
76  
77          dirNameDir.mkdirs();
78      }
79  
80      public void addFile(
81              long companyId, String portletId, long groupId, long repositoryId,
82              String fileName, long fileEntryId, String properties,
83              Date modifiedDate, String[] tagsEntries, InputStream is)
84          throws PortalException, SystemException {
85  
86          try {
87              File fileNameVersionFile = getFileNameVersionFile(
88                  companyId, repositoryId, fileName, DEFAULT_VERSION);
89  
90              if (fileNameVersionFile.exists()) {
91                  throw new DuplicateFileException();
92              }
93  
94              FileUtil.write(fileNameVersionFile, is);
95  
96              Indexer.addFile(
97                  companyId, portletId, groupId, repositoryId, fileName,
98                  fileEntryId, properties, modifiedDate, tagsEntries);
99          }
100         catch (IOException ioe) {
101             throw new SystemException();
102         }
103     }
104 
105     public void checkRoot(long companyId) {
106     }
107 
108     public void deleteDirectory(
109             long companyId, String portletId, long repositoryId, String dirName)
110         throws PortalException {
111 
112         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
113 
114         if (!dirNameDir.exists()) {
115             throw new NoSuchDirectoryException();
116         }
117 
118         FileUtil.deltree(dirNameDir);
119     }
120 
121     public void deleteFile(
122             long companyId, String portletId, long repositoryId,
123             String fileName)
124         throws PortalException, SystemException {
125 
126         try {
127             File fileNameDir = getFileNameDir(
128                 companyId, repositoryId, fileName);
129 
130             if (!fileNameDir.exists()) {
131                 throw new NoSuchFileException();
132             }
133 
134             FileUtil.deltree(fileNameDir);
135 
136             Indexer.deleteFile(companyId, portletId, repositoryId, fileName);
137         }
138         catch (SearchException se) {
139             throw new SystemException();
140         }
141     }
142 
143     public void deleteFile(
144             long companyId, String portletId, long repositoryId,
145             String fileName, double versionNumber)
146         throws PortalException {
147 
148         File fileNameVersionFile = getFileNameVersionFile(
149             companyId, repositoryId, fileName, versionNumber);
150 
151         if (!fileNameVersionFile.exists()) {
152             throw new NoSuchFileException();
153         }
154 
155         fileNameVersionFile.delete();
156     }
157 
158     public InputStream getFileAsStream(
159             long companyId, long repositoryId, String fileName,
160             double versionNumber)
161         throws PortalException, SystemException {
162 
163         try {
164             if (versionNumber == 0) {
165                 versionNumber = getHeadVersionNumber(
166                     companyId, repositoryId, fileName);
167             }
168 
169             File fileNameVersionFile = getFileNameVersionFile(
170                 companyId, repositoryId, fileName, versionNumber);
171 
172             if (!fileNameVersionFile.exists()) {
173                 throw new NoSuchFileException();
174             }
175 
176             return new FileInputStream(fileNameVersionFile);
177         }
178         catch (IOException ioe) {
179             throw new SystemException();
180         }
181     }
182 
183     public String[] getFileNames(
184             long companyId, long repositoryId, String dirName)
185         throws PortalException {
186 
187         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
188 
189         if (!dirNameDir.exists()) {
190             throw new NoSuchDirectoryException();
191         }
192 
193         String[] fileNames = FileUtil.listDirs(dirNameDir);
194 
195         Arrays.sort(fileNames);
196 
197         // Convert /${fileName} to /${dirName}/${fileName}
198 
199         for (int i = 0; i < fileNames.length; i++) {
200             fileNames[i] =
201                 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
202         }
203 
204         return fileNames;
205     }
206 
207     public long getFileSize(
208             long companyId, long repositoryId, String fileName)
209         throws PortalException {
210 
211         double versionNumber = getHeadVersionNumber(
212             companyId, repositoryId, fileName);
213 
214         File fileNameVersionFile = getFileNameVersionFile(
215             companyId, repositoryId, fileName, versionNumber);
216 
217         if (!fileNameVersionFile.exists()) {
218             throw new NoSuchFileException();
219         }
220 
221         return fileNameVersionFile.length();
222     }
223 
224     public boolean hasFile(
225         long companyId, long repositoryId, String fileName,
226         double versionNumber) {
227 
228         File fileNameVersionFile = getFileNameVersionFile(
229             companyId, repositoryId, fileName, versionNumber);
230 
231         if (fileNameVersionFile.exists()) {
232             return true;
233         }
234         else {
235             return false;
236         }
237     }
238 
239     public void move(String srcDir, String destDir) {
240     }
241 
242     public void reIndex(String[] ids) {
243         long companyId = GetterUtil.getLong(ids[0]);
244         String portletId = ids[1];
245         long groupId = GetterUtil.getLong(ids[2]);
246         long repositoryId = GetterUtil.getLong(ids[3]);
247 
248         File repistoryDir = getRepositoryDir(companyId, repositoryId);
249 
250         String[] fileNames = FileUtil.listDirs(repistoryDir);
251 
252         for (int i = 0; i < fileNames.length; i++) {
253             String fileName = fileNames[i];
254 
255             try {
256                 Document doc = Indexer.getFileDocument(
257                     companyId, portletId, groupId, repositoryId, fileName);
258 
259                 SearchEngineUtil.updateDocument(
260                     companyId, doc.get(Field.UID), doc);
261             }
262             catch (Exception e) {
263                 _log.error("Reindexing " + fileName, e);
264             }
265         }
266     }
267 
268     public void updateFile(
269             long companyId, String portletId, long groupId, long repositoryId,
270             String fileName, double versionNumber, String sourceFileName,
271             long fileEntryId, String properties, Date modifiedDate,
272             String[] tagsEntries, InputStream is)
273         throws PortalException, SystemException {
274 
275         try {
276             File fileNameVersionFile = getFileNameVersionFile(
277                 companyId, repositoryId, fileName, versionNumber);
278 
279             if (fileNameVersionFile.exists()) {
280                 throw new DuplicateFileException();
281             }
282 
283             FileUtil.write(fileNameVersionFile, is);
284 
285             Indexer.updateFile(
286                 companyId, portletId, groupId, repositoryId, fileName,
287                 fileEntryId, properties, modifiedDate, 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 }