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