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