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.webdav;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.lock.DuplicateLockException;
019    import com.liferay.portal.kernel.lock.InvalidLockException;
020    import com.liferay.portal.kernel.lock.Lock;
021    import com.liferay.portal.kernel.lock.NoSuchLockException;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.Folder;
026    import com.liferay.portal.kernel.servlet.HttpHeaders;
027    import com.liferay.portal.kernel.util.Constants;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.FileUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HttpUtil;
032    import com.liferay.portal.kernel.util.ListUtil;
033    import com.liferay.portal.kernel.util.MimeTypesUtil;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.kernel.webdav.BaseResourceImpl;
038    import com.liferay.portal.kernel.webdav.BaseWebDAVStorageImpl;
039    import com.liferay.portal.kernel.webdav.Resource;
040    import com.liferay.portal.kernel.webdav.Status;
041    import com.liferay.portal.kernel.webdav.WebDAVException;
042    import com.liferay.portal.kernel.webdav.WebDAVRequest;
043    import com.liferay.portal.kernel.webdav.WebDAVUtil;
044    import com.liferay.portal.security.auth.PrincipalException;
045    import com.liferay.portal.service.ServiceContext;
046    import com.liferay.portal.service.ServiceContextFactory;
047    import com.liferay.portal.webdav.LockException;
048    import com.liferay.portlet.asset.model.AssetEntry;
049    import com.liferay.portlet.asset.model.AssetLink;
050    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
051    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
052    import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
053    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
054    import com.liferay.portlet.documentlibrary.DuplicateFileException;
055    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
056    import com.liferay.portlet.documentlibrary.FileSizeException;
057    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
058    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
059    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
060    import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
061    import com.liferay.portlet.documentlibrary.model.DLFolder;
062    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
063    import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
064    import com.liferay.portlet.documentlibrary.util.DL;
065    import com.liferay.portlet.expando.model.ExpandoBridge;
066    import com.liferay.portlet.trash.util.TrashUtil;
067    
068    import java.io.File;
069    import java.io.InputStream;
070    
071    import java.util.ArrayList;
072    import java.util.List;
073    
074    import javax.servlet.http.HttpServletRequest;
075    import javax.servlet.http.HttpServletResponse;
076    
077    /**
078     * @author Brian Wing Shun Chan
079     * @author Alexander Chow
080     */
081    public class DLWebDAVStorageImpl extends BaseWebDAVStorageImpl {
082    
083            public static final String MS_OFFICE_2010_TEXT_XML_UTF8 =
084                    "text/xml; charset=\"utf-8\"";
085    
086            @Override
087            public int copyCollectionResource(
088                            WebDAVRequest webDAVRequest, Resource resource, String destination,
089                            boolean overwrite, long depth)
090                    throws WebDAVException {
091    
092                    try {
093                            String[] destinationArray = WebDAVUtil.getPathArray(
094                                    destination, true);
095    
096                            long companyId = webDAVRequest.getCompanyId();
097    
098                            long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
099    
100                            try {
101                                    parentFolderId = getParentFolderId(companyId, destinationArray);
102                            }
103                            catch (NoSuchFolderException nsfe) {
104                                    return HttpServletResponse.SC_CONFLICT;
105                            }
106    
107                            Folder folder = (Folder)resource.getModel();
108    
109                            long groupId = WebDAVUtil.getGroupId(companyId, destination);
110                            String name = WebDAVUtil.getResourceName(destinationArray);
111                            String description = folder.getDescription();
112    
113                            ServiceContext serviceContext = new ServiceContext();
114    
115                            serviceContext.setAddGroupPermissions(
116                                    isAddGroupPermissions(groupId));
117                            serviceContext.setAddGuestPermissions(true);
118    
119                            int status = HttpServletResponse.SC_CREATED;
120    
121                            if (overwrite) {
122                                    if (deleteResource(
123                                                    groupId, parentFolderId, name,
124                                                    webDAVRequest.getLockUuid())) {
125    
126                                            status = HttpServletResponse.SC_NO_CONTENT;
127                                    }
128                            }
129    
130                            if (depth == 0) {
131                                    DLAppServiceUtil.addFolder(
132                                            groupId, parentFolderId, name, description, serviceContext);
133                            }
134                            else {
135                                    DLAppServiceUtil.copyFolder(
136                                            groupId, folder.getFolderId(), parentFolderId, name,
137                                            description, serviceContext);
138                            }
139    
140                            return status;
141                    }
142                    catch (DuplicateFolderNameException dfne) {
143                            return HttpServletResponse.SC_PRECONDITION_FAILED;
144                    }
145                    catch (PrincipalException pe) {
146                            return HttpServletResponse.SC_FORBIDDEN;
147                    }
148                    catch (Exception e) {
149                            throw new WebDAVException(e);
150                    }
151            }
152    
153            @Override
154            public int copySimpleResource(
155                            WebDAVRequest webDAVRequest, Resource resource, String destination,
156                            boolean overwrite)
157                    throws WebDAVException {
158    
159                    File file = null;
160    
161                    try {
162                            String[] destinationArray = WebDAVUtil.getPathArray(
163                                    destination, true);
164    
165                            long companyId = webDAVRequest.getCompanyId();
166    
167                            long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
168    
169                            try {
170                                    parentFolderId = getParentFolderId(companyId, destinationArray);
171                            }
172                            catch (NoSuchFolderException nsfe) {
173                                    return HttpServletResponse.SC_CONFLICT;
174                            }
175    
176                            FileEntry fileEntry = (FileEntry)resource.getModel();
177    
178                            long groupId = WebDAVUtil.getGroupId(companyId, destination);
179                            String mimeType = fileEntry.getMimeType();
180                            String title = WebDAVUtil.getResourceName(destinationArray);
181                            String description = fileEntry.getDescription();
182                            String changeLog = StringPool.BLANK;
183    
184                            InputStream is = fileEntry.getContentStream();
185    
186                            file = FileUtil.createTempFile(is);
187    
188                            ServiceContext serviceContext = new ServiceContext();
189    
190                            serviceContext.setAddGroupPermissions(
191                                    isAddGroupPermissions(groupId));
192                            serviceContext.setAddGuestPermissions(true);
193    
194                            int status = HttpServletResponse.SC_CREATED;
195    
196                            if (overwrite) {
197                                    if (deleteResource(
198                                                    groupId, parentFolderId, title,
199                                                    webDAVRequest.getLockUuid())) {
200    
201                                            status = HttpServletResponse.SC_NO_CONTENT;
202                                    }
203                            }
204    
205                            DLAppServiceUtil.addFileEntry(
206                                    groupId, parentFolderId, title, mimeType, title, description,
207                                    changeLog, file, serviceContext);
208    
209                            return status;
210                    }
211                    catch (DuplicateFileException dfe) {
212                            return HttpServletResponse.SC_PRECONDITION_FAILED;
213                    }
214                    catch (DuplicateFolderNameException dfne) {
215                            return HttpServletResponse.SC_PRECONDITION_FAILED;
216                    }
217                    catch (LockException le) {
218                            return WebDAVUtil.SC_LOCKED;
219                    }
220                    catch (PrincipalException pe) {
221                            return HttpServletResponse.SC_FORBIDDEN;
222                    }
223                    catch (Exception e) {
224                            throw new WebDAVException(e);
225                    }
226                    finally {
227                            FileUtil.delete(file);
228                    }
229            }
230    
231            @Override
232            public int deleteResource(WebDAVRequest webDAVRequest)
233                    throws WebDAVException {
234    
235                    try {
236                            Resource resource = getResource(webDAVRequest);
237    
238                            if (resource == null) {
239                                    if (webDAVRequest.isAppleDoubleRequest()) {
240                                            return HttpServletResponse.SC_NO_CONTENT;
241                                    }
242                                    else {
243                                            return HttpServletResponse.SC_NOT_FOUND;
244                                    }
245                            }
246    
247                            Object model = resource.getModel();
248    
249                            if (model instanceof Folder) {
250                                    Folder folder = (Folder)model;
251    
252                                    long folderId = folder.getFolderId();
253    
254                                    if ((folder.getModel() instanceof DLFolder) &&
255                                            TrashUtil.isTrashEnabled(folder.getGroupId())) {
256    
257                                            DLAppServiceUtil.moveFolderToTrash(folderId);
258                                    }
259                                    else {
260                                            DLAppServiceUtil.deleteFolder(folderId);
261                                    }
262                            }
263                            else {
264                                    FileEntry fileEntry = (FileEntry)model;
265    
266                                    if (!hasLock(fileEntry, webDAVRequest.getLockUuid()) &&
267                                            (fileEntry.getLock() != null)) {
268    
269                                            return WebDAVUtil.SC_LOCKED;
270                                    }
271    
272                                    long fileEntryId = fileEntry.getFileEntryId();
273    
274                                    if ((fileEntry.getModel() instanceof DLFileEntry) &&
275                                            TrashUtil.isTrashEnabled(fileEntry.getGroupId())) {
276    
277                                            DLAppServiceUtil.moveFileEntryToTrash(fileEntryId);
278                                    }
279                                    else {
280                                            DLAppServiceUtil.deleteFileEntry(fileEntryId);
281                                    }
282                            }
283    
284                            return HttpServletResponse.SC_NO_CONTENT;
285                    }
286                    catch (PrincipalException pe) {
287                            return HttpServletResponse.SC_FORBIDDEN;
288                    }
289                    catch (Exception e) {
290                            throw new WebDAVException(e);
291                    }
292            }
293    
294            @Override
295            public Resource getResource(WebDAVRequest webDAVRequest)
296                    throws WebDAVException {
297    
298                    try {
299                            String[] pathArray = webDAVRequest.getPathArray();
300    
301                            long companyId = webDAVRequest.getCompanyId();
302                            long parentFolderId = getParentFolderId(companyId, pathArray);
303                            String name = WebDAVUtil.getResourceName(pathArray);
304    
305                            if (Validator.isNull(name)) {
306                                    String path = getRootPath() + webDAVRequest.getPath();
307    
308                                    return new BaseResourceImpl(path, StringPool.BLANK, getToken());
309                            }
310    
311                            try {
312                                    Folder folder = DLAppServiceUtil.getFolder(
313                                            webDAVRequest.getGroupId(), parentFolderId, name);
314    
315                                    if ((folder.getParentFolderId() != parentFolderId) ||
316                                            (webDAVRequest.getGroupId() != folder.getRepositoryId())) {
317    
318                                            throw new NoSuchFolderException();
319                                    }
320    
321                                    return toResource(webDAVRequest, folder, false);
322                            }
323                            catch (NoSuchFolderException nsfe) {
324                                    try {
325                                            String titleWithExtension = name;
326    
327                                            FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
328                                                    webDAVRequest.getGroupId(), parentFolderId,
329                                                    titleWithExtension);
330    
331                                            return toResource(webDAVRequest, fileEntry, false);
332                                    }
333                                    catch (NoSuchFileEntryException nsfee) {
334                                            return null;
335                                    }
336                            }
337                    }
338                    catch (Exception e) {
339                            throw new WebDAVException(e);
340                    }
341            }
342    
343            @Override
344            public List<Resource> getResources(WebDAVRequest webDAVRequest)
345                    throws WebDAVException {
346    
347                    try {
348                            long folderId = getFolderId(
349                                    webDAVRequest.getCompanyId(), webDAVRequest.getPathArray());
350    
351                            List<Resource> folders = getFolders(webDAVRequest, folderId);
352                            List<Resource> fileEntries = getFileEntries(
353                                    webDAVRequest, folderId);
354    
355                            List<Resource> resources = new ArrayList<>(
356                                    folders.size() + fileEntries.size());
357    
358                            resources.addAll(folders);
359                            resources.addAll(fileEntries);
360    
361                            return resources;
362                    }
363                    catch (Exception e) {
364                            throw new WebDAVException(e);
365                    }
366            }
367    
368            @Override
369            public boolean isSupportsClassTwo() {
370                    return true;
371            }
372    
373            @Override
374            public Status lockResource(
375                            WebDAVRequest webDAVRequest, String owner, long timeout)
376                    throws WebDAVException {
377    
378                    Resource resource = getResource(webDAVRequest);
379    
380                    Lock lock = null;
381                    int status = HttpServletResponse.SC_OK;
382    
383                    try {
384                            if (resource == null) {
385                                    status = HttpServletResponse.SC_CREATED;
386    
387                                    HttpServletRequest request =
388                                            webDAVRequest.getHttpServletRequest();
389    
390                                    String[] pathArray = webDAVRequest.getPathArray();
391    
392                                    long companyId = webDAVRequest.getCompanyId();
393                                    long groupId = webDAVRequest.getGroupId();
394                                    long parentFolderId = getParentFolderId(companyId, pathArray);
395                                    String title = WebDAVUtil.getResourceName(pathArray);
396                                    String extension = FileUtil.getExtension(title);
397    
398                                    String contentType = getContentType(
399                                            request, null, title, extension);
400    
401                                    String description = StringPool.BLANK;
402                                    String changeLog = StringPool.BLANK;
403    
404                                    File file = FileUtil.createTempFile(extension);
405    
406                                    file.createNewFile();
407    
408                                    ServiceContext serviceContext = new ServiceContext();
409    
410                                    serviceContext.setAddGroupPermissions(
411                                            isAddGroupPermissions(groupId));
412                                    serviceContext.setAddGuestPermissions(true);
413    
414                                    FileEntry fileEntry = DLAppServiceUtil.addFileEntry(
415                                            groupId, parentFolderId, title, contentType, title,
416                                            description, changeLog, file, serviceContext);
417    
418                                    resource = toResource(webDAVRequest, fileEntry, false);
419                            }
420    
421                            if (resource instanceof DLFileEntryResourceImpl) {
422                                    FileEntry fileEntry = (FileEntry)resource.getModel();
423    
424                                    ServiceContext serviceContext = new ServiceContext();
425    
426                                    serviceContext.setAttribute(
427                                            DL.MANUAL_CHECK_IN_REQUIRED,
428                                            webDAVRequest.isManualCheckInRequired());
429    
430                                    DLAppServiceUtil.checkOutFileEntry(
431                                            fileEntry.getFileEntryId(), owner, timeout, serviceContext);
432    
433                                    lock = fileEntry.getLock();
434                            }
435                            else {
436                                    boolean inheritable = false;
437    
438                                    long depth = WebDAVUtil.getDepth(
439                                            webDAVRequest.getHttpServletRequest());
440    
441                                    if (depth != 0) {
442                                            inheritable = true;
443                                    }
444    
445                                    Folder folder = (Folder)resource.getModel();
446    
447                                    lock = DLAppServiceUtil.lockFolder(
448                                            folder.getRepositoryId(), folder.getFolderId(), owner,
449                                            inheritable, timeout);
450                            }
451                    }
452                    catch (Exception e) {
453    
454                            // DuplicateLock is 423 not 501
455    
456                            if (!(e instanceof DuplicateLockException)) {
457                                    throw new WebDAVException(e);
458                            }
459    
460                            status = WebDAVUtil.SC_LOCKED;
461                    }
462    
463                    return new Status(lock, status);
464            }
465    
466            @Override
467            public Status makeCollection(WebDAVRequest webDAVRequest)
468                    throws WebDAVException {
469    
470                    try {
471                            HttpServletRequest request = webDAVRequest.getHttpServletRequest();
472    
473                            if (request.getContentLength() > 0) {
474                                    return new Status(
475                                            HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
476                            }
477    
478                            String[] pathArray = webDAVRequest.getPathArray();
479    
480                            long companyId = webDAVRequest.getCompanyId();
481                            long groupId = webDAVRequest.getGroupId();
482                            long parentFolderId = getParentFolderId(companyId, pathArray);
483                            String name = WebDAVUtil.getResourceName(pathArray);
484                            String description = StringPool.BLANK;
485    
486                            ServiceContext serviceContext = new ServiceContext();
487    
488                            serviceContext.setAddGroupPermissions(
489                                    isAddGroupPermissions(groupId));
490                            serviceContext.setAddGuestPermissions(true);
491    
492                            DLAppServiceUtil.addFolder(
493                                    groupId, parentFolderId, name, description, serviceContext);
494    
495                            String location = StringUtil.merge(pathArray, StringPool.SLASH);
496    
497                            return new Status(location, HttpServletResponse.SC_CREATED);
498                    }
499                    catch (DuplicateFolderNameException dfne) {
500                            return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
501                    }
502                    catch (DuplicateFileException dfe) {
503                            return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
504                    }
505                    catch (NoSuchFolderException nsfe) {
506                            return new Status(HttpServletResponse.SC_CONFLICT);
507                    }
508                    catch (PrincipalException pe) {
509                            return new Status(HttpServletResponse.SC_FORBIDDEN);
510                    }
511                    catch (Exception e) {
512                            throw new WebDAVException(e);
513                    }
514            }
515    
516            @Override
517            public int moveCollectionResource(
518                            WebDAVRequest webDAVRequest, Resource resource, String destination,
519                            boolean overwrite)
520                    throws WebDAVException {
521    
522                    try {
523                            String[] destinationArray = WebDAVUtil.getPathArray(
524                                    destination, true);
525    
526                            Folder folder = (Folder)resource.getModel();
527    
528                            long companyId = webDAVRequest.getCompanyId();
529                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
530                            long folderId = folder.getFolderId();
531                            long parentFolderId = getParentFolderId(
532                                    companyId, destinationArray);
533                            String name = WebDAVUtil.getResourceName(destinationArray);
534                            String description = folder.getDescription();
535    
536                            ServiceContext serviceContext = new ServiceContext();
537    
538                            serviceContext.setUserId(webDAVRequest.getUserId());
539    
540                            int status = HttpServletResponse.SC_CREATED;
541    
542                            if (overwrite) {
543                                    if (deleteResource(
544                                                    groupId, parentFolderId, name,
545                                                    webDAVRequest.getLockUuid())) {
546    
547                                            status = HttpServletResponse.SC_NO_CONTENT;
548                                    }
549                            }
550    
551                            if (parentFolderId != folder.getParentFolderId()) {
552                                    DLAppServiceUtil.moveFolder(
553                                            folderId, parentFolderId, serviceContext);
554                            }
555    
556                            if (!name.equals(folder.getName())) {
557                                    DLAppServiceUtil.updateFolder(
558                                            folderId, name, description, serviceContext);
559                            }
560    
561                            return status;
562                    }
563                    catch (PrincipalException pe) {
564                            return HttpServletResponse.SC_FORBIDDEN;
565                    }
566                    catch (DuplicateFolderNameException dfne) {
567                            return HttpServletResponse.SC_PRECONDITION_FAILED;
568                    }
569                    catch (Exception e) {
570                            throw new WebDAVException(e);
571                    }
572            }
573    
574            @Override
575            public int moveSimpleResource(
576                            WebDAVRequest webDAVRequest, Resource resource, String destination,
577                            boolean overwrite)
578                    throws WebDAVException {
579    
580                    File file = null;
581    
582                    try {
583                            String[] destinationArray = WebDAVUtil.getPathArray(
584                                    destination, true);
585    
586                            FileEntry fileEntry = (FileEntry)resource.getModel();
587    
588                            if (!hasLock(fileEntry, webDAVRequest.getLockUuid()) &&
589                                    (fileEntry.getLock() != null)) {
590    
591                                    return WebDAVUtil.SC_LOCKED;
592                            }
593    
594                            long companyId = webDAVRequest.getCompanyId();
595                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
596                            long newParentFolderId = getParentFolderId(
597                                    companyId, destinationArray);
598                            String sourceFileName = WebDAVUtil.getResourceName(
599                                    destinationArray);
600                            String title = WebDAVUtil.getResourceName(destinationArray);
601                            String description = fileEntry.getDescription();
602                            String changeLog = StringPool.BLANK;
603    
604                            ServiceContext serviceContext = new ServiceContext();
605    
606                            populateServiceContext(serviceContext, fileEntry);
607    
608                            int status = HttpServletResponse.SC_CREATED;
609    
610                            if (overwrite) {
611                                    if (deleteResource(
612                                                    groupId, newParentFolderId, title,
613                                                    webDAVRequest.getLockUuid())) {
614    
615                                            status = HttpServletResponse.SC_NO_CONTENT;
616                                    }
617                            }
618    
619                            // LPS-5415
620    
621                            if (webDAVRequest.isMac()) {
622                                    try {
623                                            FileEntry destFileEntry = DLAppServiceUtil.getFileEntry(
624                                                    groupId, newParentFolderId, title);
625    
626                                            InputStream is = fileEntry.getContentStream();
627    
628                                            file = FileUtil.createTempFile(is);
629    
630                                            DLAppServiceUtil.updateFileEntry(
631                                                    destFileEntry.getFileEntryId(),
632                                                    destFileEntry.getTitle(), destFileEntry.getMimeType(),
633                                                    destFileEntry.getTitle(),
634                                                    destFileEntry.getDescription(), changeLog, false, file,
635                                                    serviceContext);
636    
637                                            DLAppServiceUtil.deleteFileEntry(
638                                                    fileEntry.getFileEntryId());
639    
640                                            return status;
641                                    }
642                                    catch (NoSuchFileEntryException nsfee) {
643                                    }
644                            }
645    
646                            DLAppServiceUtil.updateFileEntry(
647                                    fileEntry.getFileEntryId(), sourceFileName,
648                                    fileEntry.getMimeType(), title, description, changeLog, false,
649                                    file, serviceContext);
650    
651                            if (fileEntry.getFolderId() != newParentFolderId) {
652                                    fileEntry = DLAppServiceUtil.moveFileEntry(
653                                            fileEntry.getFileEntryId(), newParentFolderId,
654                                            serviceContext);
655                            }
656    
657                            return status;
658                    }
659                    catch (PrincipalException pe) {
660                            return HttpServletResponse.SC_FORBIDDEN;
661                    }
662                    catch (DuplicateFileException dfe) {
663                            return HttpServletResponse.SC_PRECONDITION_FAILED;
664                    }
665                    catch (DuplicateFolderNameException dfne) {
666                            return HttpServletResponse.SC_PRECONDITION_FAILED;
667                    }
668                    catch (LockException le) {
669                            return WebDAVUtil.SC_LOCKED;
670                    }
671                    catch (Exception e) {
672                            throw new WebDAVException(e);
673                    }
674                    finally {
675                            FileUtil.delete(file);
676                    }
677            }
678    
679            @Override
680            public int putResource(WebDAVRequest webDAVRequest) throws WebDAVException {
681                    File file = null;
682    
683                    try {
684                            HttpServletRequest request = webDAVRequest.getHttpServletRequest();
685    
686                            String[] pathArray = webDAVRequest.getPathArray();
687    
688                            long companyId = webDAVRequest.getCompanyId();
689                            long groupId = webDAVRequest.getGroupId();
690                            long parentFolderId = getParentFolderId(companyId, pathArray);
691                            String title = WebDAVUtil.getResourceName(pathArray);
692                            String description = StringPool.BLANK;
693                            String changeLog = StringPool.BLANK;
694    
695                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
696                                    request);
697    
698                            serviceContext.setAddGroupPermissions(
699                                    isAddGroupPermissions(groupId));
700                            serviceContext.setAddGuestPermissions(true);
701    
702                            String extension = FileUtil.getExtension(title);
703    
704                            file = FileUtil.createTempFile(extension);
705    
706                            FileUtil.write(file, request.getInputStream());
707    
708                            String contentType = getContentType(
709                                    request, file, title, extension);
710    
711                            try {
712                                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
713                                            groupId, parentFolderId, title);
714    
715                                    if (!hasLock(fileEntry, webDAVRequest.getLockUuid()) &&
716                                            (fileEntry.getLock() != null)) {
717    
718                                            return WebDAVUtil.SC_LOCKED;
719                                    }
720    
721                                    long fileEntryId = fileEntry.getFileEntryId();
722    
723                                    description = fileEntry.getDescription();
724    
725                                    populateServiceContext(serviceContext, fileEntry);
726    
727                                    serviceContext.setCommand(Constants.UPDATE_WEBDAV);
728    
729                                    DLAppServiceUtil.updateFileEntry(
730                                            fileEntryId, title, contentType, title, description,
731                                            changeLog, false, file, serviceContext);
732                            }
733                            catch (NoSuchFileEntryException nsfee) {
734                                    serviceContext.setCommand(Constants.ADD_WEBDAV);
735    
736                                    DLAppServiceUtil.addFileEntry(
737                                            groupId, parentFolderId, title, contentType, title,
738                                            description, changeLog, file, serviceContext);
739                            }
740    
741                            if (_log.isInfoEnabled()) {
742                                    _log.info(
743                                            "Added " + StringUtil.merge(pathArray, StringPool.SLASH));
744                            }
745    
746                            return HttpServletResponse.SC_CREATED;
747                    }
748                    catch (FileSizeException fse) {
749                            return HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE;
750                    }
751                    catch (NoSuchFolderException nsfe) {
752                            return HttpServletResponse.SC_CONFLICT;
753                    }
754                    catch (PrincipalException pe) {
755                            return HttpServletResponse.SC_FORBIDDEN;
756                    }
757                    catch (PortalException pe) {
758                            if (_log.isWarnEnabled()) {
759                                    _log.warn(pe, pe);
760                            }
761    
762                            return HttpServletResponse.SC_CONFLICT;
763                    }
764                    catch (Exception e) {
765                            throw new WebDAVException(e);
766                    }
767                    finally {
768                            FileUtil.delete(file);
769                    }
770            }
771    
772            @Override
773            public Lock refreshResourceLock(
774                            WebDAVRequest webDAVRequest, String uuid, long timeout)
775                    throws WebDAVException {
776    
777                    Resource resource = getResource(webDAVRequest);
778    
779                    long companyId = webDAVRequest.getCompanyId();
780    
781                    Lock lock = null;
782    
783                    try {
784                            if (resource instanceof DLFileEntryResourceImpl) {
785                                    lock = DLAppServiceUtil.refreshFileEntryLock(
786                                            uuid, companyId, timeout);
787                            }
788                            else {
789                                    lock = DLAppServiceUtil.refreshFolderLock(
790                                            uuid, companyId, timeout);
791                            }
792                    }
793                    catch (Exception e) {
794                            throw new WebDAVException(e);
795                    }
796    
797                    return lock;
798            }
799    
800            @Override
801            public boolean unlockResource(WebDAVRequest webDAVRequest, String token)
802                    throws WebDAVException {
803    
804                    Resource resource = getResource(webDAVRequest);
805    
806                    try {
807                            if (resource instanceof DLFileEntryResourceImpl) {
808                                    FileEntry fileEntry = (FileEntry)resource.getModel();
809    
810                                    // Do not allow WebDAV to check in a file entry if it requires a
811                                    // manual check in
812    
813                                    if (fileEntry.isManualCheckInRequired()) {
814                                            return false;
815                                    }
816    
817                                    ServiceContext serviceContext = new ServiceContext();
818    
819                                    serviceContext.setAttribute(DL.WEBDAV_CHECK_IN_MODE, true);
820    
821                                    DLAppServiceUtil.checkInFileEntry(
822                                            fileEntry.getFileEntryId(), token, serviceContext);
823    
824                                    if (webDAVRequest.isAppleDoubleRequest()) {
825                                            DLAppServiceUtil.deleteFileEntry(
826                                                    fileEntry.getFileEntryId());
827                                    }
828                            }
829                            else {
830                                    Folder folder = (Folder)resource.getModel();
831    
832                                    DLAppServiceUtil.unlockFolder(
833                                            folder.getRepositoryId(), folder.getParentFolderId(),
834                                            folder.getName(), token);
835                            }
836    
837                            return true;
838                    }
839                    catch (Exception e) {
840                            if (e instanceof InvalidLockException) {
841                                    if (_log.isWarnEnabled()) {
842                                            _log.warn(e.getMessage());
843                                    }
844                            }
845                            else {
846                                    if (_log.isWarnEnabled()) {
847                                            _log.warn("Unable to unlock file entry", e);
848                                    }
849                            }
850                    }
851    
852                    return false;
853            }
854    
855            protected boolean deleteResource(
856                            long groupId, long parentFolderId, String name, String lockUuid)
857                    throws Exception {
858    
859                    try {
860                            Folder folder = DLAppServiceUtil.getFolder(
861                                    groupId, parentFolderId, name);
862    
863                            DLAppServiceUtil.deleteFolder(folder.getFolderId());
864    
865                            return true;
866                    }
867                    catch (NoSuchFolderException nsfe) {
868                            try {
869                                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
870                                            groupId, parentFolderId, name);
871    
872                                    if (!hasLock(fileEntry, lockUuid) &&
873                                            (fileEntry.getLock() != null)) {
874    
875                                            throw new LockException();
876                                    }
877    
878                                    DLAppServiceUtil.deleteFileEntryByTitle(
879                                            groupId, parentFolderId, name);
880    
881                                    return true;
882                            }
883                            catch (NoSuchFileEntryException nsfee) {
884                            }
885                    }
886    
887                    return false;
888            }
889    
890            protected String getContentType(
891                    HttpServletRequest request, File file, String title, String extension) {
892    
893                    String contentType = GetterUtil.getString(
894                            request.getHeader(HttpHeaders.CONTENT_TYPE),
895                            ContentTypes.APPLICATION_OCTET_STREAM);
896    
897                    if (contentType.equals(ContentTypes.APPLICATION_OCTET_STREAM) ||
898                            contentType.equals(MS_OFFICE_2010_TEXT_XML_UTF8)) {
899    
900                            contentType = MimeTypesUtil.getContentType(file, title);
901                    }
902    
903                    return contentType;
904            }
905    
906            protected List<Resource> getFileEntries(
907                            WebDAVRequest webDAVRequest, long parentFolderId)
908                    throws Exception {
909    
910                    List<Resource> resources = new ArrayList<>();
911    
912                    List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(
913                            webDAVRequest.getGroupId(), parentFolderId);
914    
915                    for (FileEntry fileEntry : fileEntries) {
916                            Resource resource = toResource(webDAVRequest, fileEntry, true);
917    
918                            resources.add(resource);
919                    }
920    
921                    return resources;
922            }
923    
924            protected long getFolderId(long companyId, String[] pathArray)
925                    throws Exception {
926    
927                    return getFolderId(companyId, pathArray, false);
928            }
929    
930            protected long getFolderId(
931                            long companyId, String[] pathArray, boolean parent)
932                    throws Exception {
933    
934                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
935    
936                    if (pathArray.length <= 1) {
937                            return folderId;
938                    }
939    
940                    long groupId = WebDAVUtil.getGroupId(companyId, pathArray);
941    
942                    int x = pathArray.length;
943    
944                    if (parent) {
945                            x--;
946                    }
947    
948                    for (int i = 2; i < x; i++) {
949                            String name = HttpUtil.decodeURL(pathArray[i]);
950    
951                            Folder folder = DLAppServiceUtil.getFolder(groupId, folderId, name);
952    
953                            if (groupId == folder.getRepositoryId()) {
954                                    folderId = folder.getFolderId();
955                            }
956                    }
957    
958                    return folderId;
959            }
960    
961            protected List<Resource> getFolders(
962                            WebDAVRequest webDAVRequest, long parentFolderId)
963                    throws Exception {
964    
965                    List<Resource> resources = new ArrayList<>();
966    
967                    long groupId = webDAVRequest.getGroupId();
968    
969                    List<Folder> folders = DLAppServiceUtil.getFolders(
970                            groupId, parentFolderId, false);
971    
972                    for (Folder folder : folders) {
973                            Resource resource = toResource(webDAVRequest, folder, true);
974    
975                            resources.add(resource);
976                    }
977    
978                    return resources;
979            }
980    
981            protected long getParentFolderId(long companyId, String[] pathArray)
982                    throws Exception {
983    
984                    return getFolderId(companyId, pathArray, true);
985            }
986    
987            protected boolean hasLock(FileEntry fileEntry, String lockUuid)
988                    throws Exception {
989    
990                    if (Validator.isNull(lockUuid)) {
991    
992                            // Client does not claim to know of a lock
993    
994                            return fileEntry.hasLock();
995                    }
996                    else {
997    
998                            // Client claims to know of a lock. Verify the lock UUID.
999    
1000                            try {
1001                                    return DLAppServiceUtil.verifyFileEntryLock(
1002                                            fileEntry.getRepositoryId(), fileEntry.getFileEntryId(),
1003                                            lockUuid);
1004                            }
1005                            catch (NoSuchLockException nsle) {
1006                                    return false;
1007                            }
1008                    }
1009            }
1010    
1011            protected void populateServiceContext(
1012                    ServiceContext serviceContext, FileEntry fileEntry) {
1013    
1014                    String className = DLFileEntryConstants.getClassName();
1015    
1016                    long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
1017                            className, fileEntry.getFileEntryId());
1018    
1019                    serviceContext.setAssetCategoryIds(assetCategoryIds);
1020    
1021                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1022                            className, fileEntry.getFileEntryId());
1023    
1024                    List<AssetLink> assetLinks = AssetLinkLocalServiceUtil.getLinks(
1025                            assetEntry.getEntryId());
1026    
1027                    long[] assetLinkEntryIds = ListUtil.toLongArray(
1028                            assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
1029    
1030                    serviceContext.setAssetLinkEntryIds(assetLinkEntryIds);
1031    
1032                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
1033                            className, fileEntry.getFileEntryId());
1034    
1035                    serviceContext.setAssetTagNames(assetTagNames);
1036    
1037                    ExpandoBridge expandoBridge = fileEntry.getExpandoBridge();
1038    
1039                    serviceContext.setExpandoBridgeAttributes(
1040                            expandoBridge.getAttributes());
1041            }
1042    
1043            protected Resource toResource(
1044                    WebDAVRequest webDAVRequest, FileEntry fileEntry, boolean appendPath) {
1045    
1046                    String parentPath = getRootPath() + webDAVRequest.getPath();
1047    
1048                    String name = StringPool.BLANK;
1049    
1050                    if (appendPath) {
1051                            name = fileEntry.getTitle();
1052                    }
1053    
1054                    return new DLFileEntryResourceImpl(
1055                            webDAVRequest, fileEntry, parentPath, name);
1056            }
1057    
1058            protected Resource toResource(
1059                    WebDAVRequest webDAVRequest, Folder folder, boolean appendPath) {
1060    
1061                    String parentPath = getRootPath() + webDAVRequest.getPath();
1062    
1063                    String name = StringPool.BLANK;
1064    
1065                    if (appendPath) {
1066                            name = folder.getName();
1067                    }
1068    
1069                    Resource resource = new BaseResourceImpl(
1070                            parentPath, name, folder.getName(), folder.getCreateDate(),
1071                            folder.getModifiedDate());
1072    
1073                    resource.setModel(folder);
1074                    resource.setClassName(Folder.class.getName());
1075                    resource.setPrimaryKey(folder.getPrimaryKey());
1076    
1077                    return resource;
1078            }
1079    
1080            private static final Log _log = LogFactoryUtil.getLog(
1081                    DLWebDAVStorageImpl.class);
1082    
1083    }