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