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