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            @Override
272            public Resource getResource(WebDAVRequest webDAVRequest)
273                    throws WebDAVException {
274    
275                    try {
276                            String[] pathArray = webDAVRequest.getPathArray();
277    
278                            long companyId = webDAVRequest.getCompanyId();
279                            long parentFolderId = getParentFolderId(companyId, pathArray);
280                            String name = WebDAVUtil.getResourceName(pathArray);
281    
282                            if (Validator.isNull(name)) {
283                                    String path = getRootPath() + webDAVRequest.getPath();
284    
285                                    return new BaseResourceImpl(path, StringPool.BLANK, getToken());
286                            }
287    
288                            try {
289                                    Folder folder = DLAppServiceUtil.getFolder(
290                                            webDAVRequest.getGroupId(), parentFolderId, name);
291    
292                                    if ((folder.getParentFolderId() != parentFolderId) ||
293                                            (webDAVRequest.getGroupId() != folder.getRepositoryId())) {
294    
295                                            throw new NoSuchFolderException();
296                                    }
297    
298                                    return toResource(webDAVRequest, folder, false);
299                            }
300                            catch (NoSuchFolderException nsfe) {
301                                    try {
302                                            String titleWithExtension = name;
303    
304                                            FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
305                                                    webDAVRequest.getGroupId(), parentFolderId,
306                                                    titleWithExtension);
307    
308                                            return toResource(webDAVRequest, fileEntry, false);
309                                    }
310                                    catch (NoSuchFileEntryException nsfee) {
311                                            return null;
312                                    }
313                            }
314                    }
315                    catch (Exception e) {
316                            throw new WebDAVException(e);
317                    }
318            }
319    
320            @Override
321            public List<Resource> getResources(WebDAVRequest webDAVRequest)
322                    throws WebDAVException {
323    
324                    try {
325                            long folderId = getFolderId(
326                                    webDAVRequest.getCompanyId(), webDAVRequest.getPathArray());
327    
328                            List<Resource> folders = getFolders(webDAVRequest, folderId);
329                            List<Resource> fileEntries = getFileEntries(
330                                    webDAVRequest, folderId);
331    
332                            List<Resource> resources = new ArrayList<Resource>(
333                                    folders.size() + fileEntries.size());
334    
335                            resources.addAll(folders);
336                            resources.addAll(fileEntries);
337    
338                            return resources;
339                    }
340                    catch (Exception e) {
341                            throw new WebDAVException(e);
342                    }
343            }
344    
345            @Override
346            public boolean isSupportsClassTwo() {
347                    return true;
348            }
349    
350            @Override
351            public Status lockResource(
352                            WebDAVRequest webDAVRequest, String owner, long timeout)
353                    throws WebDAVException {
354    
355                    Resource resource = getResource(webDAVRequest);
356    
357                    Lock lock = null;
358                    int status = HttpServletResponse.SC_OK;
359    
360                    try {
361                            if (resource == null) {
362                                    status = HttpServletResponse.SC_CREATED;
363    
364                                    HttpServletRequest request =
365                                            webDAVRequest.getHttpServletRequest();
366    
367                                    String[] pathArray = webDAVRequest.getPathArray();
368    
369                                    long companyId = webDAVRequest.getCompanyId();
370                                    long groupId = webDAVRequest.getGroupId();
371                                    long parentFolderId = getParentFolderId(companyId, pathArray);
372                                    String title = WebDAVUtil.getResourceName(pathArray);
373                                    String extension = FileUtil.getExtension(title);
374    
375                                    String contentType = getContentType(
376                                            request, null, title, extension);
377    
378                                    String description = StringPool.BLANK;
379                                    String changeLog = StringPool.BLANK;
380    
381                                    File file = FileUtil.createTempFile(extension);
382    
383                                    file.createNewFile();
384    
385                                    ServiceContext serviceContext = new ServiceContext();
386    
387                                    serviceContext.setAddGroupPermissions(
388                                            isAddGroupPermissions(groupId));
389                                    serviceContext.setAddGuestPermissions(true);
390    
391                                    FileEntry fileEntry = DLAppServiceUtil.addFileEntry(
392                                            groupId, parentFolderId, title, contentType, title,
393                                            description, changeLog, file, serviceContext);
394    
395                                    resource = toResource(webDAVRequest, fileEntry, false);
396                            }
397    
398                            if (resource instanceof DLFileEntryResourceImpl) {
399                                    FileEntry fileEntry = (FileEntry)resource.getModel();
400    
401                                    ServiceContext serviceContext = new ServiceContext();
402    
403                                    serviceContext.setAttribute(
404                                            DL.MANUAL_CHECK_IN_REQUIRED,
405                                            webDAVRequest.isManualCheckInRequired());
406    
407                                    DLAppServiceUtil.checkOutFileEntry(
408                                            fileEntry.getFileEntryId(), owner, timeout, serviceContext);
409    
410                                    lock = fileEntry.getLock();
411                            }
412                            else {
413                                    boolean inheritable = false;
414    
415                                    long depth = WebDAVUtil.getDepth(
416                                            webDAVRequest.getHttpServletRequest());
417    
418                                    if (depth != 0) {
419                                            inheritable = true;
420                                    }
421    
422                                    Folder folder = (Folder)resource.getModel();
423    
424                                    lock = DLAppServiceUtil.lockFolder(
425                                            folder.getRepositoryId(), folder.getFolderId(), owner,
426                                            inheritable, timeout);
427                            }
428                    }
429                    catch (Exception e) {
430    
431                            // DuplicateLock is 423 not 501
432    
433                            if (!(e instanceof DuplicateLockException)) {
434                                    throw new WebDAVException(e);
435                            }
436    
437                            status = WebDAVUtil.SC_LOCKED;
438                    }
439    
440                    return new Status(lock, status);
441            }
442    
443            @Override
444            public Status makeCollection(WebDAVRequest webDAVRequest)
445                    throws WebDAVException {
446    
447                    try {
448                            HttpServletRequest request = webDAVRequest.getHttpServletRequest();
449    
450                            if (request.getContentLength() > 0) {
451                                    return new Status(
452                                            HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
453                            }
454    
455                            String[] pathArray = webDAVRequest.getPathArray();
456    
457                            long companyId = webDAVRequest.getCompanyId();
458                            long groupId = webDAVRequest.getGroupId();
459                            long parentFolderId = getParentFolderId(companyId, pathArray);
460                            String name = WebDAVUtil.getResourceName(pathArray);
461                            String description = StringPool.BLANK;
462    
463                            ServiceContext serviceContext = new ServiceContext();
464    
465                            serviceContext.setAddGroupPermissions(
466                                    isAddGroupPermissions(groupId));
467                            serviceContext.setAddGuestPermissions(true);
468    
469                            DLAppServiceUtil.addFolder(
470                                    groupId, parentFolderId, name, description, serviceContext);
471    
472                            String location = StringUtil.merge(pathArray, StringPool.SLASH);
473    
474                            return new Status(location, HttpServletResponse.SC_CREATED);
475                    }
476                    catch (DuplicateFolderNameException dfne) {
477                            return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
478                    }
479                    catch (DuplicateFileException dfe) {
480                            return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
481                    }
482                    catch (NoSuchFolderException nsfe) {
483                            return new Status(HttpServletResponse.SC_CONFLICT);
484                    }
485                    catch (PrincipalException pe) {
486                            return new Status(HttpServletResponse.SC_FORBIDDEN);
487                    }
488                    catch (Exception e) {
489                            throw new WebDAVException(e);
490                    }
491            }
492    
493            @Override
494            public int moveCollectionResource(
495                            WebDAVRequest webDAVRequest, Resource resource, String destination,
496                            boolean overwrite)
497                    throws WebDAVException {
498    
499                    try {
500                            String[] destinationArray = WebDAVUtil.getPathArray(
501                                    destination, true);
502    
503                            Folder folder = (Folder)resource.getModel();
504    
505                            long companyId = webDAVRequest.getCompanyId();
506                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
507                            long folderId = folder.getFolderId();
508                            long parentFolderId = getParentFolderId(
509                                    companyId, destinationArray);
510                            String name = WebDAVUtil.getResourceName(destinationArray);
511                            String description = folder.getDescription();
512    
513                            ServiceContext serviceContext = new ServiceContext();
514    
515                            serviceContext.setUserId(webDAVRequest.getUserId());
516    
517                            int status = HttpServletResponse.SC_CREATED;
518    
519                            if (overwrite) {
520                                    if (deleteResource(
521                                                    groupId, parentFolderId, name,
522                                                    webDAVRequest.getLockUuid())) {
523    
524                                            status = HttpServletResponse.SC_NO_CONTENT;
525                                    }
526                            }
527    
528                            if (parentFolderId != folder.getParentFolderId()) {
529                                    DLAppServiceUtil.moveFolder(
530                                            folderId, parentFolderId, serviceContext);
531                            }
532    
533                            if (!name.equals(folder.getName())) {
534                                    DLAppServiceUtil.updateFolder(
535                                            folderId, name, description, serviceContext);
536                            }
537    
538                            return status;
539                    }
540                    catch (PrincipalException pe) {
541                            return HttpServletResponse.SC_FORBIDDEN;
542                    }
543                    catch (DuplicateFolderNameException dfne) {
544                            return HttpServletResponse.SC_PRECONDITION_FAILED;
545                    }
546                    catch (Exception e) {
547                            throw new WebDAVException(e);
548                    }
549            }
550    
551            @Override
552            public int moveSimpleResource(
553                            WebDAVRequest webDAVRequest, Resource resource, String destination,
554                            boolean overwrite)
555                    throws WebDAVException {
556    
557                    File file = null;
558    
559                    try {
560                            String[] destinationArray = WebDAVUtil.getPathArray(
561                                    destination, true);
562    
563                            FileEntry fileEntry = (FileEntry)resource.getModel();
564    
565                            if (!hasLock(fileEntry, webDAVRequest.getLockUuid()) &&
566                                    (fileEntry.getLock() != null)) {
567    
568                                    return WebDAVUtil.SC_LOCKED;
569                            }
570    
571                            long companyId = webDAVRequest.getCompanyId();
572                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
573                            long newParentFolderId = getParentFolderId(
574                                    companyId, destinationArray);
575                            String sourceFileName = WebDAVUtil.getResourceName(
576                                    destinationArray);
577                            String title = WebDAVUtil.getResourceName(destinationArray);
578                            String description = fileEntry.getDescription();
579                            String changeLog = StringPool.BLANK;
580    
581                            ServiceContext serviceContext = new ServiceContext();
582    
583                            populateServiceContext(serviceContext, fileEntry);
584    
585                            int status = HttpServletResponse.SC_CREATED;
586    
587                            if (overwrite) {
588                                    if (deleteResource(
589                                                    groupId, newParentFolderId, title,
590                                                    webDAVRequest.getLockUuid())) {
591    
592                                            status = HttpServletResponse.SC_NO_CONTENT;
593                                    }
594                            }
595    
596                            // LPS-5415
597    
598                            if (webDAVRequest.isMac()) {
599                                    try {
600                                            FileEntry destFileEntry = DLAppServiceUtil.getFileEntry(
601                                                    groupId, newParentFolderId, title);
602    
603                                            InputStream is = fileEntry.getContentStream();
604    
605                                            file = FileUtil.createTempFile(is);
606    
607                                            DLAppServiceUtil.updateFileEntry(
608                                                    destFileEntry.getFileEntryId(),
609                                                    destFileEntry.getTitle(), destFileEntry.getMimeType(),
610                                                    destFileEntry.getTitle(),
611                                                    destFileEntry.getDescription(), changeLog, false, file,
612                                                    serviceContext);
613    
614                                            DLAppServiceUtil.deleteFileEntry(
615                                                    fileEntry.getFileEntryId());
616    
617                                            return status;
618                                    }
619                                    catch (NoSuchFileEntryException nsfee) {
620                                    }
621                            }
622    
623                            DLAppServiceUtil.updateFileEntry(
624                                    fileEntry.getFileEntryId(), sourceFileName,
625                                    fileEntry.getMimeType(), title, description, changeLog, false,
626                                    file, serviceContext);
627    
628                            if (fileEntry.getFolderId() != newParentFolderId) {
629                                    fileEntry = DLAppServiceUtil.moveFileEntry(
630                                            fileEntry.getFileEntryId(), newParentFolderId,
631                                            serviceContext);
632                            }
633    
634                            return status;
635                    }
636                    catch (PrincipalException pe) {
637                            return HttpServletResponse.SC_FORBIDDEN;
638                    }
639                    catch (DuplicateFileException dfe) {
640                            return HttpServletResponse.SC_PRECONDITION_FAILED;
641                    }
642                    catch (DuplicateFolderNameException dfne) {
643                            return HttpServletResponse.SC_PRECONDITION_FAILED;
644                    }
645                    catch (LockException le) {
646                            return WebDAVUtil.SC_LOCKED;
647                    }
648                    catch (Exception e) {
649                            throw new WebDAVException(e);
650                    }
651                    finally {
652                            FileUtil.delete(file);
653                    }
654            }
655    
656            @Override
657            public int putResource(WebDAVRequest webDAVRequest) throws WebDAVException {
658                    File file = null;
659    
660                    try {
661                            HttpServletRequest request = webDAVRequest.getHttpServletRequest();
662    
663                            String[] pathArray = webDAVRequest.getPathArray();
664    
665                            long companyId = webDAVRequest.getCompanyId();
666                            long groupId = webDAVRequest.getGroupId();
667                            long parentFolderId = getParentFolderId(companyId, pathArray);
668                            String title = WebDAVUtil.getResourceName(pathArray);
669                            String description = StringPool.BLANK;
670                            String changeLog = StringPool.BLANK;
671    
672                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
673                                    request);
674    
675                            serviceContext.setAddGroupPermissions(
676                                    isAddGroupPermissions(groupId));
677                            serviceContext.setAddGuestPermissions(true);
678    
679                            String extension = FileUtil.getExtension(title);
680    
681                            file = FileUtil.createTempFile(extension);
682    
683                            FileUtil.write(file, request.getInputStream());
684    
685                            String contentType = getContentType(
686                                    request, file, title, extension);
687    
688                            try {
689                                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
690                                            groupId, parentFolderId, title);
691    
692                                    if (!hasLock(fileEntry, webDAVRequest.getLockUuid()) &&
693                                            (fileEntry.getLock() != null)) {
694    
695                                            return WebDAVUtil.SC_LOCKED;
696                                    }
697    
698                                    long fileEntryId = fileEntry.getFileEntryId();
699    
700                                    description = fileEntry.getDescription();
701    
702                                    populateServiceContext(serviceContext, fileEntry);
703    
704                                    DLAppServiceUtil.updateFileEntry(
705                                            fileEntryId, title, contentType, title, description,
706                                            changeLog, false, file, serviceContext);
707                            }
708                            catch (NoSuchFileEntryException nsfee) {
709                                    DLAppServiceUtil.addFileEntry(
710                                            groupId, parentFolderId, title, contentType, title,
711                                            description, changeLog, file, serviceContext);
712                            }
713    
714                            if (_log.isInfoEnabled()) {
715                                    _log.info(
716                                            "Added " + StringUtil.merge(pathArray, StringPool.SLASH));
717                            }
718    
719                            return HttpServletResponse.SC_CREATED;
720                    }
721                    catch (PrincipalException pe) {
722                            return HttpServletResponse.SC_FORBIDDEN;
723                    }
724                    catch (NoSuchFolderException nsfe) {
725                            return HttpServletResponse.SC_CONFLICT;
726                    }
727                    catch (PortalException pe) {
728                            if (_log.isWarnEnabled()) {
729                                    _log.warn(pe, pe);
730                            }
731    
732                            return HttpServletResponse.SC_CONFLICT;
733                    }
734                    catch (Exception e) {
735                            throw new WebDAVException(e);
736                    }
737                    finally {
738                            FileUtil.delete(file);
739                    }
740            }
741    
742            @Override
743            public Lock refreshResourceLock(
744                            WebDAVRequest webDAVRequest, String uuid, long timeout)
745                    throws WebDAVException {
746    
747                    Resource resource = getResource(webDAVRequest);
748    
749                    long companyId = webDAVRequest.getCompanyId();
750    
751                    Lock lock = null;
752    
753                    try {
754                            if (resource instanceof DLFileEntryResourceImpl) {
755                                    lock = DLAppServiceUtil.refreshFileEntryLock(
756                                            uuid, companyId, timeout);
757                            }
758                            else {
759                                    lock = DLAppServiceUtil.refreshFolderLock(
760                                            uuid, companyId, timeout);
761                            }
762                    }
763                    catch (Exception e) {
764                            throw new WebDAVException(e);
765                    }
766    
767                    return lock;
768            }
769    
770            @Override
771            public boolean unlockResource(WebDAVRequest webDAVRequest, String token)
772                    throws WebDAVException {
773    
774                    Resource resource = getResource(webDAVRequest);
775    
776                    try {
777                            if (resource instanceof DLFileEntryResourceImpl) {
778                                    FileEntry fileEntry = (FileEntry)resource.getModel();
779    
780                                    // Do not allow WebDAV to check in a file entry if it requires a
781                                    // manual check in
782    
783                                    if (fileEntry.isManualCheckInRequired()) {
784                                            return false;
785                                    }
786    
787                                    ServiceContext serviceContext = new ServiceContext();
788    
789                                    serviceContext.setAttribute(DL.WEBDAV_CHECK_IN_MODE, true);
790    
791                                    DLAppServiceUtil.checkInFileEntry(
792                                            fileEntry.getFileEntryId(), token, serviceContext);
793    
794                                    if (webDAVRequest.isAppleDoubleRequest()) {
795                                            DLAppServiceUtil.deleteFileEntry(
796                                                    fileEntry.getFileEntryId());
797                                    }
798                            }
799                            else {
800                                    Folder folder = (Folder)resource.getModel();
801    
802                                    DLAppServiceUtil.unlockFolder(
803                                            folder.getRepositoryId(), folder.getParentFolderId(),
804                                            folder.getName(), token);
805                            }
806    
807                            return true;
808                    }
809                    catch (Exception e) {
810                            if (e instanceof InvalidLockException) {
811                                    if (_log.isWarnEnabled()) {
812                                            _log.warn(e.getMessage());
813                                    }
814                            }
815                            else {
816                                    if (_log.isWarnEnabled()) {
817                                            _log.warn("Unable to unlock file entry", e);
818                                    }
819                            }
820                    }
821    
822                    return false;
823            }
824    
825            protected boolean deleteResource(
826                            long groupId, long parentFolderId, String name, String lockUuid)
827                    throws Exception {
828    
829                    try {
830                            Folder folder = DLAppServiceUtil.getFolder(
831                                    groupId, parentFolderId, name);
832    
833                            DLAppServiceUtil.deleteFolder(folder.getFolderId());
834    
835                            return true;
836                    }
837                    catch (NoSuchFolderException nsfe) {
838                            try {
839                                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
840                                            groupId, parentFolderId, name);
841    
842                                    if (!hasLock(fileEntry, lockUuid) &&
843                                            (fileEntry.getLock() != null)) {
844    
845                                            throw new LockException();
846                                    }
847    
848                                    DLAppServiceUtil.deleteFileEntryByTitle(
849                                            groupId, parentFolderId, name);
850    
851                                    return true;
852                            }
853                            catch (NoSuchFileEntryException nsfee) {
854                            }
855                    }
856    
857                    return false;
858            }
859    
860            protected String getContentType(
861                    HttpServletRequest request, File file, String title, String extension) {
862    
863                    String contentType = GetterUtil.getString(
864                            request.getHeader(HttpHeaders.CONTENT_TYPE),
865                            ContentTypes.APPLICATION_OCTET_STREAM);
866    
867                    if (contentType.equals(ContentTypes.APPLICATION_OCTET_STREAM) ||
868                            contentType.equals(MS_OFFICE_2010_TEXT_XML_UTF8)) {
869    
870                            contentType = MimeTypesUtil.getContentType(file, title);
871                    }
872    
873                    return contentType;
874            }
875    
876            protected List<Resource> getFileEntries(
877                            WebDAVRequest webDAVRequest, long parentFolderId)
878                    throws Exception {
879    
880                    List<Resource> resources = new ArrayList<Resource>();
881    
882                    List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(
883                            webDAVRequest.getGroupId(), parentFolderId);
884    
885                    for (FileEntry fileEntry : fileEntries) {
886                            Resource resource = toResource(webDAVRequest, fileEntry, true);
887    
888                            resources.add(resource);
889                    }
890    
891                    return resources;
892            }
893    
894            protected long getFolderId(long companyId, String[] pathArray)
895                    throws Exception {
896    
897                    return getFolderId(companyId, pathArray, false);
898            }
899    
900            protected long getFolderId(
901                            long companyId, String[] pathArray, boolean parent)
902                    throws Exception {
903    
904                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
905    
906                    if (pathArray.length <= 1) {
907                            return folderId;
908                    }
909    
910                    long groupId = WebDAVUtil.getGroupId(companyId, pathArray);
911    
912                    int x = pathArray.length;
913    
914                    if (parent) {
915                            x--;
916                    }
917    
918                    for (int i = 2; i < x; i++) {
919                            String name = pathArray[i];
920    
921                            Folder folder = DLAppServiceUtil.getFolder(groupId, folderId, name);
922    
923                            if (groupId == folder.getRepositoryId()) {
924                                    folderId = folder.getFolderId();
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    }