001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.webdav;
029
030import org.opencms.file.CmsResource;
031import org.opencms.file.CmsVfsResourceNotFoundException;
032import org.opencms.i18n.CmsMessageContainer;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.repository.CmsPropertyName;
036import org.opencms.repository.I_CmsRepositoryItem;
037import org.opencms.repository.I_CmsRepositorySession;
038import org.opencms.security.CmsPermissionViolationException;
039import org.opencms.util.CmsFileUtil;
040import org.opencms.util.CmsStringUtil;
041
042import java.io.IOException;
043import java.io.InputStream;
044import java.io.OutputStream;
045import java.util.ArrayList;
046import java.util.Arrays;
047import java.util.Date;
048import java.util.HashMap;
049import java.util.List;
050import java.util.Map;
051import java.util.Optional;
052import java.util.TreeSet;
053import java.util.stream.Collectors;
054
055import javax.servlet.http.HttpServletResponse;
056
057import org.apache.commons.logging.Log;
058import org.apache.jackrabbit.webdav.DavCompliance;
059import org.apache.jackrabbit.webdav.DavException;
060import org.apache.jackrabbit.webdav.DavMethods;
061import org.apache.jackrabbit.webdav.DavResource;
062import org.apache.jackrabbit.webdav.DavResourceFactory;
063import org.apache.jackrabbit.webdav.DavResourceIterator;
064import org.apache.jackrabbit.webdav.DavResourceIteratorImpl;
065import org.apache.jackrabbit.webdav.DavResourceLocator;
066import org.apache.jackrabbit.webdav.DavServletResponse;
067import org.apache.jackrabbit.webdav.DavSession;
068import org.apache.jackrabbit.webdav.MultiStatusResponse;
069import org.apache.jackrabbit.webdav.io.InputContext;
070import org.apache.jackrabbit.webdav.io.OutputContext;
071import org.apache.jackrabbit.webdav.lock.ActiveLock;
072import org.apache.jackrabbit.webdav.lock.LockInfo;
073import org.apache.jackrabbit.webdav.lock.LockManager;
074import org.apache.jackrabbit.webdav.lock.Scope;
075import org.apache.jackrabbit.webdav.lock.Type;
076import org.apache.jackrabbit.webdav.property.DavProperty;
077import org.apache.jackrabbit.webdav.property.DavPropertyName;
078import org.apache.jackrabbit.webdav.property.DavPropertySet;
079import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
080import org.apache.jackrabbit.webdav.property.PropEntry;
081import org.apache.jackrabbit.webdav.property.ResourceType;
082import org.apache.jackrabbit.webdav.xml.Namespace;
083
084/**
085 * Represents a resource in the WebDav repository (may not actually correspond to an actual OpenCms resource, since
086 * DavResource are also created for the target locations for move/copy operations, before any of the moving / copying happens.
087 */
088public class CmsDavResource implements DavResource {
089
090    /** Logger instance for this class. **/
091    private static final Log LOG = CmsLog.getLog(CmsDavResource.class);
092
093    /** The resource factory that produced this resource. */
094    private CmsDavResourceFactory m_factory;
095
096    /** The resource locator for this resource. */
097    private DavResourceLocator m_locator;
098
099    /** The Webdav session object. */
100    private CmsDavSession m_session;
101
102    /** Lazily initialized repository item - null means not initialized, Optional.empty means tried to load resource, but it was not found. */
103    private Optional<I_CmsRepositoryItem> m_item;
104
105    /** The lock manager. */
106    private LockManager m_lockManager;
107
108    /**
109     * Creates a new instance.
110     *
111     * @param loc the locator for this resource
112     * @param factory the factory that produced this resource
113     * @param session the Webdav session
114     * @param lockManager the lock manager
115     */
116    public CmsDavResource(
117        DavResourceLocator loc,
118        CmsDavResourceFactory factory,
119        CmsDavSession session,
120        LockManager lockManager) {
121
122        m_factory = factory;
123        m_locator = loc;
124        m_session = session;
125        m_lockManager = lockManager;
126    }
127
128    /**
129     * @see org.apache.jackrabbit.webdav.DavResource#addLockManager(org.apache.jackrabbit.webdav.lock.LockManager)
130     */
131    public void addLockManager(LockManager lockmgr) {
132
133        m_lockManager = lockmgr;
134    }
135
136    /**
137     * @see org.apache.jackrabbit.webdav.DavResource#addMember(org.apache.jackrabbit.webdav.DavResource, org.apache.jackrabbit.webdav.io.InputContext)
138     */
139    public void addMember(DavResource dres, InputContext inputContext) throws DavException {
140
141        I_CmsRepositorySession session = getRepositorySession();
142        String childPath = ((CmsDavResource)dres).getCmsPath();
143        String method = ((CmsDavInputContext)inputContext).getMethod();
144        InputStream stream = inputContext.getInputStream();
145        if (method.equals(DavMethods.METHOD_MKCOL) && (stream != null)) {
146            throw new DavException(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
147        }
148        if (dres.exists() && isLocked(dres)) {
149            throw new DavException(DavServletResponse.SC_LOCKED);
150        }
151        try {
152            if (stream != null) {
153                session.save(childPath, stream, true);
154            } else {
155                session.create(childPath);
156            }
157        } catch (CmsException e) {
158            LOG.error(e.getLocalizedMessage(), e);
159            throw new DavException(CmsDavUtil.getStatusForException(e), e);
160        } catch (Exception e) {
161            throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
162        }
163
164    }
165
166    /**
167     * @see org.apache.jackrabbit.webdav.DavResource#alterProperties(java.util.List)
168     */
169    public MultiStatusResponse alterProperties(List<? extends PropEntry> changeList) throws DavException {
170
171        if (exists() && isLocked(this)) {
172            throw new DavException(DavServletResponse.SC_LOCKED);
173        }
174
175        MultiStatusResponse res = new MultiStatusResponse(getHref(), null);
176        Map<CmsPropertyName, String> propMap = new HashMap<>();
177        for (PropEntry entry : changeList) {
178            if (entry instanceof DefaultDavProperty<?>) {
179                DefaultDavProperty<String> prop = (DefaultDavProperty<String>)entry;
180                CmsPropertyName cmsPropName = new CmsPropertyName(
181                    prop.getName().getNamespace().getURI(),
182                    prop.getName().getName());
183                propMap.put(cmsPropName, prop.getValue());
184            } else if (entry instanceof DavPropertyName) {
185                CmsPropertyName cmsPropName = new CmsPropertyName(
186                    ((DavPropertyName)entry).getNamespace().getURI(),
187                    ((DavPropertyName)entry).getName());
188                propMap.put(cmsPropName, "");
189
190            }
191        }
192        int status = HttpServletResponse.SC_OK;
193        try {
194            getRepositorySession().updateProperties(getCmsPath(), propMap);
195        } catch (CmsException e) {
196            LOG.warn(e.getLocalizedMessage(), e);
197            if (e instanceof CmsPermissionViolationException) {
198                status = HttpServletResponse.SC_FORBIDDEN;
199            }
200        }
201        for (PropEntry entry : changeList) {
202            if (entry instanceof DavPropertyName) {
203                res.add((DavPropertyName)entry, status);
204            } else if (entry instanceof DefaultDavProperty<?>) {
205                res.add((DavProperty)entry, status);
206            } else {
207                res.add((DavPropertyName)entry, HttpServletResponse.SC_FORBIDDEN);
208            }
209        }
210        return res;
211    }
212
213    /**
214     * @see org.apache.jackrabbit.webdav.DavResource#copy(org.apache.jackrabbit.webdav.DavResource, boolean)
215     */
216    public void copy(DavResource dres, boolean shallow) throws DavException {
217
218        CmsDavResource other = (CmsDavResource)dres;
219        boolean targetParentExists = false;
220        try {
221            targetParentExists = dres.getCollection().exists();
222        } catch (Exception e) {
223            LOG.warn(e.getLocalizedMessage(), e);
224        }
225        if (!targetParentExists) {
226            throw new DavException(HttpServletResponse.SC_CONFLICT);
227        }
228
229        try {
230            getRepositorySession().copy(getCmsPath(), other.getCmsPath(), true, shallow);
231        } catch (CmsException e) {
232            LOG.error(e.getLocalizedMessage(), e);
233            throw new DavException(CmsDavUtil.getStatusForException(e));
234        }
235    }
236
237    /**
238     * Deletes the resource.
239     *
240     * @throws DavException if an error occurs
241     */
242    public void delete() throws DavException {
243
244        if (!exists()) {
245            throw new DavException(HttpServletResponse.SC_NOT_FOUND);
246        }
247        try {
248            getRepositorySession().delete(getCmsPath());
249        } catch (CmsException e) {
250            LOG.error(e.getLocalizedMessage(), e);
251            throw new DavException(CmsDavUtil.getStatusForException(e), e);
252        }
253
254    }
255
256    /**
257     * @see org.apache.jackrabbit.webdav.DavResource#exists()
258     */
259    public boolean exists() {
260
261        return getItem() != null;
262
263    }
264
265    /**
266     * @see org.apache.jackrabbit.webdav.DavResource#getCollection()
267     */
268    public DavResource getCollection() {
269
270        DavResourceLocator locator = m_locator.getFactory().createResourceLocator(
271            m_locator.getPrefix(),
272            m_locator.getWorkspacePath(),
273            CmsResource.getParentFolder(m_locator.getResourcePath()));
274        try {
275            return m_factory.createResource(locator, m_session);
276        } catch (DavException e) {
277            return null;
278
279        }
280    }
281
282    /**
283     * @see org.apache.jackrabbit.webdav.DavResource#getComplianceClass()
284     */
285    public String getComplianceClass() {
286
287        return DavCompliance.concatComplianceClasses(new String[] {DavCompliance._1_, DavCompliance._2_});
288    }
289
290    /**
291     * @see org.apache.jackrabbit.webdav.DavResource#getDisplayName()
292     */
293    public String getDisplayName() {
294
295        String result = CmsResource.getName(getCmsPath());
296        result = result.replace("/", "");
297        return result;
298    }
299
300    /**
301     * @see org.apache.jackrabbit.webdav.DavResource#getFactory()
302     */
303    public DavResourceFactory getFactory() {
304
305        return m_factory;
306    }
307
308    /**
309     * @see org.apache.jackrabbit.webdav.DavResource#getHref()
310     */
311    public String getHref() {
312
313        String href = m_locator.getHref(true);
314        String result = CmsFileUtil.removeTrailingSeparator(href);
315        return result;
316    }
317
318    /**
319     * @see org.apache.jackrabbit.webdav.DavResource#getLocator()
320     */
321    public DavResourceLocator getLocator() {
322
323        return m_locator;
324    }
325
326    /**
327     * @see org.apache.jackrabbit.webdav.DavResource#getLock(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
328     */
329    public ActiveLock getLock(Type type, Scope scope) {
330
331        return m_lockManager.getLock(type, scope, this);
332    }
333
334    /**
335     * @see org.apache.jackrabbit.webdav.DavResource#getLocks()
336     */
337    public ActiveLock[] getLocks() {
338
339        ActiveLock writeLock = getLock(Type.WRITE, Scope.EXCLUSIVE);
340        return (writeLock != null) ? new ActiveLock[] {writeLock} : new ActiveLock[0];
341    }
342
343    /**
344     * @see org.apache.jackrabbit.webdav.DavResource#getMembers()
345     */
346    public DavResourceIterator getMembers() {
347
348        I_CmsRepositorySession session = getRepositorySession();
349        try {
350            List<I_CmsRepositoryItem> children = session.list(getCmsPath());
351            List<DavResource> childDavRes = children.stream().map(child -> {
352                String childPath = CmsStringUtil.joinPaths(m_locator.getWorkspacePath(), child.getName());
353                DavResourceLocator childLocator = m_locator.getFactory().createResourceLocator(
354                    m_locator.getPrefix(),
355                    m_locator.getWorkspacePath(),
356                    childPath);
357                return new CmsDavResource(childLocator, m_factory, m_session, m_lockManager);
358            }).filter(child -> {
359                boolean exists = child.exists();
360                if (!exists) {
361                    // one case where this happens is when the child resource has a name that would be
362                    // modified by the configured file translation rules.
363                    LOG.warn(
364                        "Invalid child resource: "
365                            + child.getLocator().getPrefix()
366                            + ":"
367                            + child.getLocator().getResourcePath());
368                }
369                return exists;
370            }).collect(Collectors.toList());
371            return new DavResourceIteratorImpl(childDavRes);
372        } catch (Exception e) {
373            LOG.error(e.getLocalizedMessage(), e);
374            return null;
375        }
376
377    }
378
379    /**
380     * @see org.apache.jackrabbit.webdav.DavResource#getModificationTime()
381     */
382    public long getModificationTime() {
383
384        I_CmsRepositoryItem item = getItem();
385        return item.getLastModifiedDate();
386    }
387
388    /**
389     * @see org.apache.jackrabbit.webdav.DavResource#getProperties()
390     */
391    public DavPropertySet getProperties() {
392
393        DavPropertySet result = new DavPropertySet();
394        ResourceType typeProp = new ResourceType(
395            isCollection() ? ResourceType.COLLECTION : ResourceType.DEFAULT_RESOURCE);
396        result.add(typeProp);
397        result.add(
398            new DefaultDavProperty<String>(
399                DavPropertyName.GETLASTMODIFIED,
400                CmsDavUtil.DATE_FORMAT.format(new Date(getItem().getLastModifiedDate()))));
401        result.add(new DefaultDavProperty<String>(DavPropertyName.DISPLAYNAME, "" + getItem().getName()));
402        if (!isCollection()) {
403            result.add(
404                new DefaultDavProperty<String>(DavPropertyName.GETCONTENTLENGTH, "" + getItem().getContentLength()));
405
406            result.add(new DefaultDavProperty<String>(DavPropertyName.GETETAG, getETag()));
407
408        }
409        try {
410            Map<CmsPropertyName, String> cmsProps = getRepositorySession().getProperties(getCmsPath());
411            for (Map.Entry<CmsPropertyName, String> entry : cmsProps.entrySet()) {
412                CmsPropertyName propName = entry.getKey();
413                DavPropertyName name = DavPropertyName.create(
414                    propName.getName(),
415                    Namespace.getNamespace(propName.getNamespace()));
416                result.add(new DefaultDavProperty<String>(name, entry.getValue()));
417            }
418        } catch (Exception e) {
419            LOG.error(e.getLocalizedMessage(), e);
420        }
421        return result;
422    }
423
424    /**
425     * @see org.apache.jackrabbit.webdav.DavResource#getProperty(org.apache.jackrabbit.webdav.property.DavPropertyName)
426     */
427    public DavProperty<?> getProperty(DavPropertyName name) {
428
429        return getProperties().get(name);
430    }
431
432    /**
433     * @see org.apache.jackrabbit.webdav.DavResource#getPropertyNames()
434     */
435    public DavPropertyName[] getPropertyNames() {
436
437        return getProperties().getPropertyNames();
438    }
439
440    /**
441     * @see org.apache.jackrabbit.webdav.DavResource#getResourcePath()
442     */
443    public String getResourcePath() {
444
445        return m_locator.getResourcePath();
446    }
447
448    /**
449     * @see org.apache.jackrabbit.webdav.DavResource#getSession()
450     */
451    public DavSession getSession() {
452
453        return m_session;
454    }
455
456    /**
457     * @see org.apache.jackrabbit.webdav.DavResource#getSupportedMethods()
458     */
459    public String getSupportedMethods() {
460
461        TreeSet<String> methods = new TreeSet<>();
462        I_CmsRepositoryItem item = getItem();
463        if (item == null) {
464            methods.addAll(Arrays.asList(DavMethods.METHOD_OPTIONS, DavMethods.METHOD_PUT, DavMethods.METHOD_MKCOL));
465            methods.add(DavMethods.METHOD_LOCK);
466        } else {
467            methods.addAll(
468                Arrays.asList(
469                    DavMethods.METHOD_OPTIONS,
470                    DavMethods.METHOD_HEAD,
471                    DavMethods.METHOD_POST,
472                    DavMethods.METHOD_DELETE));
473            methods.add(DavMethods.METHOD_PROPFIND);
474            methods.add(DavMethods.METHOD_PROPPATCH);
475
476            Arrays.asList(DavMethods.METHOD_COPY, DavMethods.METHOD_MOVE);
477            if (!item.isCollection()) {
478                methods.add(DavMethods.METHOD_PUT);
479            }
480
481        }
482        return CmsStringUtil.listAsString(new ArrayList<>(methods), ", ");
483    }
484
485    /**
486     * @see org.apache.jackrabbit.webdav.DavResource#hasLock(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
487     */
488    public boolean hasLock(Type type, Scope scope) {
489
490        return m_lockManager.getLock(type, scope, this) != null;
491    }
492
493    /**
494     * @see org.apache.jackrabbit.webdav.DavResource#isCollection()
495     */
496    public boolean isCollection() {
497
498        I_CmsRepositoryItem item = getItem();
499        return (item != null) && item.isCollection();
500    }
501
502    /**
503     * @see org.apache.jackrabbit.webdav.DavResource#isLockable(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
504     */
505    public boolean isLockable(Type type, Scope scope) {
506
507        // TODO Auto-generated method stub
508        return false;
509    }
510
511    /**
512     * @see org.apache.jackrabbit.webdav.DavResource#lock(org.apache.jackrabbit.webdav.lock.LockInfo)
513     */
514    public ActiveLock lock(LockInfo reqLockInfo) throws DavException {
515
516        return m_lockManager.createLock(reqLockInfo, this);
517    }
518
519    /**
520     * @see org.apache.jackrabbit.webdav.DavResource#move(org.apache.jackrabbit.webdav.DavResource)
521     */
522    public void move(DavResource destination) throws DavException {
523
524        CmsDavResource other = (CmsDavResource)destination;
525        if (isLocked(this)) {
526            throw new DavException(DavServletResponse.SC_LOCKED);
527        }
528
529        try {
530            getRepositorySession().move(getCmsPath(), other.getCmsPath(), true);
531        } catch (CmsException e) {
532            LOG.error(e.getLocalizedMessage(), e);
533            throw new DavException(CmsDavUtil.getStatusForException(e));
534        }
535
536    }
537
538    /**
539     * @see org.apache.jackrabbit.webdav.DavResource#refreshLock(org.apache.jackrabbit.webdav.lock.LockInfo, java.lang.String)
540     */
541    public ActiveLock refreshLock(LockInfo reqLockInfo, String lockToken) throws DavException {
542
543        return m_lockManager.refreshLock(reqLockInfo, lockToken, this);
544    }
545
546    /**
547     * @see org.apache.jackrabbit.webdav.DavResource#removeMember(org.apache.jackrabbit.webdav.DavResource)
548     */
549    public void removeMember(DavResource member) throws DavException {
550
551        if (isLocked(this) || isLocked(member)) {
552            throw new DavException(DavServletResponse.SC_LOCKED);
553        }
554        ((CmsDavResource)member).delete();
555    }
556
557    /**
558     * @see org.apache.jackrabbit.webdav.DavResource#removeProperty(org.apache.jackrabbit.webdav.property.DavPropertyName)
559     */
560    public void removeProperty(DavPropertyName propertyName) throws DavException {
561
562        if (exists() && isLocked(this)) {
563            throw new DavException(DavServletResponse.SC_LOCKED);
564        }
565
566        I_CmsRepositorySession session = getRepositorySession();
567        Map<CmsPropertyName, String> props = new HashMap<>();
568        CmsPropertyName key = new CmsPropertyName(propertyName.getNamespace().getURI(), propertyName.getName());
569        props.put(key, "");
570        try {
571            session.updateProperties(getCmsPath(), props);
572        } catch (CmsException e) {
573            LOG.error(e.getLocalizedMessage(), e);
574            throw new DavException(500);
575        }
576    }
577
578    /**
579     * @see org.apache.jackrabbit.webdav.DavResource#setProperty(org.apache.jackrabbit.webdav.property.DavProperty)
580     */
581    public void setProperty(DavProperty<?> property) throws DavException {
582
583        if (exists() && isLocked(this)) {
584            throw new DavException(DavServletResponse.SC_LOCKED);
585        }
586
587        if (!(property instanceof DefaultDavProperty)) {
588            throw new DavException(HttpServletResponse.SC_FORBIDDEN);
589        }
590        I_CmsRepositorySession session = getRepositorySession();
591        Map<CmsPropertyName, String> props = new HashMap<>();
592        DavPropertyName propertyName = property.getName();
593        String newValue = ((DefaultDavProperty<String>)property).getValue();
594        if (newValue == null) {
595            newValue = "";
596        }
597        CmsPropertyName key = new CmsPropertyName(propertyName.getNamespace().getURI(), propertyName.getName());
598        props.put(key, newValue);
599        try {
600            session.updateProperties(getCmsPath(), props);
601        } catch (CmsException e) {
602            LOG.error(e.getLocalizedMessage(), e);
603            throw new DavException(500);
604        }
605
606    }
607
608    /**
609     * @see org.apache.jackrabbit.webdav.DavResource#spool(org.apache.jackrabbit.webdav.io.OutputContext)
610     */
611    public void spool(OutputContext outputContext) throws IOException {
612
613        I_CmsRepositoryItem item = getItem();
614        outputContext.setContentType(item.getMimeType());
615        outputContext.setContentLength(item.getContentLength());
616        outputContext.setModificationTime(item.getLastModifiedDate());
617        outputContext.setETag(getETag());
618        OutputStream out = outputContext.getOutputStream();
619        if (out != null) {
620            out.write(item.getContent());
621        }
622
623    }
624
625    /**
626     * @see org.apache.jackrabbit.webdav.DavResource#unlock(java.lang.String)
627     */
628    public void unlock(String lockToken) throws DavException {
629
630        m_lockManager.releaseLock(lockToken, this);
631    }
632
633    /**
634     * Gets the OpenCms path corresponding to this resource's locator.
635     *
636     * @return the OpenCms path
637     */
638    private String getCmsPath() {
639
640        String path = m_locator.getResourcePath();
641        String workspace = m_locator.getWorkspacePath();
642        Optional<String> remainingPath = CmsStringUtil.removePrefixPath(workspace, path);
643        return remainingPath.orElse(null);
644
645    }
646
647    /**
648     * Computes the ETag for the item (the item must be not null).
649     *
650     * @return the ETag for the repository item
651     */
652    private String getETag() {
653
654        return "\"" + getItem().getContentLength() + "-" + getItem().getLastModifiedDate() + "\"";
655    }
656
657    /**
658     * Tries to load the appropriate repository item for this resource.
659     *
660     * @return the repository item, or null if none was found
661     */
662    private I_CmsRepositoryItem getItem() {
663
664        if (m_item == null) {
665            try {
666                I_CmsRepositoryItem item = getRepositorySession().getItem(getCmsPath());
667                m_item = Optional.of(item);
668
669            } catch (Exception e) {
670                boolean isFiltered = false;
671                if (e instanceof CmsException) {
672                    CmsMessageContainer messageContainer = ((CmsException)e).getMessageContainer();
673                    if (messageContainer != null) {
674                        String messageKey = messageContainer.getKey();
675                        if (org.opencms.repository.Messages.ERR_ITEM_FILTERED_1.equals(messageKey)) {
676                            isFiltered = true;
677                        }
678                    }
679                }
680                if (e instanceof CmsVfsResourceNotFoundException) {
681                    LOG.info(e.getLocalizedMessage(), e);
682                } else if (isFiltered) {
683                    LOG.warn(e.getLocalizedMessage(), e);
684                } else {
685                    LOG.error(e.getLocalizedMessage(), e);
686                }
687                m_item = Optional.empty();
688
689            }
690        }
691        return m_item.orElse(null);
692
693    }
694
695    /**
696     * Gets the OpenCms repository session for which this resource was created.
697     *
698     * @return the OpenCms repository session
699     */
700    private I_CmsRepositorySession getRepositorySession() {
701
702        return m_session.getRepositorySession();
703    }
704
705    /**
706     * Return true if this resource cannot be modified due to a write lock
707     * that is not owned by the current session.
708     *
709     * @param res the resource to check
710     *
711     * @return true if this resource cannot be modified due to a write lock
712     */
713    private boolean isLocked(DavResource res) {
714
715        ActiveLock lock = res.getLock(Type.WRITE, Scope.EXCLUSIVE);
716        if (lock == null) {
717            return false;
718        } else {
719            for (String sLockToken : m_session.getLockTokens()) {
720                if (sLockToken.equals(lock.getToken())) {
721                    return false;
722                }
723            }
724            return true;
725        }
726    }
727
728}