1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.documentlibrary.util;
16  
17  import com.liferay.documentlibrary.model.FileModel;
18  import com.liferay.portal.kernel.exception.PortalException;
19  import com.liferay.portal.kernel.search.Document;
20  import com.liferay.portal.kernel.search.Indexer;
21  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
22  import com.liferay.portal.kernel.search.SearchEngineUtil;
23  import com.liferay.portal.kernel.search.SearchException;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.StringBundler;
27  import com.liferay.portal.kernel.util.StringPool;
28  import com.liferay.portal.kernel.util.StringUtil;
29  import com.liferay.portal.kernel.util.Validator;
30  import com.liferay.portlet.documentlibrary.util.DLUtil;
31  
32  import java.io.File;
33  
34  import java.util.ArrayList;
35  import java.util.Collection;
36  
37  /**
38   * <a href="AdvancedFileSystemHook.java.html"><b><i>View Source</i></b></a>
39   *
40   * <p>
41   * See http://issues.liferay.com/browse/LPS-1976.
42   * </p>
43   *
44   * @author Jorge Ferrer
45   * @author Ryan Park
46   * @author Brian Wing Shun Chan
47   */
48  public class AdvancedFileSystemHook extends FileSystemHook {
49  
50      public void reindex(String[] ids) throws SearchException {
51          long companyId = GetterUtil.getLong(ids[0]);
52          String portletId = ids[1];
53          long groupId = GetterUtil.getLong(ids[2]);
54          long repositoryId = GetterUtil.getLong(ids[3]);
55  
56          File repositoryDir = getRepositoryDir(companyId, repositoryId);
57  
58          String[] fileNames = FileUtil.listDirs(repositoryDir);
59  
60          for (String fileName : fileNames) {
61              Collection<Document> documents = getDocuments(
62                  companyId, portletId, groupId, repositoryId,
63                  repositoryDir.getPath() + StringPool.SLASH + fileName);
64  
65              SearchEngineUtil.updateDocuments(companyId, documents);
66          }
67      }
68  
69      public void updateFile(
70              long companyId, String portletId, long groupId, long repositoryId,
71              String fileName, String newFileName, boolean reindex)
72          throws PortalException {
73  
74          super.updateFile(
75              companyId, portletId, groupId, repositoryId, fileName, newFileName,
76              reindex);
77  
78          File newFileNameDir = getFileNameDir(
79              companyId, repositoryId, newFileName);
80  
81          String[] fileNameVersions = FileUtil.listFiles(newFileNameDir);
82  
83          for (String fileNameVersion : fileNameVersions) {
84              String ext = FileUtil.getExtension(fileNameVersion);
85  
86              if (ext.equals(_HOOK_EXTENSION)) {
87                  continue;
88              }
89  
90              File fileNameVersionFile = new File(
91                  newFileNameDir + StringPool.SLASH + fileNameVersion);
92              File newFileNameVersionFile = new File(
93                  newFileNameDir + StringPool.SLASH +
94                      FileUtil.stripExtension(fileNameVersion) +
95                          StringPool.PERIOD + _HOOK_EXTENSION);
96  
97              fileNameVersionFile.renameTo(newFileNameVersionFile);
98          }
99      }
100 
101     protected void buildPath(StringBundler sb, String fileNameFragment) {
102         int fileNameFragmentLength = fileNameFragment.length();
103 
104         if ((fileNameFragmentLength <= 2) || (getDepth(sb.toString()) > 3)) {
105             return;
106         }
107 
108         for (int i = 0;i < fileNameFragmentLength;i += 2) {
109             if ((i + 2) < fileNameFragmentLength) {
110                 sb.append(fileNameFragment.substring(i, i + 2));
111                 sb.append(StringPool.SLASH);
112 
113                 if (getDepth(sb.toString()) > 3) {
114                     return;
115                 }
116             }
117         }
118 
119         return;
120     }
121 
122     protected int getDepth(String path) {
123         String[] fragments = StringUtil.split(path, StringPool.SLASH);
124 
125         return fragments.length;
126     }
127 
128     protected File getDirNameDir(
129         long companyId, long repositoryId, String dirName) {
130 
131         File repositoryDir = getRepositoryDir(companyId, repositoryId);
132 
133         return new File(repositoryDir + StringPool.SLASH + dirName);
134     }
135 
136     protected Collection<Document> getDocuments(
137             long companyId, String portletId, long groupId, long repositoryId,
138             String fileName)
139         throws SearchException {
140 
141         Collection<Document> documents = new ArrayList<Document>();
142 
143         String shortFileName = FileUtil.getShortFileName(fileName);
144 
145         if (shortFileName.equals("DLFE") ||
146             Validator.isNumber(shortFileName)) {
147 
148             String[] curFileNames = FileUtil.listDirs(fileName);
149 
150             for (String curFileName : curFileNames) {
151                 documents.addAll(
152                     getDocuments(
153                         companyId, portletId, groupId, repositoryId,
154                         fileName + StringPool.SLASH + curFileName));
155             }
156         }
157         else {
158             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
159 
160             FileModel fileModel = new FileModel();
161 
162             if (shortFileName.endsWith(_HOOK_EXTENSION)) {
163                 shortFileName = FileUtil.stripExtension(shortFileName);
164             }
165 
166             fileModel.setCompanyId(companyId);
167             fileModel.setFileName(shortFileName);
168             fileModel.setGroupId(groupId);
169             fileModel.setPortletId(portletId);
170             fileModel.setRepositoryId(repositoryId);
171 
172             Document document = indexer.getDocument(fileModel);
173 
174             if (document != null) {
175                 documents.add(document);
176             }
177         }
178 
179         return documents;
180     }
181 
182     protected File getFileNameDir(
183         long companyId, long repositoryId, String fileName) {
184 
185         String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
186 
187         if (ext.equals(StringPool.PERIOD)) {
188             ext += _HOOK_EXTENSION;
189         }
190 
191         StringBundler sb = new StringBundler();
192 
193         String fileNameFragment = FileUtil.stripExtension(fileName);
194 
195         if (fileNameFragment.startsWith("DLFE-")) {
196             fileNameFragment = fileNameFragment.substring(5);
197 
198             sb.append("DLFE" + StringPool.SLASH);
199         }
200 
201         buildPath(sb, fileNameFragment);
202 
203         File repositoryDir = getRepositoryDir(companyId, repositoryId);
204 
205         File fileNameDir = new File(
206             repositoryDir + StringPool.SLASH + sb.toString() +
207                 StringPool.SLASH + fileNameFragment + ext);
208 
209         return fileNameDir;
210     }
211 
212     protected File getFileNameVersionFile(
213         long companyId, long repositoryId, String fileName, String version) {
214 
215         String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
216 
217         if (ext.equals(StringPool.PERIOD)) {
218             ext += _HOOK_EXTENSION;
219         }
220 
221         int pos = fileName.lastIndexOf(StringPool.SLASH);
222 
223         if (pos == -1) {
224             StringBundler sb = new StringBundler();
225 
226             String fileNameFragment = FileUtil.stripExtension(fileName);
227 
228             if (fileNameFragment.startsWith("DLFE-")) {
229                 fileNameFragment = fileNameFragment.substring(5);
230 
231                 sb.append("DLFE" + StringPool.SLASH);
232             }
233 
234             buildPath(sb, fileNameFragment);
235 
236             File repositoryDir = getRepositoryDir(companyId, repositoryId);
237 
238             return new File(
239                 repositoryDir + StringPool.SLASH + sb.toString() +
240                     StringPool.SLASH + fileNameFragment + ext +
241                         StringPool.SLASH + fileNameFragment +
242                             StringPool.UNDERLINE + version + ext);
243         }
244         else {
245             File fileNameDir = getDirNameDir(companyId, repositoryId, fileName);
246 
247             String fileNameFragment = FileUtil.stripExtension(
248                 fileName.substring(pos + 1));
249 
250             return new File(
251                 fileNameDir + StringPool.SLASH + fileNameFragment +
252                     StringPool.UNDERLINE + version + ext);
253         }
254     }
255 
256     protected String getHeadVersionNumber(
257         long companyId, long repositoryId, String fileName) {
258 
259         File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
260 
261         if (!fileNameDir.exists()) {
262             return DEFAULT_VERSION;
263         }
264 
265         String[] versionNumbers = FileUtil.listFiles(fileNameDir);
266 
267         String headVersionNumber = DEFAULT_VERSION;
268 
269         for (int i = 0; i < versionNumbers.length; i++) {
270             String versionNumberFragment = versionNumbers[i];
271 
272             int x = versionNumberFragment.lastIndexOf(StringPool.UNDERLINE);
273             int y = versionNumberFragment.lastIndexOf(StringPool.PERIOD);
274 
275             if (x > -1) {
276                 versionNumberFragment = versionNumberFragment.substring(
277                     x + 1, y);
278             }
279 
280             String versionNumber = versionNumberFragment;
281 
282             if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
283                 headVersionNumber = versionNumber;
284             }
285         }
286 
287         return headVersionNumber;
288     }
289 
290     private static final String _HOOK_EXTENSION = "afsh";
291 
292 }