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.model.FileModel;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.search.Document;
020    import com.liferay.portal.kernel.search.Indexer;
021    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
022    import com.liferay.portal.kernel.search.SearchEngineUtil;
023    import com.liferay.portal.kernel.search.SearchException;
024    import com.liferay.portal.kernel.util.FileUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portlet.documentlibrary.util.DLUtil;
031    
032    import java.io.File;
033    
034    import java.util.ArrayList;
035    import java.util.Collection;
036    
037    /**
038     * <p>
039     * See http://issues.liferay.com/browse/LPS-1976.
040     * </p>
041     *
042     * @author Jorge Ferrer
043     * @author Ryan Park
044     * @author Brian Wing Shun Chan
045     */
046    public class AdvancedFileSystemHook extends FileSystemHook {
047    
048            public void reindex(String[] ids) throws SearchException {
049                    long companyId = GetterUtil.getLong(ids[0]);
050                    String portletId = ids[1];
051                    long groupId = GetterUtil.getLong(ids[2]);
052                    long repositoryId = GetterUtil.getLong(ids[3]);
053    
054                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
055    
056                    String[] fileNames = FileUtil.listDirs(repositoryDir);
057    
058                    for (String fileName : fileNames) {
059                            Collection<Document> documents = getDocuments(
060                                    companyId, portletId, groupId, repositoryId,
061                                    repositoryDir.getPath() + StringPool.SLASH + fileName);
062    
063                            SearchEngineUtil.updateDocuments(companyId, documents);
064                    }
065            }
066    
067            public void updateFile(
068                            long companyId, String portletId, long groupId, long repositoryId,
069                            String fileName, String newFileName, boolean reindex)
070                    throws PortalException {
071    
072                    super.updateFile(
073                            companyId, portletId, groupId, repositoryId, fileName, newFileName,
074                            reindex);
075    
076                    File newFileNameDir = getFileNameDir(
077                            companyId, repositoryId, newFileName);
078    
079                    String[] fileNameVersions = FileUtil.listFiles(newFileNameDir);
080    
081                    for (String fileNameVersion : fileNameVersions) {
082                            String ext = FileUtil.getExtension(fileNameVersion);
083    
084                            if (ext.equals(_HOOK_EXTENSION)) {
085                                    continue;
086                            }
087    
088                            File fileNameVersionFile = new File(
089                                    newFileNameDir + StringPool.SLASH + fileNameVersion);
090                            File newFileNameVersionFile = new File(
091                                    newFileNameDir + StringPool.SLASH +
092                                            FileUtil.stripExtension(fileNameVersion) +
093                                                    StringPool.PERIOD + _HOOK_EXTENSION);
094    
095                            fileNameVersionFile.renameTo(newFileNameVersionFile);
096                    }
097            }
098    
099            protected void buildPath(StringBundler sb, String fileNameFragment) {
100                    int fileNameFragmentLength = fileNameFragment.length();
101    
102                    if ((fileNameFragmentLength <= 2) || (getDepth(sb.toString()) > 3)) {
103                            return;
104                    }
105    
106                    for (int i = 0;i < fileNameFragmentLength;i += 2) {
107                            if ((i + 2) < fileNameFragmentLength) {
108                                    sb.append(fileNameFragment.substring(i, i + 2));
109                                    sb.append(StringPool.SLASH);
110    
111                                    if (getDepth(sb.toString()) > 3) {
112                                            return;
113                                    }
114                            }
115                    }
116    
117                    return;
118            }
119    
120            protected int getDepth(String path) {
121                    String[] fragments = StringUtil.split(path, StringPool.SLASH);
122    
123                    return fragments.length;
124            }
125    
126            protected File getDirNameDir(
127                    long companyId, long repositoryId, String dirName) {
128    
129                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
130    
131                    return new File(repositoryDir + StringPool.SLASH + dirName);
132            }
133    
134            protected Collection<Document> getDocuments(
135                            long companyId, String portletId, long groupId, long repositoryId,
136                            String fileName)
137                    throws SearchException {
138    
139                    Collection<Document> documents = new ArrayList<Document>();
140    
141                    String shortFileName = FileUtil.getShortFileName(fileName);
142    
143                    if (shortFileName.equals("DLFE") ||
144                            Validator.isNumber(shortFileName)) {
145    
146                            String[] curFileNames = FileUtil.listDirs(fileName);
147    
148                            for (String curFileName : curFileNames) {
149                                    documents.addAll(
150                                            getDocuments(
151                                                    companyId, portletId, groupId, repositoryId,
152                                                    fileName + StringPool.SLASH + curFileName));
153                            }
154                    }
155                    else {
156                            Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
157    
158                            FileModel fileModel = new FileModel();
159    
160                            if (shortFileName.endsWith(_HOOK_EXTENSION)) {
161                                    shortFileName = FileUtil.stripExtension(shortFileName);
162                            }
163    
164                            fileModel.setCompanyId(companyId);
165                            fileModel.setFileName(shortFileName);
166                            fileModel.setGroupId(groupId);
167                            fileModel.setPortletId(portletId);
168                            fileModel.setRepositoryId(repositoryId);
169    
170                            Document document = indexer.getDocument(fileModel);
171    
172                            if (document != null) {
173                                    documents.add(document);
174                            }
175                    }
176    
177                    return documents;
178            }
179    
180            protected File getFileNameDir(
181                    long companyId, long repositoryId, String fileName) {
182    
183                    String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
184    
185                    if (ext.equals(StringPool.PERIOD)) {
186                            ext += _HOOK_EXTENSION;
187                    }
188    
189                    StringBundler sb = new StringBundler();
190    
191                    String fileNameFragment = FileUtil.stripExtension(fileName);
192    
193                    if (fileNameFragment.startsWith("DLFE-")) {
194                            fileNameFragment = fileNameFragment.substring(5);
195    
196                            sb.append("DLFE" + StringPool.SLASH);
197                    }
198    
199                    buildPath(sb, fileNameFragment);
200    
201                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
202    
203                    File fileNameDir = new File(
204                            repositoryDir + StringPool.SLASH + sb.toString() +
205                                    StringPool.SLASH + fileNameFragment + ext);
206    
207                    return fileNameDir;
208            }
209    
210            protected File getFileNameVersionFile(
211                    long companyId, long repositoryId, String fileName, String version) {
212    
213                    String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
214    
215                    if (ext.equals(StringPool.PERIOD)) {
216                            ext += _HOOK_EXTENSION;
217                    }
218    
219                    int pos = fileName.lastIndexOf(StringPool.SLASH);
220    
221                    if (pos == -1) {
222                            StringBundler sb = new StringBundler();
223    
224                            String fileNameFragment = FileUtil.stripExtension(fileName);
225    
226                            if (fileNameFragment.startsWith("DLFE-")) {
227                                    fileNameFragment = fileNameFragment.substring(5);
228    
229                                    sb.append("DLFE" + StringPool.SLASH);
230                            }
231    
232                            buildPath(sb, fileNameFragment);
233    
234                            File repositoryDir = getRepositoryDir(companyId, repositoryId);
235    
236                            return new File(
237                                    repositoryDir + StringPool.SLASH + sb.toString() +
238                                            StringPool.SLASH + fileNameFragment + ext +
239                                                    StringPool.SLASH + fileNameFragment +
240                                                            StringPool.UNDERLINE + version + ext);
241                    }
242                    else {
243                            File fileNameDir = getDirNameDir(companyId, repositoryId, fileName);
244    
245                            String fileNameFragment = FileUtil.stripExtension(
246                                    fileName.substring(pos + 1));
247    
248                            return new File(
249                                    fileNameDir + StringPool.SLASH + fileNameFragment +
250                                            StringPool.UNDERLINE + version + ext);
251                    }
252            }
253    
254            protected String getHeadVersionNumber(
255                    long companyId, long repositoryId, String fileName) {
256    
257                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
258    
259                    if (!fileNameDir.exists()) {
260                            return DEFAULT_VERSION;
261                    }
262    
263                    String[] versionNumbers = FileUtil.listFiles(fileNameDir);
264    
265                    String headVersionNumber = DEFAULT_VERSION;
266    
267                    for (int i = 0; i < versionNumbers.length; i++) {
268                            String versionNumberFragment = versionNumbers[i];
269    
270                            int x = versionNumberFragment.lastIndexOf(StringPool.UNDERLINE);
271                            int y = versionNumberFragment.lastIndexOf(StringPool.PERIOD);
272    
273                            if (x > -1) {
274                                    versionNumberFragment = versionNumberFragment.substring(
275                                            x + 1, y);
276                            }
277    
278                            String versionNumber = versionNumberFragment;
279    
280                            if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
281                                    headVersionNumber = versionNumber;
282                            }
283                    }
284    
285                    return headVersionNumber;
286            }
287    
288            private static final String _HOOK_EXTENSION = "afsh";
289    
290    }