001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.documentlibrary.util;
016    
017    import com.liferay.documentlibrary.DuplicateDirectoryException;
018    import com.liferay.documentlibrary.DuplicateFileException;
019    import com.liferay.documentlibrary.NoSuchDirectoryException;
020    import com.liferay.documentlibrary.NoSuchFileException;
021    import com.liferay.documentlibrary.model.FileModel;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.search.Document;
025    import com.liferay.portal.kernel.search.Indexer;
026    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
027    import com.liferay.portal.kernel.search.SearchEngineUtil;
028    import com.liferay.portal.kernel.search.SearchException;
029    import com.liferay.portal.kernel.util.FileUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.PropsKeys;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.util.PropsUtil;
036    import com.liferay.portlet.documentlibrary.util.DLUtil;
037    
038    import java.io.File;
039    import java.io.FileInputStream;
040    import java.io.IOException;
041    import java.io.InputStream;
042    
043    import java.util.ArrayList;
044    import java.util.Arrays;
045    import java.util.Collection;
046    import java.util.Date;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Sten Martinez
051     */
052    public class FileSystemHook extends BaseHook {
053    
054            public FileSystemHook() {
055                    _rootDir = new File(_ROOT_DIR);
056    
057                    if (!_rootDir.exists()) {
058                            _rootDir.mkdirs();
059                    }
060            }
061    
062            public void addDirectory(long companyId, long repositoryId, String dirName)
063                    throws PortalException {
064    
065                    File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
066    
067                    if (dirNameDir.exists()) {
068                            throw new DuplicateDirectoryException(dirNameDir.getPath());
069                    }
070    
071                    dirNameDir.mkdirs();
072            }
073    
074            public void addFile(
075                            long companyId, String portletId, long groupId, long repositoryId,
076                            String fileName, long fileEntryId, String properties,
077                            Date modifiedDate, ServiceContext serviceContext, InputStream is)
078                    throws PortalException, SystemException {
079    
080                    try {
081                            File fileNameVersionFile = getFileNameVersionFile(
082                                    companyId, repositoryId, fileName, DEFAULT_VERSION);
083    
084                            if (fileNameVersionFile.exists()) {
085                                    throw new DuplicateFileException(fileNameVersionFile.getPath());
086                            }
087    
088                            FileUtil.write(fileNameVersionFile, is);
089    
090                            Indexer indexer = IndexerRegistryUtil.getIndexer(
091                                    FileModel.class);
092    
093                            FileModel fileModel = new FileModel();
094    
095                            fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
096                            fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
097                            fileModel.setCompanyId(companyId);
098                            fileModel.setFileEntryId(fileEntryId);
099                            fileModel.setFileName(fileName);
100                            fileModel.setGroupId(groupId);
101                            fileModel.setModifiedDate(modifiedDate);
102                            fileModel.setPortletId(portletId);
103                            fileModel.setProperties(properties);
104                            fileModel.setRepositoryId(repositoryId);
105    
106                            indexer.reindex(fileModel);
107                    }
108                    catch (IOException ioe) {
109                            throw new SystemException(ioe);
110                    }
111            }
112    
113            public void checkRoot(long companyId) {
114            }
115    
116            public void deleteDirectory(
117                            long companyId, String portletId, long repositoryId, String dirName)
118                    throws PortalException {
119    
120                    File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
121    
122                    if (!dirNameDir.exists()) {
123                            throw new NoSuchDirectoryException(dirNameDir.getPath());
124                    }
125    
126                    FileUtil.deltree(dirNameDir);
127            }
128    
129            public void deleteFile(
130                            long companyId, String portletId, long repositoryId,
131                            String fileName)
132                    throws PortalException {
133    
134                    File fileNameDir = getFileNameDir(
135                            companyId, repositoryId, fileName);
136    
137                    if (!fileNameDir.exists()) {
138                            throw new NoSuchFileException(fileNameDir.getPath());
139                    }
140    
141                    FileUtil.deltree(fileNameDir);
142    
143                    FileModel fileModel = new FileModel();
144    
145                    fileModel.setCompanyId(companyId);
146                    fileModel.setFileName(fileName);
147                    fileModel.setPortletId(portletId);
148                    fileModel.setRepositoryId(repositoryId);
149    
150                    Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
151    
152                    indexer.delete(fileModel);
153            }
154    
155            public void deleteFile(
156                            long companyId, String portletId, long repositoryId,
157                            String fileName, String versionNumber)
158                    throws PortalException {
159    
160                    File fileNameVersionFile = getFileNameVersionFile(
161                            companyId, repositoryId, fileName, versionNumber);
162    
163                    if (!fileNameVersionFile.exists()) {
164                            throw new NoSuchFileException(fileNameVersionFile.getPath());
165                    }
166    
167                    fileNameVersionFile.delete();
168            }
169    
170            public InputStream getFileAsStream(
171                            long companyId, long repositoryId, String fileName,
172                            String versionNumber)
173                    throws PortalException, SystemException {
174    
175                    try {
176                            if (Validator.isNull(versionNumber)) {
177                                    versionNumber = getHeadVersionNumber(
178                                            companyId, repositoryId, fileName);
179                            }
180    
181                            File fileNameVersionFile = getFileNameVersionFile(
182                                    companyId, repositoryId, fileName, versionNumber);
183    
184                            if (!fileNameVersionFile.exists()) {
185                                    throw new NoSuchFileException(fileNameVersionFile.getPath());
186                            }
187    
188                            return new FileInputStream(fileNameVersionFile);
189                    }
190                    catch (IOException ioe) {
191                            throw new SystemException(ioe);
192                    }
193            }
194    
195            public String[] getFileNames(
196                            long companyId, long repositoryId, String dirName)
197                    throws PortalException {
198    
199                    File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
200    
201                    if (!dirNameDir.exists()) {
202                            throw new NoSuchDirectoryException(dirNameDir.getPath());
203                    }
204    
205                    String[] fileNames = FileUtil.listDirs(dirNameDir);
206    
207                    Arrays.sort(fileNames);
208    
209                    // Convert /${fileName} to /${dirName}/${fileName}
210    
211                    for (int i = 0; i < fileNames.length; i++) {
212                            fileNames[i] =
213                                    StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
214                    }
215    
216                    return fileNames;
217            }
218    
219            public long getFileSize(
220                            long companyId, long repositoryId, String fileName)
221                    throws PortalException {
222    
223                    String versionNumber = getHeadVersionNumber(
224                            companyId, repositoryId, fileName);
225    
226                    File fileNameVersionFile = getFileNameVersionFile(
227                            companyId, repositoryId, fileName, versionNumber);
228    
229                    if (!fileNameVersionFile.exists()) {
230                            throw new NoSuchFileException(fileNameVersionFile.getPath());
231                    }
232    
233                    return fileNameVersionFile.length();
234            }
235    
236            public boolean hasFile(
237                    long companyId, long repositoryId, String fileName,
238                    String versionNumber) {
239    
240                    File fileNameVersionFile = getFileNameVersionFile(
241                            companyId, repositoryId, fileName, versionNumber);
242    
243                    if (fileNameVersionFile.exists()) {
244                            return true;
245                    }
246                    else {
247                            return false;
248                    }
249            }
250    
251            public void move(String srcDir, String destDir) {
252            }
253    
254            public void reindex(String[] ids) throws SearchException {
255                    long companyId = GetterUtil.getLong(ids[0]);
256                    String portletId = ids[1];
257                    long groupId = GetterUtil.getLong(ids[2]);
258                    long repositoryId = GetterUtil.getLong(ids[3]);
259    
260                    Collection<Document> documents = new ArrayList<Document>();
261    
262                    File repistoryDir = getRepositoryDir(companyId, repositoryId);
263    
264                    String[] fileNames = FileUtil.listDirs(repistoryDir);
265    
266                    for (int i = 0; i < fileNames.length; i++) {
267                            String fileName = fileNames[i];
268    
269                            Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
270    
271                            FileModel fileModel = new FileModel();
272    
273                            fileModel.setCompanyId(companyId);
274                            fileModel.setFileName(fileName);
275                            fileModel.setGroupId(groupId);
276                            fileModel.setPortletId(portletId);
277                            fileModel.setRepositoryId(repositoryId);
278    
279                            Document document = indexer.getDocument(fileModel);
280    
281                            if (document == null) {
282                                    continue;
283                            }
284    
285                            documents.add(document);
286                    }
287    
288                    SearchEngineUtil.updateDocuments(companyId, documents);
289            }
290    
291            public void updateFile(
292                            long companyId, String portletId, long groupId, long repositoryId,
293                            long newRepositoryId, String fileName, long fileEntryId)
294                    throws PortalException {
295    
296                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
297                    File newFileNameDir = getFileNameDir(
298                            companyId, newRepositoryId, fileName);
299    
300                    FileUtil.copyDirectory(fileNameDir, newFileNameDir);
301    
302                    FileUtil.deltree(fileNameDir);
303    
304                    Indexer indexer = IndexerRegistryUtil.getIndexer(
305                            FileModel.class);
306    
307                    FileModel fileModel = new FileModel();
308    
309                    fileModel.setCompanyId(companyId);
310                    fileModel.setFileName(fileName);
311                    fileModel.setPortletId(portletId);
312                    fileModel.setRepositoryId(repositoryId);
313    
314                    indexer.delete(fileModel);
315    
316                    fileModel.setRepositoryId(newRepositoryId);
317                    fileModel.setGroupId(groupId);
318    
319                    indexer.reindex(fileModel);
320            }
321    
322            public void updateFile(
323                            long companyId, String portletId, long groupId, long repositoryId,
324                            String fileName, String newFileName, boolean reindex)
325                    throws PortalException {
326    
327                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
328                    File newFileNameDir = getFileNameDir(
329                            companyId, repositoryId, newFileName);
330    
331                    FileUtil.copyDirectory(fileNameDir, newFileNameDir);
332    
333                    FileUtil.deltree(fileNameDir);
334    
335                    if (reindex) {
336                            Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
337    
338                            FileModel fileModel = new FileModel();
339    
340                            fileModel.setCompanyId(companyId);
341                            fileModel.setFileName(fileName);
342                            fileModel.setPortletId(portletId);
343                            fileModel.setRepositoryId(repositoryId);
344    
345                            indexer.delete(fileModel);
346    
347                            fileModel.setFileName(newFileName);
348                            fileModel.setGroupId(groupId);
349    
350                            indexer.reindex(fileModel);
351                    }
352            }
353    
354            public void updateFile(
355                            long companyId, String portletId, long groupId, long repositoryId,
356                            String fileName, String versionNumber, String sourceFileName,
357                            long fileEntryId, String properties, Date modifiedDate,
358                            ServiceContext serviceContext, InputStream is)
359                    throws PortalException, SystemException {
360    
361                    try {
362                            File fileNameVersionFile = getFileNameVersionFile(
363                                    companyId, repositoryId, fileName, versionNumber);
364    
365                            if (fileNameVersionFile.exists()) {
366                                    throw new DuplicateFileException(fileNameVersionFile.getPath());
367                            }
368    
369                            FileUtil.write(fileNameVersionFile, is);
370    
371                            Indexer indexer = IndexerRegistryUtil.getIndexer(
372                                    FileModel.class);
373    
374                            FileModel fileModel = new FileModel();
375    
376                            fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
377                            fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
378                            fileModel.setCompanyId(companyId);
379                            fileModel.setFileEntryId(fileEntryId);
380                            fileModel.setFileName(fileName);
381                            fileModel.setGroupId(groupId);
382                            fileModel.setModifiedDate(modifiedDate);
383                            fileModel.setPortletId(portletId);
384                            fileModel.setProperties(properties);
385                            fileModel.setRepositoryId(repositoryId);
386    
387                            indexer.reindex(fileModel);
388                    }
389                    catch (IOException ioe) {
390                            throw new SystemException(ioe);
391                    }
392            }
393    
394            protected File getCompanyDir(long companyId) {
395                    File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
396    
397                    if (!companyDir.exists()) {
398                            companyDir.mkdirs();
399                    }
400    
401                    return companyDir;
402            }
403    
404            protected File getDirNameDir(
405                    long companyId, long repositoryId, String dirName) {
406    
407                    return getFileNameDir(companyId, repositoryId, dirName);
408            }
409    
410            protected File getFileNameDir(
411                    long companyId, long repositoryId, String fileName) {
412    
413                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
414    
415                    File fileNameDir = new File(
416                            repositoryDir + StringPool.SLASH + fileName);
417    
418                    return fileNameDir;
419            }
420    
421            protected File getFileNameVersionFile(
422                    long companyId, long repositoryId, String fileName, String version) {
423    
424                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
425    
426                    File fileNameVersionFile = new File(
427                            fileNameDir + StringPool.SLASH + version);
428    
429                    return fileNameVersionFile;
430            }
431    
432            protected String getHeadVersionNumber(
433                    long companyId, long repositoryId, String fileName) {
434    
435                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
436    
437                    if (!fileNameDir.exists()) {
438                            return DEFAULT_VERSION;
439                    }
440    
441                    String[] versionNumbers = FileUtil.listFiles(fileNameDir);
442    
443                    String headVersionNumber = DEFAULT_VERSION;
444    
445                    for (String versionNumber : versionNumbers) {
446                            if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
447                                    headVersionNumber = versionNumber;
448                            }
449                    }
450    
451                    return headVersionNumber;
452            }
453    
454            protected File getRepositoryDir(long companyId, long repositoryId) {
455                    File companyDir = getCompanyDir(companyId);
456    
457                    File repositoryDir = new File(
458                            companyDir + StringPool.SLASH + repositoryId);
459    
460                    if (!repositoryDir.exists()) {
461                            repositoryDir.mkdirs();
462                    }
463    
464                    return repositoryDir;
465            }
466    
467            private static final String _ROOT_DIR = PropsUtil.get(
468                    PropsKeys.DL_HOOK_FILE_SYSTEM_ROOT_DIR);
469    
470            private File _rootDir;
471    
472    }