You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2005/06/06 19:36:13 UTC
svn commit: r180346 [5/9] - in
/incubator/jackrabbit/trunk/contrib/jcr-server: ./ client/
client/src/java/org/apache/jackrabbit/client/
client/src/java/org/apache/jackrabbit/webdav/client/methods/ commons/
commons/src/ commons/src/java/ commons/src/java/org/
commons/src/java/org/apache/ commons/src/java/org/apache/jackrabbit/
commons/src/java/org/apache/jackrabbit/nodetype/
commons/src/java/org/apache/jackrabbit/nodetype/xml/
commons/src/java/org/apache/jackrabbit/util/
commons/src/java/org/apache/jackrabbit/util/uuid/
commons/src/java/org/apache/jackrabbit/value/ server/
server/src/java/org/apache/jackrabbit/server/
server/src/java/org/apache/jackrabbit/server/io/
server/src/java/org/apache/jackrabbit/server/jcr/
server/src/java/org/apache/jackrabbit/server/simple/
server/src/java/org/apache/jackrabbit/webdav/jcr/
server/src/java/org/apache/jackrabbit/webdav/jcr/lock/
server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/
server/src/java/org/apache/jackrabbit/webdav/jcr/observation/
server/src/java/org/apache/jackrabbit/webdav/jcr/property/
server/src/java/org/apache/jackrabbit/webdav/jcr/search/
server/src/java/org/apache/jackrabbit/webdav/jcr/transaction/
server/src/java/org/apache/jackrabbit/webdav/jcr/version/
server/src/java/org/apache/jackrabbit/webdav/jcr/version/report/
server/src/java/org/apache/jackrabbit/webdav/simple/ webapp/
webapp/src/java/ webapp/src/java/org/ webapp/src/java/org/apache/
webapp/src/java/org/apache/jackrabbit/
webapp/src/java/org/apache/jackrabbit/j2ee/ webapp/src/webapp/
webapp/src/webapp/WEB-INF/ webdav/
webdav/src/java/org/apache/jackrabbit/webdav/
webdav/src/java/org/apache/jackrabbit/webdav/jcr/
webdav/src/java/org/apache/jackrabbit/webdav/lock/
webdav/src/java/org/apache/jackrabbit/webdav/property/
webdav/src/java/org/apache/jackrabbit/webdav/util/
webdav/src/java/org/apache/jackrabbit/webdav/version/report/
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.search.SearchResource;
+import org.apache.jackrabbit.webdav.search.QueryGrammerSet;
+import org.apache.jackrabbit.webdav.search.SearchInfo;
+import org.apache.jackrabbit.webdav.transaction.TransactionResource;
+import org.apache.jackrabbit.webdav.transaction.TransactionInfo;
+import org.apache.jackrabbit.webdav.transaction.TransactionConstants;
+import org.apache.jackrabbit.webdav.transaction.TxLockManager;
+import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
+import org.apache.jackrabbit.webdav.jcr.search.SearchResourceImpl;
+import org.apache.jackrabbit.webdav.observation.*;
+import org.apache.jackrabbit.webdav.version.*;
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.version.report.ReportType;
+import org.apache.jackrabbit.webdav.version.report.SupportedReportSetProperty;
+import org.apache.jackrabbit.webdav.lock.*;
+import org.apache.jackrabbit.webdav.property.*;
+import org.apache.jackrabbit.webdav.property.ResourceType;
+import org.apache.jackrabbit.util.Text;
+
+import javax.jcr.Session;
+import javax.jcr.RepositoryException;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * <code>AbstractResource</code> provides functionality common to all
+ * resources.
+ */
+abstract class AbstractResource implements DavResource, ObservationResource,
+ TransactionResource, DeltaVResource, SearchResource {
+
+ private static Logger log = Logger.getLogger(AbstractResource.class);
+
+ private final DavResourceLocator locator;
+ private final DavSession session;
+ private final DavResourceFactory factory;
+
+ private SubscriptionManager subsMgr;
+ private TxLockManagerImpl txMgr;
+ private String transactionId;
+
+ private long modificationTime = DavResource.UNDEFINED_MODIFICATIONTIME;
+
+ protected boolean initedProps;
+ protected DavPropertySet properties = new DavPropertySet();
+ protected SupportedLock supportedLock = new SupportedLock();
+ protected SupportedReportSetProperty supportedReports = new SupportedReportSetProperty();
+
+ /**
+ * Create a new <code>AbstractResource</code>
+ *
+ * @param locator
+ * @param session
+ */
+ AbstractResource(DavResourceLocator locator, DavSession session, DavResourceFactory factory) {
+ if (session == null) {
+ throw new IllegalArgumentException("Creating AbstractItemResource: DavSession must not be null.");
+ }
+
+ this.locator = locator;
+ this.session = session;
+ this.factory = factory;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getLocator()
+ */
+ public DavResourceLocator getLocator() {
+ return locator;
+ }
+
+ /**
+ * Returns the path of the underlaying repository item or the item to
+ * be created (PUT/MKCOL). If the resource exists but does not represent
+ * a repository item <code>null</code> is returned.
+ *
+ * @return path of the underlaying repository item.
+ * @see DavResource#getResourcePath()
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#getResourcePath()
+ */
+ public String getResourcePath() {
+ return locator.getResourcePath();
+ }
+
+ /**
+ * @see DavResource#getHref()
+ * @see DavResourceLocator#getHref(boolean)
+ */
+ public String getHref() {
+ return locator.getHref(isCollection());
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getModificationTime()
+ */
+ public long getModificationTime() {
+ return modificationTime;
+ }
+
+ /**
+ * Set the modificationTime field and adds the {@link DavPropertyName.GETLASTMODIFIED}
+ * property to the set of properties.
+ * @param modificationTime
+ */
+ void setModificationTime(long modificationTime) {
+ this.modificationTime = modificationTime;
+ if (this.modificationTime >= 0) {
+ properties.add(new DefaultDavProperty(DavPropertyName.GETLASTMODIFIED,
+ DavConstants.modificationDateFormat.format(new Date(modificationTime))));
+ }
+ }
+
+ /**
+ * Returns <code>null</code>
+ *
+ * @return Always returns <code>null</code>
+ * @see org.apache.jackrabbit.webdav.DavResource#getStream()
+ */
+ public InputStream getStream() {
+ return null;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getPropertyNames()
+ */
+ public DavPropertyName[] getPropertyNames() {
+ return getProperties().getPropertyNames();
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getProperty(org.apache.jackrabbit.webdav.property.DavPropertyName)
+ */
+ public DavProperty getProperty(DavPropertyName name) {
+ return getProperties().get(name);
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getProperties()
+ */
+ public DavPropertySet getProperties() {
+ if (!initedProps) {
+ initProperties();
+ }
+ return properties;
+ }
+
+ /**
+ * Throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ *
+ * @param property
+ * @throws DavException Always throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ * @see org.apache.jackrabbit.webdav.DavResource#setProperty(org.apache.jackrabbit.webdav.property.DavProperty)
+ */
+ public void setProperty(DavProperty property) throws DavException {
+ throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+
+ /**
+ * Throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ *
+ * @param propertyName
+ * @throws DavException Always throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ * @see org.apache.jackrabbit.webdav.DavResource#removeProperty(org.apache.jackrabbit.webdav.property.DavPropertyName)
+ */
+ public void removeProperty(DavPropertyName propertyName) throws DavException {
+ throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+
+ /**
+ * Throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ *
+ * @param destination
+ * @throws DavException Always throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ * @see DavResource#move(org.apache.jackrabbit.webdav.DavResource)
+ */
+ public void move(DavResource destination) throws DavException {
+ throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+
+ /**
+ * Throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ *
+ * @param destination
+ * @param shallow
+ * @throws DavException Always throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ * @see DavResource#copy(org.apache.jackrabbit.webdav.DavResource, boolean)
+ */
+ public void copy(DavResource destination, boolean shallow) throws DavException {
+ throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+
+
+ /**
+ * Returns true, if the {@link SupportedLock} property contains an entry
+ * with the given type and scope. By default resources allow for {@link org.apache.jackrabbit.webdav.transaction.TransactionConstants.XML_TRANSACTION
+ * transaction} lock only.
+ *
+ * @param type
+ * @param scope
+ * @return true if this resource may be locked by the given type and scope.
+ * @see DavResource#isLockable(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
+ */
+ public boolean isLockable(Type type, Scope scope) {
+ return supportedLock.isSupportedLock(type, scope);
+ }
+
+ /**
+ * Returns true if this resource has a lock applied with the given type and scope.
+ *
+ * @param type
+ * @param scope
+ * @return true if this resource has a lock applied with the given type and scope.
+ * @see DavResource#hasLock(Type, Scope)
+ */
+ public boolean hasLock(Type type, Scope scope) {
+ return getLock(type, scope) != null;
+ }
+
+ /**
+ * @see DavResource#getLock(Type, Scope)
+ */
+ public ActiveLock getLock(Type type, Scope scope) {
+ ActiveLock lock = null;
+ if (TransactionConstants.TRANSACTION.equals(type)) {
+ lock = txMgr.getLock(type, scope, this);
+ }
+ return lock;
+ }
+
+ /**
+ * @see DavResource#getLocks()
+ * todo improve....
+ */
+ public ActiveLock[] getLocks() {
+ List locks = new ArrayList();
+ // tx locks
+ ActiveLock l = getLock(TransactionConstants.TRANSACTION, TransactionConstants.LOCAL);
+ if (l != null) {
+ locks.add(l);
+ }
+ l = getLock(TransactionConstants.TRANSACTION, TransactionConstants.GLOBAL);
+ if (l != null) {
+ locks.add(l);
+ }
+ // write lock (either exclusive or session-scoped).
+ l = getLock(Type.WRITE, Scope.EXCLUSIVE);
+ if (l != null) {
+ locks.add(l);
+ } else {
+ l = getLock(Type.WRITE, ItemResourceConstants.EXCLUSIVE_SESSION);
+ if (l != null) {
+ locks.add(l);
+ }
+ }
+ return (ActiveLock[]) locks.toArray(new ActiveLock[locks.size()]);
+ }
+
+ /**
+ * @see DavResource#lock(org.apache.jackrabbit.webdav.lock.LockInfo)
+ */
+ public ActiveLock lock(LockInfo reqLockInfo) throws DavException {
+ if (isLockable(reqLockInfo.getType(), reqLockInfo.getScope())) {
+ return txMgr.createLock(reqLockInfo, this);
+ } else {
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+ }
+
+ /**
+ * Only transaction lock may be available on this resource.
+ *
+ * @param info
+ * @param lockToken
+ * @throws DavException
+ * @see DavResource#refreshLock(org.apache.jackrabbit.webdav.lock.LockInfo, String)
+ */
+ public ActiveLock refreshLock(LockInfo info, String lockToken) throws DavException {
+ return txMgr.refreshLock(info, lockToken, this);
+ }
+
+ /**
+ * Throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED} since only transaction
+ * locks may be present on this resource, that need to be released by calling
+ * {@link TransactionResource#unlock(String, org.apache.jackrabbit.webdav.transaction.TransactionInfo)}.
+ *
+ * @param lockToken
+ * @throws DavException Always throws {@link DavServletResponse#SC_METHOD_NOT_ALLOWED}
+ */
+ public void unlock(String lockToken) throws DavException {
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+
+ /**
+ * @see DavResource#addLockManager(org.apache.jackrabbit.webdav.lock.LockManager)
+ */
+ public void addLockManager(LockManager lockMgr) {
+ if (lockMgr instanceof TxLockManagerImpl) {
+ txMgr = (TxLockManagerImpl) lockMgr;
+ }
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getFactory()
+ */
+ public DavResourceFactory getFactory() {
+ return factory;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * @see org.apache.jackrabbit.webdav.transaction.TransactionResource#getSession()
+ * @see org.apache.jackrabbit.webdav.observation.ObservationResource#getSession()
+ */
+ public DavSession getSession() {
+ return session;
+ }
+
+ //--------------------------------------< ObservationResource interface >---
+ /**
+ * @see ObservationResource#init(SubscriptionManager)
+ */
+ public void init(SubscriptionManager subsMgr) {
+ this.subsMgr = subsMgr;
+ }
+
+ /**
+ * @see ObservationResource#subscribe(org.apache.jackrabbit.webdav.observation.SubscriptionInfo, String)
+ * @see SubscriptionManager#subscribe(org.apache.jackrabbit.webdav.observation.SubscriptionInfo, String, org.apache.jackrabbit.webdav.observation.ObservationResource)
+ */
+ public Subscription subscribe(SubscriptionInfo info, String subscriptionId)
+ throws DavException {
+ return subsMgr.subscribe(info, subscriptionId, this);
+ }
+
+ /**
+ * @see ObservationResource#unsubscribe(String)
+ * @see SubscriptionManager#unsubscribe(String, org.apache.jackrabbit.webdav.observation.ObservationResource)
+ */
+ public void unsubscribe(String subscriptionId) throws DavException {
+ subsMgr.unsubscribe(subscriptionId, this);
+ }
+
+ /**
+ * @see ObservationResource#poll(String)
+ * @see SubscriptionManager#poll(String, org.apache.jackrabbit.webdav.observation.ObservationResource)
+ */
+ public EventDiscovery poll(String subscriptionId) throws DavException {
+ return subsMgr.poll(subscriptionId, this);
+ }
+
+ //--------------------------------------< TransactionResource interface >---
+ /**
+ * @see TransactionResource#init(TxLockManager, String)
+ */
+ public void init(TxLockManager txMgr, String transactionId) {
+ this.txMgr = (TxLockManagerImpl) txMgr;
+ this.transactionId = transactionId;
+ }
+
+ /**
+ * @see TransactionResource#unlock(String, org.apache.jackrabbit.webdav.transaction.TransactionInfo)
+ */
+ public void unlock(String lockToken, TransactionInfo tInfo) throws DavException {
+ txMgr.releaseLock(tInfo, lockToken, this);
+ }
+
+ /**
+ * @see TransactionResource#getTransactionId()
+ */
+ public String getTransactionId() {
+ return transactionId;
+ }
+
+ //-------------------------------------------< DeltaVResource interface >---
+ /**
+ * @param optionsInfo
+ * @return object to be used in the OPTIONS response body or <code>null</code>
+ * @see DeltaVResource#getOptionResponse(org.apache.jackrabbit.webdav.version.OptionsInfo)
+ */
+ public OptionsResponse getOptionResponse(OptionsInfo optionsInfo) {
+ OptionsResponse oR = null;
+ if (optionsInfo != null) {
+ oR = new OptionsResponse();
+ // currently on DAV:version-history-collection-set and
+ // DAV:workspace-collection-set is supported.
+ if (optionsInfo.containsElement(DeltaVConstants.XML_VH_COLLECTION_SET, DeltaVConstants.NAMESPACE)) {
+ String[] hrefs = new String[] { getLocatorFromResourcePath(ItemResourceConstants.VERSIONSTORAGE_PATH).getHref(true)};
+ oR.addEntry(DeltaVConstants.XML_VH_COLLECTION_SET, DeltaVConstants.NAMESPACE, hrefs);
+ } else if (optionsInfo.containsElement(DeltaVConstants.XML_WSP_COLLECTION_SET, DeltaVConstants.NAMESPACE)) {
+ // workspaces cannot be created anywhere.
+ oR.addEntry(DeltaVConstants.XML_WSP_COLLECTION_SET, DeltaVConstants.NAMESPACE, new String[0]);
+ }
+ }
+ return oR;
+ }
+
+ /**
+ * @param reportInfo
+ * @return the requested report
+ * @throws DavException
+ * @see DeltaVResource#getReport(org.apache.jackrabbit.webdav.version.report.ReportInfo)
+ */
+ public Report getReport(ReportInfo reportInfo) throws DavException {
+ if (reportInfo == null) {
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST, "A REPORT request must provide a valid XML request body.");
+ }
+ if (!exists()) {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+
+ if (supportedReports.isSupportedReport(reportInfo)) {
+ try {
+ Report report = ReportType.getType(reportInfo).createReport();
+ report.setInfo(reportInfo);
+ report.setResource(this);
+ return report;
+ } catch (IllegalArgumentException e) {
+ // should never occur.
+ throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
+ } else {
+ throw new DavException(DavServletResponse.SC_UNPROCESSABLE_ENTITY, "Unkown report "+ reportInfo.getReportElement().getNamespacePrefix() + reportInfo.getReportElement().getName() +"requested.");
+ }
+ }
+
+ /**
+ * The JCR api does not provide methods to create new workspaces. Calling
+ * <code>addWorkspace</code> on this resource will always fail.
+ *
+ * @param workspace
+ * @throws DavException Always throws.
+ * @see DeltaVResource#addWorkspace(org.apache.jackrabbit.webdav.DavResource)
+ */
+ public void addWorkspace(DavResource workspace) throws DavException {
+ throw new DavException(DavServletResponse.SC_FORBIDDEN);
+ }
+
+ /**
+ * Return an array of <code>DavResource</code> objects that are referenced
+ * by the property with the specified name.
+ *
+ * @param hrefPropertyName
+ * @return array of <code>DavResource</code>s
+ * @throws DavException
+ * @see DeltaVResource#getReferenceResources(org.apache.jackrabbit.webdav.property.DavPropertyName)
+ */
+ public DavResource[] getReferenceResources(DavPropertyName hrefPropertyName) throws DavException {
+ DavProperty prop = getProperty(hrefPropertyName);
+ if (prop == null || !(prop instanceof HrefProperty)) {
+ throw new DavException(DavServletResponse.SC_CONFLICT, "Unknown Href-Property '"+hrefPropertyName+"' on resource "+getResourcePath());
+ }
+
+ List hrefs = ((HrefProperty)prop).getHrefs();
+ DavResource[] refResources = new DavResource[hrefs.size()];
+ Iterator hrefIter = hrefs.iterator();
+ int i = 0;
+ while (hrefIter.hasNext()) {
+ refResources[i] = getResourceFromHref((String)hrefIter.next());
+ i++;
+ }
+ return refResources;
+ }
+
+ /**
+ * Retrieve the <code>DavResource</code> object that is represented by
+ * the given href String.
+ *
+ * @param href
+ * @return <code>DavResource</code> object
+ */
+ private DavResource getResourceFromHref(String href) throws DavException {
+ // build a new locator: remove trailing prefix
+ DavResourceLocator locator = getLocator();
+ String prefix = locator.getPrefix();
+ if (href.startsWith(prefix)) {
+ href = href.substring(prefix.length());
+ }
+ DavResourceLocator loc = locator.getFactory().createResourceLocator(prefix, href);
+
+ // create a new resource object
+ try {
+ DavResource res;
+ if (getRepositorySession().itemExists(loc.getResourcePath())) {
+ res = createResourceFromLocator(loc);
+ } else {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+ return res;
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ }
+ }
+
+ //-------------------------------------------< SearchResource interface >---
+ /**
+ * @return
+ * @see org.apache.jackrabbit.webdav.search.SearchResource#getQueryGrammerSet()
+ */
+ public QueryGrammerSet getQueryGrammerSet() {
+ return new SearchResourceImpl(getLocator(), getSession()).getQueryGrammerSet();
+ }
+
+ /**
+ * @param sInfo
+ * @return
+ * @throws DavException
+ * @see SearchResource#search(org.apache.jackrabbit.webdav.search.SearchInfo)
+ */
+ public MultiStatus search(SearchInfo sInfo) throws DavException {
+ return new SearchResourceImpl(getLocator(), getSession()).search(sInfo);
+ }
+ //--------------------------------------------------------------------------
+ /**
+ * Fill the set of default properties
+ */
+ protected void initProperties() {
+ if (getDisplayName() != null) {
+ properties.add(new DefaultDavProperty(DavPropertyName.DISPLAYNAME, getDisplayName()));
+ }
+ if (isCollection()) {
+ properties.add(new ResourceType(ResourceType.COLLECTION));
+ // Windows XP support
+ properties.add(new DefaultDavProperty(DavPropertyName.ISCOLLECTION, "1"));
+ } else {
+ properties.add(new ResourceType(ResourceType.DEFAULT_RESOURCE));
+ // Windows XP support
+ properties.add(new DefaultDavProperty(DavPropertyName.ISCOLLECTION, "0"));
+ }
+ // todo: add etag
+
+ // default last modified
+ setModificationTime(new Date().getTime());
+ // default creation time
+ properties.add(new DefaultDavProperty(DavPropertyName.CREATIONDATE, DavConstants.creationDateFormat.format(new Date(0))));
+
+ // supported lock property
+ properties.add(supportedLock);
+
+ // set current lock information. If no lock is applied to this resource,
+ // an empty lockdiscovery will be returned in the response.
+ properties.add(new LockDiscovery(getLocks()));
+
+ // observation resource
+ SubscriptionDiscovery subsDiscovery = subsMgr.getSubscriptionDiscovery(this);
+ properties.add(subsDiscovery);
+
+ properties.add(new SupportedMethodSetProperty(getSupportedMethods().split(",\\s")));
+
+ // DeltaV properties
+ properties.add(supportedReports);
+ // creator-displayname, comment: not value available from jcr
+ properties.add(new DefaultDavProperty(DeltaVConstants.CREATOR_DISPLAYNAME, null, true));
+ properties.add(new DefaultDavProperty(DeltaVConstants.COMMENT, null, true));
+
+ // 'workspace' property as defined by RFC 3253
+ String workspaceHref = getWorkspaceHref();
+ if (workspaceHref != null) {
+ properties.add(new HrefProperty(DeltaVConstants.WORKSPACE, workspaceHref, true));
+ }
+ // TODO: required supported-live-property-set
+ }
+
+ /**
+ * Create a new <code>DavResource</code> from the given locator.
+ * @param loc
+ * @return new <code>DavResource</code>
+ */
+ protected DavResource createResourceFromLocator(DavResourceLocator loc)
+ throws DavException {
+ DavResource res = factory.createResource(loc, session);
+ if (res instanceof AbstractResource) {
+ ((AbstractResource)res).transactionId = this.transactionId;
+ }
+ return res;
+ }
+
+ /**
+ * Build a <code>DavResourceLocator</code> from the given resource path.
+ *
+ * @param resourcePath
+ * @return a new <code>DavResourceLocator</code>
+ * @see DavLocatorFactory#createResourceLocator(String, String, String)
+ */
+ protected DavResourceLocator getLocatorFromResourcePath(String resourcePath) {
+ DavResourceLocator loc = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), resourcePath);
+ return loc;
+ }
+
+ /**
+ * Retrieve the name/label of a repository item from the given href by
+ * splitting of the part after the last slash. If the removeIndex
+ * flag is set to true, any trailing index (e.g. '[1]') will be removed.
+ *
+ * @param resourceHref
+ * @param removeIndex
+ * @return the name of the item
+ */
+ protected static String getResourceName(String resourceHref, boolean removeIndex) {
+ if (resourceHref == null) {
+ return resourceHref;
+ }
+
+ // cut the extension
+ int pos = resourceHref.lastIndexOf('.');
+ if (pos > 0) {
+ resourceHref = resourceHref.substring(pos+1);
+ } else if (resourceHref.endsWith("/")) {
+ resourceHref = resourceHref.substring(0, resourceHref.length()-1);
+ }
+
+ // retrieve the last part of the path
+ String name = Text.getLabel(resourceHref);
+ // remove index
+ if (removeIndex) {
+ if (name.endsWith("]")) {
+ name = name.substring(0, name.lastIndexOf('['));
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Shortcut for <code>getSession().getRepositorySession()</code>
+ *
+ * @return repository session present in the {@link #session}.
+ */
+ protected Session getRepositorySession() {
+ return getSession().getRepositorySession();
+ }
+
+ /**
+ * Define the set of locks supported by this resource.
+ *
+ * @see org.apache.jackrabbit.webdav.lock.SupportedLock
+ */
+ abstract protected void initLockSupport();
+
+ /**
+ * Define the set of reports supported by this resource.
+ *
+ * @see org.apache.jackrabbit.webdav.version.report.SupportedReportSetProperty
+ */
+ abstract protected void initSupportedReports();
+
+ /**
+ * Retrieve the href of the workspace the current session belongs to.
+ *
+ * @return href of the workspace
+ */
+ abstract protected String getWorkspaceHref();
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.DavLocatorFactory;
+
+/**
+ * <code>DavLocatorFactoryImpl</code>...
+ */
+public class DavLocatorFactoryImpl implements DavLocatorFactory {
+
+ private static Logger log = Logger.getLogger(DavLocatorFactoryImpl.class);
+
+ private final String pathPrefix;
+
+ /**
+ * Create a new factory
+ *
+ * @param pathPrefix Prefix, that needs to be removed in order to retrieve
+ * the path of the repository item from a given <code>DavResourceLocator</code>.
+ */
+ public DavLocatorFactoryImpl(String pathPrefix) {
+ this.pathPrefix = pathPrefix;
+ }
+
+ /**
+ * Create a new <code>DavResourceLocator</code>. Any leading
+ * path-prefix (as defined with the constructor) and trailing '/' with
+ * the request handle is removed. The first label of the remaining handle is
+ * treated as workspace name. The remaining part of the given request handle
+ * is said to be the resource handle ("/" if an empty string remains).
+ * If the request handle does neither provide workspace name nor resource
+ * handle both values are set to <code>null</code>; the path object then
+ * represents the root resource that has no corresponding item in the JCR
+ * repository.
+ *
+ * @param prefix
+ * @param requestHandle
+ * @return a new <code>DavResourceLocator</code>
+ * @throws IllegalArgumentException if the request handle is <code>null</code>
+ */
+ public DavResourceLocator createResourceLocator(String prefix, String requestHandle) {
+ if (requestHandle == null) {
+ throw new IllegalArgumentException("Request handle must not be null.");
+ }
+
+ StringBuffer b = new StringBuffer("");
+ if (prefix != null) {
+ b.append(prefix);
+ if (pathPrefix != null && !prefix.endsWith(pathPrefix)) {
+ b.append(pathPrefix);
+ }
+ }
+ String rlPrefix = b.toString();
+
+ // remove path-prefix defined with the servlet that may preceed the
+ // the requestHandle
+ if (pathPrefix != null && requestHandle.startsWith(pathPrefix)) {
+ requestHandle = requestHandle.substring(pathPrefix.length());
+ }
+
+ // remove trailing "/" that is present with collections
+ if (requestHandle.endsWith("/")) {
+ requestHandle = requestHandle.substring(0, requestHandle.length()-1);
+ }
+
+ String resourcePath;
+ String workspacePath;
+
+ // an empty requestHandle (after removal of the "/") signifies a request
+ // to the root that does not represent a repository item.
+ if ("".equals(requestHandle)) {
+ resourcePath = null;
+ workspacePath = null;
+ } else {
+ // look for the first slash ignoring the leading one
+ int pos = requestHandle.indexOf('/', 1);
+ if (pos == -1) {
+ // request to a 'workspace' resource that in the same time
+ // represent the root node of the repository.
+ workspacePath = requestHandle;
+ resourcePath = ItemResourceConstants.ROOT_ITEM_PATH;
+ } else {
+ // separate the workspace name from the path of the repository
+ // item.
+ workspacePath = requestHandle.substring(0, pos);
+ resourcePath = requestHandle.substring(pos);
+ }
+ }
+
+ return new DavResourceLocatorImpl(rlPrefix, workspacePath, resourcePath, this);
+ }
+
+ /**
+ * Create a new <code>DavResourceLocator</code> from the specified prefix,
+ * workspace path and resource path, whithout modifying the specified Strings.
+ *
+ * @param prefix
+ * @param workspacePath
+ * @param resourcePath
+ * @return a new <code>DavResourceLocator</code>
+ * @see DavLocatorFactory#createResourceLocator(String, String, String)
+ */
+ public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath) {
+ return new DavResourceLocatorImpl(prefix, workspacePath, resourcePath, this);
+ }
+
+ /**
+ * Private inner class <code>DavResourceLocatorImpl</code> implementing
+ * the <code>DavResourceLocator</code> interface.
+ */
+ private class DavResourceLocatorImpl implements DavResourceLocator {
+
+ private final String prefix;
+ private final String workspacePath;
+ private final String resourcePath;
+ private final DavLocatorFactory factory;
+
+ /**
+ * Create a new <code>DavResourceLocatorImpl</code>.
+ *
+ * @param prefix
+ * @param workspacePath
+ * @param resourcePath
+ */
+ DavResourceLocatorImpl(String prefix, String workspacePath, String resourcePath, DavLocatorFactory factory) {
+ this.prefix = prefix;
+ this.workspacePath = workspacePath;
+ this.resourcePath = resourcePath;
+ this.factory = factory;
+ }
+
+ /**
+ * Return the prefix used to build the href String. This includes the initial
+ * hrefPrefix as well a the path prefix.
+ *
+ * @return prefix String used to build the href.
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Return the resource path of <code>null</code> if this locator object
+ * represents the '/' request handle. To a request handle specifying a
+ * workspace name only the '/' resource path is assigned, which represents
+ * the root node of the repository.
+ *
+ * @return resource path or <code>null</code>
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#getResourcePath()
+ */
+ public String getResourcePath() {
+ return resourcePath;
+ }
+
+ /**
+ * Return the workspace path or <code>null</code> if this locator object
+ * represents the '/' request handle.
+ *
+ * @return workspace path or <code>null</code>
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#getWorkspacePath()
+ */
+ public String getWorkspacePath() {
+ return workspacePath;
+ }
+
+ /**
+ * Return the workspace name or <code>null</code> if this locator object
+ * represents the '/' request handle.
+ *
+ * @return workspace name or <code>null</code>
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#getWorkspaceName()
+ */
+ public String getWorkspaceName() {
+ if (workspacePath != null) {
+ return workspacePath.substring(1);
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the specified locator object refers to a resource within
+ * the same workspace.
+ *
+ * @param locator
+ * @return true if the workspace name is equal to this workspace name.
+ * @see DavResourceLocator#isSameWorkspace(org.apache.jackrabbit.webdav.DavResourceLocator)
+ */
+ public boolean isSameWorkspace(DavResourceLocator locator) {
+ return (locator == null) ? false : isSameWorkspace(locator.getWorkspaceName());
+ }
+
+ /**
+ * Returns true if the specified string equals to this workspace name or
+ * if this workspace name is null.
+ *
+ * @param workspaceName
+ * @return true if the workspace name is equal to this workspace name.
+ * @see DavResourceLocator#isSameWorkspace(String)
+ */
+ public boolean isSameWorkspace(String workspaceName) {
+ if (getWorkspaceName() == null) {
+ return true;
+ } else {
+ return getWorkspaceName().equals(workspaceName);
+ }
+ }
+
+ /**
+ * Builds the 'href' from the prefix, the workspace name and the
+ * resource path present and assures a trailing '/' in case the href
+ * is used for collection.
+ *
+ * @param isCollection
+ * @return href String representing the text of the href element
+ * @see org.apache.jackrabbit.webdav.DavConstants#XML_HREF
+ * @see DavResourceLocator#getHref(boolean)
+ */
+ public String getHref(boolean isCollection) {
+ StringBuffer href = new StringBuffer(prefix);
+ if (workspacePath != null) {
+ href.append(workspacePath);
+ }
+ if (resourcePath != null) {
+ href.append(resourcePath);
+ }
+ if (isCollection && href.charAt(href.length()-1) != '/') {
+ href.append("/");
+ }
+ return href.toString();
+ }
+
+ /**
+ * Returns true if the 'workspaceName' field is <code>null</code>.
+ *
+ * @return true if the 'workspaceName' field is <code>null</code>.
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#isRootLocation()
+ */
+ public boolean isRootLocation() {
+ return workspacePath == null;
+ }
+
+ /**
+ * Return the factory that created this locator.
+ *
+ * @return factory
+ * @see org.apache.jackrabbit.webdav.DavResourceLocator#getFactory()
+ */
+ public DavLocatorFactory getFactory() {
+ return factory;
+ }
+
+ /**
+ * Computes the hash code using the prefix, the workspace name and the
+ * resource path.
+ *
+ * @return the hash code
+ */
+ public int hashCode() {
+ int hashCode = prefix.hashCode();
+ if (workspacePath != null) {
+ hashCode += workspacePath.hashCode();
+ }
+ if (resourcePath != null) {
+ hashCode += resourcePath.hashCode();
+ }
+ return hashCode % Integer.MAX_VALUE;
+ }
+
+ /**
+ * Equality of locators is achieved if prefix and resource path
+ * are equal.
+ *
+ * @param obj the object to compare to
+ * @return <code>true</code> if the 2 objects are equal;
+ * <code>false</code> otherwise
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof DavResourceLocatorImpl) {
+ DavResourceLocatorImpl locator = (DavResourceLocatorImpl) obj;
+ boolean equalWsName = (workspacePath == null) ? locator.workspacePath == null : workspacePath.equals(locator.workspacePath);
+ boolean equalRPath = (resourcePath == null) ? locator.resourcePath == null : resourcePath.equals(locator.resourcePath);
+
+ return prefix.equals(locator.prefix) && equalWsName && equalRPath;
+ }
+ return false;
+ }
+ }
+}
+
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.transaction.TransactionResource;
+import org.apache.jackrabbit.webdav.transaction.TransactionDavServletRequest;
+import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
+import org.apache.jackrabbit.webdav.observation.ObservationResource;
+import org.apache.jackrabbit.webdav.version.DeltaVServletRequest;
+import org.apache.jackrabbit.webdav.version.VersionControlledResource;
+import org.apache.jackrabbit.webdav.jcr.version.VersionItemCollection;
+import org.apache.jackrabbit.webdav.jcr.version.VersionHistoryItemCollection;
+import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
+
+import javax.jcr.*;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+
+/**
+ * <code>DavResourceFactoryImpl</code>...
+ */
+public class DavResourceFactoryImpl implements DavResourceFactory {
+
+ private static Logger log = Logger.getLogger(DavResourceFactoryImpl.class);
+
+ private final TxLockManagerImpl txMgr;
+ private final SubscriptionManager subsMgr;
+
+ /**
+ * Create a new <code>DavResourceFactoryImpl</code>.
+ *
+ * @param txMgr
+ * @param subsMgr
+ */
+ public DavResourceFactoryImpl(TxLockManagerImpl txMgr, SubscriptionManager subsMgr) {
+ this.txMgr = txMgr;
+ this.subsMgr = subsMgr;
+ }
+
+ /**
+ * Create a new <code>DavResource</code> 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.
+ * <p/>
+ * 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 {
+
+ DavSession session = request.getDavSession();
+
+ DavResource resource;
+ if (locator.isRootLocation()) {
+ resource = new RootCollection(locator, session, this);
+ } else {
+ 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.getMethod())) {
+ Item item = session.getRepositorySession().getItem(locator.getResourcePath());
+ Version v = ((Node)item).getVersionHistory().getVersionByLabel(labelHeader);
+ DavResourceLocator vloc = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), v.getPath());
+ 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.getResourcePath() + "'");
+ throw new JcrDavException(e);
+ }
+ }
+
+ ((TransactionResource)resource).init(txMgr, ((TransactionDavServletRequest)request).getTransactionId());
+ ((ObservationResource)resource).init(subsMgr);
+ return resource;
+ }
+
+ /**
+ * Create a new <code>DavResource</code> 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 {
+ DavResource resource;
+ try {
+ resource = createResourceForItem(locator, session);
+ } catch (RepositoryException e) {
+ log.info("Creating resource for non-existing repository item ...");
+ if (locator.isRootLocation()) {
+ resource = new RootCollection(locator, session, this);
+ } else {
+ // todo: is this correct?
+ resource = new VersionControlledItemCollection(locator, session, this, null);
+ }
+ }
+
+ // todo: currently transactionId is set manually after creation > to be improved.
+ resource.addLockManager(txMgr);
+ ((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 session
+ * @return DavResource representing a repository item.
+ * @throws RepositoryException if {@link Session#getItem(String)} fails.
+ */
+ private DavResource createResourceForItem(DavResourceLocator locator, DavSession session) throws RepositoryException {
+ DavResource resource;
+ Item item = session.getRepositorySession().getItem(locator.getResourcePath());
+ if (item.isNode()) {
+ // create special resources for Version and VersionHistory
+ if (item instanceof Version) {
+ resource = new VersionItemCollection(locator, session, this, item);
+ } else if (item instanceof VersionHistory) {
+ resource = new VersionHistoryItemCollection(locator, session, this, item);
+ } else if (ItemResourceConstants.ROOT_ITEM_PATH.equals(locator.getResourcePath())) {
+ resource = new RootItemCollection(locator, session, this, item);
+ } else{
+ resource = new VersionControlledItemCollection(locator, session, this, item);
+ }
+ } else {
+ resource = new DefaultItemResource(locator, session, this, item);
+ }
+ return resource;
+ }
+
+ /**
+ * 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;
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,746 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.property.*;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.jcr.nodetype.NodeTypeProperty;
+import org.apache.jackrabbit.webdav.jcr.lock.JcrActiveLock;
+import org.apache.jackrabbit.webdav.ordering.*;
+import org.apache.jackrabbit.webdav.lock.*;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.util.Text;
+
+import javax.jcr.*;
+import javax.jcr.lock.Lock;
+import javax.jcr.nodetype.NodeType;
+import java.util.*;
+import java.io.*;
+
+/**
+ * <code>DefaultItemCollection</code> represents a JCR node item.
+ */
+public class DefaultItemCollection extends AbstractItemResource
+ implements OrderingResource {
+
+ private static Logger log = Logger.getLogger(DefaultItemCollection.class);
+
+ private InputStream in;
+
+ /**
+ * Create a new <code>DefaultItemCollection</code>.
+ *
+ * @param locator
+ * @param session
+ */
+ protected DefaultItemCollection(DavResourceLocator locator, DavSession session,
+ DavResourceFactory factory, Item item) {
+ super(locator, session, factory, item);
+ if (exists() && !(item instanceof Node)) {
+ throw new IllegalArgumentException("A collection resource can not be constructed from a Property item.");
+ }
+ }
+
+ //----------------------------------------------< DavResource interface >---
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getComplianceClass()
+ */
+ public String getComplianceClass() {
+ StringBuffer sb = new StringBuffer(super.getComplianceClass());
+ sb.append(", ").append(OrderingResource.COMPLIANCE_CLASS);
+ return sb.toString();
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getSupportedMethods()
+ */
+ public String getSupportedMethods() {
+ StringBuffer sb = new StringBuffer(super.getSupportedMethods());
+ // Ordering
+ if (isOrderable()) {
+ sb.append(", ").append(OrderingResource.METHODS);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Always returns true
+ *
+ * @return true
+ * @see org.apache.jackrabbit.webdav.DavResource#isCollection()
+ */
+ public boolean isCollection() {
+ return true;
+ }
+
+
+ /**
+ * Returns an {@link java.io.InputStream} to the content of this collection.
+ *
+ * @return
+ * @see org.apache.jackrabbit.webdav.DavResource#getStream()
+ */
+ public InputStream getStream() {
+ initProperties();
+ return in;
+ }
+
+ /**
+ * This implementation of the <code>DavResource</code> does only allow
+ * to set the jcr:mixinnodetypes property. Please note that the existing list of
+ * mixin nodetypes will be completely replaces.<br>
+ * In order to add / set any other repository property on the underlaying
+ * {@link javax.jcr.Node} use <code>addMember(DavResource)</code> or
+ * <code>addMember(DavResource, InputStream)</code> or modify the value
+ * of the corresponding resource.
+ *
+ * @param property
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.DavResource#setProperty(org.apache.jackrabbit.webdav.property.DavProperty)
+ * @see #JCR_MIXINNODETYPES
+ * @todo undo incomplete modifications...
+ */
+ public void setProperty(DavProperty property) throws DavException {
+ if (!exists()) {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+ if (property.getName().equals(JCR_MIXINNODETYPES)) {
+ try {
+ Node n = (Node)item;
+ NodeType[] existingMixin = n.getMixinNodeTypes();
+ NodeTypeProperty mix = new NodeTypeProperty(property);
+ Set mixins = mix.getNodeTypeNames();
+
+ for (int i = 0; i < existingMixin.length; i++) {
+ String name = existingMixin[i].getName();
+ if (mixins.contains(name)){
+ // do not add existing mixins
+ mixins.remove(name);
+ } else {
+ // remove mixin that are not contained in the new list
+ n.removeMixin(name);
+ }
+ }
+
+ // add the remaining mixing types that are not yet set
+ Iterator it = mixins.iterator();
+ while (it.hasNext()) {
+ n.addMixin((String)it.next());
+ }
+ complete();
+
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ }
+ } else {
+ // all props except for mixinnodetypes are read-only
+ throw new DavException(DavServletResponse.SC_CONFLICT);
+ }
+ }
+
+ /**
+ * This implementation of the <code>DavResource</code> does only allow
+ * to remove the jcr:mixinnodetypes property.
+ *
+ * @param propertyName
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.DavResource#removeProperty(org.apache.jackrabbit.webdav.property.DavPropertyName)
+ * @see #JCR_MIXINNODETYPES
+ * @todo undo incomplete modifications...
+ */
+ public void removeProperty(DavPropertyName propertyName) throws DavException {
+ if (!exists()) {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+ if (JCR_MIXINNODETYPES.equals(propertyName)) {
+ // remove all mixin nodetypes
+ try {
+ Node n = (Node)item;
+ NodeType[] mixins = n.getMixinNodeTypes();
+ for (int i = 0; i < mixins.length; i++) {
+ n.removeMixin(mixins[i].getName());
+ }
+ complete();
+
+ } catch (RepositoryException e) {
+ // NoSuchNodeTypeException, ConstraintViolationException should never occur...
+ throw new JcrDavException(e);
+ }
+ } else {
+ // all props except for mixinnodetypes are read-only
+ throw new DavException(DavServletResponse.SC_CONFLICT);
+ }
+ }
+
+ /**
+ * If the specified resource represents a collection, a new node is {@link Node#addNode(String)
+ * added} to the item represented by this resource. If an input stream is specified
+ * together with a collection resource {@link Session#importXML(String, java.io.InputStream, int)}
+ * is called instead and this resource path is used as <code>parentAbsPath</code> argument.
+ * <p/>
+ * However, if the specified resource is not of resource type collection a
+ * new {@link Property} is set or an existing one is changed by modifying its
+ * value.<br>
+ * NOTE: with the current implementation it is not possible to create or
+ * modify multivalue JCR properties.<br>
+ * NOTE: if the JCR property represented by the specified resource has an
+ * {@link PropertyType#UNDEFINED undefined} resource type, its value will be
+ * changed/set to type {@link PropertyType#BINARY binary}.
+ *
+ * @param resource
+ * @param in
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.DavResource#addMember(org.apache.jackrabbit.webdav.DavResource, java.io.InputStream)
+ * @see Node#addNode(String)
+ * @see Node#setProperty(String, java.io.InputStream)
+ */
+ public void addMember(DavResource resource, InputStream in)
+ throws DavException {
+
+ /* RFC 2815 states that all 'parents' must exist in order all addition of members */
+ if (!exists()) {
+ throw new DavException(DavServletResponse.SC_CONFLICT);
+ }
+
+ try {
+ Node n = (Node) item;
+ if (resource.isCollection()) {
+ if (in == null) {
+ // MKCOL without a request body, try if a default-primary-type is defined.
+ n.addNode(resource.getDisplayName());
+ } else {
+ // MKCOL, which is not allowed for existing resources
+ if (getTransactionId() == null) {
+ // if not part of a transaction directely import on workspace
+ // since changes would be explicitely saved in the
+ // complete-call.
+ getRepositorySession().getWorkspace().importXML(getResourcePath(), in, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+ } else {
+ // changes will not be persisted unless the tx is completed.
+ getRepositorySession().importXML(getResourcePath(), in, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+ }
+ }
+ } else {
+ if (in == null) {
+ // PUT: not possible
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Cannot create a new non-collection resource without request body.");
+ } else {
+ // TODO: find a way to create non-binary and multivalue properties
+ // PUT : create new or overwrite existing property.
+ // NOTE: will fail for multivalue properties.
+ n.setProperty(getResourceName(resource.getResourcePath(), true), in);
+ }
+ }
+ complete();
+ } catch (ItemExistsException e) {
+ // according to RFC 2518: MKCOL only possible on non-existing/deleted resource
+ throw new JcrDavException(e, DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ } catch (IOException e) {
+ throw new DavException(DavServletResponse.SC_UNPROCESSABLE_ENTITY, e.getMessage());
+ }
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#addMember(org.apache.jackrabbit.webdav.DavResource)
+ */
+ public void addMember(DavResource resource) throws DavException {
+ addMember(resource, resource.getStream());
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.DavResource#getMembers()
+ */
+ public DavResourceIterator getMembers() {
+ ArrayList memberList = new ArrayList();
+ if (exists()) {
+ try {
+ Node n = (Node)item;
+ // add all node members
+ NodeIterator it = n.getNodes();
+ while (it.hasNext()) {
+ Node node = it.nextNode();
+ DavResourceLocator loc = getLocatorFromItem(node);
+ memberList.add(createResourceFromLocator(loc));
+ }
+ // add all property members
+ PropertyIterator propIt = n.getProperties();
+ while (propIt.hasNext()) {
+ Property prop = propIt.nextProperty();
+ DavResourceLocator loc = getLocatorFromItem(prop);
+ memberList.add(createResourceFromLocator(loc));
+ }
+ } catch (RepositoryException e) {
+ // ignore
+ log.error(e.getMessage());
+ } catch (DavException e) {
+ // should never occur.
+ log.error(e.getMessage());
+ }
+ }
+ return new DavResourceIteratorImpl(memberList);
+ }
+
+ /**
+ * Removes the repository item represented by the specified member
+ * resource.
+ *
+ * @throws DavException if this resource does not exist or if an error occurs
+ * while deleting the underlaying item.
+ * @see DavResource#removeMember(DavResource)
+ * @see javax.jcr.Item#remove()
+ */
+ public void removeMember(DavResource member) throws DavException {
+ Session session = getRepositorySession();
+ try {
+ if (!exists() || !session.itemExists(member.getResourcePath())) {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+ if (!getResourcePath().equals(Text.getRelativeParent(member.getResourcePath(), 1))) {
+ throw new DavException(DavServletResponse.SC_CONFLICT, member.getResourcePath() + "is not member of this resource (" + getResourcePath() + ")");
+ }
+ session.getItem(member.getResourcePath()).remove();
+ complete();
+ } catch (RepositoryException e) {
+ log.error("Unexpected error: " + e.getMessage());
+ throw new JcrDavException(e);
+ }
+ }
+
+ /**
+ * @param type
+ * @param scope
+ * @return true if a lock with the specified type and scope is present on
+ * this resource, false otherwise. If retrieving the corresponding information
+ * fails, false is returned.
+ * @see org.apache.jackrabbit.webdav.DavResource#hasLock(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
+ */
+ public boolean hasLock(Type type, Scope scope) {
+ if (isLockable(type, scope)) {
+ if (Type.WRITE.equals(type)) {
+ try {
+ return ((Node) item).isLocked();
+ } catch (RepositoryException e) {
+ log.error(e.getMessage());
+ }
+ } else {
+ return super.hasLock(type, scope);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the lock with the specified type and scope.
+ *
+ * @param type
+ * @param scope
+ * @return lock with the specified type and scope is present on this
+ * resource or <code>null</code>. NOTE: If retrieving the write lock present
+ * on the underlaying repository item fails, <code>null</code> is return.
+ * @see org.apache.jackrabbit.webdav.DavResource#getLock(org.apache.jackrabbit.webdav.lock.Type, org.apache.jackrabbit.webdav.lock.Scope)
+ * @see javax.jcr.Node#getLock() for the write locks.
+ */
+ public ActiveLock getLock(Type type, Scope scope) {
+ ActiveLock lock = null;
+ if (isLockable(type, scope)) {
+ if (Type.WRITE.equals(type)) {
+ try {
+ if (!exists()) {
+ log.warn("Unable to retrieve lock: no item found at '" + getResourcePath() + "'");
+ } else if (((Node) item).isLocked()) {
+ Lock jcrLock = ((Node) item).getLock();
+ // TODO: find out whether this lock is session-scoped or not!
+ lock = new JcrActiveLock(jcrLock);
+ }
+ } catch (AccessDeniedException e) {
+ log.error("Error while accessing resource lock: "+e.getMessage());
+ } catch (UnsupportedRepositoryOperationException e) {
+ log.error("Error while accessing resource lock: "+e.getMessage());
+ } catch (RepositoryException e) {
+ log.error("Error while accessing resource lock: "+e.getMessage());
+ }
+ } else {
+ lock = super.getLock(type, scope);
+ }
+ }
+ return lock;
+ }
+
+ /**
+ * Creates a lock on this resource by locking the underlaying
+ * {@link javax.jcr.Node node}. Except for the {@link org.apache.jackrabbit.webdav.lock.LockInfo#isDeep()} }
+ * all information included in the <code>LockInfo</code> object is ignored.
+ * Lock timeout is defined by JCR implementation.
+ *
+ * @param reqLockInfo
+ * @return lock object representing the lock created on this resource.
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.DavResource#lock(org.apache.jackrabbit.webdav.lock.LockInfo)
+ * @see Node#lock(boolean, boolean)
+ */
+ public ActiveLock lock(LockInfo reqLockInfo) throws DavException {
+
+ if (!isLockable(reqLockInfo.getType(), reqLockInfo.getScope())) {
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+
+ if (Type.WRITE.equals(reqLockInfo.getType())) {
+ if (!exists()) {
+ log.warn("Cannot create a write lock for non-existing JCR node (" + getResourcePath() + ")");
+ throw new DavException(DavServletResponse.SC_NOT_FOUND);
+ }
+ try {
+ boolean sessionScoped = EXCLUSIVE_SESSION.equals(reqLockInfo.getScope());
+ Lock jcrLock = ((Node)item).lock(reqLockInfo.isDeep(), sessionScoped);
+ return new JcrActiveLock(jcrLock, sessionScoped);
+
+ } catch (RepositoryException e) {
+ // UnsupportedRepositoryOperationException should not occur...
+ throw new JcrDavException(e);
+ }
+ } else {
+ return super.lock(reqLockInfo);
+ }
+ }
+
+ /**
+ * Refreshes the lock on this resource. With this implementation the
+ * {@link javax.jcr.lock lock} present on the underlaying {@link javax.jcr.Node node}
+ * is refreshed. The timeout indicated by the <code>LockInfo</code>
+ * object is ignored.
+ *
+ * @param reqLockInfo LockInfo as build from the request.
+ * @param lockToken
+ * @return the updated lock info object.
+ * @throws org.apache.jackrabbit.webdav.DavException in case the lock could not be refreshed.
+ * @see org.apache.jackrabbit.webdav.DavResource#refreshLock(org.apache.jackrabbit.webdav.lock.LockInfo, String)
+ * @see javax.jcr.lock.Lock#refresh()
+ */
+ public ActiveLock refreshLock(LockInfo reqLockInfo, String lockToken)
+ throws DavException {
+
+ if (lockToken == null) {
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+
+ ActiveLock lock = getLock(reqLockInfo.getType(), reqLockInfo.getScope());
+ if (lock == null) {
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "No lock with the given scope/type present on this resource.");
+ }
+
+ if (Type.WRITE.equals(lock.getType())) {
+ try {
+ Lock jcrLock = ((Node) item).getLock();
+ jcrLock.refresh();
+ return new JcrActiveLock(jcrLock, EXCLUSIVE_SESSION.equals(lock.getScope()));
+ } catch (RepositoryException e) {
+ /*
+ NOTE: LockException is only thrown by Lock.refresh()
+ the lock exception thrown by Node.getLock() was circumvented
+ by the init test if there is a lock applied...
+ NOTE: UnsupportedRepositoryOperationException should not occur
+ */
+ throw new JcrDavException(e);
+ }
+ } else {
+ return super.refreshLock(reqLockInfo, lockToken);
+ }
+ }
+
+ /**
+ * Remove the write lock from this resource by unlocking the underlaying
+ * {@link javax.jcr.Node node}.
+ *
+ * @param lockToken
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.DavResource#unlock(String)
+ * @see javax.jcr.Node#unlock()
+ */
+ public void unlock(String lockToken) throws DavException {
+ ActiveLock lock = getWriteLock();
+ if (lock != null && lockToken.equals(lock.getToken())) {
+ try {
+ ((Node) item).unlock();
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ }
+ } else {
+ super.unlock(lockToken);
+ }
+ }
+
+ /**
+ * Returns the write lock present on this resource or <code>null</code> if
+ * no write lock exists. NOTE: that the scope of a write lock may either
+ * be {@link org.apache.jackrabbit.webdav.lock.Scope#EXCLUSIVE} or {@link #EXCLUSIVE_SESSION}.
+ *
+ * @return write lock or <code>null</code>
+ * @throws DavException if this resource does not represent a repository item.
+ */
+ private ActiveLock getWriteLock() throws DavException {
+ if (!exists()) {
+ throw new DavException(DavServletResponse.SC_NOT_FOUND, "Unable to retrieve write lock for non existing repository item (" + getResourcePath() + ")");
+ }
+ ActiveLock writeLock = getLock(Type.WRITE, Scope.EXCLUSIVE);
+ if (writeLock == null) {
+ writeLock = getLock(Type.WRITE, EXCLUSIVE_SESSION);
+ }
+ return writeLock;
+ }
+
+ //-----------------------------------------< OrderingResource interface >---
+ /**
+ * Returns true if this resource exists and the nodetype defining the
+ * underlaying repository node allow to reorder this nodes children.
+ *
+ * @return true if {@link #orderMembers(OrderPatch)} can be called on this
+ * resource.
+ * @see org.apache.jackrabbit.webdav.ordering.OrderingResource#isOrderable()
+ * @see javax.jcr.nodetype.NodeType#hasOrderableChildNodes()
+ */
+ public boolean isOrderable() {
+ boolean orderable = false;
+ if (exists()) {
+ try {
+ orderable = ((Node) item).getPrimaryNodeType().hasOrderableChildNodes();
+ } catch (RepositoryException e) {
+ log.warn(e.getMessage());
+ }
+ }
+ return orderable;
+ }
+
+ /**
+ * Reorder the child nodes of the repository item represented by this
+ * resource as indicated by the specified {@link OrderPatch} object.
+ *
+ * @param orderPatch
+ * @throws org.apache.jackrabbit.webdav.DavException
+ * @see org.apache.jackrabbit.webdav.ordering.OrderingResource#orderMembers(org.apache.jackrabbit.webdav.ordering.OrderPatch)
+ * @see Node#orderBefore(String, String)
+ */
+ public void orderMembers(OrderPatch orderPatch) throws DavException {
+ if (!isOrderable()) {
+ throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+ // only custom ordering is allowed
+ if (!OrderingConstants.ORDERING_TYPE_CUSTOM.equalsIgnoreCase(orderPatch.getOrderingType())) {
+ throw new DavException(DavServletResponse.SC_UNPROCESSABLE_ENTITY,"Only DAV:custom ordering type supported.");
+ }
+
+ OrderPatch.Member[] instructions = orderPatch.getOrderInstructions();
+ Node n = (Node)item;
+ try {
+ for (int i = 0; i < instructions.length; i++) {
+ String srcRelPath = getResourceName(n.getPath() + instructions[i].getMemberHandle(), false);
+ Position pos = instructions[i].getPosition();
+ String destRelPath = getRelDestinationPath(pos, n.getNodes());
+
+ n.orderBefore(srcRelPath, destRelPath);
+ }
+ } catch (RepositoryException e) {
+ // UnsupportedRepositoryException should not occur
+ throw new JcrDavException(e);
+ }
+ }
+
+ /**
+ * Retrieve the relative path of the child node that acts as destination.
+ * A <code>null</code> destination path is used to place the child node indicated
+ * by the source path at the end of the list.
+ *
+ * @param position
+ * @param childNodes
+ * @return the relative path of the child node used as destination or <code>null</code>
+ * if the source node should be placed at the last position.
+ * @throws javax.jcr.RepositoryException
+ */
+ private String getRelDestinationPath(Position position, NodeIterator childNodes)
+ throws RepositoryException {
+
+ String destRelPath = null;
+ if (position.getType() == Position.TYPE_FIRST) {
+ while (childNodes.hasNext()) {
+ Node firstChild = childNodes.nextNode();
+ destRelPath = firstChild.getPath();
+ }
+ // no child nodes available > reordering to 'first' position fails.
+ if (destRelPath == null) {
+ throw new ItemNotFoundException("No 'first' item found for reordering.");
+ }
+ } else if (position.getType() == Position.TYPE_AFTER) {
+ String afterRelPath = getResourceName(position.getSegment(), false);
+ boolean found = false;
+ while (childNodes.hasNext() && destRelPath == null) {
+ String childPath = childNodes.nextNode().getPath();
+ if (found) {
+ destRelPath = childPath;
+ } else {
+ found = afterRelPath.equals(Text.getLabel(childPath));
+ }
+ }
+ } else {
+ destRelPath = position.getSegment();
+ }
+
+ if (destRelPath != null) {
+ destRelPath = getResourceName(destRelPath, false);
+ }
+
+ return destRelPath;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Extend the general {@link #supportedLock} field by lock entries specific for this
+ * resource: write locks (exclusive or exclusive session-scoped) in case the underlaying
+ * node has the node type mix:lockable.
+ *
+ * @see org.apache.jackrabbit.JcrConstants#MIX_LOCKABLE
+ */
+ protected void initLockSupport() {
+ super.initLockSupport();
+ // add exclusive write lock if allowed for the given node
+ try {
+ if (exists() && ((Node)item).isNodeType(JcrConstants.MIX_LOCKABLE)) {
+ supportedLock.addEntry(Type.WRITE, Scope.EXCLUSIVE);
+ // TODO: do session-scoped lock properly (including session caching and proper scope discovery)
+ //supportedLock.addEntry(new SessionScopedLockEntry());
+ }
+ } catch (RepositoryException e) {
+ log.warn(e.getMessage());
+ }
+ }
+
+ /**
+ * Fill the property set for this resource.
+ */
+ protected void initProperties() {
+ super.initProperties();
+ if (exists()) {
+ try {
+ String prefix = "_tmp_" + item.getName();
+ // create tmpFile in default system-tmp directory
+ File tmpfile = File.createTempFile(prefix, null, null);
+ tmpfile.deleteOnExit();
+ FileOutputStream out = new FileOutputStream(tmpfile);
+ getSession().getRepositorySession().exportSystemView(item.getPath(), out, false, true);
+ out.close();
+ in = new FileInputStream(tmpfile);
+
+ properties.add(new DefaultDavProperty(DavPropertyName.GETCONTENTLENGTH, new Long(tmpfile.length())));
+ properties.add(new DefaultDavProperty(DavPropertyName.GETCONTENTTYPE, "text/xml"));
+
+ } catch (IOException e) {
+ log.error("Error while property initialization: "+e.getMessage());
+ } catch (RepositoryException e) {
+ log.error("Error while property initialization: "+e.getMessage());
+ }
+
+ Node n = (Node)item;
+ // overwrite the default modificationtime if possible
+ try {
+ if (n.hasProperty(JcrConstants.JCR_LASTMODIFIED)) {
+ setModificationTime(n.getProperty(JcrConstants.JCR_LASTMODIFIED).getLong());
+ }
+ } catch (RepositoryException e) {
+ log.warn("Error while accessing jcr:lastModified property");
+ }
+ // overwrite the default creation date if possible
+ try {
+ if (n.hasProperty(JcrConstants.JCR_CREATED)) {
+ long creationTime = n.getProperty(JcrConstants.JCR_CREATED).getValue().getLong();
+ properties.add(new DefaultDavProperty(DavPropertyName.CREATIONDATE,
+ DavConstants.creationDateFormat.format(new Date(creationTime))));
+ }
+ } catch (RepositoryException e) {
+ log.warn("Error while accessing jcr:created property");
+ }
+
+ // add node-specific resource properties
+ try {
+ properties.add(new NodeTypeProperty(JCR_PRIMARYNODETYPE, n.getPrimaryNodeType(), false));
+ properties.add(new NodeTypeProperty(JCR_MIXINNODETYPES, n.getMixinNodeTypes(), false));
+ properties.add(new DefaultDavProperty(JCR_INDEX, new Integer(n.getIndex())));
+ addHrefProperty(JCR_REFERENCES, n.getReferences(), false);
+ if (n.isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
+ properties.add(new DefaultDavProperty(JCR_UUID, n.getUUID()));
+ }
+ } catch (RepositoryException e) {
+ log.error("Failed to retrieve primary nodetype property: " + e.getMessage());
+ }
+ try {
+ Item primaryItem = n.getPrimaryItem();
+ addHrefProperty(JCR_PRIMARYITEM, new Item[] {primaryItem}, false);
+ } catch (ItemNotFoundException e) {
+ log.info("No primary item present on this node '" + getResourcePath() + "'");
+ } catch (RepositoryException e) {
+ log.error("Error while retrieving primary item: " + e.getMessage());
+ }
+
+ // property defined by RFC 3648: this resource always has custom ordering!
+ if (isOrderable()) {
+ properties.add(new OrderingType(OrderingConstants.ORDERING_TYPE_CUSTOM));
+ }
+ }
+ }
+
+ /**
+ * Add a {@link org.apache.jackrabbit.webdav.property.HrefProperty} with the
+ * specified property name and values. Each item present in the specified
+ * values array is referenced in the resulting property.
+ *
+ * @param name
+ * @param values
+ * @param isProtected
+ */
+ protected void addHrefProperty(DavPropertyName name, Item[] values, boolean isProtected) {
+ if (values == null) {
+ return;
+ }
+ try {
+ String[] pHref = new String[values.length];
+ for (int i = 0; i < values.length; i++) {
+ pHref[i] = this.getLocatorFromResourcePath(values[i].getPath()).getHref(true);
+ }
+ properties.add(new HrefProperty(name, pHref, isProtected));
+ } catch (RepositoryException e) {
+ e.getMessage();
+ }
+ }
+
+ /**
+ * Add a new {@link HrefProperty href property} to the property set, where
+ * all items present in the specifed iterator are referenced in the
+ * resulting property.
+ *
+ * @param name
+ * @param itemIterator
+ * @param isProtected
+ * @see #addHrefProperty(DavPropertyName, Item[], boolean)
+ */
+ protected void addHrefProperty(DavPropertyName name, Iterator itemIterator,
+ boolean isProtected) {
+ ArrayList l = new ArrayList();
+ while (itemIterator.hasNext()) {
+ l.add(itemIterator.next());
+ }
+ addHrefProperty(name, (Item[]) l.toArray(new Item[l.size()]), isProtected);
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
------------------------------------------------------------------------------
svn:eol-style = native