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