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