org.apache.jackrabbit.webdav.jcr.DavResourceFactoryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jackrabbit-jcr-server
Show all versions of jackrabbit-jcr-server
WebDAV server implementations for JCR
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.webdav.jcr;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavMethods;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.DavResourceFactory;
import org.apache.jackrabbit.webdav.DavResourceLocator;
import org.apache.jackrabbit.webdav.DavServletRequest;
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
import org.apache.jackrabbit.webdav.jcr.version.VersionHistoryItemCollection;
import org.apache.jackrabbit.webdav.jcr.version.VersionItemCollection;
import org.apache.jackrabbit.webdav.observation.ObservationResource;
import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
import org.apache.jackrabbit.webdav.transaction.TransactionDavServletRequest;
import org.apache.jackrabbit.webdav.transaction.TransactionResource;
import org.apache.jackrabbit.webdav.version.DeltaVServletRequest;
import org.apache.jackrabbit.webdav.version.VersionControlledResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
/**
* DavResourceFactoryImpl
...
*/
public class DavResourceFactoryImpl implements DavResourceFactory {
private static Logger log = LoggerFactory.getLogger(DavResourceFactoryImpl.class);
private final TxLockManagerImpl txMgr;
private final SubscriptionManager subsMgr;
/**
* Create a new DavResourceFactoryImpl
.
*
* @param txMgr
* @param subsMgr
*/
public DavResourceFactoryImpl(TxLockManagerImpl txMgr, SubscriptionManager subsMgr) {
this.txMgr = txMgr;
this.subsMgr = subsMgr;
}
/**
* Create a new DavResource
from the specified locator and request
* objects. Note, that in contrast to
* {@link #createResource(DavResourceLocator, DavSession)} the locator may
* point to a non-existing resource.
*
* If the request contains a {@link org.apache.jackrabbit.webdav.version.DeltaVServletRequest#getLabel()
* Label header}, the resource is build from the indicated
* {@link org.apache.jackrabbit.webdav.version.VersionResource version} instead.
*
* @param locator
* @param request
* @param response
* @return
* @see DavResourceFactory#createResource(org.apache.jackrabbit.webdav.DavResourceLocator, org.apache.jackrabbit.webdav.DavServletRequest, org.apache.jackrabbit.webdav.DavServletResponse)
*/
public DavResource createResource(DavResourceLocator locator,
DavServletRequest request,
DavServletResponse response) throws DavException {
JcrDavSession.checkImplementation(request.getDavSession());
JcrDavSession session = (JcrDavSession)request.getDavSession();
DavResource resource;
if (locator.isRootLocation()) {
// root
resource = new RootCollection(locator, session, this);
} else if (locator.getResourcePath().equals(locator.getWorkspacePath())) {
// workspace resource
resource = new WorkspaceResourceImpl(locator, session, this);
} else {
// resource corresponds to a repository item
try {
resource = createResourceForItem(locator, session);
/* if the created resource is version-controlled and the request
contains a Label header, the corresponding Version must be used
instead.*/
if (request instanceof DeltaVServletRequest && isVersionControlled(resource)) {
String labelHeader = ((DeltaVServletRequest)request).getLabel();
if (labelHeader != null && DavMethods.isMethodAffectedByLabel(request)) {
Item item = getItem(session, locator);
Version v = ((Node)item).getVersionHistory().getVersionByLabel(labelHeader);
DavResourceLocator vloc = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), v.getPath(), false);
resource = new VersionItemCollection(vloc, session, this, v);
}
}
} catch (PathNotFoundException e) {
/* item does not exist yet: create the default resources
Note: MKCOL request forces a collection-resource even if there already
exists a repository-property with the given path. the MKCOL will
in that particular case fail with a 405 (method not allowed).*/
if (DavMethods.getMethodCode(request.getMethod()) == DavMethods.DAV_MKCOL) {
resource = new VersionControlledItemCollection(locator, session, this, null);
} else {
resource = new DefaultItemResource(locator, session, this, null);
}
} catch (RepositoryException e) {
log.error("Failed to build resource from item '"+ locator.getRepositoryPath() + "'");
throw new JcrDavException(e);
}
}
if (request instanceof TransactionDavServletRequest && resource instanceof TransactionResource) {
((TransactionResource)resource).init(txMgr, ((TransactionDavServletRequest)request).getTransactionId());
}
if (resource instanceof ObservationResource) {
((ObservationResource)resource).init(subsMgr);
}
return resource;
}
/**
* Create a new DavResource
from the given locator and session.
*
* @param locator
* @param session
* @return DavResource representing either a repository item or the {@link RootCollection}.
* @throws DavException if the given locator does neither refer to a repository item
* nor does represent the {@link org.apache.jackrabbit.webdav.DavResourceLocator#isRootLocation()
* root location}.
*/
public DavResource createResource(DavResourceLocator locator, DavSession session) throws DavException {
JcrDavSession.checkImplementation(session);
JcrDavSession sessionImpl = (JcrDavSession)session;
DavResource resource;
if (locator.isRootLocation()) {
resource = new RootCollection(locator, sessionImpl, this);
} else if (locator.getResourcePath().equals(locator.getWorkspacePath())) {
resource = new WorkspaceResourceImpl(locator, sessionImpl, this);
} else {
try {
resource = createResourceForItem(locator, sessionImpl);
} catch (RepositoryException e) {
log.debug("Creating resource for non-existing repository item: " + locator.getRepositoryPath());
// todo: is this correct?
resource = new VersionControlledItemCollection(locator, sessionImpl, this, null);
}
}
// todo: currently transactionId is set manually after creation > to be improved.
resource.addLockManager(txMgr);
if (resource instanceof ObservationResource) {
((ObservationResource)resource).init(subsMgr);
}
return resource;
}
/**
* Tries to retrieve the repository item defined by the locator's resource
* path and build the corresponding WebDAV resource. The following distinction
* is made between items: Version nodes, VersionHistory nodes, root node,
* unspecified nodes and finally property items.
*
* @param locator
* @param sessionImpl
* @return DavResource representing a repository item.
* @throws RepositoryException if {@link javax.jcr.Session#getItem(String)} fails.
*/
private DavResource createResourceForItem(DavResourceLocator locator, JcrDavSession sessionImpl) throws RepositoryException, DavException {
DavResource resource;
Item item = getItem(sessionImpl, locator);
if (item.isNode()) {
// create special resources for Version and VersionHistory
if (item instanceof Version) {
resource = new VersionItemCollection(locator, sessionImpl, this, item);
} else if (item instanceof VersionHistory) {
resource = new VersionHistoryItemCollection(locator, sessionImpl, this, item);
} else{
resource = new VersionControlledItemCollection(locator, sessionImpl, this, item);
}
} else {
resource = new DefaultItemResource(locator, sessionImpl, this, item);
}
return resource;
}
private Item getItem(JcrDavSession sessionImpl, DavResourceLocator locator)
throws PathNotFoundException, RepositoryException {
return sessionImpl.getRepositorySession().getItem(locator.getRepositoryPath());
}
/**
* Returns true, if the specified resource is a {@link VersionControlledResource}
* and has a version history.
*
* @param resource
* @return true if the specified resource is version-controlled.
*/
private boolean isVersionControlled(DavResource resource) {
boolean vc = false;
if (resource instanceof VersionControlledResource) {
try {
vc = ((VersionControlledResource)resource).getVersionHistory() != null;
} catch (DavException e) {
log.debug("Resource '" + resource.getHref() + "' is not version-controlled.");
}
}
return vc;
}
}