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