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