001    /**
002     * Copyright (c) 2000-present 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.util;
016    
017    import com.liferay.document.library.kernel.exception.FileExtensionException;
018    import com.liferay.document.library.kernel.exception.FileNameException;
019    import com.liferay.document.library.kernel.exception.FileSizeException;
020    import com.liferay.document.library.kernel.exception.FolderNameException;
021    import com.liferay.document.library.kernel.exception.InvalidFileVersionException;
022    import com.liferay.document.library.kernel.exception.SourceFileNameException;
023    import com.liferay.document.library.kernel.util.DLUtil;
024    import com.liferay.document.library.kernel.util.DLValidator;
025    import com.liferay.portal.kernel.util.FileUtil;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.UnicodeFormatter;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.util.PrefsPropsUtil;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.portlet.documentlibrary.webdav.DLWebDAVUtil;
034    
035    import java.io.File;
036    import java.io.IOException;
037    import java.io.InputStream;
038    
039    /**
040     * @author Adolfo Pérez
041     */
042    public final class DLValidatorImpl implements DLValidator {
043    
044            @Override
045            public String fixName(String name) {
046                    if (Validator.isNull(name)) {
047                            return StringPool.UNDERLINE;
048                    }
049    
050                    for (String blacklistChar : PropsValues.DL_CHAR_BLACKLIST) {
051                            name = StringUtil.replace(
052                                    name, blacklistChar, StringPool.UNDERLINE);
053                    }
054    
055                    name = replaceDLCharLastBlacklist(name);
056    
057                    return replaceDLNameBlacklist(name);
058            }
059    
060            @Override
061            public boolean isValidName(String name) {
062                    if (Validator.isNull(name)) {
063                            return false;
064                    }
065    
066                    for (String blacklistChar : PropsValues.DL_CHAR_BLACKLIST) {
067                            if (name.contains(blacklistChar)) {
068                                    return false;
069                            }
070                    }
071    
072                    for (String blacklistLastChar : PropsValues.DL_CHAR_LAST_BLACKLIST) {
073                            if (blacklistLastChar.startsWith(UnicodeFormatter.UNICODE_PREFIX)) {
074                                    blacklistLastChar = UnicodeFormatter.parseString(
075                                            blacklistLastChar);
076                            }
077    
078                            if (name.endsWith(blacklistLastChar)) {
079                                    return false;
080                            }
081                    }
082    
083                    String nameWithoutExtension = FileUtil.stripExtension(name);
084    
085                    for (String blacklistName : PropsValues.DL_NAME_BLACKLIST) {
086                            if (StringUtil.equalsIgnoreCase(
087                                            nameWithoutExtension, blacklistName)) {
088    
089                                    return false;
090                            }
091                    }
092    
093                    return true;
094            }
095    
096            @Override
097            public void validateDirectoryName(String directoryName)
098                    throws FolderNameException {
099    
100                    if (!isValidName(directoryName)) {
101                            throw new FolderNameException(directoryName);
102                    }
103            }
104    
105            @Override
106            public void validateFileExtension(String fileName)
107                    throws FileExtensionException {
108    
109                    boolean validFileExtension = false;
110    
111                    String[] fileExtensions = PrefsPropsUtil.getStringArray(
112                            PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
113    
114                    for (String fileExtension : fileExtensions) {
115                            if (StringPool.STAR.equals(fileExtension) ||
116                                    StringUtil.endsWith(fileName, fileExtension)) {
117    
118                                    validFileExtension = true;
119    
120                                    break;
121                            }
122                    }
123    
124                    if (!validFileExtension) {
125                            throw new FileExtensionException(fileName);
126                    }
127            }
128    
129            @Override
130            public void validateFileName(String fileName) throws FileNameException {
131                    if (!isValidName(fileName)) {
132                            throw new FileNameException(fileName);
133                    }
134    
135                    if (!DLWebDAVUtil.isRepresentableTitle(fileName)) {
136                            throw new FileNameException(
137                                    "Unrepresentable WebDAV title for file name " + fileName);
138                    }
139            }
140    
141            @Override
142            public void validateFileSize(String fileName, byte[] bytes)
143                    throws FileSizeException {
144    
145                    if (bytes == null) {
146                            throw new FileSizeException(fileName);
147                    }
148    
149                    validateFileSize(fileName, bytes.length);
150            }
151    
152            @Override
153            public void validateFileSize(String fileName, File file)
154                    throws FileSizeException {
155    
156                    if (file == null) {
157                            throw new FileSizeException(fileName);
158                    }
159    
160                    validateFileSize(fileName, file.length());
161            }
162    
163            @Override
164            public void validateFileSize(String fileName, InputStream is)
165                    throws FileSizeException {
166    
167                    try {
168                            if (is == null) {
169                                    throw new FileSizeException(fileName);
170                            }
171    
172                            validateFileSize(fileName, is.available());
173                    }
174                    catch (IOException ioe) {
175                            new FileSizeException(ioe);
176                    }
177            }
178    
179            @Override
180            public void validateFileSize(String fileName, long size)
181                    throws FileSizeException {
182    
183                    long maxSize = PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE);
184    
185                    if ((maxSize > 0) && (size > maxSize)) {
186                            throw new FileSizeException(fileName);
187                    }
188            }
189    
190            @Override
191            public void validateSourceFileExtension(
192                            String fileExtension, String sourceFileName)
193                    throws SourceFileNameException {
194    
195                    String sourceFileExtension = FileUtil.getExtension(sourceFileName);
196    
197                    if (Validator.isNotNull(sourceFileName) &&
198                            PropsValues.DL_FILE_EXTENSIONS_STRICT_CHECK &&
199                            !fileExtension.equals(sourceFileExtension)) {
200    
201                            throw new SourceFileNameException(sourceFileExtension);
202                    }
203            }
204    
205            @Override
206            public void validateVersionLabel(String versionLabel)
207                    throws InvalidFileVersionException {
208    
209                    if (Validator.isNull(versionLabel)) {
210                            return;
211                    }
212    
213                    if (!DLUtil.isValidVersion(versionLabel)) {
214                            throw new InvalidFileVersionException(
215                                    "Invalid version label " + versionLabel);
216                    }
217            }
218    
219            protected String replaceDLCharLastBlacklist(String title) {
220                    String previousTitle = null;
221    
222                    while (!title.equals(previousTitle)) {
223                            previousTitle = title;
224    
225                            for (String blacklistLastChar :
226                                            PropsValues.DL_CHAR_LAST_BLACKLIST) {
227    
228                                    if (blacklistLastChar.startsWith(
229                                                    UnicodeFormatter.UNICODE_PREFIX)) {
230    
231                                            blacklistLastChar = UnicodeFormatter.parseString(
232                                                    blacklistLastChar);
233                                    }
234    
235                                    if (title.endsWith(blacklistLastChar)) {
236                                            title = StringUtil.replaceLast(
237                                                    title, blacklistLastChar, StringPool.BLANK);
238                                    }
239                            }
240                    }
241    
242                    return title;
243            }
244    
245            protected String replaceDLNameBlacklist(String title) {
246                    String extension = FileUtil.getExtension(title);
247                    String nameWithoutExtension = FileUtil.stripExtension(title);
248    
249                    for (String blacklistName : PropsValues.DL_NAME_BLACKLIST) {
250                            if (StringUtil.equalsIgnoreCase(
251                                            nameWithoutExtension, blacklistName)) {
252    
253                                    if (Validator.isNull(extension)) {
254                                            return nameWithoutExtension + StringPool.UNDERLINE;
255                                    }
256    
257                                    return nameWithoutExtension + StringPool.UNDERLINE +
258                                            StringPool.PERIOD + extension;
259                            }
260                    }
261    
262                    return title;
263            }
264    
265    }