001    /**
002     * Copyright (c) 2000-2013 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.exception.SystemException;
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.ContentTypes;
028    import com.liferay.portal.kernel.util.FileUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.ListUtil;
031    import com.liferay.portal.kernel.util.MimeTypesUtil;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.kernel.webdav.BaseResourceImpl;
036    import com.liferay.portal.kernel.webdav.BaseWebDAVStorageImpl;
037    import com.liferay.portal.kernel.webdav.Resource;
038    import com.liferay.portal.kernel.webdav.Status;
039    import com.liferay.portal.kernel.webdav.WebDAVException;
040    import com.liferay.portal.kernel.webdav.WebDAVRequest;
041    import com.liferay.portal.kernel.webdav.WebDAVUtil;
042    import com.liferay.portal.model.Lock;
043    import com.liferay.portal.security.auth.PrincipalException;
044    import com.liferay.portal.service.ServiceContext;
045    import com.liferay.portal.service.ServiceContextFactory;
046    import com.liferay.portal.webdav.LockException;
047    import com.liferay.portlet.asset.model.AssetEntry;
048    import com.liferay.portlet.asset.model.AssetLink;
049    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
050    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
051    import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
052    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
053    import com.liferay.portlet.documentlibrary.DuplicateFileException;
054    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
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 (PrincipalException pe) {
743                            return HttpServletResponse.SC_FORBIDDEN;
744                    }
745                    catch (NoSuchFolderException nsfe) {
746                            return HttpServletResponse.SC_CONFLICT;
747                    }
748                    catch (PortalException pe) {
749                            if (_log.isWarnEnabled()) {
750                                    _log.warn(pe, pe);
751                            }
752    
753                            return HttpServletResponse.SC_CONFLICT;
754                    }
755                    catch (Exception e) {
756                            throw new WebDAVException(e);
757                    }
758                    finally {
759                            FileUtil.delete(file);
760                    }
761            }
762    
763            @Override
764            public Lock refreshResourceLock(
765                            WebDAVRequest webDAVRequest, String uuid, long timeout)
766                    throws WebDAVException {
767    
768                    Resource resource = getResource(webDAVRequest);
769    
770                    long companyId = webDAVRequest.getCompanyId();
771    
772                    Lock lock = null;
773    
774                    try {
775                            if (resource instanceof DLFileEntryResourceImpl) {
776                                    lock = DLAppServiceUtil.refreshFileEntryLock(
777                                            uuid, companyId, timeout);
778                            }
779                            else {
780                                    lock = DLAppServiceUtil.refreshFolderLock(
781                                            uuid, companyId, timeout);
782                            }
783                    }
784                    catch (Exception e) {
785                            throw new WebDAVException(e);
786                    }
787    
788                    return lock;
789            }
790    
791            @Override
792            public boolean unlockResource(WebDAVRequest webDAVRequest, String token)
793                    throws WebDAVException {
794    
795                    Resource resource = getResource(webDAVRequest);
796    
797                    try {
798                            if (resource instanceof DLFileEntryResourceImpl) {
799                                    FileEntry fileEntry = (FileEntry)resource.getModel();
800    
801                                    // Do not allow WebDAV to check in a file entry if it requires a
802                                    // manual check in
803    
804                                    if (fileEntry.isManualCheckInRequired()) {
805                                            return false;
806                                    }
807    
808                                    ServiceContext serviceContext = new ServiceContext();
809    
810                                    serviceContext.setAttribute(DL.WEBDAV_CHECK_IN_MODE, true);
811    
812                                    DLAppServiceUtil.checkInFileEntry(
813                                            fileEntry.getFileEntryId(), token, serviceContext);
814    
815                                    if (webDAVRequest.isAppleDoubleRequest()) {
816                                            DLAppServiceUtil.deleteFileEntry(
817                                                    fileEntry.getFileEntryId());
818                                    }
819                            }
820                            else {
821                                    Folder folder = (Folder)resource.getModel();
822    
823                                    DLAppServiceUtil.unlockFolder(
824                                            folder.getRepositoryId(), folder.getParentFolderId(),
825                                            folder.getName(), token);
826                            }
827    
828                            return true;
829                    }
830                    catch (Exception e) {
831                            if (e instanceof InvalidLockException) {
832                                    if (_log.isWarnEnabled()) {
833                                            _log.warn(e.getMessage());
834                                    }
835                            }
836                            else {
837                                    if (_log.isWarnEnabled()) {
838                                            _log.warn("Unable to unlock file entry", e);
839                                    }
840                            }
841                    }
842    
843                    return false;
844            }
845    
846            protected boolean deleteResource(
847                            long groupId, long parentFolderId, String name, String lockUuid)
848                    throws Exception {
849    
850                    try {
851                            Folder folder = DLAppServiceUtil.getFolder(
852                                    groupId, parentFolderId, name);
853    
854                            DLAppServiceUtil.deleteFolder(folder.getFolderId());
855    
856                            return true;
857                    }
858                    catch (NoSuchFolderException nsfe) {
859                            try {
860                                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
861                                            groupId, parentFolderId, name);
862    
863                                    if (!hasLock(fileEntry, lockUuid) &&
864                                            (fileEntry.getLock() != null)) {
865    
866                                            throw new LockException();
867                                    }
868    
869                                    DLAppServiceUtil.deleteFileEntryByTitle(
870                                            groupId, parentFolderId, name);
871    
872                                    return true;
873                            }
874                            catch (NoSuchFileEntryException nsfee) {
875                            }
876                    }
877    
878                    return false;
879            }
880    
881            protected String getContentType(
882                    HttpServletRequest request, File file, String title, String extension) {
883    
884                    String contentType = GetterUtil.getString(
885                            request.getHeader(HttpHeaders.CONTENT_TYPE),
886                            ContentTypes.APPLICATION_OCTET_STREAM);
887    
888                    if (contentType.equals(ContentTypes.APPLICATION_OCTET_STREAM) ||
889                            contentType.equals(MS_OFFICE_2010_TEXT_XML_UTF8)) {
890    
891                            contentType = MimeTypesUtil.getContentType(file, title);
892                    }
893    
894                    return contentType;
895            }
896    
897            protected List<Resource> getFileEntries(
898                            WebDAVRequest webDAVRequest, long parentFolderId)
899                    throws Exception {
900    
901                    List<Resource> resources = new ArrayList<Resource>();
902    
903                    List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(
904                            webDAVRequest.getGroupId(), parentFolderId);
905    
906                    for (FileEntry fileEntry : fileEntries) {
907                            Resource resource = toResource(webDAVRequest, fileEntry, true);
908    
909                            resources.add(resource);
910                    }
911    
912                    return resources;
913            }
914    
915            protected long getFolderId(long companyId, String[] pathArray)
916                    throws Exception {
917    
918                    return getFolderId(companyId, pathArray, false);
919            }
920    
921            protected long getFolderId(
922                            long companyId, String[] pathArray, boolean parent)
923                    throws Exception {
924    
925                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
926    
927                    if (pathArray.length <= 1) {
928                            return folderId;
929                    }
930    
931                    long groupId = WebDAVUtil.getGroupId(companyId, pathArray);
932    
933                    int x = pathArray.length;
934    
935                    if (parent) {
936                            x--;
937                    }
938    
939                    for (int i = 2; i < x; i++) {
940                            String name = pathArray[i];
941    
942                            Folder folder = DLAppServiceUtil.getFolder(groupId, folderId, name);
943    
944                            if (groupId == folder.getRepositoryId()) {
945                                    folderId = folder.getFolderId();
946                            }
947                    }
948    
949                    return folderId;
950            }
951    
952            protected List<Resource> getFolders(
953                            WebDAVRequest webDAVRequest, long parentFolderId)
954                    throws Exception {
955    
956                    List<Resource> resources = new ArrayList<Resource>();
957    
958                    long groupId = webDAVRequest.getGroupId();
959    
960                    List<Folder> folders = DLAppServiceUtil.getFolders(
961                            groupId, parentFolderId, false);
962    
963                    for (Folder folder : folders) {
964                            Resource resource = toResource(webDAVRequest, folder, true);
965    
966                            resources.add(resource);
967                    }
968    
969                    return resources;
970            }
971    
972            protected long getParentFolderId(long companyId, String[] pathArray)
973                    throws Exception {
974    
975                    return getFolderId(companyId, pathArray, true);
976            }
977    
978            protected boolean hasLock(FileEntry fileEntry, String lockUuid)
979                    throws Exception {
980    
981                    if (Validator.isNull(lockUuid)) {
982    
983                            // Client does not claim to know of a lock
984    
985                            return fileEntry.hasLock();
986                    }
987                    else {
988    
989                            // Client claims to know of a lock. Verify the lock UUID.
990    
991                            try {
992                                    return DLAppServiceUtil.verifyFileEntryLock(
993                                            fileEntry.getRepositoryId(), fileEntry.getFileEntryId(),
994                                            lockUuid);
995                            }
996                            catch (NoSuchLockException nsle) {
997                                    return false;
998                            }
999                    }
1000            }
1001    
1002            protected void populateServiceContext(
1003                            ServiceContext serviceContext, FileEntry fileEntry)
1004                    throws SystemException {
1005    
1006                    String className = DLFileEntryConstants.getClassName();
1007    
1008                    long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
1009                            className, fileEntry.getFileEntryId());
1010    
1011                    serviceContext.setAssetCategoryIds(assetCategoryIds);
1012    
1013                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1014                            className, fileEntry.getFileEntryId());
1015    
1016                    List<AssetLink> assetLinks = AssetLinkLocalServiceUtil.getLinks(
1017                            assetEntry.getEntryId());
1018    
1019                    long[] assetLinkEntryIds = StringUtil.split(
1020                            ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
1021    
1022                    serviceContext.setAssetLinkEntryIds(assetLinkEntryIds);
1023    
1024                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
1025                            className, fileEntry.getFileEntryId());
1026    
1027                    serviceContext.setAssetTagNames(assetTagNames);
1028    
1029                    ExpandoBridge expandoBridge = fileEntry.getExpandoBridge();
1030    
1031                    serviceContext.setExpandoBridgeAttributes(
1032                            expandoBridge.getAttributes());
1033            }
1034    
1035            protected Resource toResource(
1036                    WebDAVRequest webDAVRequest, FileEntry fileEntry, boolean appendPath) {
1037    
1038                    String parentPath = getRootPath() + webDAVRequest.getPath();
1039    
1040                    String name = StringPool.BLANK;
1041    
1042                    if (appendPath) {
1043                            name = fileEntry.getTitle();
1044                    }
1045    
1046                    return new DLFileEntryResourceImpl(
1047                            webDAVRequest, fileEntry, parentPath, name);
1048            }
1049    
1050            protected Resource toResource(
1051                    WebDAVRequest webDAVRequest, Folder folder, boolean appendPath) {
1052    
1053                    String parentPath = getRootPath() + webDAVRequest.getPath();
1054    
1055                    String name = StringPool.BLANK;
1056    
1057                    if (appendPath) {
1058                            name = folder.getName();
1059                    }
1060    
1061                    Resource resource = new BaseResourceImpl(
1062                            parentPath, name, folder.getName(), folder.getCreateDate(),
1063                            folder.getModifiedDate());
1064    
1065                    resource.setModel(folder);
1066                    resource.setClassName(Folder.class.getName());
1067                    resource.setPrimaryKey(folder.getPrimaryKey());
1068    
1069                    return resource;
1070            }
1071    
1072            private static Log _log = LogFactoryUtil.getLog(DLWebDAVStorageImpl.class);
1073    
1074    }