001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.imagegallery.webdav;
016    
017    import com.liferay.documentlibrary.DuplicateFileException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.CharPool;
023    import com.liferay.portal.kernel.util.FileUtil;
024    import com.liferay.portal.kernel.util.MimeTypesUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.webdav.BaseResourceImpl;
029    import com.liferay.portal.kernel.webdav.BaseWebDAVStorageImpl;
030    import com.liferay.portal.kernel.webdav.Resource;
031    import com.liferay.portal.kernel.webdav.Status;
032    import com.liferay.portal.kernel.webdav.WebDAVException;
033    import com.liferay.portal.kernel.webdav.WebDAVRequest;
034    import com.liferay.portal.kernel.webdav.WebDAVUtil;
035    import com.liferay.portal.security.auth.PrincipalException;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
038    import com.liferay.portlet.imagegallery.DuplicateFolderNameException;
039    import com.liferay.portlet.imagegallery.NoSuchFolderException;
040    import com.liferay.portlet.imagegallery.NoSuchImageException;
041    import com.liferay.portlet.imagegallery.model.IGFolder;
042    import com.liferay.portlet.imagegallery.model.IGFolderConstants;
043    import com.liferay.portlet.imagegallery.model.IGImage;
044    import com.liferay.portlet.imagegallery.service.IGFolderServiceUtil;
045    import com.liferay.portlet.imagegallery.service.IGImageServiceUtil;
046    
047    import java.io.File;
048    import java.io.InputStream;
049    
050    import java.util.ArrayList;
051    import java.util.List;
052    
053    import javax.servlet.http.HttpServletRequest;
054    import javax.servlet.http.HttpServletResponse;
055    
056    /**
057     * @author Alexander Chow
058     */
059    public class IGWebDAVStorageImpl extends BaseWebDAVStorageImpl {
060    
061            public int copyCollectionResource(
062                            WebDAVRequest webDavRequest, Resource resource, String destination,
063                            boolean overwrite, long depth)
064                    throws WebDAVException {
065    
066                    try {
067                            String[] destinationArray = WebDAVUtil.getPathArray(
068                                    destination, true);
069    
070                            long companyId = webDavRequest.getCompanyId();
071    
072                            long parentFolderId = IGFolderConstants.DEFAULT_PARENT_FOLDER_ID;
073    
074                            try {
075                                    parentFolderId = getParentFolderId(companyId, destinationArray);
076                            }
077                            catch (NoSuchFolderException nsfe) {
078                                    return HttpServletResponse.SC_CONFLICT;
079                            }
080    
081                            IGFolder folder = (IGFolder)resource.getModel();
082    
083                            long groupId = WebDAVUtil.getGroupId(companyId, destination);
084                            String name = WebDAVUtil.getResourceName(destinationArray);
085                            String description = folder.getDescription();
086    
087                            int status = HttpServletResponse.SC_CREATED;
088    
089                            if (overwrite) {
090                                    if (deleteResource(groupId, parentFolderId, name)) {
091                                            status = HttpServletResponse.SC_NO_CONTENT;
092                                    }
093                            }
094    
095                            ServiceContext serviceContext = new ServiceContext();
096    
097                            serviceContext.setAddCommunityPermissions(
098                                    isAddCommunityPermissions(groupId));
099                            serviceContext.setAddGuestPermissions(true);
100                            serviceContext.setScopeGroupId(groupId);
101    
102                            if (depth == 0) {
103                                    IGFolderServiceUtil.addFolder(
104                                            parentFolderId, name, description, serviceContext);
105                            }
106                            else {
107                                    IGFolderServiceUtil.copyFolder(
108                                            folder.getFolderId(), parentFolderId, name, description,
109                                            serviceContext);
110                            }
111    
112                            return status;
113                    }
114                    catch (DuplicateFolderNameException dfne) {
115                            return HttpServletResponse.SC_PRECONDITION_FAILED;
116                    }
117                    catch (PrincipalException pe) {
118                            return HttpServletResponse.SC_FORBIDDEN;
119                    }
120                    catch (Exception e) {
121                            throw new WebDAVException(e);
122                    }
123            }
124    
125            public int copySimpleResource(
126                            WebDAVRequest webDavRequest, Resource resource, String destination,
127                            boolean overwrite)
128                    throws WebDAVException {
129    
130                    File file = null;
131    
132                    try {
133                            String[] destinationArray = WebDAVUtil.getPathArray(
134                                    destination, true);
135    
136                            long companyId = webDavRequest.getCompanyId();
137    
138                            long parentFolderId = IGFolderConstants.DEFAULT_PARENT_FOLDER_ID;
139    
140                            try {
141                                    parentFolderId = getParentFolderId(companyId, destinationArray);
142                            }
143                            catch (NoSuchFolderException nsfe) {
144                                    return HttpServletResponse.SC_CONFLICT;
145                            }
146    
147                            IGImage image = (IGImage)resource.getModel();
148    
149                            long groupId = WebDAVUtil.getGroupId(companyId, destination);
150                            String name = WebDAVUtil.getResourceName(destinationArray);
151                            String description = image.getDescription();
152                            String contentType = MimeTypesUtil.getContentType(
153                                    image.getNameWithExtension());
154    
155                            file = FileUtil.createTempFile(image.getImageType());
156    
157                            InputStream is = resource.getContentAsStream();
158    
159                            FileUtil.write(file, is);
160    
161                            ServiceContext serviceContext = new ServiceContext();
162    
163                            serviceContext.setAddCommunityPermissions(
164                                    isAddCommunityPermissions(groupId));
165                            serviceContext.setAddGuestPermissions(true);
166    
167                            int status = HttpServletResponse.SC_CREATED;
168    
169                            if (overwrite) {
170                                    if (deleteResource(groupId, parentFolderId, name)) {
171                                            status = HttpServletResponse.SC_NO_CONTENT;
172                                    }
173                            }
174    
175                            IGImageServiceUtil.addImage(
176                                    groupId, parentFolderId, name, description, file, contentType,
177                                    serviceContext);
178    
179                            return status;
180                    }
181                    catch (DuplicateFolderNameException dfne) {
182                            return HttpServletResponse.SC_PRECONDITION_FAILED;
183                    }
184                    catch (DuplicateFileException dfe) {
185                            return HttpServletResponse.SC_PRECONDITION_FAILED;
186                    }
187                    catch (PrincipalException pe) {
188                            return HttpServletResponse.SC_FORBIDDEN;
189                    }
190                    catch (Exception e) {
191                            throw new WebDAVException(e);
192                    }
193                    finally {
194                            if (file != null) {
195                                    file.delete();
196                            }
197                    }
198            }
199    
200            public int deleteResource(WebDAVRequest webDavRequest)
201                    throws WebDAVException {
202    
203                    try {
204                            Resource resource = getResource(webDavRequest);
205    
206                            if (resource == null) {
207                                    return HttpServletResponse.SC_NOT_FOUND;
208                            }
209    
210                            Object model = resource.getModel();
211    
212                            if (model instanceof IGFolder) {
213                                    IGFolder folder = (IGFolder)model;
214    
215                                    IGFolderServiceUtil.deleteFolder(folder.getFolderId());
216                            }
217                            else {
218                                    IGImage image = (IGImage)model;
219    
220                                    IGImageServiceUtil.deleteImage(image.getImageId());
221                            }
222    
223                            return HttpServletResponse.SC_NO_CONTENT;
224                    }
225                    catch (PrincipalException pe) {
226                            return HttpServletResponse.SC_FORBIDDEN;
227                    }
228                    catch (Exception e) {
229                            throw new WebDAVException(e);
230                    }
231            }
232    
233            public Resource getResource(WebDAVRequest webDavRequest)
234                    throws WebDAVException {
235    
236                    try {
237                            String[] pathArray = webDavRequest.getPathArray();
238    
239                            long companyId = webDavRequest.getCompanyId();
240                            long parentFolderId = getParentFolderId(companyId, pathArray);
241                            String name = WebDAVUtil.getResourceName(pathArray);
242    
243                            if (Validator.isNull(name)) {
244                                    String path = getRootPath() + webDavRequest.getPath();
245    
246                                    return new BaseResourceImpl(path, StringPool.BLANK, getToken());
247                            }
248    
249                            try {
250                                    IGFolder folder = IGFolderServiceUtil.getFolder(
251                                            webDavRequest.getGroupId(), parentFolderId, name);
252    
253                                    if ((folder.getParentFolderId() != parentFolderId) ||
254                                            (webDavRequest.getGroupId() != folder.getGroupId())) {
255    
256                                            throw new NoSuchFolderException();
257                                    }
258    
259                                    return toResource(webDavRequest, folder, false);
260                            }
261                            catch (NoSuchFolderException nsfe) {
262                                    try {
263                                            long groupId = webDavRequest.getGroupId();
264    
265                                            IGImage image =
266                                                    IGImageServiceUtil.
267                                                            getImageByFolderIdAndNameWithExtension(
268                                                                    groupId, parentFolderId, name);
269    
270                                            return toResource(webDavRequest, image, false);
271                                    }
272                                    catch (NoSuchImageException nsie) {
273                                            return null;
274                                    }
275                            }
276                    }
277                    catch (Exception e) {
278                            throw new WebDAVException(e);
279                    }
280            }
281    
282            public List<Resource> getResources(WebDAVRequest webDavRequest)
283                    throws WebDAVException {
284    
285                    try {
286                            long folderId = getFolderId(
287                                    webDavRequest.getCompanyId(), webDavRequest.getPathArray());
288    
289                            List<Resource> folders = getFolders(webDavRequest, folderId);
290                            List<Resource> images = getImages(webDavRequest, folderId);
291    
292                            List<Resource> resources = new ArrayList<Resource>(
293                                    folders.size() + images.size());
294    
295                            resources.addAll(folders);
296                            resources.addAll(images);
297    
298                            return resources;
299                    }
300                    catch (Exception e) {
301                            throw new WebDAVException(e);
302                    }
303            }
304    
305            public Status makeCollection(WebDAVRequest webDavRequest)
306                    throws WebDAVException {
307    
308                    try {
309                            HttpServletRequest request = webDavRequest.getHttpServletRequest();
310    
311                            if (request.getContentLength() > 0) {
312                                    return new Status(
313                                            HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
314                            }
315    
316                            String[] pathArray = webDavRequest.getPathArray();
317    
318                            long companyId = webDavRequest.getCompanyId();
319                            long groupId = webDavRequest.getGroupId();
320                            long parentFolderId = getParentFolderId(companyId, pathArray);
321                            String name = WebDAVUtil.getResourceName(pathArray);
322                            String description = StringPool.BLANK;
323    
324                            ServiceContext serviceContext = new ServiceContext();
325    
326                            serviceContext.setAddCommunityPermissions(
327                                    isAddCommunityPermissions(groupId));
328                            serviceContext.setAddGuestPermissions(true);
329                            serviceContext.setPlid(getPlid(webDavRequest.getGroupId()));
330                            serviceContext.setScopeGroupId(webDavRequest.getGroupId());
331    
332                            IGFolderServiceUtil.addFolder(
333                                    parentFolderId, name, description, serviceContext);
334    
335                            String location = StringUtil.merge(pathArray, StringPool.SLASH);
336    
337                            return new Status(location, HttpServletResponse.SC_CREATED);
338                    }
339                    catch (DuplicateFolderNameException dfne) {
340                            return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
341                    }
342                    catch (NoSuchFolderException nsfe) {
343                            return new Status(HttpServletResponse.SC_CONFLICT);
344                    }
345                    catch (PrincipalException pe) {
346                            return new Status(HttpServletResponse.SC_FORBIDDEN);
347                    }
348                    catch (Exception e) {
349                            throw new WebDAVException(e);
350                    }
351            }
352    
353            public int moveCollectionResource(
354                            WebDAVRequest webDavRequest, Resource resource, String destination,
355                            boolean overwrite)
356                    throws WebDAVException {
357    
358                    try {
359                            String[] destinationArray = WebDAVUtil.getPathArray(
360                                    destination, true);
361    
362                            IGFolder folder = (IGFolder)resource.getModel();
363    
364                            long companyId = webDavRequest.getCompanyId();
365                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
366                            long folderId = folder.getFolderId();
367                            long parentFolderId = getParentFolderId(
368                                    companyId, destinationArray);
369                            String name = WebDAVUtil.getResourceName(destinationArray);
370                            String description = folder.getDescription();
371    
372                            ServiceContext serviceContext = new ServiceContext();
373    
374                            int status = HttpServletResponse.SC_CREATED;
375    
376                            if (overwrite) {
377                                    if (deleteResource(groupId, parentFolderId, name)) {
378                                            status = HttpServletResponse.SC_NO_CONTENT;
379                                    }
380                            }
381    
382                            IGFolderServiceUtil.updateFolder(
383                                    folderId, parentFolderId, name, description, false,
384                                    serviceContext);
385    
386                            return status;
387                    }
388                    catch (PrincipalException pe) {
389                            return HttpServletResponse.SC_FORBIDDEN;
390                    }
391                    catch (DuplicateFolderNameException dfne) {
392                            return HttpServletResponse.SC_PRECONDITION_FAILED;
393                    }
394                    catch (Exception e) {
395                            throw new WebDAVException(e);
396                    }
397            }
398    
399            public int moveSimpleResource(
400                            WebDAVRequest webDavRequest, Resource resource, String destination,
401                            boolean overwrite)
402                    throws WebDAVException {
403    
404                    try {
405                            String[] destinationArray = WebDAVUtil.getPathArray(
406                                    destination, true);
407    
408                            IGImage image = (IGImage)resource.getModel();
409    
410                            long companyId = webDavRequest.getCompanyId();
411                            long groupId = WebDAVUtil.getGroupId(companyId, destinationArray);
412                            long parentFolderId = getParentFolderId(
413                                    companyId, destinationArray);
414                            String name = WebDAVUtil.getResourceName(destinationArray);
415                            String description = image.getDescription();
416                            File file = null;
417                            String contentType = null;
418    
419                            ServiceContext serviceContext = new ServiceContext();
420    
421                            int status = HttpServletResponse.SC_CREATED;
422    
423                            if (overwrite) {
424                                    if (deleteResource(groupId, parentFolderId, name)) {
425                                            status = HttpServletResponse.SC_NO_CONTENT;
426                                    }
427                            }
428    
429                            IGImageServiceUtil.updateImage(
430                                    image.getImageId(), groupId, parentFolderId, name, description,
431                                    file, contentType, serviceContext);
432    
433                            return status;
434                    }
435                    catch (PrincipalException pe) {
436                            return HttpServletResponse.SC_FORBIDDEN;
437                    }
438                    catch (DuplicateFileException dfe) {
439                            return HttpServletResponse.SC_PRECONDITION_FAILED;
440                    }
441                    catch (DuplicateFolderNameException dfne) {
442                            return HttpServletResponse.SC_PRECONDITION_FAILED;
443                    }
444                    catch (Exception e) {
445                            throw new WebDAVException(e);
446                    }
447            }
448    
449            public int putResource(WebDAVRequest webDavRequest) throws WebDAVException {
450                    File file = null;
451    
452                    try {
453                            HttpServletRequest request = webDavRequest.getHttpServletRequest();
454    
455                            String[] pathArray = webDavRequest.getPathArray();
456    
457                            long companyId = webDavRequest.getCompanyId();
458                            long groupId = webDavRequest.getGroupId();
459                            long parentFolderId = getParentFolderId(companyId, pathArray);
460                            String name = WebDAVUtil.getResourceName(pathArray);
461                            String description = StringPool.BLANK;
462    
463                            file = FileUtil.createTempFile(FileUtil.getExtension(name));
464    
465                            FileUtil.write(file, request.getInputStream());
466    
467                            String contentType = MimeTypesUtil.getContentType(name);
468    
469                            ServiceContext serviceContext = new ServiceContext();
470    
471                            serviceContext.setAddCommunityPermissions(
472                                    isAddCommunityPermissions(groupId));
473                            serviceContext.setAddGuestPermissions(true);
474    
475                            try {
476                                    IGImage image =
477                                            IGImageServiceUtil.getImageByFolderIdAndNameWithExtension(
478                                                    groupId, parentFolderId, name);
479    
480                                    long imageId = image.getImageId();
481    
482                                    description = image.getDescription();
483    
484                                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
485                                            IGImage.class.getName(), imageId);
486    
487                                    serviceContext.setAssetTagNames(assetTagNames);
488    
489                                    IGImageServiceUtil.updateImage(
490                                            imageId, groupId, parentFolderId, name, description, file,
491                                            contentType, serviceContext);
492                            }
493                            catch (NoSuchImageException nsie) {
494                                    IGImageServiceUtil.addImage(
495                                            groupId, parentFolderId, name, description, file,
496                                            contentType, serviceContext);
497                            }
498    
499                            return HttpServletResponse.SC_CREATED;
500                    }
501                    catch (PrincipalException pe) {
502                            return HttpServletResponse.SC_FORBIDDEN;
503                    }
504                    catch (PortalException pe) {
505                            if (_log.isWarnEnabled()) {
506                                    _log.warn(pe, pe);
507                            }
508    
509                            return HttpServletResponse.SC_CONFLICT;
510                    }
511                    catch (Exception e) {
512                            throw new WebDAVException(e);
513                    }
514                    finally {
515                            if (file != null) {
516                                    file.delete();
517                            }
518                    }
519            }
520    
521            protected boolean deleteResource(
522                            long groupId, long parentFolderId, String name)
523                    throws PortalException, SystemException {
524    
525                    try {
526                            IGFolder folder = IGFolderServiceUtil.getFolder(
527                                    groupId, parentFolderId, name);
528    
529                            IGFolderServiceUtil.deleteFolder(folder.getFolderId());
530    
531                            return true;
532                    }
533                    catch (NoSuchFolderException nsfe) {
534                            if (name.indexOf(CharPool.PERIOD) == -1) {
535                                    return false;
536                            }
537    
538                            try {
539                                    IGImageServiceUtil.deleteImageByFolderIdAndNameWithExtension(
540                                            groupId, parentFolderId, name);
541    
542                                    return true;
543                            }
544                            catch (NoSuchImageException nsie) {
545                            }
546                    }
547    
548                    return false;
549            }
550    
551            protected List<Resource> getFolders(
552                            WebDAVRequest webDavRequest, long parentFolderId)
553                    throws Exception {
554    
555                    List<Resource> resources = new ArrayList<Resource>();
556    
557                    long groupId = webDavRequest.getGroupId();
558    
559                    List<IGFolder> folders = IGFolderServiceUtil.getFolders(
560                            groupId, parentFolderId);
561    
562                    for (IGFolder folder : folders) {
563                            Resource resource = toResource(webDavRequest, folder, true);
564    
565                            resources.add(resource);
566                    }
567    
568                    return resources;
569            }
570    
571            protected List<Resource> getImages(
572                            WebDAVRequest webDavRequest, long parentFolderId)
573                    throws Exception {
574    
575                    long groupId = webDavRequest.getGroupId();
576    
577                    List<Resource> resources = new ArrayList<Resource>();
578    
579                    List<IGImage> images = IGImageServiceUtil.getImages(
580                            groupId, parentFolderId);
581    
582                    for (IGImage image : images) {
583                            Resource resource = toResource(webDavRequest, image, true);
584    
585                            resources.add(resource);
586                    }
587    
588                    return resources;
589            }
590    
591            protected long getFolderId(long companyId, String[] pathArray)
592                    throws Exception {
593    
594                    return getFolderId(companyId, pathArray, false);
595            }
596    
597            protected long getFolderId(
598                            long companyId, String[] pathArray, boolean parent)
599                    throws Exception {
600    
601                    long folderId = IGFolderConstants.DEFAULT_PARENT_FOLDER_ID;
602    
603                    if (pathArray.length <= 1) {
604                            return folderId;
605                    }
606                    else {
607                            long groupId = WebDAVUtil.getGroupId(companyId, pathArray);
608    
609                            int x = pathArray.length;
610    
611                            if (parent) {
612                                    x--;
613                            }
614    
615                            for (int i = 2; i < x; i++) {
616                                    String name = pathArray[i];
617    
618                                    IGFolder folder = IGFolderServiceUtil.getFolder(
619                                            groupId, folderId, name);
620    
621                                    if (groupId == folder.getGroupId()) {
622                                            folderId = folder.getFolderId();
623                                    }
624                            }
625                    }
626    
627                    return folderId;
628            }
629    
630            protected long getParentFolderId(long companyId, String[] pathArray)
631                    throws Exception {
632    
633                    return getFolderId(companyId, pathArray, true);
634            }
635    
636            protected Resource toResource(
637                    WebDAVRequest webDavRequest, IGImage image, boolean appendPath) {
638    
639                    String parentPath = getRootPath() + webDavRequest.getPath();
640                    String name = StringPool.BLANK;
641    
642                    if (appendPath) {
643                            name = image.getNameWithExtension();
644                    }
645    
646                    return new IGImageResourceImpl(image, parentPath, name);
647            }
648    
649            protected Resource toResource(
650                    WebDAVRequest webDavRequest, IGFolder folder, boolean appendPath) {
651    
652                    String parentPath = getRootPath() + webDavRequest.getPath();
653                    String name = StringPool.BLANK;
654    
655                    if (appendPath) {
656                            name = folder.getName();
657                    }
658    
659                    Resource resource = new BaseResourceImpl(
660                            parentPath, name, folder.getName(), folder.getCreateDate(),
661                            folder.getModifiedDate());
662    
663                    resource.setModel(folder);
664                    resource.setClassName(IGFolder.class.getName());
665                    resource.setPrimaryKey(folder.getPrimaryKey());
666    
667                    return resource;
668            }
669    
670            private static Log _log = LogFactoryUtil.getLog(IGWebDAVStorageImpl.class);
671    
672    }