1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.documentlibrary.util;
21  
22  import com.liferay.documentlibrary.DuplicateDirectoryException;
23  import com.liferay.documentlibrary.DuplicateFileException;
24  import com.liferay.documentlibrary.NoSuchDirectoryException;
25  import com.liferay.documentlibrary.NoSuchFileException;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.search.Document;
31  import com.liferay.portal.kernel.search.Field;
32  import com.liferay.portal.kernel.search.SearchEngineUtil;
33  import com.liferay.portal.kernel.search.SearchException;
34  import com.liferay.portal.kernel.util.FileUtil;
35  import com.liferay.portal.kernel.util.GetterUtil;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.util.PropsKeys;
38  import com.liferay.portal.util.PropsUtil;
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   */
55  public class FileSystemHook extends BaseHook {
56  
57      public FileSystemHook() {
58          _rootDir = new File(_ROOT_DIR);
59  
60          if (!_rootDir.exists()) {
61              _rootDir.mkdirs();
62          }
63      }
64  
65      public void addDirectory(long companyId, long repositoryId, String dirName)
66          throws PortalException {
67  
68          File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
69  
70          if (dirNameDir.exists()) {
71              throw new DuplicateDirectoryException();
72          }
73  
74          dirNameDir.mkdirs();
75      }
76  
77      public void addFile(
78              long companyId, String portletId, long groupId, long repositoryId,
79              String fileName, String properties, Date modifiedDate,
80              String[] tagsEntries, InputStream is)
81          throws PortalException, SystemException {
82  
83          try {
84              File fileNameVersionFile = getFileNameVersionFile(
85                  companyId, repositoryId, fileName, DEFAULT_VERSION);
86  
87              if (fileNameVersionFile.exists()) {
88                  throw new DuplicateFileException();
89              }
90  
91              FileUtil.write(fileNameVersionFile, is);
92  
93              Indexer.addFile(
94                  companyId, portletId, groupId, repositoryId, fileName,
95                  properties, modifiedDate, tagsEntries);
96          }
97          catch (IOException ioe) {
98              throw new SystemException();
99          }
100     }
101 
102     public void checkRoot(long companyId) {
103     }
104 
105     public void deleteDirectory(
106             long companyId, String portletId, long repositoryId, String dirName)
107         throws PortalException {
108 
109         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
110 
111         if (!dirNameDir.exists()) {
112             throw new NoSuchDirectoryException();
113         }
114 
115         FileUtil.deltree(dirNameDir);
116     }
117 
118     public void deleteFile(
119             long companyId, String portletId, long repositoryId,
120             String fileName)
121         throws PortalException, SystemException {
122 
123         try {
124             File fileNameDir = getFileNameDir(
125                 companyId, repositoryId, fileName);
126 
127             if (!fileNameDir.exists()) {
128                 throw new NoSuchFileException();
129             }
130 
131             FileUtil.deltree(fileNameDir);
132 
133             Indexer.deleteFile(companyId, portletId, repositoryId, fileName);
134         }
135         catch (SearchException se) {
136             throw new SystemException();
137         }
138     }
139 
140     public void deleteFile(
141             long companyId, String portletId, long repositoryId,
142             String fileName, double versionNumber)
143         throws PortalException {
144 
145         File fileNameVersionFile = getFileNameVersionFile(
146             companyId, repositoryId, fileName, versionNumber);
147 
148         if (!fileNameVersionFile.exists()) {
149             throw new NoSuchFileException();
150         }
151 
152         fileNameVersionFile.delete();
153     }
154 
155     public InputStream getFileAsStream(
156             long companyId, long repositoryId, String fileName,
157             double versionNumber)
158         throws PortalException, SystemException {
159 
160         try {
161             if (versionNumber == 0) {
162                 versionNumber = getHeadVersionNumber(
163                     companyId, repositoryId, fileName);
164             }
165 
166             File fileNameVersionFile = getFileNameVersionFile(
167                 companyId, repositoryId, fileName, versionNumber);
168 
169             if (!fileNameVersionFile.exists()) {
170                 throw new NoSuchFileException();
171             }
172 
173             return new FileInputStream(fileNameVersionFile);
174         }
175         catch (IOException ioe) {
176             throw new SystemException();
177         }
178     }
179 
180     public String[] getFileNames(
181             long companyId, long repositoryId, String dirName)
182         throws PortalException {
183 
184         File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
185 
186         if (!dirNameDir.exists()) {
187             throw new NoSuchDirectoryException();
188         }
189 
190         String[] fileNames = FileUtil.listDirs(dirNameDir);
191 
192         Arrays.sort(fileNames);
193 
194         // Convert /${fileName} to /${dirName}/${fileName}
195 
196         for (int i = 0; i < fileNames.length; i++) {
197             fileNames[i] =
198                 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
199         }
200 
201         return fileNames;
202     }
203 
204     public long getFileSize(
205             long companyId, long repositoryId, String fileName)
206         throws PortalException {
207 
208         double versionNumber = getHeadVersionNumber(
209             companyId, repositoryId, fileName);
210 
211         File fileNameVersionFile = getFileNameVersionFile(
212             companyId, repositoryId, fileName, versionNumber);
213 
214         if (!fileNameVersionFile.exists()) {
215             throw new NoSuchFileException();
216         }
217 
218         return fileNameVersionFile.length();
219     }
220 
221     public boolean hasFile(
222         long companyId, long repositoryId, String fileName,
223         double versionNumber) {
224 
225         File fileNameVersionFile = getFileNameVersionFile(
226             companyId, repositoryId, fileName, versionNumber);
227 
228         if (fileNameVersionFile.exists()) {
229             return true;
230         }
231         else {
232             return false;
233         }
234     }
235 
236     public void move(String srcDir, String destDir) {
237     }
238 
239     public void reIndex(String[] ids) {
240         long companyId = GetterUtil.getLong(ids[0]);
241         String portletId = ids[1];
242         long groupId = GetterUtil.getLong(ids[2]);
243         long repositoryId = GetterUtil.getLong(ids[3]);
244 
245         File repistoryDir = getRepositoryDir(companyId, repositoryId);
246 
247         String[] fileNames = FileUtil.listDirs(repistoryDir);
248 
249         for (int i = 0; i < fileNames.length; i++) {
250             String fileName = fileNames[i];
251 
252             try {
253                 Document doc = Indexer.getFileDocument(
254                     companyId, portletId, groupId, repositoryId, fileName);
255 
256                 SearchEngineUtil.updateDocument(
257                     companyId, doc.get(Field.UID), doc);
258             }
259             catch (Exception e) {
260                 _log.error("Reindexing " + fileName, e);
261             }
262         }
263     }
264 
265     public void updateFile(
266             long companyId, String portletId, long groupId, long repositoryId,
267             String fileName, double versionNumber, String sourceFileName,
268             String properties, Date modifiedDate, String[] tagsEntries,
269             InputStream is)
270         throws PortalException, SystemException {
271 
272         try {
273             File fileNameVersionFile = getFileNameVersionFile(
274                 companyId, repositoryId, fileName, versionNumber);
275 
276             if (fileNameVersionFile.exists()) {
277                 throw new DuplicateFileException();
278             }
279 
280             FileUtil.write(fileNameVersionFile, is);
281 
282             Indexer.updateFile(
283                 companyId, portletId, groupId, repositoryId, fileName,
284                 properties, modifiedDate, tagsEntries);
285         }
286         catch (IOException ioe) {
287             throw new SystemException();
288         }
289     }
290 
291     public void updateFile(
292             long companyId, String portletId, long groupId, long repositoryId,
293             long newRepositoryId, String fileName)
294         throws SystemException {
295 
296         try {
297             File fileNameDir = getFileNameDir(
298                 companyId, repositoryId, fileName);
299             File newFileNameDir = getFileNameDir(
300                 companyId, newRepositoryId, fileName);
301 
302             FileUtil.copyDirectory(fileNameDir, newFileNameDir);
303 
304             FileUtil.deltree(fileNameDir);
305 
306             try {
307                 Indexer.deleteFile(
308                     companyId, portletId, repositoryId, fileName);
309             }
310             catch (SearchException se) {
311             }
312 
313             Indexer.addFile(
314                 companyId, portletId, groupId, newRepositoryId, fileName);
315         }
316         catch (SearchException se) {
317             throw new SystemException();
318         }
319     }
320 
321     protected File getCompanyDir(long companyId) {
322         File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
323 
324         if (!companyDir.exists()) {
325             companyDir.mkdirs();
326         }
327 
328         return companyDir;
329     }
330 
331     protected File getDirNameDir(
332         long companyId, long repositoryId, String dirName) {
333 
334         return getFileNameDir(companyId, repositoryId, dirName);
335     }
336 
337     protected File getRepositoryDir(long companyId, long repositoryId) {
338         File companyDir = getCompanyDir(companyId);
339 
340         File repositoryDir = new File(
341             companyDir + StringPool.SLASH + repositoryId);
342 
343         if (!repositoryDir.exists()) {
344             repositoryDir.mkdirs();
345         }
346 
347         return repositoryDir;
348     }
349 
350     protected File getFileNameDir(
351         long companyId, long repositoryId, String fileName) {
352 
353         File repositoryDir = getRepositoryDir(companyId, repositoryId);
354 
355         File fileNameDir = new File(
356             repositoryDir + StringPool.SLASH + fileName);
357 
358         return fileNameDir;
359     }
360 
361     protected File getFileNameVersionFile(
362         long companyId, long repositoryId, String fileName, double version) {
363 
364         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
365 
366         File fileNameVersionFile = new File(
367             fileNameDir + StringPool.SLASH + version);
368 
369         return fileNameVersionFile;
370     }
371 
372     protected double getHeadVersionNumber(
373         long companyId, long repositoryId, String fileName) {
374 
375         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
376 
377         if (!fileNameDir.exists()) {
378             return DEFAULT_VERSION;
379         }
380 
381         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
382 
383         double headVersionNumber = DEFAULT_VERSION;
384 
385         for (int i = 0; i < versionNumbers.length; i++) {
386             double versionNumber = GetterUtil.getDouble(versionNumbers[i]);
387 
388             if (versionNumber > headVersionNumber) {
389                 headVersionNumber = versionNumber;
390             }
391         }
392 
393         return headVersionNumber;
394     }
395 
396     private static final String _ROOT_DIR = PropsUtil.get(
397         PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
398 
399     private static Log _log = LogFactoryUtil.getLog(FileSystemHook.class);
400 
401     private File _rootDir;
402 
403 }