You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by oz...@apache.org on 2004/09/20 11:10:03 UTC

cvs commit: jakarta-slide/proposals/external-tm/conf Slide-ds.xml Domain.xml

ozeigermann    2004/09/20 02:10:03

  Added:       proposals/external-tm/src/share/org/apache/slide/store
                        ExternalTransactionStore.java
               proposals/external-tm/src/share/org/apache/slide/common
                        AbstractService.java
               proposals/external-tm/conf Slide-ds.xml Domain.xml
  Log:
  Added extension for external transaction manager by Alejandro Gu�zar contributed 
  at http://issues.apache.org/bugzilla/show_bug.cgi?id=31290
  
  Revision  Changes    Path
  1.1                  jakarta-slide/proposals/external-tm/src/share/org/apache/slide/store/ExternalTransactionStore.java
  
  Index: ExternalTransactionStore.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/proposals/external-tm/src/share/org/apache/slide/store/ExternalTransactionStore.java,v 1.1 2004/09/20 09:10:02 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 09:10:02 $
   *
   * ====================================================================
   *
   * Copyright 1999-2003 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.slide.store;
  
  import java.util.Hashtable;
  
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.transaction.TransactionManager;
  
  import org.apache.slide.common.Namespace;
  import org.apache.slide.common.ServiceParameterErrorException;
  import org.apache.slide.common.ServiceParameterMissingException;
  import org.apache.slide.util.logger.Logger;
  
  /**
   * Store that allows for transactional caching of data over JTA transactions
   * provided by an external transaction manager.
   *
   * @version $Revision: 1.1 $
   */
  public class ExternalTransactionStore extends ExtendedStore {
    private TransactionManager txManager;
  
    /**
     * Parameter to specify the JNDI name of the transaction manager.
     */
    public static final String TX_MANAGER_NAME_PARAMETER = "tx-manager-name";
  
    /**
     * Default value for the transaction manager name parameter.
     */
    public static final String DEFAULT_TX_MANAGER_NAME = "java:/TransactionManager";
  
    private static final String LOG_CHANNEL = AppServerStore.class.getName();
  
    /**
     * Default constructor.
     */
    public ExternalTransactionStore() {
    }
  
    /* (non-Javadoc)
     * @see org.apache.slide.common.Service#setParameters(java.util.Hashtable)
     */
    public void setParameters(Hashtable parameters)
        throws ServiceParameterErrorException, ServiceParameterMissingException {
      super.setParameters(parameters);
  
      String txManagerName = (String) parameters.get(TX_MANAGER_NAME_PARAMETER);
      if (txManagerName == null) {
        txManagerName = DEFAULT_TX_MANAGER_NAME;
      }
  
      Logger logger = getLogger();
      logger.log("Setting transaction manager name for store " + getName() +
          " to " + txManagerName, LOG_CHANNEL, Logger.INFO);
  
      try {
        txManager = (TransactionManager) new InitialContext().lookup(txManagerName);
      }
      catch (NamingException e) {
        logger.log("Could not retrieve transaction manager named: " +
            txManagerName + "from JNDI context! Using default value", e,
            LOG_CHANNEL, Logger.WARNING);
      }
    }
  
    /* (non-Javadoc)
     * @see org.apache.slide.common.Service#setNamespace(
     *  org.apache.slide.common.Namespace)
     */
    public void setNamespace(Namespace namespace) {
      super.setNamespace(namespace);
      namespace.initTransactionManager(txManager);
    }
  }
  
  
  
  1.1                  jakarta-slide/proposals/external-tm/src/share/org/apache/slide/common/AbstractService.java
  
  Index: AbstractService.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/proposals/external-tm/src/share/org/apache/slide/common/AbstractService.java,v 1.1 2004/09/20 09:10:02 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 09:10:02 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 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.slide.common;
  
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.Arrays;
  
  import javax.transaction.xa.XAException;
  import javax.transaction.xa.XAResource;
  import javax.transaction.xa.Xid;
  
  import org.apache.slide.transaction.SlideTransactionManager;
  
  /**
   * Slide Service abstract implementation with support for multiple
   * simultaneous transaction context.
   *
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractService extends AbstractServiceBase
      implements Service {
  
  
      // -------------------------------------------------------------- Constants
  
  
      public static final int TX_IDLE = 0;
      public static final int TX_PREPARED = 1;
      public static final int TX_SUSPENDED = 2;
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * Current transaction context.
       */
      protected Hashtable currentContexts = new Hashtable();
  
  
      // ----------------------------------------------------- XAResource Mathods
  
  
      /**
       * Commit the global transaction specified by xid.
       *
       * @param xid A global transaction identifier
       * @param onePhase If true, the resource manager should use a one-phase
       * commit protocol to commit the work done on behalf of xid.
       * @exception XAException An error has occurred. Possible XAExceptions
       * are XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR,
       * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO. If the resource
       * manager did not commit the transaction and the paramether onePhase is
       * set to true, the resource manager may throw one of the XA_RB*
       * exceptions. Upon return, the resource manager has rolled back the
       * branch's work and has released all held resources.
       */
      public void commit(Xid xid, boolean onePhase)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (currentContext == null)
              throw new XAException(XAException.XAER_NOTA);
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
          if (!Arrays.equals(currentContext.getGlobalTransactionId(),
              xid.getGlobalTransactionId()))
              throw new XAException(XAException.XAER_PROTO);
  
          if (!onePhase && currentContextTuple.getStatus() != TX_PREPARED)
              throw new XAException(XAException.XAER_PROTO);
          if (onePhase &&
              (!((currentContextTuple.getStatus() == TX_IDLE) ||
                 (currentContextTuple.getStatus() == TX_SUSPENDED))))
              throw new XAException(XAException.XAER_PROTO);
  
          if (((ContextTuple) currentContexts.get(Thread.currentThread()))
              .getRollbackOnly()) {
              rollback(xid);
              throw new XAException(XAException.XA_RBROLLBACK);
          }
  
          currentContexts.remove(Thread.currentThread());
  
      }
  
  
      /**
       * Ends the work performed on behalf of a transaction branch. The
       * resource manager disassociates the XA resource from the transaction
       * branch specified and let the transaction be completed.
       * If TMSUSPEND is specified in flags, the transaction branch is
       * temporarily suspended in incomplete state. The transaction context is
       * in suspened state and must be resumed via start with TMRESUME specified.
       * If TMFAIL is specified, the portion of work has failed. The resource
       * manager may mark the transaction as rollback-only.
       * If TMSUCCESS is specified, the portion of work has completed
       * successfully.
       *
       * @param xid A global transaction identifier that is the same as what
       * was used previously in the start method.
       * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
       * @exception XAException An error has occurred. Possible XAException
       * values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA, XAER_INVAL,
       * XAER_PROTO, or XA_RB*.
       */
      public void end(Xid xid, int flags)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (currentContext == null)
              throw new XAException(XAException.XAER_NOTA);
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
          if (!Arrays.equals(currentContext.getGlobalTransactionId(),
              xid.getGlobalTransactionId()))
              throw new XAException(XAException.XAER_PROTO);
  
          if (flags == XAResource.TMSUSPEND)
              currentContextTuple.setStatus(TX_SUSPENDED);
  
          if (flags == XAResource.TMFAIL)
              ((ContextTuple) currentContexts.get(Thread.currentThread()))
                  .setRollbackOnly(true);
  
      }
  
  
      /**
       * Tell the resource manager to forget about a heuristically completed
       * transaction branch.
       *
       * @param xid A global transaction identifier
       * @exception XAException An error has occurred. Possible exception values
       * are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
       */
      public void forget(Xid xid)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (currentContext == null)
              throw new XAException(XAException.XAER_NOTA);
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
          if (!Arrays.equals(currentContext.getGlobalTransactionId(),
              xid.getGlobalTransactionId()))
              throw new XAException(XAException.XAER_PROTO);
  
          currentContexts.remove(Thread.currentThread());
  
      }
  
  
      /**
       * Obtain the current transaction timeout value set for this XAResource
       * instance. If XAResource.setTransactionTimeout was not use prior to
       * invoking this method, the return value is the default timeout set for
       * the resource manager; otherwise, the value used in the previous
       * setTransactionTimeout call is returned.
       *
       * @return the transaction timeout value in seconds.
       * @exception XAException An error has occurred. Possible exception
       * values are XAER_RMERR, XAER_RMFAIL.
       */
      public int getTransactionTimeout()
          throws XAException {
  
          return ((ContextTuple) currentContexts.get(Thread.currentThread()))
              .getTransactionTimeout();
  
      }
  
  
      /**
       * This method is called to determine if the resource manager instance
       * represented by the target object is the same as the resouce manager
       * instance represented by the parameter xares.
       *
       * @param xares An XAResource object whose resource manager instance is
       * to be compared with the resource manager instance of the target object.
       * @return true if it's the same RM instance; otherwise false.
       * @exception XAException An error has occurred. Possible exception values
       * are XAER_RMERR, XAER_RMFAIL.
       */
      public boolean isSameRM(XAResource xares)
          throws XAException {
  
          if (xares == null)
              return false;
  
          return (this == xares);
  
      }
  
  
      /**
       * Ask the resource manager to prepare for a transaction commit of the
       * transaction specified in xid.
       *
       * @param xid A global transaction identifier
       * @return A value indicating the resource manager's vote on the outcome
       * of the transaction. The possible values are: XA_RDONLY or XA_OK. If
       * the resource manager wants to roll back the transaction, it should do
       * so by raising an appropriate XAException in the prepare method.
       * @exception XAException An error has occurred. Possible exception
       * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL,
       * or XAER_PROTO.
       */
      public int prepare(Xid xid)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (currentContext == null)
              throw new XAException(XAException.XAER_NOTA);
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
  
          if (!Arrays.equals(currentContext.getGlobalTransactionId(),
              xid.getGlobalTransactionId()))
              throw new XAException(XAException.XAER_PROTO);
  
          if (!((currentContextTuple.getStatus() == TX_IDLE) ||
                (currentContextTuple.getStatus() == TX_SUSPENDED)))
              throw new XAException(XAException.XAER_PROTO);
  
          if (((ContextTuple) currentContexts.get(Thread.currentThread()))
              .getRollbackOnly()) {
              // FIXME: Don't know if should be automatically rollbacked in that
              // case
              throw new XAException(XAException.XA_RBROLLBACK);
          }
  
          currentContextTuple.setStatus(TX_PREPARED);
  
          return XAResource.XA_OK;
  
      }
  
  
      /**
       * Obtain a list of prepared transaction branches from a resource manager.
       * The transaction manager calls this method during recovery to obtain the
       * list of transaction branches that are currently in prepared or
       * heuristically completed states.
       *
       * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must
       * be used when no other flags are set in flags.
       * @return The resource manager returns zero or more XIDs for the
       * transaction branches that are currently in a prepared or heuristically
       * completed state. If an error occurs during the operation, the resource
       * manager should throw the appropriate XAException.
       * @exception XAException An error has occurred. Possible values are
       * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
       */
      public Xid[] recover(int flag)
          throws XAException {
  
          ContextTuple currentContextTuple =
             (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
             currentContextTuple!=null?currentContextTuple.getXid():null;
  
          Vector list = new Vector();
  
          if ((currentContextTuple.getStatus() == TX_PREPARED) &&
              (currentContext != null))
             list.addElement(currentContext);
  
          return (Xid[]) list.toArray(new Xid[list.size()]);
  
      }
  
  
      /**
       * Inform the resource manager to roll back work done on behalf of a
       * transaction branch.
       *
       * @param xid A global transaction identifier
       * @exception XAException An error has occurred
       */
      public void rollback(Xid xid)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (currentContext == null)
              throw new XAException(XAException.XAER_NOTA);
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
          if (!Arrays.equals(currentContext.getGlobalTransactionId(),
              xid.getGlobalTransactionId()))
              throw new XAException(XAException.XAER_PROTO);
  
          currentContexts.remove(Thread.currentThread());
  
      }
  
  
      /**
       * Set the current transaction timeout value for this XAResource instance.
       *
       * @param seconds the transaction timeout value in seconds.
       * @return true if transaction timeout value is set successfully;
       * otherwise false.
       * @exception XAException An error has occurred. Possible exception
       * values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
       */
      public boolean setTransactionTimeout(int seconds)
          throws XAException {
  
          ((ContextTuple) currentContexts.get(Thread.currentThread()))
              .setTransactionTimeout(seconds);
          return true;
  
      }
  
  
      /**
       * Start work on behalf of a transaction branch specified in xid If
       * TMJOIN is specified, the start is for joining a transaction previously
       * seen by the resource manager. If TMRESUME is specified, the start is
       * to resume a suspended transaction specified in the parameter xid. If
       * neither TMJOIN nor TMRESUME is specified and the transaction specified
       * by xid has previously been seen by the resource manager, the resource
       * manager throws the XAException exception with XAER_DUPID error code.
       *
       * @param xid A global transaction identifier to be associated with the
       * resource
       * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
       * @exception XAException An error has occurred. Possible exceptions are
       * XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, XAER_NOTA,
       * XAER_INVAL, or XAER_PROTO.
       */
      public void start(Xid xid, int flags)
          throws XAException {
  
          ContextTuple currentContextTuple =
              (ContextTuple) currentContexts.get(Thread.currentThread());
          Xid currentContext =
              currentContextTuple!=null?currentContextTuple.getXid():null;
  
          if (xid == null)
              throw new XAException(XAException.XAER_INVAL);
          if ( (currentContext != null) &&
               (!Arrays.equals(currentContext.getGlobalTransactionId(),
                xid.getGlobalTransactionId())) )
              throw new XAException(XAException.XAER_OUTSIDE);
  
          switch (flags) {
          case XAResource.TMNOFLAGS:
              if (currentContext != null)
                  throw new XAException(XAException.XAER_INVAL);
              currentContext = xid;
              // is the idle status really ok ???
              currentContexts.put
                  (Thread.currentThread(),new ContextTuple
                      (xid, TX_IDLE,
                       SlideTransactionManager.DEFAULT_TRANSACTION_TIMEOUT,
                       false));
              break;
          case XAResource.TMJOIN:
              if (currentContext == null)
                  throw new XAException(XAException.XAER_NOTA);
              if (!Arrays.equals(currentContext.getGlobalTransactionId(),
                  xid.getGlobalTransactionId()))
                  throw new XAException(XAException.XAER_INVAL);
              break;
          case XAResource.TMRESUME:
              if (currentContext == null)
                  throw new XAException(XAException.XAER_NOTA);
              if (currentContextTuple.getStatus() != TX_SUSPENDED)
                  throw new XAException(XAException.XAER_INVAL);
              currentContextTuple.setStatus(TX_IDLE);
              break;
          }
  
      }
  
  
      // ------------------------------------------------ ContextTuple InnerClass
  
  
      /**
       * inner class to pack both the xid and the status
       **/
      private class ContextTuple {
          private Xid xid;
          private int status;
          private int transactionTimeout;
          private boolean rollbackOnly;
          public ContextTuple(Xid xid, int status, int transactionTimeout,
                              boolean rollbackOnly) {
              this.xid    = xid;
              setStatus(status);
              setTransactionTimeout(transactionTimeout);
              setRollbackOnly(rollbackOnly);
          }
          public Xid getXid() {
              return xid;
          }
          public int getStatus() {
              return status;
          }
          public void setStatus(int status) {
              this.status = status;
          }
          public int getTransactionTimeout() {
              return transactionTimeout;
          }
          public void setTransactionTimeout(int transactionTimeout) {
              this.transactionTimeout = transactionTimeout;
          }
          public boolean getRollbackOnly() {
              return rollbackOnly;
          }
          public void setRollbackOnly(boolean rollbackOnly) {
              this.rollbackOnly = rollbackOnly;
          }
  
      }
  
  
  }
  
  
  1.1                  jakarta-slide/proposals/external-tm/conf/Slide-ds.xml
  
  Index: Slide-ds.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <datasources>
    <local-tx-datasource>
      <jndi-name>RepositoryTestDS</jndi-name>
      <connection-url>jdbc:mysql:///RepositoryTest</connection-url>
      <driver-class>com.mysql.jdbc.Driver</driver-class>
      <user-name>root</user-name>
      <!-- password>impasible</password -->
    </local-tx-datasource>
  </datasources>
  
  
  1.1                  jakarta-slide/proposals/external-tm/conf/Domain.xml
  
  Index: Domain.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <slide default="repository-test" logger="log4j.Log4jLogger" logger-level="6">
    <namespace name="repository-test">
      <definition>
        <store name="general-store" 
          classname="org.apache.slide.store.ExternalTransactionStore">
          <parameter name="tx-manager-name">java:/TransactionManager</parameter>
          <nodestore classname="org.apache.slide.store.impl.rdbms.J2EEStore">
            <parameter name="datasource">java:/RepositoryTestDS</parameter>
            <parameter name="adapter">
              org.apache.slide.store.impl.rdbms.MySql41RDBMSAdapter</parameter>
            <!-- leave the transaction manager in charge of db commits/rollbacks -->
            <parameter name="tm-commits">true</parameter>
          </nodestore>
          <securitystore>
            <reference store="nodestore"/>
          </securitystore>
          <lockstore>
            <reference store="nodestore"/>
          </lockstore>
          <revisiondescriptorsstore>
            <reference store="nodestore"/>
          </revisiondescriptorsstore>
          <revisiondescriptorstore>
            <reference store="nodestore"/>
          </revisiondescriptorstore>
          <contentstore>
            <reference store="nodestore"/>
          </contentstore>
        </store>
        <scope match="/" store="general-store"/>
      </definition>
      <configuration>
        <!-- Actions mapping -->
        <read-object>/actions/read</read-object>
        <create-object>/actions/write</create-object>
        <remove-object>/actions/write</remove-object>
        <grant-permission>/actions/write-acl</grant-permission>
        <revoke-permission>/actions/write-acl</revoke-permission>
        <read-permissions>/actions/read-acl</read-permissions>
        <read-own-permissions> 
          /actions/read-current-user-privilege-set</read-own-permissions>
        <lock-object>/actions/write</lock-object>
        <kill-lock>/actions/unlock</kill-lock>
        <read-locks>/actions/read</read-locks>
        <read-revision-metadata>/actions/read</read-revision-metadata>
        <create-revision-metadata> 
          /actions/write-properties</create-revision-metadata>
        <modify-revision-metadata> 
          /actions/write-properties</modify-revision-metadata>
        <remove-revision-metadata> 
          /actions/write-properties</remove-revision-metadata>
        <read-revision-content>/actions/read</read-revision-content>
        <create-revision-content>/actions/write-content</create-revision-content>
        <modify-revision-content>/actions/write-content</modify-revision-content>
        <remove-revision-content>/actions/write-content</remove-revision-content>
        <bind-member>/actions/bind</bind-member>
        <unbind-member>/actions/unbind</unbind-member>
        <!-- Paths configuration -->
        <userspath>/users</userspath>
        <rolespath>/roles</rolespath>
        <actionspath>/actions</actionspath>
        <filespath>/files</filespath>
        <parameter name="dav">true</parameter>
        <parameter name="standalone">true</parameter>
        <parameter name="acl_inheritance_type">path</parameter>
      </configuration>
      <data>
        <objectnode classname="org.apache.slide.structure.SubjectNode" uri="/">
          <permission action="all" subject="/roles/coach" inheritable="true"/>
          <permission action="/actions/read-acl" subject="all" inheritable="true" 
            negative="true"/>
          <permission action="/actions/write-acl" subject="all" 
            inheritable="true" negative="true"/>
          <permission action="/actions/unlock" subject="all" inheritable="true" 
            negative="true"/>
          <permission action="/actions/read" subject="all" inheritable="true"/>
          <!-- /users -->
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/users">
            <permission action="all" subject="self" inheritable="true"/>
            <permission action="all" subject="unauthenticated" inheritable="true" 
              negative="true"/>
            <!-- /users/coach represents the administrator -->
            <objectnode classname="org.apache.slide.structure.SubjectNode" 
              uri="/users/coach">
              <revision>
                <property namespace="http://jakarta.apache.org/slide/" 
                  name="password">qkqcemd8</property>
              </revision>
            </objectnode>
            <!-- /users/rival represents a non-administrator -->
            <objectnode classname="org.apache.slide.structure.SubjectNode" 
              uri="/users/rival">
              <revision>
                <property namespace="http://jakarta.apache.org/slide/" 
                  name="password">wawawa</property>
              </revision>
            </objectnode>
          </objectnode>
          <!-- /roles -->
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/roles">
            <permission action="all" subject="self" inheritable="true"/>
            <permission action="all" subject="unauthenticated" inheritable="true" 
              negative="true"/>
            <objectnode classname="org.apache.slide.structure.SubjectNode" 
              uri="/roles/coach">
              <revision>
                <property name="group-member-set"><![CDATA[<D:href xmlns:D='DAV:'>/users/coach</D:href>]]>
                   </property>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.SubjectNode" 
              uri="/roles/user">
              <revision>
                <property name="group-member-set"><![CDATA[<D:href xmlns:D='DAV:'>/users/coach</D:href><D:href xmlns:D='DAV:'>/users/rival</D:href>]]>
                   </property>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.SubjectNode" 
              uri="/roles/guest">
              <revision>
                <property name="group-member-set"><![CDATA[<D:href xmlns:D='DAV:'>/users/guest</D:href>]]>
                   </property>
              </revision>
            </objectnode>
          </objectnode>
          <!-- action -->
          <objectnode classname="org.apache.slide.structure.ActionNode" 
            uri="/actions">
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/read">
              <revision>
                <property name="privilege-member-set"> <![CDATA[<D:href xmlns:D='DAV:'>/actions/read-acl</D:href> <D:href xmlns:D='DAV:'>/actions/read-current-user-privilege-set</D:href>]]>
                   </property>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/read-acl">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/read-current-user-privilege-set">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/write">
              <revision>
                <property name="privilege-member-set"> <![CDATA[<D:href xmlns:D='DAV:'>/actions/write-acl</D:href> <D:href xmlns:D='DAV:'>/actions/write-properties</D:href> <D:href xmlns:D='DAV:'>/actions/write-content</D:href>]]>
                   </property>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/write-acl">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/write-properties">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/write-content">
              <revision>
                <property name="privilege-member-set"> <![CDATA[<D:href xmlns:D='DAV:'>/actions/bind</D:href> <D:href xmlns:D='DAV:'>/actions/unbind</D:href>]]>
                   </property>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/bind">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/unbind">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
            <objectnode classname="org.apache.slide.structure.ActionNode" 
              uri="/actions/unlock">
              <revision>
                <property name="privilege-member-set"/>
              </revision>
            </objectnode>
          </objectnode>
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/files">
            <permission action="all" subject="unauthenticated" 
              inheritable="true"/>
            <permission action="/actions/write" subject="/roles/user" 
              inheritable="true"/>
            <permission action="/actions/read-acl" subject="owner" 
              inheritable="true"/>
          </objectnode>
          <!-- DeltaV: default history and workspace paths -->
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/history">
            <permission action="all" subject="/roles/coach" inheritable="true"/>
            <permission action="/actions/read" subject="unauthenticated" 
              inheritable="true"/>
          </objectnode>
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/workspace">
            <permission action="all" subject="/roles/coach" inheritable="true"/>
            <permission action="/actions/read" subject="unauthenticated" 
              inheritable="true"/>
          </objectnode>
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
            uri="/workingresource">
            <permission action="all" subject="/roles/coach" inheritable="true"/>
            <permission action="/actions/read" subject="unauthenticated" 
              inheritable="true"/>
          </objectnode>
        </objectnode>
      </data>
    </namespace>
    <!-- DeltaV global parameters -->
    <parameter name="historypath">/history</parameter>
    <parameter name="workspacepath">/workspace</parameter>
    <parameter name="workingresourcepath">/workingresource</parameter>
    <parameter name="auto-version">checkout-checkin</parameter>
    <parameter name="auto-version-control">false</parameter>
    <parameter name="versioncontrol-exclude"/>
    <parameter name="checkout-fork">forbidden</parameter>
    <parameter name="checkin-fork">forbidden</parameter>
  </slide>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org