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.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.search.SearchException;
020    import com.liferay.portal.kernel.util.FileUtil;
021    import com.liferay.portal.service.ServiceContext;
022    import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
023    
024    import java.io.File;
025    import java.io.InputStream;
026    
027    import java.util.Date;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     */
032    public class SafeFileNameHookWrapper implements Hook {
033    
034            public SafeFileNameHookWrapper(Hook hook) {
035                    _hook = hook;
036            }
037    
038            public void addDirectory(long companyId, long repositoryId, String dirName)
039                    throws PortalException, SystemException {
040    
041                    String safeDirName = FileUtil.encodeSafeFileName(dirName);
042    
043                    if (!safeDirName.equals(dirName)) {
044                            try {
045                                    _hook.move(dirName, safeDirName);
046                            }
047                            catch (Exception e) {
048                            }
049                    }
050    
051                    _hook.addDirectory(companyId, repositoryId, safeDirName);
052            }
053    
054            public void addFile(
055                            long companyId, String portletId, long groupId, long repositoryId,
056                            String fileName, long fileEntryId, String properties,
057                            Date modifiedDate, ServiceContext serviceContext, byte[] bytes)
058                    throws PortalException, SystemException {
059    
060                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
061    
062                    renameUnsafeFile(
063                            companyId, portletId, groupId, repositoryId, fileName,
064                            safeFileName);
065    
066                    _hook.addFile(
067                            companyId, portletId, groupId, repositoryId, safeFileName,
068                            fileEntryId, properties, modifiedDate, serviceContext, bytes);
069            }
070    
071            public void addFile(
072                            long companyId, String portletId, long groupId, long repositoryId,
073                            String fileName, long fileEntryId, String properties,
074                            Date modifiedDate, ServiceContext serviceContext, File file)
075                    throws PortalException, SystemException {
076    
077                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
078    
079                    renameUnsafeFile(
080                            companyId, portletId, groupId, repositoryId, fileName,
081                            safeFileName);
082    
083                    _hook.addFile(
084                            companyId, portletId, groupId, repositoryId, safeFileName,
085                            fileEntryId, properties, modifiedDate, serviceContext, file);
086            }
087    
088            public void addFile(
089                            long companyId, String portletId, long groupId, long repositoryId,
090                            String fileName, long fileEntryId, String properties,
091                            Date modifiedDate, ServiceContext serviceContext, InputStream is)
092                    throws PortalException, SystemException {
093    
094                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
095    
096                    renameUnsafeFile(
097                            companyId, portletId, groupId, repositoryId, fileName,
098                            safeFileName);
099    
100                    _hook.addFile(
101                            companyId, portletId, groupId, repositoryId, safeFileName,
102                            fileEntryId, properties, modifiedDate, serviceContext, is);
103            }
104    
105            public void checkRoot(long companyId) throws SystemException {
106                    _hook.checkRoot(companyId);
107            }
108    
109            public void deleteDirectory(
110                            long companyId, String portletId, long repositoryId, String dirName)
111                    throws PortalException, SystemException {
112    
113                    String safeDirName = FileUtil.encodeSafeFileName(dirName);
114    
115                    if (!safeDirName.equals(dirName)) {
116                            try {
117                                    _hook.deleteDirectory(
118                                            companyId, portletId, repositoryId, dirName);
119    
120                                    return;
121                            }
122                            catch (Exception e) {
123                            }
124                    }
125    
126                    _hook.deleteDirectory(companyId, portletId, repositoryId, safeDirName);
127            }
128    
129            public void deleteFile(
130                            long companyId, String portletId, long repositoryId,
131                            String fileName)
132                    throws PortalException, SystemException {
133    
134                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
135    
136                    if (!safeFileName.equals(fileName) &&
137                            _hook.hasFile(
138                                    companyId, repositoryId, fileName,
139                                    DLFileEntryConstants.DEFAULT_VERSION)) {
140    
141                            _hook.deleteFile(companyId, portletId, repositoryId, fileName);
142    
143                            return;
144                    }
145    
146                    _hook.deleteFile(companyId, portletId, repositoryId, safeFileName);
147            }
148    
149            public void deleteFile(
150                            long companyId, String portletId, long repositoryId,
151                            String fileName, String versionNumber)
152                    throws PortalException, SystemException {
153    
154                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
155    
156                    if (!safeFileName.equals(fileName) &&
157                            _hook.hasFile(
158                                    companyId, repositoryId, fileName, versionNumber)) {
159    
160                            _hook.deleteFile(
161                                    companyId, portletId, repositoryId, fileName, versionNumber);
162    
163                            return;
164                    }
165    
166                    _hook.deleteFile(
167                            companyId, portletId, repositoryId, safeFileName, versionNumber);
168            }
169    
170            public byte[] getFile(long companyId, long repositoryId, String fileName)
171                    throws PortalException, SystemException {
172    
173                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
174    
175                    if (!safeFileName.equals(fileName) &&
176                            _hook.hasFile(
177                                    companyId, repositoryId, fileName,
178                                    DLFileEntryConstants.DEFAULT_VERSION)) {
179    
180                            return _hook.getFile(companyId, repositoryId, fileName);
181                    }
182    
183                    return _hook.getFile(companyId, repositoryId, safeFileName);
184            }
185    
186            public byte[] getFile(
187                            long companyId, long repositoryId, String fileName,
188                            String versionNumber)
189                    throws PortalException, SystemException {
190    
191                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
192    
193                    if (!safeFileName.equals(fileName) &&
194                            _hook.hasFile(companyId, repositoryId, fileName, versionNumber)) {
195    
196                            return _hook.getFile(
197                                    companyId, repositoryId, fileName, versionNumber);
198                    }
199    
200                    return _hook.getFile(
201                            companyId, repositoryId, safeFileName, versionNumber);
202            }
203    
204            public InputStream getFileAsStream(
205                            long companyId, long repositoryId, String fileName)
206                    throws PortalException, SystemException {
207    
208                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
209    
210                    if (!safeFileName.equals(fileName) &&
211                            _hook.hasFile(
212                                    companyId, repositoryId, fileName,
213                                    DLFileEntryConstants.DEFAULT_VERSION)) {
214    
215                            return _hook.getFileAsStream(companyId, repositoryId, fileName);
216                    }
217    
218                    return _hook.getFileAsStream(companyId, repositoryId, safeFileName);
219            }
220    
221            public InputStream getFileAsStream(
222                            long companyId, long repositoryId, String fileName,
223                            String versionNumber)
224                    throws PortalException, SystemException {
225    
226                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
227    
228                    if (!safeFileName.equals(fileName) &&
229                            _hook.hasFile(
230                                    companyId, repositoryId, fileName, versionNumber)) {
231    
232                            return _hook.getFileAsStream(
233                                    companyId, repositoryId, fileName, versionNumber);
234                    }
235    
236                    return _hook.getFileAsStream(
237                            companyId, repositoryId, safeFileName, versionNumber);
238            }
239    
240            public String[] getFileNames(
241                            long companyId, long repositoryId, String dirName)
242                    throws PortalException, SystemException {
243    
244                    String safeDirName = FileUtil.encodeSafeFileName(dirName);
245    
246                    if (!safeDirName.equals(dirName)) {
247                            try {
248                                    _hook.move(dirName, safeDirName);
249                            }
250                            catch (Exception e) {
251                            }
252                    }
253    
254                    String[] fileNames = _hook.getFileNames(
255                            companyId, repositoryId, safeDirName);
256    
257                    String[] decodedFileNames = new String[fileNames.length];
258    
259                    for (int i = 0; i < fileNames.length; i++) {
260                            decodedFileNames[i] = FileUtil.decodeSafeFileName(fileNames[i]);
261                    }
262    
263                    return decodedFileNames;
264            }
265    
266            public long getFileSize(
267                            long companyId, long repositoryId, String fileName)
268                    throws PortalException, SystemException {
269    
270                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
271    
272                    if (!safeFileName.equals(fileName) &&
273                            _hook.hasFile(
274                                    companyId, repositoryId, fileName,
275                                    DLFileEntryConstants.DEFAULT_VERSION)) {
276    
277                            return _hook.getFileSize(companyId, repositoryId, fileName);
278                    }
279    
280                    return _hook.getFileSize(companyId, repositoryId, safeFileName);
281            }
282    
283            public boolean hasFile(
284                            long companyId, long repositoryId, String fileName,
285                            String versionNumber)
286                    throws PortalException, SystemException {
287    
288                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
289    
290                    if (!safeFileName.equals(fileName) &&
291                            _hook.hasFile(companyId, repositoryId, fileName, versionNumber)) {
292    
293                            return true;
294                    }
295    
296                    return _hook.hasFile(
297                            companyId, repositoryId, safeFileName, versionNumber);
298            }
299    
300            public void move(String srcDir, String destDir) throws SystemException {
301                    _hook.move(srcDir, destDir);
302            }
303    
304            public void reindex(String[] ids) throws SearchException {
305                    _hook.reindex(ids);
306            }
307    
308            public void updateFile(
309                            long companyId, String portletId, long groupId, long repositoryId,
310                            long newRepositoryId, String fileName, long fileEntryId)
311                    throws PortalException, SystemException {
312    
313                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
314    
315                    renameUnsafeFile(
316                            companyId, portletId, groupId, repositoryId, fileName,
317                            safeFileName);
318    
319                    _hook.updateFile(
320                            companyId, portletId, groupId, repositoryId, newRepositoryId,
321                            safeFileName, fileEntryId);
322            }
323    
324            public void updateFile(
325                            long companyId, String portletId, long groupId, long repositoryId,
326                            String fileName, String newFileName, boolean reindex)
327                    throws PortalException, SystemException {
328    
329                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
330                    String safeNewFileName = FileUtil.encodeSafeFileName(newFileName);
331    
332                    if (!safeFileName.equals(fileName)) {
333                            if (_hook.hasFile(
334                                            companyId, repositoryId, fileName,
335                                            DLFileEntryConstants.DEFAULT_VERSION)) {
336    
337                                    safeFileName = fileName;
338                            }
339                    }
340    
341                    _hook.updateFile(
342                            companyId, portletId, groupId, repositoryId, safeFileName,
343                            safeNewFileName, reindex);
344            }
345    
346            public void updateFile(
347                            long companyId, String portletId, long groupId, long repositoryId,
348                            String fileName, String versionNumber, String sourceFileName,
349                            long fileEntryId, String properties, Date modifiedDate,
350                            ServiceContext serviceContext, byte[] bytes)
351                    throws PortalException, SystemException {
352    
353                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
354                    String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
355    
356                    renameUnsafeFile(
357                            companyId, portletId, groupId, repositoryId, fileName,
358                            safeFileName);
359                    renameUnsafeFile(
360                            companyId, portletId, groupId, repositoryId, sourceFileName,
361                            safeSourceFileName);
362    
363                    _hook.updateFile(
364                            companyId, portletId, groupId, repositoryId, safeFileName,
365                            versionNumber, safeSourceFileName, fileEntryId, properties,
366                            modifiedDate, serviceContext, bytes);
367            }
368    
369            public void updateFile(
370                            long companyId, String portletId, long groupId, long repositoryId,
371                            String fileName, String versionNumber, String sourceFileName,
372                            long fileEntryId, String properties, Date modifiedDate,
373                            ServiceContext serviceContext, File file)
374                    throws PortalException, SystemException {
375    
376                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
377                    String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
378    
379                    renameUnsafeFile(
380                            companyId, portletId, groupId, repositoryId, fileName,
381                            safeFileName);
382                    renameUnsafeFile(
383                            companyId, portletId, groupId, repositoryId, sourceFileName,
384                            safeSourceFileName);
385    
386                    _hook.updateFile(
387                            companyId, portletId, groupId, repositoryId, safeFileName,
388                            versionNumber, safeSourceFileName, fileEntryId, properties,
389                            modifiedDate, serviceContext, file);
390            }
391    
392            public void updateFile(
393                            long companyId, String portletId, long groupId, long repositoryId,
394                            String fileName, String versionNumber, String sourceFileName,
395                            long fileEntryId, String properties, Date modifiedDate,
396                            ServiceContext serviceContext, InputStream is)
397                    throws PortalException, SystemException {
398    
399                    String safeFileName = FileUtil.encodeSafeFileName(fileName);
400                    String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
401    
402                    renameUnsafeFile(
403                            companyId, portletId, groupId, repositoryId, fileName,
404                            safeFileName);
405                    renameUnsafeFile(
406                            companyId, portletId, groupId, repositoryId, sourceFileName,
407                            safeSourceFileName);
408    
409                    _hook.updateFile(
410                            companyId, portletId, groupId, repositoryId, safeFileName,
411                            versionNumber, safeSourceFileName, fileEntryId, properties,
412                            modifiedDate, serviceContext, is);
413            }
414    
415            protected void renameUnsafeFile(
416                            long companyId, String portletId, long groupId, long repositoryId,
417                            String fileName, String safeFileName)
418                    throws PortalException, SystemException {
419    
420                    if (!safeFileName.equals(fileName)) {
421                            if (_hook.hasFile(
422                                            companyId, repositoryId, fileName,
423                                            DLFileEntryConstants.DEFAULT_VERSION)) {
424    
425                                    _hook.updateFile(
426                                            companyId, portletId, groupId, repositoryId, fileName,
427                                            safeFileName, true);
428                            }
429                    }
430            }
431    
432            private Hook _hook;
433    
434    }