1   /**
2    * Copyright (c) 2000-2008 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.search.SearchException;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.kernel.util.StringPool;
34  import com.liferay.portal.lucene.LuceneUtil;
35  import com.liferay.portal.util.PropsUtil;
36  import com.liferay.util.FileUtil;
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.Arrays;
44  
45  import org.apache.commons.logging.Log;
46  import org.apache.commons.logging.LogFactory;
47  import org.apache.lucene.document.Document;
48  import org.apache.lucene.index.IndexWriter;
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   */
57  public class FileSystemHook extends BaseHook {
58  
59      public FileSystemHook() {
60          _rootDir = new File(_ROOT_DIR);
61  
62          if (!_rootDir.exists()) {
63              _rootDir.mkdirs();
64          }
65      }
66  
67      public void addDirectory(long companyId, long repositoryId, String dirName)
68          throws PortalException, SystemException {
69  
70          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
71  
72          if (dirNameDir.exists()) {
73              throw new DuplicateDirectoryException();
74          }
75  
76          dirNameDir.mkdirs();
77      }
78  
79      public void addFile(
80              long companyId, String portletId, long groupId, long repositoryId,
81              String fileName, String properties, String[] tagsEntries,
82              InputStream is)
83          throws PortalException, SystemException {
84  
85          try {
86              File fileNameVersionFile = getFileNameVersionFile(
87                  companyId, repositoryId, fileName, DEFAULT_VERSION);
88  
89              if (fileNameVersionFile.exists()) {
90                  throw new DuplicateFileException();
91              }
92  
93              FileUtil.write(fileNameVersionFile, is);
94  
95              Indexer.addFile(
96                  companyId, portletId, groupId, repositoryId, fileName,
97                  properties, tagsEntries);
98          }
99          catch (IOException ioe) {
100             throw new SystemException();
101         }
102     }
103 
104     public void checkRoot(long companyId) throws SystemException {
105     }
106 
107     public void deleteDirectory(
108             long companyId, String portletId, long repositoryId, String dirName)
109         throws PortalException, SystemException {
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 (IOException ioe) {
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, SystemException {
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, SystemException {
185 
186         try {
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 +
202                         fileNames[i];
203             }
204 
205             return fileNames;
206         }
207         catch (IOException ioe) {
208             throw new SystemException();
209         }
210     }
211 
212     public long getFileSize(
213             long companyId, long repositoryId, String fileName)
214         throws PortalException, SystemException {
215 
216         try {
217             double versionNumber = getHeadVersionNumber(
218                 companyId, repositoryId, fileName);
219 
220             File fileNameVersionFile = getFileNameVersionFile(
221                 companyId, repositoryId, fileName, versionNumber);
222 
223             if (!fileNameVersionFile.exists()) {
224                 throw new NoSuchFileException();
225             }
226 
227             return fileNameVersionFile.length();
228         }
229         catch (IOException ioe) {
230             throw new SystemException();
231         }
232     }
233 
234     public boolean hasFile(
235             long companyId, long repositoryId, String fileName,
236             double versionNumber)
237         throws PortalException, SystemException {
238 
239         File fileNameVersionFile = getFileNameVersionFile(
240             companyId, repositoryId, fileName, versionNumber);
241 
242         if (fileNameVersionFile.exists()) {
243             return true;
244         }
245         else {
246             return false;
247         }
248     }
249 
250     public void move(String srcDir, String destDir) throws SystemException {
251     }
252 
253     public void reIndex(String[] ids) throws SearchException {
254         long companyId = GetterUtil.getLong(ids[0]);
255         String portletId = ids[1];
256         long groupId = GetterUtil.getLong(ids[2]);
257         long repositoryId = GetterUtil.getLong(ids[3]);
258 
259         IndexWriter writer = null;
260 
261         try {
262             writer = LuceneUtil.getWriter(companyId);
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                 try {
272                     Document doc = Indexer.getAddFileDocument(
273                         companyId, portletId, groupId, repositoryId, fileName);
274 
275                     writer.addDocument(doc);
276                 }
277                 catch (Exception e) {
278                     _log.error("Reindexing " + fileName, e);
279                 }
280             }
281         }
282         catch (IOException ioe) {
283             throw new SearchException(ioe);
284         }
285         finally {
286             try {
287                 if (writer != null) {
288                     LuceneUtil.write(companyId);
289                 }
290             }
291             catch (Exception e) {
292                 _log.error(e);
293             }
294         }
295     }
296 
297     public void updateFile(
298             long companyId, String portletId, long groupId, long repositoryId,
299             String fileName, double versionNumber, String sourceFileName,
300             String properties, String[] tagsEntries, InputStream is)
301         throws PortalException, SystemException {
302 
303         try {
304             File fileNameVersionFile = getFileNameVersionFile(
305                 companyId, repositoryId, fileName, versionNumber);
306 
307             if (fileNameVersionFile.exists()) {
308                 throw new DuplicateFileException();
309             }
310 
311             FileUtil.write(fileNameVersionFile, is);
312 
313             Indexer.updateFile(
314                 companyId, portletId, groupId, repositoryId, fileName,
315                 properties, tagsEntries);
316         }
317         catch (IOException ioe) {
318             throw new SystemException();
319         }
320     }
321 
322     public void updateFile(
323             long companyId, String portletId, long groupId, long repositoryId,
324             long newRepositoryId, String fileName)
325         throws PortalException, SystemException {
326 
327         try {
328             File fileNameDir = getFileNameDir(
329                 companyId, repositoryId, fileName);
330             File newFileNameDir = getFileNameDir(
331                 companyId, newRepositoryId, fileName);
332 
333             FileUtil.copyDirectory(fileNameDir, newFileNameDir);
334 
335             FileUtil.deltree(fileNameDir);
336 
337             try {
338                 Indexer.deleteFile(
339                     companyId, portletId, repositoryId, fileName);
340             }
341             catch (IOException ioe) {
342             }
343 
344             Indexer.addFile(
345                 companyId, portletId, groupId, newRepositoryId, fileName);
346         }
347         catch (IOException ioe) {
348             throw new SystemException();
349         }
350     }
351 
352     protected File getCompanyDir(long companyId) {
353         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
354 
355         if (!companyDir.exists()) {
356             companyDir.mkdirs();
357         }
358 
359         return companyDir;
360     }
361 
362     protected File getDirNameDir(
363         long companyId, long repositoryId, String dirName) {
364 
365         return getFileNameDir(companyId, repositoryId, dirName);
366     }
367 
368     protected File getRepositoryDir(long companyId, long repositoryId) {
369         File companyDir = getCompanyDir(companyId);
370 
371         File repositoryDir = new File(
372             companyDir + StringPool.SLASH + repositoryId);
373 
374         if (!repositoryDir.exists()) {
375             repositoryDir.mkdirs();
376         }
377 
378         return repositoryDir;
379     }
380 
381     protected File getFileNameDir(
382         long companyId, long repositoryId, String fileName) {
383 
384         File repositoryDir = getRepositoryDir(companyId, repositoryId);
385 
386         File fileNameDir = new File(
387             repositoryDir + StringPool.SLASH + fileName);
388 
389         return fileNameDir;
390     }
391 
392     protected File getFileNameVersionFile(
393         long companyId, long repositoryId, String fileName, double version) {
394 
395         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
396 
397         File fileNameVersionFile = new File(
398             fileNameDir + StringPool.SLASH + version);
399 
400         return fileNameVersionFile;
401     }
402 
403     protected double getHeadVersionNumber(
404             long companyId, long repositoryId, String fileName)
405         throws IOException {
406 
407         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
408 
409         if (!fileNameDir.exists()) {
410             return DEFAULT_VERSION;
411         }
412 
413         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
414 
415         double headVersionNumber = DEFAULT_VERSION;
416 
417         for (int i = 0; i < versionNumbers.length; i++) {
418             double versionNumber = GetterUtil.getDouble(versionNumbers[i]);
419 
420             if (versionNumber > headVersionNumber) {
421                 headVersionNumber = versionNumber;
422             }
423         }
424 
425         return headVersionNumber;
426     }
427 
428     private static final String _ROOT_DIR = PropsUtil.get(
429         PropsUtil.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
430 
431     private static Log _log = LogFactory.getLog(FileSystemHook.class);
432 
433     private File _rootDir;
434 
435 }