1   /**
2    * Copyright (c) 2000-2007 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, 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();
90              }
91  
92              FileUtil.write(fileNameVersionFile, is);
93  
94              Indexer.addFile(
95                  companyId, portletId, groupId, repositoryId, properties,
96                  fileName);
97          }
98          catch (IOException ioe) {
99              throw new SystemException();
100         }
101     }
102 
103     public void checkRoot(long companyId) throws SystemException {
104     }
105 
106     public void deleteDirectory(
107             long companyId, String portletId, long repositoryId, String dirName)
108         throws PortalException, SystemException {
109 
110         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
111 
112         if (!dirNameDir.exists()) {
113             throw new NoSuchDirectoryException();
114         }
115 
116         FileUtil.deltree(dirNameDir);
117     }
118 
119     public void deleteFile(
120             long companyId, String portletId, long repositoryId,
121             String fileName)
122         throws PortalException, SystemException {
123 
124         try {
125             File fileNameDir = getFileNameDir(
126                 companyId, repositoryId, fileName);
127 
128             if (!fileNameDir.exists()) {
129                 throw new NoSuchFileException();
130             }
131 
132             FileUtil.deltree(fileNameDir);
133 
134             Indexer.deleteFile(companyId, portletId, repositoryId, fileName);
135         }
136         catch (IOException ioe) {
137             throw new SystemException();
138         }
139     }
140 
141     public void deleteFile(
142             long companyId, String portletId, long repositoryId,
143             String fileName, double versionNumber)
144         throws PortalException, SystemException {
145 
146         File fileNameVersionFile = getFileNameVersionFile(
147             companyId, repositoryId, fileName, versionNumber);
148 
149         if (!fileNameVersionFile.exists()) {
150             throw new NoSuchFileException();
151         }
152 
153         fileNameVersionFile.delete();
154     }
155 
156     public InputStream getFileAsStream(
157             long companyId, long repositoryId, String fileName,
158             double versionNumber)
159         throws PortalException, SystemException {
160 
161         try {
162             if (versionNumber == 0) {
163                 versionNumber = getHeadVersionNumber(
164                     companyId, repositoryId, fileName);
165             }
166 
167             File fileNameVersionFile = getFileNameVersionFile(
168                 companyId, repositoryId, fileName, versionNumber);
169 
170             if (!fileNameVersionFile.exists()) {
171                 throw new NoSuchFileException();
172             }
173 
174             return new FileInputStream(fileNameVersionFile);
175         }
176         catch (IOException ioe) {
177             throw new SystemException();
178         }
179     }
180 
181     public String[] getFileNames(
182             long companyId, long repositoryId, String dirName)
183         throws PortalException, SystemException {
184 
185         try {
186             File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
187 
188             if (!dirNameDir.exists()) {
189                 throw new NoSuchDirectoryException();
190             }
191 
192             String[] fileNames = FileUtil.listDirs(dirNameDir);
193 
194             Arrays.sort(fileNames);
195 
196             // Convert /${fileName} to /${dirName}/${fileName}
197 
198             for (int i = 0; i < fileNames.length; i++) {
199                 fileNames[i] =
200                     StringPool.SLASH + dirName + StringPool.SLASH +
201                         fileNames[i];
202             }
203 
204             return fileNames;
205         }
206         catch (IOException ioe) {
207             throw new SystemException();
208         }
209     }
210 
211     public long getFileSize(
212             long companyId, long repositoryId, String fileName)
213         throws PortalException, SystemException {
214 
215         try {
216             double versionNumber = getHeadVersionNumber(
217                 companyId, repositoryId, fileName);
218 
219             File fileNameVersionFile = getFileNameVersionFile(
220                 companyId, repositoryId, fileName, versionNumber);
221 
222             if (!fileNameVersionFile.exists()) {
223                 throw new NoSuchFileException();
224             }
225 
226             return fileNameVersionFile.length();
227         }
228         catch (IOException ioe) {
229             throw new SystemException();
230         }
231     }
232 
233     public boolean hasFile(
234             long companyId, long repositoryId, String fileName,
235             double versionNumber)
236         throws PortalException, SystemException {
237 
238         File fileNameVersionFile = getFileNameVersionFile(
239             companyId, repositoryId, fileName, versionNumber);
240 
241         if (fileNameVersionFile.exists()) {
242             return true;
243         }
244         else {
245             return false;
246         }
247     }
248 
249     public void move(String srcDir, String destDir) throws SystemException {
250     }
251 
252     public void reIndex(String[] ids) throws SearchException {
253         long companyId = GetterUtil.getLong(ids[0]);
254         String portletId = ids[1];
255         long groupId = GetterUtil.getLong(ids[2]);
256         long repositoryId = GetterUtil.getLong(ids[3]);
257 
258         IndexWriter writer = null;
259 
260         try {
261             writer = LuceneUtil.getWriter(companyId);
262 
263             File repistoryDir = getRepositoryDir(companyId, repositoryId);
264 
265             String[] fileNames = FileUtil.listDirs(repistoryDir);
266 
267             for (int i = 0; i < fileNames.length; i++) {
268                 String fileName = fileNames[i];
269 
270                 try {
271                     Document doc = IndexerImpl.getAddFileDocument(
272                         companyId, portletId, groupId, repositoryId, fileName);
273 
274                     writer.addDocument(doc);
275                 }
276                 catch (Exception e) {
277                     _log.error("Reindexing " + fileName, e);
278                 }
279             }
280         }
281         catch (IOException ioe) {
282             throw new SearchException(ioe);
283         }
284         finally {
285             try {
286                 if (writer != null) {
287                     LuceneUtil.write(companyId);
288                 }
289             }
290             catch (Exception e) {
291                 _log.error(e);
292             }
293         }
294     }
295 
296     public void updateFile(
297             long companyId, String portletId, long groupId, long repositoryId,
298             String fileName, double versionNumber, String sourceFileName,
299             String properties, InputStream is)
300         throws PortalException, SystemException {
301 
302         try {
303             File fileNameVersionFile = getFileNameVersionFile(
304                 companyId, repositoryId, fileName, versionNumber);
305 
306             if (fileNameVersionFile.exists()) {
307                 throw new DuplicateFileException();
308             }
309 
310             FileUtil.write(fileNameVersionFile, is);
311 
312             Indexer.updateFile(
313                 companyId, portletId, groupId, repositoryId, properties,
314                 fileName);
315         }
316         catch (IOException ioe) {
317             throw new SystemException();
318         }
319     }
320 
321     public void updateFile(
322             long companyId, String portletId, long groupId, long repositoryId,
323             long newRepositoryId, String fileName)
324         throws PortalException, SystemException {
325 
326         try {
327             File fileNameDir = getFileNameDir(
328                 companyId, repositoryId, fileName);
329             File newFileNameDir = getFileNameDir(
330                 companyId, newRepositoryId, fileName);
331 
332             FileUtil.copyDirectory(fileNameDir, newFileNameDir);
333 
334             FileUtil.deltree(fileNameDir);
335 
336             try {
337                 Indexer.deleteFile(
338                     companyId, portletId, repositoryId, fileName);
339             }
340             catch (IOException ioe) {
341             }
342 
343             Indexer.addFile(
344                 companyId, portletId, groupId, newRepositoryId, fileName);
345         }
346         catch (IOException ioe) {
347             throw new SystemException();
348         }
349     }
350 
351     protected File getCompanyDir(long companyId) {
352         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
353 
354         if (!companyDir.exists()) {
355             companyDir.mkdirs();
356         }
357 
358         return companyDir;
359     }
360 
361     protected File getDirNameDir(
362         long companyId, long repositoryId, String dirName) {
363 
364         return getFileNameDir(companyId, repositoryId, dirName);
365     }
366 
367     protected File getRepositoryDir(long companyId, long repositoryId) {
368         File companyDir = getCompanyDir(companyId);
369 
370         File repositoryDir = new File(
371             companyDir + StringPool.SLASH + repositoryId);
372 
373         if (!repositoryDir.exists()) {
374             repositoryDir.mkdirs();
375         }
376 
377         return repositoryDir;
378     }
379 
380     protected File getFileNameDir(
381         long companyId, long repositoryId, String fileName) {
382 
383         File repositoryDir = getRepositoryDir(companyId, repositoryId);
384 
385         File fileNameDir = new File(
386             repositoryDir + StringPool.SLASH + fileName);
387 
388         return fileNameDir;
389     }
390 
391     protected File getFileNameVersionFile(
392         long companyId, long repositoryId, String fileName, double version) {
393 
394         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
395 
396         File fileNameVersionFile = new File(
397             fileNameDir + StringPool.SLASH + version);
398 
399         return fileNameVersionFile;
400     }
401 
402     protected double getHeadVersionNumber(
403             long companyId, long repositoryId, String fileName)
404         throws IOException {
405 
406         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
407 
408         if (!fileNameDir.exists()) {
409             return DEFAULT_VERSION;
410         }
411 
412         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
413 
414         double headVersionNumber = DEFAULT_VERSION;
415 
416         for (int i = 0; i < versionNumbers.length; i++) {
417             double versionNumber = GetterUtil.getDouble(versionNumbers[i]);
418 
419             if (versionNumber > headVersionNumber) {
420                 headVersionNumber = versionNumber;
421             }
422         }
423 
424         return headVersionNumber;
425     }
426 
427     private static final String _ROOT_DIR = PropsUtil.get(
428         PropsUtil.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
429 
430     private static Log _log = LogFactory.getLog(FileSystemHook.class);
431 
432     private File _rootDir;
433 
434 }