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