001    /**
002     * Copyright (c) 2000-2011 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") ||
120                            Validator.isNumber(shortFileName)) {
121    
122                            String[] curFileNames = FileUtil.listDirs(fileName);
123    
124                            for (String curFileName : curFileNames) {
125                                    fileNames.addAll(
126                                            getAdvancedFileNames(
127                                                    companyId, repositoryId,
128                                                    fileName + StringPool.SLASH + curFileName));
129                            }
130                    }
131                    else {
132                            if (shortFileName.endsWith(_HOOK_EXTENSION)) {
133                                    shortFileName = FileUtil.stripExtension(shortFileName);
134                            }
135    
136                            fileNames.add(shortFileName);
137                    }
138    
139                    return fileNames;
140            }
141    
142            protected int getDepth(String path) {
143                    String[] fragments = StringUtil.split(path, CharPool.SLASH);
144    
145                    return fragments.length;
146            }
147    
148            @Override
149            protected File getDirNameDir(
150                    long companyId, long repositoryId, String dirName) {
151    
152                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
153    
154                    return new File(repositoryDir + StringPool.SLASH + dirName);
155            }
156    
157            @Override
158            protected File getFileNameDir(
159                    long companyId, long repositoryId, String fileName) {
160    
161                    if (fileName.indexOf(CharPool.SLASH) != -1) {
162                            return getDirNameDir(companyId, repositoryId, fileName);
163                    }
164    
165                    String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
166    
167                    if (ext.equals(StringPool.PERIOD)) {
168                            ext += _HOOK_EXTENSION;
169                    }
170    
171                    StringBundler sb = new StringBundler();
172    
173                    String fileNameFragment = FileUtil.stripExtension(fileName);
174    
175                    if (fileNameFragment.startsWith("DLFE-")) {
176                            fileNameFragment = fileNameFragment.substring(5);
177    
178                            sb.append("DLFE" + StringPool.SLASH);
179                    }
180    
181                    buildPath(sb, fileNameFragment);
182    
183                    File repositoryDir = getRepositoryDir(companyId, repositoryId);
184    
185                    File fileNameDir = new File(
186                            repositoryDir + StringPool.SLASH + sb.toString() +
187                                    StringPool.SLASH + fileNameFragment + ext);
188    
189                    return fileNameDir;
190            }
191    
192            @Override
193            protected File getFileNameVersionFile(
194                    long companyId, long repositoryId, String fileName, String version) {
195    
196                    String ext = StringPool.PERIOD + FileUtil.getExtension(fileName);
197    
198                    if (ext.equals(StringPool.PERIOD)) {
199                            ext += _HOOK_EXTENSION;
200                    }
201    
202                    int pos = fileName.lastIndexOf(CharPool.SLASH);
203    
204                    if (pos == -1) {
205                            StringBundler sb = new StringBundler();
206    
207                            String fileNameFragment = FileUtil.stripExtension(fileName);
208    
209                            if (fileNameFragment.startsWith("DLFE-")) {
210                                    fileNameFragment = fileNameFragment.substring(5);
211    
212                                    sb.append("DLFE" + StringPool.SLASH);
213                            }
214    
215                            buildPath(sb, fileNameFragment);
216    
217                            File repositoryDir = getRepositoryDir(companyId, repositoryId);
218    
219                            return new File(
220                                    repositoryDir + StringPool.SLASH + sb.toString() +
221                                            StringPool.SLASH + fileNameFragment + ext +
222                                                    StringPool.SLASH + fileNameFragment +
223                                                            StringPool.UNDERLINE + version + ext);
224                    }
225                    else {
226                            File fileNameDir = getDirNameDir(companyId, repositoryId, fileName);
227    
228                            String fileNameFragment = FileUtil.stripExtension(
229                                    fileName.substring(pos + 1));
230    
231                            return new File(
232                                    fileNameDir + StringPool.SLASH + fileNameFragment +
233                                            StringPool.UNDERLINE + version + ext);
234                    }
235            }
236    
237            @Override
238            protected String getHeadVersionLabel(
239                    long companyId, long repositoryId, String fileName) {
240    
241                    File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
242    
243                    if (!fileNameDir.exists()) {
244                            return VERSION_DEFAULT;
245                    }
246    
247                    String[] versionLabels = FileUtil.listFiles(fileNameDir);
248    
249                    String headVersionLabel = VERSION_DEFAULT;
250    
251                    for (int i = 0; i < versionLabels.length; i++) {
252                            String versionLabelFragment = versionLabels[i];
253    
254                            int x = versionLabelFragment.lastIndexOf(CharPool.UNDERLINE);
255                            int y = versionLabelFragment.lastIndexOf(CharPool.PERIOD);
256    
257                            if (x > -1) {
258                                    versionLabelFragment = versionLabelFragment.substring(x + 1, y);
259                            }
260    
261                            String versionLabel = versionLabelFragment;
262    
263                            if (DLUtil.compareVersions(versionLabel, headVersionLabel) > 0) {
264                                    headVersionLabel = versionLabel;
265                            }
266                    }
267    
268                    return headVersionLabel;
269            }
270    
271            private static final String _HOOK_EXTENSION = "afsh";
272    
273    }