You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by ra...@apache.org on 2002/10/29 17:05:28 UTC

cvs commit: jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/portlets/html/cms content-administration-customize.vm content-administration.vm content.vm

raphael     2002/10/29 08:05:27

  Added:       scratchpad/jetspeed-cms build.properties build.xml
                        readme.txt
               scratchpad/jetspeed-cms/lib hsql.jar jdbc-se2.0.jar
                        jdbc2_0-stdext.jar jta.jar slide-kernel.jar
                        slide-roles.jar slide-stores.jar
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/modules/actions/portlets
                        CmsAdminAction.java
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide
                        Catalog.java ContentItem.java Link.java
                        Permission.java Resource.java
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms
                        CmsService.java DefaultCmsService.java
                        JetspeedCMSException.java
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/manager
                        CmsManager.java CmsManagerFactory.java
                        CmsManagerSlideImpl.java
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/repository/slide
                        JDBCDescriptorsStore.java
                        JetspeedDescriptorsStore.java Utility.java
               scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/util/cms
                        CMSLink.java
               scratchpad/jetspeed-cms/src/sql Slide-tables.sql
                        reinit_slide.sql
               scratchpad/jetspeed-cms/webapp/WEB-INF/conf
                        CmsResources.properties Domain.xml
                        TurbineResources.properties cms-portlets.xreg
               scratchpad/jetspeed-cms/webapp/WEB-INF/db cms-slide.backup
                        cms-slide.data cms-slide.properties
                        cms-slide.script
               scratchpad/jetspeed-cms/webapp/WEB-INF/psml/user/turbine/html
                        default.psml
               scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm
                        GlobalMacros.vm
               scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/portlets/html/cms
                        content-administration-customize.vm
                        content-administration.vm content.vm
  Log:
  Initial commit of Slide CMS integration contributed by Christophe Lombart <ch...@skynet.be>
  
  Revision  Changes    Path
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/build.properties
  
  Index: build.properties
  ===================================================================
  # Servlet engine locations for the tests
  
  # Note: If you don't want to run the test on a given servlet engine, just
  #       comment it's home property. For example, if you don't want to run the
  #       tests on the Resin 1.2, comment out the "resin.home.12" property.
  
  
  tomcat.home.40=D:/MyApplication/Apache Tomcat 4.0
  install.war=D:/MyApplication/Apache Tomcat 4.0/webapps
  deploy.war=D:/MyApplication/Apache Tomcat 4.0/webapps
  locale.default=en
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!-- Build file JETSPEED CMS Service -->
  
  <!DOCTYPE project >
  
  
  
  <project name="jetspeed-cms" default="jar" basedir=".">
  
      <!-- Give user a chance to override without editing this file 
           (and without typing -D each time they invoke a target) -->    
  
      <property file="${user.home}/.build.properties" />
      <property file="build.properties" />
    
      <!-- Generic project properties -->
  
      <property name="project.fullname" value="Jetspeed CMS Service"/>
      <property name="project.name" value="jetspeed-cms"/>
      <property name="project.version" value="0.1"/>      
  
      <!-- =================================================================== -->
      <!-- Set the properties related to the source tree                       -->
      <!-- =================================================================== -->
  
      <!-- Source locations for the build -->    
  
      <property name="src.dir" value="src"/>
      <property name="src.java.dir" value="${src.dir}/java"/>    
      <property name="src.xml.dir" value="${src.dir}/xml"/>
      <property name="src.config-server.dir" value="${src.dir}/config-server"/>
      <property name="lib.dir" value="lib"/>    
      <property name="jetspeed.lib.dir" value="../../lib"/>    
      <property name="jetspeed.build.dir" value="../../build/lib"/>    
      <property name="jetspeed.bin.dir" value="../../bin"/>    
      <property name="webapp.dir" value="webapp"/>        
      
      <!-- =================================================================== -->
      <!-- Set the properties related to the build area                        -->
      <!-- =================================================================== -->
  
      <!-- Destination locations for the build (relative to the basedir as -->
      <!-- specified in the 'basedir' attribute of the project tag)        -->
  
      <property name="build.dir" value="bin"/>        
      <property name="build.dest.dir" value="${build.dir}/classes"/>        
      <property name="javadocs.destdir" value="docs/api"/>    
      <property name="release.dir" value="${project.name}-${project.version}/"/>
  	  <property name="install.war" value="${build.dir}/webapp"/>
  
      <!-- Miscellaneous settings -->
  
      <property name="year" value="2002"/>
      <property name="locale.default" value="en"/>
      <property name="ant.home" value="."/>
      <property name="debug" value="on"/>
      <property name="optimize" value="off"/>
      <property name="deprecation" value="off"/>  
  
      <!-- =================================================================== -->
      <!-- Builds Classpath                                                    -->
      <!-- =================================================================== -->
      <path id="classpath">
          <fileset dir="${jetspeed.build.dir}">
  
              <!-- Everything in the build lib dir -->
  
              <include name="*.jar"/>
          </fileset>
          <fileset dir="${lib.dir}">
  
              <!-- Everything in the project's lib dir -->
  
              <include name="*.jar"/>
          </fileset>        
          <fileset dir="${jetspeed.lib.dir}">
  
              <!-- Everything in the jetspeed lib dir -->
  
              <include name="*.jar"/>
          </fileset>        
          <fileset dir="${jetspeed.bin.dir}">
  
              <!-- Jetspeed jar -->
  
              <include name="*.jar"/>
          </fileset>        
      </path>
  
      <!-- =================================================================== -->
      <!-- Initializes the build.                                              -->
      <!-- =================================================================== -->    
      <target name="init">
  
          <!-- So that we can use the ${TSTAMP}, ${DSTAMP}, ... time stamps
               in targets, if need be -->
          <tstamp/>
  
          <echo message="---------- ${project.fullname} ${project.version} ----------"/>
          <echo message=""/>
  
          <echo message="java.class.path = ${java.class.path}"/>        
          <echo message=""/>
          <echo message="java.home = ${java.home}"/>
          <echo message="ant.home = ${ant.home}"/>
          <echo message="user.home = ${user.home}"/>
          <echo message=""/>
          <echo message="basedir = ${basedir}"/>
          <echo message=""/>        
          <echo message="junit.jar = ${junit.jar}"/>
          <echo message="build.compiler = ${build.compiler}"/>
          <echo message="locale.default = ${locale.default}"/>
                  
          <mkdir dir="${build.dir}"/>
          <mkdir dir="${build.dest.dir}"/>
                    
      </target>
  
      <!-- ================================================================== -->
      <!-- Displays usage information                                         -->
      <!-- ================================================================== -->
      <target name="usage" description="Displays usage information">
          <echo message="Use -projecthelp to see the available targets"/>
      </target>
  
      <!-- =================================================================== -->
      <!-- Compiles the class files                                            -->
      <!-- =================================================================== -->
      <target 
          name="compile"  
          depends="init"
          description="Compiles the class files"
      >
          
          <javac 
              classpathref="classpath"
              srcdir="${src.java.dir}/" 
              destdir="${build.dest.dir}" 
              debug="${debug}"
              deprecation="${deprecation}"
              optimize="${optimize}">            
  	    
          </javac>
  
       </target>
  	
     
      <!-- =================================================================== -->
      <!-- Creates the jar file                                               -->
      <!-- =================================================================== -->
      <target name="jar" depends="compile" description="Creates the jar file">
          <jar
              jarfile="${build.dir}/${project.name}-${project.version}.jar" 
              basedir="${build.dest.dir}"            
              includes="org/"/>
      </target>
              
      <!-- ================================================================== -->
      <!-- jars the source                                                    -->
      <!-- ================================================================== -->
      <target name="jar-src"
              depends="init"
              description="Generates the jetspeed-cms.{ver}.src.jar file containing source only">
          <jar jarfile="${build.dir}/${project.name}-${project.version}.src.jar"
              basedir="${src.java.dir}" />
      </target>
      
      <!-- =================================================================== -->
      <!-- Generates the project's API documentation                           -->
      <!-- =================================================================== -->
      <target 
          name="javadocs" depends="jar" 
          description="Generates the project's API documentation"
      >
          <mkdir dir="${javadocs.destdir}"/>
          
          <javadoc        
              sourcepath="${src.java.dir}" 
              packagenames="org.*"
              destdir="${javadocs.destdir}"         
              author="true"
              private="false"
              version="true"
              use="true"
              windowtitle="${project.fullname} API"
              doctitle="${project.fullname}"                
              bottom="Copyright &#169; ${year} jetspeed-cms service. All Rights Reserved."
          >
              <classpath refid="classpath"/>
          </javadoc>
  
      </target>
          
       
   
      <!-- =================================================================== -->
      <!-- Installs jetspeed cms service  on a local Jetspeed application      -->
      <!-- =================================================================== -->
      <target name="install" depends="jar" description="Installs all jetspeed-cms files (jars, classes,  web-app, ... on a local server">
          <copy todir="${install.war}/jetspeed">
              <fileset dir="${webapp.dir}"/> 
          </copy>       
          <copy todir="${install.war}/jetspeed/WEB-INF/lib">
              <fileset dir="${lib.dir}">
                  <include name="*.jar"/>                
                  <exclude name="servlet*.jar"/>
              </fileset>            
          </copy>       
          <copy todir="${install.war}/jetspeed/WEB-INF/classes">
              <fileset dir="${build.dest.dir}">
                  <!-- Do not include test files in the runtime jar -->
                   <exclude name="**/Test*.*"/>
                   <exclude name="**/test*.*"/>
  
                  <!-- Also exclude the test cactus.properties file -->
                  <exclude name="cactus.properties"/>
              </fileset>
          </copy>  
  
      </target>    
  
      
      
      <!-- =================================================================== -->
      <!-- Rebuilds everything                                                 -->
      <!-- This is a little quicker than "clean; build" because there is no    -->
      <!-- second JVM bootup.                                                  -->
      <!-- =================================================================== -->
      <target name="rebuild" depends="jar" 
              description="Rebuilds everything"
      />
       
  </project>
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/readme.txt
  
  Index: readme.txt
  ===================================================================
  CMS Service Proposal
  ====================
  
  GOAL
  ----
  
  Create a flexible CMS service which can transparently support different CMS engines.
  The goal is not to create a new CMS engine specific to Jetspeed but define an interface 
  which can support the most important CMS engine.
  We will start with a default implementation based on Slide (http://jakarta.apache.org/slide).
  
  
  
  Features
  --------
  
  * Content Types
          + Catalog/folder
  	+ Unstructured content : HTML, MS Office document, pdf, ...
  	+ External URI : link to other external content 
  	+ XML content
  	
  	Each content type match to a java class (see org.apache.jetspeed.om.cms & org.apache.jetspeed.om.cms). So, it should be possible 
  	to create other content classes like images, ...
  
  
  * Security :  require complete integration/mapping with the Jetspeed security model
  
  * versioning
  
  * Index & query
  
  * Workflow
  
  * Notification
  
  * Content editing
  
  
  * Webdav support
  
  
  * Portlets : viewers, content administration, editor, notification, workflow follow-up, ...
  
  * Multi CMS engine support : we can imagine to support different CMS engine by using 
  
  * other ideas ?
  
  Development steps
  -----------------
  
  
  Phase 1:
  
  
  Phase 2:
  
  
  Phase 3:
  
  
  
  Service API
  -----------
  
  * Object model
  
  
  * Retrieve Resource
  
  * Create Resource
  
  * Assign security
  
  ...<TO DO>...
  
  
  Default implementation : Slide
  ------------------------------
  
  * Slide configuration : see CmsResources.properties & domain.xml in the conf folder.
  * Security : implemented by using a specific Slide store (see on org.apache.jetspeed.services.cms.slide.JetspeedDescriptorStore)
  
  * Default Repository : 
  	+ meta data : HSQL
  	+ content :  file system
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/hsql.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/jdbc-se2.0.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/jdbc2_0-stdext.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/jta.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/slide-kernel.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/slide-roles.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/lib/slide-stores.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/modules/actions/portlets/CmsAdminAction.java
  
  Index: CmsAdminAction.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  package org.apache.jetspeed.modules.actions.portlets;
  
  // Jetspeed Struff
  import org.apache.jetspeed.portal.portlets.VelocityPortlet;
  import org.apache.jetspeed.modules.actions.portlets.VelocityPortletAction;
  import org.apache.jetspeed.util.PortletConfigState;
  
  
  // Turbine stuff
  import org.apache.turbine.util.Log;
  import org.apache.turbine.util.RunData;
  
  // Velocity Stuff
  import org.apache.velocity.context.Context;
  
  
  /**
   * Action used for CMS Admin (CRUD on content/catalog).
   *
   * <p>Don't call it from the URL, the Portlet and the Action are automatically
   * associated through the registry PortletName
   *
   * @author <a href="mailto:Christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  public class CmsAdminAction extends VelocityPortletAction
  {
  
  
      private static final String CUSTOMIZE_TEMPLATE = "customize-template";
      /**
       * Subclasses should override this method if they wish to
       * build specific content when maximized. Default behavior is
       * to do the same as normal content.
       */
      protected void buildMaximizedContext( VelocityPortlet portlet,
                                            Context context,
                                            RunData rundata )
      {
          buildNormalContext( portlet, context, rundata);
  
      }
  
      /**
       * Subclasses should override this method if they wish to
       * provide their own customization behavior.
       * Default is to use Portal base customizer action
       */
      protected void buildConfigureContext( VelocityPortlet portlet,
                                            Context context,
                                            RunData rundata )
      {
  
          setTemplate(rundata, getParameterUsingFallback(portlet, rundata, CUSTOMIZE_TEMPLATE, null));
  
  
      }
  
      /**
       * Subclasses must override this method to provide default behavior
       * for the portlet action
       */
      protected void buildNormalContext( VelocityPortlet portlet,
                                         Context context,
                                         RunData rundata )
      {
          //portlet.getPortletConfig().getInitParameter("text"));
      }
  
  
      public void doCreateCatalog(RunData data, Context context)
      {
          //String text = data.getParameters().getString("text");
          //VelocityPortlet portlet = (VelocityPortlet)context.get("portlet");
          //portlet.setAttribute("text",text,data);
  
      }
  
      protected String getParameterUsingFallback(VelocityPortlet portlet, RunData rundata,
                                               String attrName, String attrDefValue)
      {
          return PortletConfigState.getParameter(portlet, rundata, attrName, attrDefValue);
      }
  
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide/Catalog.java
  
  Index: Catalog.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jetspeed.om.cms.slide;
  
  import java.util.Vector;
  import java.util.TreeMap;
  import java.util.Comparator;
  
  
  /**
   * <p> Wrapper class for a slide catalog resource (ObjectNode).<br>
   * Used to access to the catalog attributes
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public class Catalog extends Resource
  {
  
  	protected String logicalName = "";
  	private String title = "";
  	private String parentUri ="";
  	public static String TYPE="Catalog";
  	private TreeMap items = new TreeMap(new ItemComparator());
  
  	/**
  	* Constructor
  	*/
  	public Catalog()
  	{
  		super();
  		descriptor.setProperty("resourcetype","<collection/>");
  	}
  
  	public void addResource(String itemKey, Resource resource)
  	{
  		items.put(itemKey, resource);
  	}
  
  	public Vector getItems()
  	{
  		return new Vector(items.values()); // return a vector of "Resource"
  	}
  
  	/**
  	* Use in the comparator class for the treemap
  	*
  	*/
  	public String getKey()
  	{
  		return "1" + this.getTitle( ); // "1" because the catalog should
                                      // before the contentItem reference
  	}
  
  	public void setLogicalName(String logicalName)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("logicalName", logicalName);
  		}
  
       	this.logicalName = logicalName;
  	}
  
  	public String getLogicalName()
  	{
  		if ((descriptor != null) && ((this.logicalName == null) || (this.logicalName.equals(""))))
  		{
  			this.logicalName = (String) this.getProperty("logicalName");
  		}
  
  		return this.logicalName;
  	}
  
  	public void setTitle(String title)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("title", title);
  		}
  
  		this.title = title;
  	}
  
  	public String getTitle()
  	{
  		if ((descriptor != null) && ((this.title == null) || (this.title.equals(""))))
  		{
  			this.title = (String) this.getProperty("title");
  		}
  
  		return this.title;
  	}
  
  
  	public void setParentUri(String parentUri)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("parentUri", parentUri);
  		}
  
  		this.parentUri = parentUri;
  	}
  
  	public String getParentUri()
  	{
  		if ((descriptor != null) && ((this.parentUri == null) || (this.parentUri.equals(""))))
  		{
  			this.parentUri = (String) this.getProperty("parentUri");
  		}
  
  		return this.parentUri;
  	}
  
  	public String getType()
  	{
  		return Catalog.TYPE;
  	}
  
  	class ItemComparator implements Comparator
  	{
  		public int compare (Object key1, Object key2)
  		{
          	return ((String) key1).compareTo((String)key2);
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide/ContentItem.java
  
  Index: ContentItem.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jetspeed.om.cms.slide;
  
  import org.apache.turbine.util.Log;
  
  /**
   * <p> Wrapper class for a content Item (ObjectNode).<br>
   * Used to access to the content attributes
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  
  public class ContentItem extends Resource
  {
  	private String logicalName = "";
  	private String description = "";
  	private String contentType= "";            // URL, HTML Text or upload// if contentType = URL => external or portal link
  	private String contentReference = "";  // url or HTML content
  	private String contentClass="" ; // Application or Document
  	private String title = "";
  	private String author = "";
  	private Integer creationDate_year;
  	private Integer creationDate_month;
  	private Integer creationDate_day;
  	private String parentUri;
  
  	public static String TYPE = "ContentItem";
  
  	/**
  	* getKey() : use in the comparator defined in the Catalog.java class
  	*/
  	public String getKey()
  	{
  		return "2" + this.getTitle( ); // "2" because the contentItem should
  									 // after the catalogs reference
  	}
  
  	public boolean contentTypeisURLPortal()
  	{
  		String type = this.getContentType();
  
  		if (type == null)
  		{
  			return false;
  		}
  
  		return type.equals("URLPORT");
  	}
  
  	public boolean contentTypeisURLInternet()
  	{
  		String type = this.getContentType();
  
  		if (type == null)
  		{
  			return false;
  		}
  
  		return type.equals("URLINT");
  	}
  
  	public boolean contentTypeisHTML()
  	{
  		String type = this.getContentType();
  
  		if (type == null)
  		{
  			return false;
  		}
  
  		return type.equals("HTML");
  	}
  
  	public boolean contentTypeisUpload()
  	{
  		String type = this.getContentType();
  
  		if (type == null)
  		{
  			return false;
  		}
  
  		return type.equals("UPLOAD");
  	}
  
  	public void setContentClass(String contentClass)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("contentClass", contentClass);
  		}
  
   		this.contentClass = contentClass;
  	}
  
  	public String getContentClass()
  	{
  		if ((descriptor != null) && ((this.contentClass == null) || (this.contentClass.equals(""))))
  		{
  			this.contentClass = (String) this.getProperty("contentClass");
  		}
  
  		return this.contentClass;
  	}
  
  	public void setLogicalName(String logicalName)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("logicalName", logicalName);
  		}
  
  		this.logicalName = logicalName;
  	}
  
  	public String getLogicalName()
  	{
  
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("ContentItem.getLogicalName() :" + this.uri);
  		}
  
  		if ((descriptor != null) && ((this.logicalName == null) || (this.logicalName.equals(""))))
  		{
  			this.logicalName = (String) this.getProperty("logicalName");
  		}
  
  		return this.logicalName;
  	}
  
  	public void setDescription(String description)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("description", description);
  		}
  
  		this.description = description;
  	}
  
  	public String getDescription()
  	{
  		if ((descriptor != null) && ((this.description == null) || (this.description.equals(""))))
  		{
  			this.description = (String) this.getProperty("description");
  		}
  
  		return this.description;
  	}
  
  	public void setContentType(String contentType)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("contentType", contentType);
  		}
  
  		this.contentType = contentType;
  	}
  
  	public String getContentType()
  	{
  		if ((descriptor != null) && ((this.contentType == null) || (this.contentType.equals(""))))
  		{
  			this.contentType = (String) this.getProperty("contentType");
  		}
  
  		return this.contentType;
  	}
  
  	public void setContentReference(String contentReference)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("contentReference", contentReference);
  		}
  	  this.contentReference = contentReference;
  	}
  
  	public String getContentReference()
  	{
  		if ((descriptor != null) && ((this.contentReference == null) || (this.contentReference.equals(""))))
  		{
  			this.contentReference = (String) this.getProperty("contentReference");
  		}
  
  		return this.contentReference;
  	}
  
  	public void setTitle(String title)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("title", title);
  		}
  
  		this.title = title;
  	}
  
  	public String getTitle()
  	{
  		if ((descriptor != null) && ((this.title == null) || (this.title.equals(""))))
  		{
  			this.title = (String) this.getProperty("title");
  		}
  
  		return this.title;
  	}
  
  	public void setAuthor(String author)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("author", author);
  		}
  
  		this.author = author;
  	}
  
  	public String getAuthor()
  	{
  		if ((descriptor != null) && ((this.author == null) || (this.author.equals(""))))
  		{
  			this.author = (String) this.getProperty("author");
  		}
  
  		return this.author;
  	}
  
  	public void setCreationDate_year(Integer creationDate_year)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("creationDate_year", creationDate_year);
  		}
  
  		this.creationDate_year = creationDate_year;
  	}
  
  	public Integer getCreationDate_year()
  	{
  		if ((descriptor != null) && ((this.creationDate_year == null)))
  		{
  			this.creationDate_year = (Integer)this.getProperty("creationDate_year");
  		}
  
  		return this.creationDate_year;
  	}
  
  	public void setCreationDate_month(Integer creationDate_month)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("creationDate_month", creationDate_month);
  		}
  
  		this.creationDate_month = creationDate_month;
  	}
  
  	public Integer getCreationDate_month()
  	{
  		if ((descriptor != null) && ((this.creationDate_month == null)))
  		{
  			this.creationDate_month = (Integer) this.getProperty("creationDate_month");
  		}
  
  		return this.creationDate_month;
  	}
  
  	public void setCreationDate_day(Integer creationDate_day)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("creationDate_day", creationDate_day);
  		}
  
  		this.creationDate_day = creationDate_day;
  	}
  
  	public Integer getCreationDate_day()
  	{
  		if ((descriptor != null) && ((this.creationDate_day == null)))
  		{
  			this.creationDate_day = (Integer)this.getProperty("creationDate_day");
  		}
  
  		return this.creationDate_day;
  	}
  
  	public void setParentUri(String parentUri)
  	{
  		if (descriptor != null)
  		{
  			descriptor.setProperty("parentUri", parentUri);
  		}
  
  		this.parentUri = parentUri;
  	}
  
  	public String getParentUri()
  	{
  		if ((descriptor != null) && ((this.parentUri == null) || (this.parentUri.equals(""))))
  		{
  			this.parentUri = (String) this.getProperty("parentUri");
  		}
  
  		return this.parentUri;
  	}
  
  	public String getType()
  	{
  		return ContentItem.TYPE;
  	}
  }
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide/Link.java
  
  Index: Link.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  package  org.apache.jetspeed.om.cms.slide;
  
  /**
   * <p> Wrapper class for a link node.<br>
   * Used to access to the Link attributes
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public class Link extends Resource
  {
  	private String targetResourceUri;
  	public transient static String TYPE="Link";
  
  	public String getType()
  	{
  		return Link.TYPE;
  	}
  
  	public void setTargetResourceUri(String newTargetResourceUri)
  	{
  		targetResourceUri = newTargetResourceUri;
  	}
  
  	public String getTargetResourceUri()
  	{
  		return targetResourceUri;
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide/Permission.java
  
  Index: Permission.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package  org.apache.jetspeed.om.cms.slide;
  
  /**
   * <p> Permission assign to a {@link Resource}
   *
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public class Permission
  {
  
  	private String actor;
  	private String action;
  	private boolean inheritable;
  	private boolean negative;
  
  	public String getActor()
  	{
  		return actor;
  	}
  
  	public void setActor(String actor)
  	{
  		this.actor = actor;
  	}
  
  	public void setAction(String action)
  	{
  		this.action = action;
  	}
  
  	public String getAction()
  	{
  		return action;
  	}
  
  	public void setInheritable(boolean inheritable)
  	{
  		this.inheritable = inheritable;
  	}
  
  	public boolean isInheritable()
  	{
  		return inheritable;
  	}
  
  	public void setNegative(boolean negative)
  	{
  		this.negative = negative;
  	}
  
  	public boolean isNegative()
  	{
  		return negative;
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/om/cms/slide/Resource.java
  
  Index: Resource.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package  org.apache.jetspeed.om.cms.slide;
  
  import java.util.Vector;
  import org.apache.slide.content.NodeRevisionDescriptor;
  
  
  /**
   * <p> Ancestor class used for all content management resource
   *
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public class Resource
  {
  	public static String TYPE="Resource";
  	protected String uri;
  	protected NodeRevisionDescriptor descriptor;
  	protected Vector permissions;
  
  	public Resource ()
  	{
  		descriptor = new NodeRevisionDescriptor(0);
  		permissions = new Vector();
  	}
  
  	public void setDescriptor(NodeRevisionDescriptor descriptor)
  	{
  		this.descriptor = descriptor ;
  	}
  
  	public NodeRevisionDescriptor getDesciptor()
  	{
  		return descriptor;
  	}
  
  	public String getKey()
  	{
  		return "";
  	} // has to be defined in descendents
  
  	public String getTitle()
  	{
  		return "";
  	} // has to be defined in descendents
  
  	public void setUri(String uri)
  	{
  		this.uri = uri;
  	}
  
  	public String getUri()
  	{
  		return this.uri;
  	}
  
  	public String getType()
  	{
  		return Resource.TYPE;
  	}
  
  	public void setPermissions(Vector permissions)
  	{
  		this.permissions = permissions;
  	}
  
  	public Vector getPermissions()
  	{
  		return this.permissions;
  	}
  
  	public void addPermission(Permission permission)
  	{
  		permissions.add(permission);
  	}
  
  	protected Object getProperty(String propertyName)
  	{
  		try
  		{
  			return descriptor.getProperty(propertyName).getValue();
  		}
  		catch (Exception e)
  		{ //return null if the propertuy doesn't exits
  			return null;
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/CmsService.java
  
  Index: CmsService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms;
  
  // JDK
  import java.util.Vector;
  
  // Turbine
  import org.apache.turbine.util.upload.FileItem;
  import org.apache.turbine.services.Service;
  
  // Jetspeed
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  import org.apache.jetspeed.services.cms.manager.CmsManager;
  
  
  /**
   * Interface used by the CMS Jetspeed Service
   *
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public interface CmsService extends Service
  {
  
  	/**
       * The key in the TurbineResources.properties that references this
       * service.
       */
      public static final String SERVICE_NAME = "CmsService";
  
      public CmsManager getCmsManager() throws JetspeedCMSException;
  
  	public CmsManager getCmsManager(String nameSpace) throws JetspeedCMSException;
  
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/DefaultCmsService.java
  
  Index: DefaultCmsService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms;
  
  
  
  // Java core classes
  import java.util.*;
  
  // Tubine
  import org.apache.turbine.services.*;
  import org.apache.turbine.services.resources.*;
  
  // Jetspeed
  import org.apache.jetspeed.services.cms.manager.CmsManagerFactory;
  import org.apache.jetspeed.services.cms.manager.CmsManager;
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  
  
  /**
   * Default CMS service.
   * This class is an implementation of {@link CmsService}.
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  public class DefaultCmsService
      extends BaseService
      implements CmsService
  {
  
      /**
       *  List of all Cms Manager used by the service.
       *  TO DO : replace by the pool service (?)
       */
       private Hashtable cmsRepositories = new Hashtable();
  
      /**
       * Default namespace value.
       */
      private final static String DEFAULT_NAMESPACE_VALUE = "jetspeed-content";
  
      /**
       * Initialize the CMS Service.
       * @exception InitializationException error during initialization
       */
  	public void init() throws InitializationException
  	{
          // init the default CmsManager
          try
          {
  	        this.getCmsManager();
  		}
  		catch( JetspeedCMSException e)
  		{
  			throw new InitializationException("CMSService: Unable to retrieve default CMSManager");
  		}
  
          setInit(true);
  	}
  
      public CmsManager getCmsManager() throws JetspeedCMSException
      {
  		return this.getCmsManager(DEFAULT_NAMESPACE_VALUE);
  	}
  
      public CmsManager getCmsManager(String nameSpace) throws JetspeedCMSException
      {
  		CmsManager cms = null;
  
  		try
  		{
  			cms = (CmsManager) cmsRepositories.get(nameSpace);
  
  			if (cms == null)
  			{
  				cms = CmsManagerFactory.getInstance(nameSpace);
  				cmsRepositories.put(nameSpace, cms);
  			}
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("System Error : impossible to access to the content repository");
  		}
  
  		return cms;
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/JetspeedCMSException.java
  
  Index: JetspeedCMSException.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms;
  
  import org.apache.jetspeed.util.JetspeedException;
  
  
  /**
  *  Occurs when anything unexpected happens within Jetspeed with CMS service.
  *
  *  @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
  *
  */
  public class JetspeedCMSException extends JetspeedException
  {
      private boolean isAccessDenied;
  
      public JetspeedCMSException()
      {
          super();
      }
  
      public JetspeedCMSException(String message)
      {
          super(message);
      }
  
  	/**
  	 * Returns the isAccessDenied.
  	 * @return boolean
  	 */
  	public boolean isAccessDenied()
  	{
  		return isAccessDenied;
  	}
  
  	/**
  	 * Sets the isAccessDenied.
  	 * @param isAccessDenied The isAccessDenied to set
  	 */
  	public void setIsAccessDenied(boolean isAccessDenied)
  	{
  		this.isAccessDenied = isAccessDenied;
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/manager/CmsManager.java
  
  Index: CmsManager.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms.manager;
  
  // JDK
  import java.util.Vector;
  
  //Jetspeed
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  import org.apache.jetspeed.om.cms.slide.*;
  import org.apache.turbine.util.upload.FileItem;
  
  /**
   * Cms manager
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  public interface CmsManager
  {
  
  	/**
  	* Initialise the CmsManager.
  	* @param nameSpace used assigned to the CmsManager. This namespace can be
  	* used to read parameters assigned to this namespace in the JR.prop
  	*/
  	void init (String namespace)
  		   throws JetspeedCMSException;
  
  	/**
  	* Export the CMS repository into an xml file
  	* @param userNode User reference
  	* @param xmlFileName output file
  	*/
  	public void exportRepository (String userNode, String xmlFileName)
  		   throws JetspeedCMSException;
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param Catalog object to populate
  	*/
  	 public void populateCatalog (String userNode, Catalog catalog)
  		   throws JetspeedCMSException;
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param catalog object to populate
  	* @param withSubCatalog - retrieve or not sub-catalogs
  	* @param withContent - retrieve or not child ContentItems
  	*/
  	public void populateCatalog (String userNode, Catalog catalog,
  								 boolean withSubCatalog, boolean withContent)
  		   throws JetspeedCMSException;
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param catalog object to populate
  	* @param withSubCatalog - retrieve or not sub-catalogs
  	* @param withContent - retrieve or not child ContentItems
  	* @param numberOfLevels - number of tree level to populate
  	*/
  	public void populateCatalog (String userNode, Catalog catalog,
  								 boolean withSubCatalog, boolean withContent,
  								 int numberOfLevels )
  		   throws JetspeedCMSException  ;
  
  	/**
  	* Get all children from a specific parent uri
  	*
  	* @param userNode User reference
  	* @param parentUri uri used to get children
  	*/
  	public Vector getUriList (String userNode, String parentUri)
  		   throws JetspeedCMSException;
  
  
  	/**
  	* Get a resource object (Catalog or ContentItem)  from the repository
  	* based on a uri.
  	* @param userNode User reference
  	* @param uri
  	* @return resource that match to this uri
  	*/
  	public Resource getResource (String userNode, String uri )
  		   throws JetspeedCMSException ;
  
  	/**
  	* Get all catalogs defined between 2 uri (from - to)
  	*
  	* @param userNode User reference
  	* @param fromuri : first element of the interval
  	* @param toUri  : last element of the interval
  	* @return catalogs found between both uri
  	*/
  
  
  	public Vector getCatalogs(String userNode, String fromUri, String toUri)
  		   throws JetspeedCMSException ;
  
  	/**
  	* Get Security information assigned to an uri
  	* @param userNode User reference
  	* @param uri for which the security info is asked
  	*/
  	public Vector getSecurity (String userNode, String uri )
  		   throws JetspeedCMSException ;
  
  	/**
  	* Grant permission to an uri
  	* @param userNode User reference
  	* @param uri on which permission has to be set
  	* @param userUri User uri reference
  	* @param actionUri Action used in the permission (read, modify, write, ...)
  	* @param inheritable true if the permission has to be apply on child uri
  	* @param negative true if the permission is negative
  	*/
  	public void grantPermission (String userNode, String objectUri , String userUri,
  								 String actionUri, boolean inheritable,
  								 boolean negative)
  		   throws JetspeedCMSException ;
  	/**
  	* Create a new resource in the repository
  	* @param userNode User reference
  	* @param resource object describing the new resource
  	*/
  	public void createResource (String userNode, Resource resource)
  		   throws JetspeedCMSException ;
  	/**
  	* Create a new resource in the repository with a content stream
  	* @param userNode User reference
  	* @param resource object describing the new resource
  	* @param stream stream which match to the resource content
  	*/
  	public void createResource (String userNode, Resource resource, FileItem stream)
  		   throws JetspeedCMSException;
  
  	/**
  	* Create a new link in the repository
  	* @param userNode User reference
  	* @param link object describing the new link
  	*/
  	public void createLink (String userNode, Link link)
  	 throws JetspeedCMSException;
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/manager/CmsManagerFactory.java
  
  Index: CmsManagerFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms.manager;
  
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.util.TurbineException;
  import org.apache.turbine.services.resources.ResourceService;
  
  
  import org.apache.jetspeed.services.resources.JetspeedResources;
  import org.apache.jetspeed.services.cms.CmsService;
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  
  /**
   * Factory class for creating Jetspeed CmsManager.
   * The Cms class is configured in the JR.p
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  public class CmsManagerFactory
  {
  
      private static String cmsManagerClassName = null;
      private static Class cmsManagerClass = null;
  
      /**
       * Factory method to create CmsManager instances.
       *
       * @param namespace associated to a CMS repository
       * @throws Exception when the cmsManager instance can't be created.
       * @return CmsManager a new created cmsManager.
       */
      public static CmsManager getInstance(String namespace)
          throws JetspeedCMSException
  
      {
          CmsManager cmsManager = null;
  
          if (null == cmsManagerClassName)
          {
              try
              {
                  ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                           .getResources(CmsService.SERVICE_NAME);
                  cmsManagerClassName = serviceConf.getString("CmsManager." + namespace + ".class");
                  cmsManagerClass = Class.forName(cmsManagerClassName);
              }
              catch(Exception e)
              {
                  throw new JetspeedCMSException(
                      "CmsManagerFactory: Failed to create a Class object for Group implementation: " + e.toString());
              }
          }
  
          try
          {
              cmsManager = (CmsManager) cmsManagerClass.newInstance();
              cmsManager.init(namespace);
  
          }
          catch(Exception e)
          {
              throw new JetspeedCMSException("Failed instantiate an CmsManager implementation object: " + e.toString());
          }
  
          return cmsManager;
      }
  
  }
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/manager/CmsManagerSlideImpl.java
  
  Index: CmsManagerSlideImpl.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms.manager;
  /**
   * Slide implementation for the CmsManager
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   *
   */
  
  // Java 2 SDK
  import java.util.*;
  import java.io.FileWriter;
  import java.io.FileInputStream;
  import java.util.Vector;
  
  // Turbine
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.services.resources.ResourceService;
  import org.apache.turbine.util.upload.FileItem;
  import org.apache.turbine.util.Log;
  
  // Slide
  
  import org.apache.slide.structure.*;
  import org.apache.slide.content.*;
  import org.apache.slide.common.*;
  import org.apache.slide.lock.*;
  import org.apache.slide.security.*;
  import org.apache.slide.authenticate.CredentialsToken;
  import org.apache.slide.authenticate.SecurityToken;
  import org.apache.slide.security.AccessDeniedException;
  
  // Jetspeed
  import org.apache.jetspeed.om.cms.slide.*;
  import org.apache.jetspeed.services.cms.CmsService;
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  
  
  public class CmsManagerSlideImpl
  {
  
  	private NamespaceAccessToken token = null;
  	private Structure structure = null;
  	private Security security = null;
  	private Content content = null;
  	private Lock lock = null;
  	private static String PROPERTY_CLASS_NAME = "resourceClassName";
  	String nameSpace = null;
  
  	/**
  	* Initialise the CmsManager.
  	* @param nameSpace used assigned to the CmsManager. This namespace can be
  	* used to read parameters assigned to this namespace in the JR.prop
  	*/
  	void init (String namespace)
  			throws JetspeedCMSException
  	{
  		try
  		{
  			ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
  															.getResources(CmsService.SERVICE_NAME);
  			String domainFile = serviceConf.getString("CmsManager." + namespace + ".domainfile");
  			Domain.init(new FileInputStream(domainFile));
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException();
  		}
  
  		token = Domain.accessNamespace(new SecurityToken(new String()), namespace);
  
  		structure = token.getStructureHelper();
  		security = token.getSecurityHelper();
  		content = token.getContentHelper();
  		lock = token.getLockHelper();
  		this.nameSpace = namespace;
  	}
  
  	/**
  	* Export the CMS repository into an xml file
  	* @param userNode User reference
  	* @param xmlFileName output file
  	*/
  
  	public void exportRepository (String userNode, String xmlFileName)
  		   throws JetspeedCMSException
  	{
  		try
  		{
  			SlideToken slideToken = this.getSlideToken ( userNode );
  			token.exportData(slideToken, new FileWriter( xmlFileName ));
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to export the content respository");
  		}
  	}
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param Catalog object to populate
  	*/
  	public void populateCatalog (String userNode, Catalog catalog)
  		   throws JetspeedCMSException
  	{
  		this.populateCatalog(userNode, catalog, true, true, -1);
  	}
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param catalog object to populate
  	* @param withSubCatalog - retrieve or not sub-catalogs
  	* @param withContent - retrieve or not child ContentItems
  	*/
  	public void populateCatalog (String userNode, Catalog catalog,
  								 boolean withSubCatalog, boolean withContent)
  		   throws JetspeedCMSException
  	{
  		this.populateCatalog(userNode, catalog, withSubCatalog,
  							 withContent, -1);
  	}
  
  	/**
  	* Populate a catalog structure from the repository
  	*
  	* @param userNode User reference
  	* @param catalog object to populate
  	* @param withSubCatalog - retrieve or not sub-catalogs
  	* @param withContent - retrieve or not child ContentItems
  	* @param numberOfLevels - number of tree level to populate
  	*/
  	public void populateCatalog (String userNode, Catalog catalog,
  								 boolean withSubCatalog, boolean withContent,
  								 int numberOfLevels )
  		   throws JetspeedCMSException
  	{
  		try
  		{
  			int tmpLevel = numberOfLevels ;
  			SlideToken slideToken = this.getSlideToken ( userNode );
  			ObjectNode objectNode = structure.retrieve(slideToken, catalog.getUri());
  
  			// -----------------  Get catalog children
  			Enumeration childrenUri = objectNode.enumerateChildren();
  			this.getChildren(userNode, childrenUri, catalog,
  							 withSubCatalog, withContent, numberOfLevels);
  
  			// -----------------  Get links
  			Enumeration linksUri = objectNode.enumerateLinks();
  			this.getChildren(userNode, linksUri, catalog,
  							 withSubCatalog, withContent, tmpLevel);
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to get catalog information");
  		}
  	}
  
  	/**
  	* Get all children from a specific parent uri
  	*
  	* @param userNode User reference
  	* @param parentUri uri used to get children
  	*/
  	public Vector getUriList (String userNode, String parentUri)
  		   throws JetspeedCMSException
  	{
  		try
  		{
  
  			Vector uriList = new Vector();
  
  			// Add the parent uri
  			uriList.add(parentUri);
  			//System.out.println("URI : " + parentUri);
  
  			// Retrieve children
  			SlideToken slideToken = this.getSlideToken ( userNode );
  			ObjectNode objectNode = structure.retrieve(slideToken, parentUri);
  			Enumeration children = objectNode.enumerateChildren();
  
  			// Add children to the vector
  			while (children.hasMoreElements())
  			{
  				String uriChild  = (String) children.nextElement();
  				Vector v = this.getUriList(userNode, uriChild);
  				uriList.addAll(v);
  			}
  
  			return uriList;
  		}
  		catch (Exception e)
  		{
  		   throw new JetspeedCMSException("Impossible to get the uri List");
  		}
  	}
  
  
  	/**
  	* Get a resource object (Catalog or ContentItem)  from the repository
  	* based on a uri.
  	* @param userNode User reference
  	* @param uri
  	* @return resource that match to this uri
  	*/
  	public Resource getResource (String userNode, String uri )
  		   throws JetspeedCMSException
  	{
  
  		Resource resource = null;
  
  		try
  		{
  			// Get the last NodeRevisionDescriptor
  			SlideToken slideToken = this.getSlideToken( userNode );
  
  			// uri parameter can be point to a linkNode => retrieve its target
  			// objectnode
  			ObjectNode objectNode = structure.retrieve(slideToken, uri, true);
  
  			// Get the last Node revision descriptor
  			NodeRevisionDescriptors revisionDescriptors =
  				 content.retrieve(slideToken, objectNode.getUri());
  			NodeRevisionDescriptor revisionDescriptor =
  				 content.retrieve(slideToken, revisionDescriptors);
  
  			// Check if the resource is a Catalog or an ContentItem
  			// (based on the property class name) & an create an object for this resource
  			NodeProperty p = revisionDescriptor.getProperty(PROPERTY_CLASS_NAME);
  			String className = (String) p.getValue();
  			resource = (Resource) Class.forName( className ).newInstance();
  			resource.setUri(uri);
  			// Populate the resource properties
  			resource.setDescriptor(revisionDescriptor);
  
  			// populate Security info
  			resource.setPermissions(this.getSecurity(userNode, uri));
  			return resource;
  		}
  		catch (AccessDeniedException e)
  		{
  			JetspeedCMSException e1 = new JetspeedCMSException("Impossible to get the content resource");
  			e1.setIsAccessDenied(true);
  			throw e1;
  		}
  		catch (NullPointerException e)
  		{
  			// Trigger when the objectNode has not the correct properties
  			// eg. :  for a User or Action node in Slide. These type of node are mapped to Catalog
  
  			Catalog catalog = new Catalog();
  			catalog.setUri(uri);
  			catalog.setLogicalName(uri);
  			catalog.setTitle(uri);
  			return catalog;
  		}
  		catch (RevisionDescriptorNotFoundException e)
  		{
  			// if  no revision descriptor => create an empty catalog object which
  			// contains the uri data, a default title and a default logical name
  			// This case arrives when the descriptor stores are not init by the
  			// method Slide.createResource(...)
  			// For example, after reading domain.xml, Slide will add all
  			// namespace defined in the "scoop" xml tag in the target store
  			// But in our case, we need different properties defined via the
  			// NodeRevisionDescriptor like the title, logical name, ...
  
  		   ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
  												 .getResources(CmsService.SERVICE_NAME);
  
  			if (uri.equals(serviceConf.getString("catalog.root.uri")))
  			{
  				Catalog catalog = new Catalog();
  				catalog.setUri(uri);
  				catalog.setLogicalName(serviceConf.getString("catalog.root.logicalame"));
  				catalog.setTitle(serviceConf.getString("catalog.root.title"));
  				return catalog;
  			}
  			else
  			{
  				// getResource called for a user/action ...
  				Catalog catalog = new Catalog();
  				catalog.setUri(uri);
  				catalog.setLogicalName(uri);
  				catalog.setTitle(uri);
  				return catalog;
  				//e.printStackTrace();
  				//return null;
  			}
  		}
  		catch ( Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to get the content resource");
  		}
  	}
  
  	/**
  	* Get all catalogs defined between 2 uri (from - to)
  	*
  	* @param userNode User reference
  	* @param fromuri : first element of the interval
  	* @param toUri  : last element of the interval
  	* @return catalogs found between both uri
  	*/
  	public Vector getCatalogs(String userNode, String fromUri, String toUri)
  		   throws JetspeedCMSException
  	{
  
  		Vector catalogs = new Vector();
  		String currentUri = toUri;
  
  		while ( true )
  		{
  			try
  			{
  				Catalog catalog = (Catalog) this.getResource(userNode , currentUri);
  				catalogs.insertElementAt(catalog, 0);
  
  				if ((currentUri.equals(fromUri)) ||
  					(catalog.getParentUri() == null) ||
  					(catalog.getParentUri().equals("")) )
  				{
  					break;
  				}
  
  				currentUri = catalog.getParentUri();
  			}
  			catch (JetspeedCMSException e)
  			{
  				// If the exception is accessDenied : continue the loop for other catalog
  				// else throw the exception
  				if (!e.isAccessDenied())
  				{
  					throw new JetspeedCMSException("Impossible to get the complete catalog path");
  				}
  			}
  		}
  
  		return catalogs;
  	}
  
  	/**
  	* Get Security information assigned to an uri
  	* @param userNode User reference
  	* @param uri for which the security info is asked
  	*/
  	public Vector getSecurity (String userNode, String uri )
  		   throws JetspeedCMSException
  	{
  		try
  		{
  			// Get the SlideToken in function of a SubjectNode string
  			SlideToken slideToken = this.getSlideToken( userNode );
  			// Retrieve security info
  			Enumeration e = security.enumeratePermissions(slideToken, uri);
  			Vector permissions = new Vector();
  
  			while (e.hasMoreElements())
  			{
  				org.apache.slide.security.NodePermission node =
  					(org.apache.slide.security.NodePermission) e.nextElement();
  				Permission p = new Permission();
  				p.setAction(node.getActionUri());
  				p.setActor(node.getSubjectUri());
  				p.setInheritable(node.isInheritable());
  				p.setNegative(node.isNegative());
  				permissions.add(p);
  			}
  
  			return permissions;
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to get the security information " + uri);
  		}
  	}
  
  	/**
  	* Grant permission to an uri
  	* @param userNode User reference
  	* @param uri on which permission has to be set
  	* @param userUri User uri reference
  	* @param actionUri Action used in the permission (read, modify, write, ...)
  	* @param inheritable true if the permission has to be apply on child uri
  	* @param negative true if the permission is negative
  	*/
  	public void grantPermission (String userNode, String objectUri , String userUri,
  								 String actionUri, boolean inheritable,
  								 boolean negative)
  		   throws JetspeedCMSException
  	{
  
  		try
  		{
  
  			// Get the SlideToken in function of a SubjectNode string
  			SlideToken slideToken = this.getSlideToken( userNode );
  
  			// uri parameter can be point to a linkNode => retrieve its target
  			// objectnode
  			ObjectNode objectNode = structure.retrieve(slideToken, objectUri, true);
  
  			// uri parameter can be point to a linkNode => retrieve its target
  			// objectnode
  			SubjectNode subjectNode = (SubjectNode) structure.retrieve(slideToken, userUri, true);
  
  			// Retrieve the Action Node
  			ActionNode actionNode = (ActionNode) structure.retrieve(slideToken, actionUri);
  
  			// Grant the permission
  			NodePermission perm = new NodePermission(objectNode, subjectNode,
  													  actionNode, inheritable,
  													  negative);
  			security.grantPermission(slideToken, perm);
  
  
  		}
  		catch ( Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to grant the permission");
  		}
  	}
  
  	/**
  	* Create a new resource in the repository
  	* @param userNode User reference
  	* @param resource object describing the new resource
  	*/
  	public void createResource (String userNode, Resource resource)
  		   throws JetspeedCMSException
  	{
  		try
  		{
  
  			// Get the SlideToken in function of a SubjectNode string
  			SlideToken slideToken = this.getSlideToken( userNode );
  
  			// Create the new resource ( Slide subjectNode )
  			SubjectNode subject = new SubjectNode();
  			structure.create(slideToken, subject, resource.getUri());
  
  			// ---- Create the new content revision descriptor
  			NodeRevisionDescriptor descriptor = resource.getDesciptor();
  			descriptor.setProperty(this.PROPERTY_CLASS_NAME,
  									 resource.getClass().getName());
  
  			if (resource instanceof Catalog)
  			{
  				// Get content length
  				descriptor.setProperty("getcontentlength", new Long(0));
  
  				// Resource type (collection) - use xml element recognize by webdav client
  				descriptor.setProperty(new NodeProperty("resourcetype", "<collection/>", true));
  			}
  			else
  			{
  				// Get content length
  				descriptor.setProperty("getcontentlength", new Long(0));
  
  				// Last modification date
  				descriptor.setLastModified(new Date());
  
  				// Etag generation
  				String etag = resource.getUri().hashCode() + "_"
  								//+ revisionNumber.hashCode() + "_"
  							   + descriptor.getContentLength();
  				descriptor.setProperty(new NodeProperty("getetag", etag, true));
  
  				descriptor.setProperty(new NodeProperty("getcontenttype", "", true));
  
  				// Resource type (collection or other type of content)
  				descriptor.setProperty(new NodeProperty("resourcetype", "", true));
  
  				// Source
  				descriptor.setProperty(new NodeProperty("source", "", true));
  
  				// Content Language
  				//revisionDescriptor.setProperty("getcontentlanguage", stream., true);
  
  				// Owner
  				//String owner = slideToken.getCredentialsToken().getPublicCredentials();
  				//descriptorescriptor.setProperty(new NodeProperty("owner", owner, true));
  
  				// For Microsoft tools
  
  				// Is hidden
  				NodeProperty property = new NodeProperty("ishidden", "0", "MICROSOFT");
  				descriptor.setProperty(property);
  
  				// Is collection
  				property = new NodeProperty("iscollection", "0", "MICROSOFT");
  				descriptor.setProperty(property);
  
  				// Is read only
  				property = new NodeProperty("isreadonly", "0", "MICROSOFT");
  				descriptor.setProperty(property);
  
  				// Last accessed
  				property = new NodeProperty("lastaccessed", (new Date()).toString(),
  											"MICROSOFT");
  				descriptor.setProperty(property);
  			}
  
  			content.create(slideToken, resource.getUri(), descriptor, null);
  
  		   // Grant permission if needed
  
  			Vector permissions = resource.getPermissions();
  
  			for (Enumeration e = permissions.elements(); e.hasMoreElements();)
  			{
  				Permission p = (Permission) e.nextElement();
  				this.grantPermission(userNode,resource.getUri(), p.getActor(),
  							  		p.getAction(), p.isInheritable(), p.isNegative());
  			}
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to create the content resource");
  		}
  	}
  
  	/**
  	* Create a new resource in the repository with a content stream
  	* @param userNode User reference
  	* @param resource object describing the new resource
  	* @param stream stream which match to the resource content
  	*/
  	public void createResource (String userNode, Resource resource, FileItem stream)
  		   throws JetspeedCMSException
  	{
  		try
  		{
  
  			// Get the SlideToken in function of a SubjectNode string
  			SlideToken slideToken = this.getSlideToken( userNode );
  
  			// Create the new resource ( Slide subjectNode )
  			SubjectNode subject = new SubjectNode();
  			structure.create(slideToken, subject, resource.getUri());
  
  			// Create the new content revision descriptor
  			NodeRevisionDescriptor descriptor = resource.getDesciptor();
  	   		descriptor.setProperty(this.PROPERTY_CLASS_NAME,
  								   resource.getClass().getName());
  
  	   		// Get content length
  	   		descriptor.setProperty("getcontentlength", new Long(stream.getSize()));
  
  	   		// Last modification date
  	   		descriptor.setLastModified(new Date());
  
  	   		// Etag generation
  	   		String etag = resource.getUri().hashCode() + "_"
  						   //+ revisionNumber.hashCode() + "_"
  						   + descriptor.getContentLength();
  	   		descriptor.setProperty(new NodeProperty("getetag", etag, true));
  
  	   		String contentType = stream.getContentType();
  	   		descriptor.setProperty(new NodeProperty("getcontenttype", contentType, true));
  
  	   		// Resource type (collection or other type of content
  	   		descriptor.setProperty(new NodeProperty("resourcetype", "", true));
  
  	   		// Source
  	   		descriptor.setProperty(new NodeProperty("source", "", true));
  
  	   		// displayname : use in a webdav client
  	   		String displayName = stream.getFileName().substring( stream.getFileName().lastIndexOf("\\")+1 );
  
  	   		descriptor.setProperty(new NodeProperty("displayname",
  												    "<![CDATA[" + displayName+ "]]>"));
  
  	   		// Content Language
  	   		//revisionDescriptor.setProperty("getcontentlanguage", stream., true);
  
  	   		// Owner
  	   		//String owner = slideToken.getCredentialsToken().getPublicCredentials();
  	   		//descriptorescriptor.setProperty(new NodeProperty("owner", owner, true));
  
  	   		// For Microsoft tools
  
  	   		// Is hidden
  	   		NodeProperty property = new NodeProperty("ishidden", "0", "MICROSOFT");
  	   		descriptor.setProperty(property);
  
  	   		// Is collection
  	   		property = new NodeProperty("iscollection", "0", "MICROSOFT");
  	   		descriptor.setProperty(property);
  
  	   		// Is read only
  	   		property = new NodeProperty("isreadonly", "0", "MICROSOFT");
  	   		descriptor.setProperty(property);
  
  	   		// Last accessed
  	   		property = new NodeProperty("lastaccessed", (new Date()).toString(),
  									    "MICROSOFT");
  	   		descriptor.setProperty(property);
  
  	   		// Add the content stream
  	   		NodeRevisionContent revisionContent = new NodeRevisionContent();
  	   		revisionContent.setContent(stream.getInputStream());
  
  	   		// Add all stuff in the slide repository
  	   		content.create(slideToken, resource.getUri(), descriptor, revisionContent);
  
  	   		// Grant permission if needed
  	   		Vector permissions = resource.getPermissions();
  
  	   		for (Enumeration e = permissions.elements(); e.hasMoreElements();)
  	   		{
  		 		Permission p = (Permission) e.nextElement();
  		 		this.grantPermission(userNode,resource.getUri(), p.getActor(),
  							  		 p.getAction(), p.isInheritable(), p.isNegative());
  	   		}
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to create the content resource");
  		}
  	}
  
  	/**
  	* Create a new link in the repository
  	* @param userNode User reference
  	* @param link object describing the new link
  	*/
  	public void createLink (String userNode, Link link)
  		throws JetspeedCMSException
  	{
  		try
  		{
  			// Get the SlideToken in function of a SubjectNode string
  			SlideToken slideToken = this.getSlideToken( userNode );
  
  			ObjectNode resourceNode = (ObjectNode) structure.retrieve(slideToken,
  											link.getTargetResourceUri() );
  			LinkNode linkNode = new LinkNode();
  			structure.createLink(slideToken, linkNode, link.getUri(), resourceNode);
  		}
  		catch (Exception e)
  		{
  			throw new JetspeedCMSException("Impossible to get the link");
  		}
  	}
  
  
  	// ------------------------------------------------------------------------------------------------
  	//
  	//  PRIVATE METHODS
  	//
  	// ------------------------------------------------------------------------------------------------
  
  	/**
  	* Create a new SlideToken instance in function
  	* of a SubjectNode
  	*
  	* @param user reference
  	* @returnv a Slide toke object
  	*/
  	private SlideToken getSlideToken (String userNode)
  	{
  		CredentialsToken credToken = new CredentialsToken(new String(userNode));
  
  		return new SlideTokenImpl(credToken);
  	}
  
  	private void getChildren(String userNode, Enumeration children,
  							 Catalog catalog, boolean withSubCatalog,
  							 boolean withContent,int numberOfLevels)
  		throws JetspeedCMSException
  	{
  
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("Slide.getChildren for : " + catalog.getUri());
  		}
  
  		if (numberOfLevels != -1)
  		{
  			numberOfLevels--;
  		}
  
  		while (children.hasMoreElements())
  		{
  			String childUri = (String) children.nextElement();
  
  			if (Log.getLogger().isDebugEnabled())
  			{
  				Log.debug("Slide.getChildren -  Child found : " + childUri);
  			}
  
  		   try
  		   {
  				Resource resource = this.getResource(userNode, childUri);
  
  				if (resource instanceof Catalog)
  				{
  					if (withSubCatalog)
  					{
  						// numberOfLevels == -1 means all levels in the repository tree
  						if ((numberOfLevels == -1) || (numberOfLevels > 0))
  						{
  							int tmp = numberOfLevels;
  							this.populateCatalog( userNode,
  												  (Catalog) resource,
  								  				  withSubCatalog,
  								  				  withContent,
  								  				  numberOfLevels );
  						}
  
  						if (Log.getLogger().isDebugEnabled())
  						{
  							Log.debug("Slide.add Children : " + resource.getKey());
  						}
  
  						catalog.addResource( resource.getKey(), resource);
  					}
  				}
  				else
  				{
  					if (withContent)
  					{
  						catalog.addResource(resource.getKey(), resource);
  					}
  				}
  			}
  			catch (JetspeedCMSException e)
  			{
  				// if the exception is AccessDenied : continue the loop for other children
  				// else it is a more serious exception => throws the exception to the caller
  				if (!e.isAccessDenied())
  				{
  					throw new JetspeedCMSException("Impossible to get the children information ");
  				}
  			}
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/repository/slide/JDBCDescriptorsStore.java
  
  Index: JDBCDescriptorsStore.java
  ===================================================================
  /*
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Jetspeed", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.jetspeed.services.cms.repository.slide;
  
  import java.lang.reflect.Constructor;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.Vector;
  import java.util.Date;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.sql.*;
  import javax.transaction.xa.XAException;
  import javax.transaction.xa.Xid;
  import org.apache.slide.common.*;
  import org.apache.slide.store.*;
  import org.apache.slide.structure.*;
  import org.apache.slide.security.*;
  import org.apache.slide.lock.*;
  import org.apache.slide.content.*;
  import org.apache.slide.util.logger.Logger;
  
  /**
   * JDBC 1.0 and 2.0 compliant store implementation.
   * This class comes from Slide code. Can be replace by another descriptor
   * store.
   *
   *
   *
   * TO DO : Use J2EE Datastore instead of this class
   *
   * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
   * @author Dirk Verbeeck
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  
  public class JDBCDescriptorsStore
      extends AbstractSimpleService
      implements LockStore, NodeStore, RevisionDescriptorsStore,
      RevisionDescriptorStore, SecurityStore
  {
  
      // -------------------------------------------------------------- Constants
  
      // Column numbers
  
      // Structure descriptors
  
      protected static final int OBJECTS_URI = 1;
      protected static final int OBJECTS_CLASS = 2;
  
      protected static final int CHILDREN_URI = 1;
      protected static final int CHILDREN_CHILDURI = 2;
  
      protected static final int LINKS_LINK = 1;
      protected static final int LINKS_LINKTO = 2;
  
      // Security descriptors
  
      protected static final int PERMISSIONS_OBJECT = 1;
      protected static final int PERMISSIONS_REVISION_NUMBER = 2;
      protected static final int PERMISSIONS_SUBJECT = 3;
      protected static final int PERMISSIONS_ACTION = 4;
      protected static final int PERMISSIONS_INHERITABLE = 5;
      protected static final int PERMISSIONS_NEGATIVE = 6;
  
      // Lock descriptors
  
      protected static final int LOCKS_ID = 1;
      protected static final int LOCKS_OBJECT = 2;
      protected static final int LOCKS_SUBJECT = 3;
      protected static final int LOCKS_TYPE = 4;
      protected static final int LOCKS_EXPIRATIONDATE = 5;
      protected static final int LOCKS_INHERITABLE = 6;
      protected static final int LOCKS_EXCLUSIVE = 7;
  
      // Content descriptors
  
      protected static final int REVISIONS_URI = 1;
      protected static final int REVISIONS_ISVERSIONED = 2;
      protected static final int REVISIONS_INITIALREVISION = 3;
  
      protected static final int WORKINGREVISION_URI = 1;
      protected static final int WORKINGREVISION_BASEREVISION = 2;
      protected static final int WORKINGREVISION_NUMBER = 3;
  
      protected static final int LATESTREVISIONS_URI = 1;
      protected static final int LATESTREVISIONS_BRANCHNAME = 2;
      protected static final int LATESTREVISIONS_NUMBER = 3;
  
      protected static final int BRANCHES_URI = 1;
      protected static final int BRANCHES_NUMBER = 2;
      protected static final int BRANCHES_CHILDNUMBER = 3;
  
      protected static final int REVISION_URI = 1;
      protected static final int REVISION_NUMBER = 2;
      protected static final int REVISION_BRANCHNAME = 3;
  
      protected static final int LABEL_URI = 1;
      protected static final int LABEL_NUMBER = 2;
      protected static final int LABEL_LABEL = 3;
  
      protected static final int PROPERTY_URI = 1;
      protected static final int PROPERTY_NUMBER = 2;
      protected static final int PROPERTY_NAME = 3;
      protected static final int PROPERTY_VALUE = 4;
      protected static final int PROPERTY_NAMESPACE = 5;
      protected static final int PROPERTY_TYPE = 6;
      protected static final int PROPERTY_PROTECTED = 7;
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * Database connection.
       */
      protected Connection connection;
  
  
      /**
       * Driver class name.
       */
      protected String driver;
  
  
      /**
       * Connection URL.
       */
      protected String url;
  
  
      /**
       * User name.
       */
      protected String user;
  
  
      /**
       * Password.
       */
      protected String password;
  
  
      /**
       * JDBC Version to use.
       */
      protected int jdbcVersion;
  
      /**
       * This store doesn't handle nested transactions, this variable keeps track
       * if the store is already enlisted to a transaction.
       */
      protected boolean alreadyEnlisted=false;
  
      // -------------------------------------------------------- Service Methods
  
      /**
       * Returns the sql statements to create the database objects.
       */
      protected String[] getDatabaseCreateStatements()
      {
          String[] statements = {
              "create table objects(uri varchar(65536) primary key," +
              "    classname varchar(4096))",
              "create table children(uri varchar(65536), " +
              "    childuri varchar(65536))",
              "create table links(link varchar(65536), " +
              "    linkto varchar(65536))",
              "create table permissions(object varchar(65536)," +
              "    revisionnumber varchar(20), " +
              "    subject varchar(65536), action varchar(65536), " +
              "    inheritable int, negative int)",
              "create table locks(id varchar(65536), object varchar(4096)," +
              "    subject varchar(4096), type varchar(4096), " +
              "    expirationdate varchar(15), inheritable int, " +
              "    xexclusive int)",
              "create table revisions(uri varchar(65536) primary key, " +
              "    isversioned int, initialrevision varchar(10))",
              "create table workingrevision(uri varchar(65536), " +
              "    baserevision varchar(20), xnumber varchar(20))",
              "create table latestrevisions(uri varchar(65536), " +
              "    branchname varchar(4096), xnumber varchar(20))",
              "create table branches(uri varchar(65536), xnumber varchar(20)," +
              "    childnumber varchar(20))",
              "create table revision(uri varchar(65536), xnumber varchar(20)," +
              "    branchname varchar(4096))",
              "create table label(uri varchar(65536), xnumber varchar(20)," +
              "    label varchar(4096))",
              "create table property(uri varchar(65536), xnumber varchar(20)," +
              "    name varchar(4096), value varchar(65536), " +
              "    namespace varchar(4096), type varchar(100), protected int)"};
  
          return statements;
      }
  
      /**
       * Initializes the data source with a set of parameters.
       *
       * @param parameters Hashtable containing the parameters' name
       * and associated value
       * @exception ServiceParameterErrorException Incorrect service parameter
       * @exception ServiceParameterMissingException Service parameter missing
       */
      public void setParameters(Hashtable parameters)
          throws ServiceParameterErrorException,
          ServiceParameterMissingException
  	{
  
          // Driver classname
          driver = (String) parameters.get("driver");
  
          // Connection url
          url = (String) parameters.get("url");
  
          // FIXME: before slide 1.0.12 the database url was passed
          // without "jdbc:" this compatibility code sould be removed in the
          // future code changed 18 jul 2001
          if (!url.startsWith("jdbc:"))
          {
              url="jdbc:" + url;
  		}
          // end compatibility code
  
          // User name
          user = (String) parameters.get("user");
          if (user == null)
          {
              user = new String();
          }
  
          // Password
          password = (String) parameters.get("password");
          if (password == null)
          {
              password = new String();
          }
  
          // JDBC version to use
          jdbcVersion = 1;
          String version = (String) parameters.get("jdbcversion");
          if (version != null)
          {
              jdbcVersion = (new Integer(version)).intValue();
          }
      }
  
      /**
       * Connects to JDBC and creates the basic table structure.
       *
       * @exception ServiceConnectionFailedException Connection to the
       * database failed
       */
      public synchronized void connect()
          throws ServiceConnectionFailedException
      {
          getLogger().log("Connecting to \"" + url + "\" as user \"" + user + "\"",LOG_CHANNEL,Logger.INFO);
          try
          {
          	connection = DriverManager.getConnection(url, user, password);
          }
          catch (SQLException e)
          {
              getLogger().log("Connecting to \"" + url + "\" as user \"" + user + "\" failed",LOG_CHANNEL,Logger.ERROR);
              getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceConnectionFailedException(this, e);
          }
  
          // all updates must be done inside a transaction, no auto commits
          try
          {
              connection.setAutoCommit(false);
          }
          catch (SQLException e)
          {
  		}
         /*
          Statement statement = null;
          try {
              statement = connection.createStatement();
              String[] statements = getDatabaseCreateStatements();
              for (int i=0; i<statements.length ; i++ ) {
                  statement.execute(statements[i]);
              }
  
              // Cloudscape needs a commit on DDL statements (create,...)
              connection.commit();
  
          } catch (SQLException e) {
              try { connection.rollback(); } catch (SQLException ex) { }
          } finally {
              closeStatement(statement);
          }
          */
          // we are just connected and are not enlisted
      	alreadyEnlisted=false;
      }
  
      /**
       * Disconnects from data source.
       *
       * @exception ServiceDisconnectionFailedException Disconnection
       * from database failed
       */
      public void disconnect()
          throws ServiceDisconnectionFailedException
  	{
          getLogger().log("Disconnecting from \"" + url + "\" as user \"" + user + "\"",LOG_CHANNEL,Logger.INFO);
          try
          {
          	if (connection != null)
          	{
                  connection.close();
  			}
              connection = null;
          }
          catch (SQLException e)
          {
              getLogger().log("Disconnecting from \"" + url + "\" as user \"" + user + "\" failed",LOG_CHANNEL,Logger.ERROR);
              getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceDisconnectionFailedException(this, e);
          }
      }
  
      /**
       * Initializes data source.
       * <p/>
       * Occurs in four steps :
       * <li>Driver class is loaded</li>
       * <li>Driver is intantiated</li>
       * <li>Driver registration in the driver manager</li>
       * <li>Creation of the basic tables, if they didn't exist before</li>
       *
       * @exception ServiceInitializationFailedException Throws an exception
       * if the data source has already been initialized before
       */
      public synchronized void initialize(NamespaceAccessToken token)
          throws ServiceInitializationFailedException
      {
          try
          {
              // Loading and registering driver
              token.getLogger().log("Loading and registering driver: " + driver,LOG_CHANNEL,Logger.INFO);
              Class driverClass = Class.forName(driver);
              Driver databaseDriver = (Driver) driverClass.newInstance();
              DriverManager.registerDriver(databaseDriver);
          }
          catch (ClassNotFoundException e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
          catch (InstantiationException e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
          catch (IllegalAccessException e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
          catch (SQLException e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
          catch (ClassCastException e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
          catch (Exception e)
          {
              token.getLogger().log("Loading and registering driver " + driver + " failed",LOG_CHANNEL,Logger.ERROR);
              token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
              throw new ServiceInitializationFailedException(this, e.getMessage());
          }
      }
  
  
      /**
       * Deletes data source. Should remove stored data if possible.
       *
       * @exception ServiceResetFailedException Reset failed
       */
      public synchronized void reset()
          throws ServiceResetFailedException
      {
          Statement statement = null;
         /*
          try {
              connectIfNeeded();
  
              statement = connection.createStatement();
              String s = null;
  
              s = "drop table objects";
              statement.execute(s);
  
              s = "drop table children";
              statement.execute(s);
  
              s = "drop table links";
              statement.execute(s);
  
              s = "drop table permissions";
              statement.execute(s);
  
              s = "drop table locks";
              statement.execute(s);
  
              s = "drop table revisions";
              statement.execute(s);
  
              s = "drop table workingrevision";
              statement.execute(s);
  
              s = "drop table latestrevisions";
              statement.execute(s);
  
              s = "drop table branches";
              statement.execute(s);
  
              s = "drop table revision";
              statement.execute(s);
  
              s = "drop table label";
              statement.execute(s);
  
              s = "drop table property";
              statement.execute(s);
  
              statement.close();
              disconnect();
          } catch (SQLException e) {
              throw new ServiceResetFailedException(this, e.getMessage());
          } catch (ServiceAccessException e) {
              throw new ServiceResetFailedException(this, e.getMessage());
          } catch (ServiceConnectionFailedException e) {
              throw new ServiceResetFailedException(this, e.getMessage());
          } catch (ServiceDisconnectionFailedException e) {
              throw new ServiceResetFailedException(this, e.getMessage());
          } finally {
              closeStatement(statement);
          }
          */
      }
  
  
      /**
       * This function tells whether or not the data source is connected.
       *
       * @return boolean true if we are connected
       * @exception ServiceAccessException Error accessing DataSource
       */
      public boolean isConnected()
          throws ServiceAccessException
      {
          try
          {
              return ((connection != null) && (!connection.isClosed()));
          }
          catch (SQLException e)
          {
              throw new ServiceAccessException(this, e);
          }
      }
  
  
      // ----------------------------------------------------- XAResource Methods
  
  
      /**
       * Commit the global transaction specified by xid.
       */
      public void commit(Xid xid, boolean onePhase)
          throws XAException
      {
          super.commit(xid, onePhase);
  
          try
          {
  //            getLogger().log("commit",LOG_CHANNEL,Logger.DEBUG);
              connection.commit();
          }
          catch (SQLException e)
          {
              throw new XAException(XAException.XA_RBCOMMFAIL);
          }
          alreadyEnlisted=false;
      }
  
  
      /**
       * Inform the resource manager to roll back work done on behalf of a
       * transaction branch.
       */
      public void rollback(Xid xid)
          throws XAException
      {
          super.rollback(xid);
  
          try
          {
  //            getLogger().log("rollback",LOG_CHANNEL,Logger.DEBUG);
              connection.rollback();
          }
          catch (SQLException e)
          {
              throw new XAException(XAException.XA_HEURCOM);
          }
          alreadyEnlisted=false;
      }
  
  
      /**
       * Start work on behalf of a transaction branch specified in xid.
       */
      public void start(Xid xid, int flags)
          throws XAException
      {
          super.start(xid, flags);
          if (!alreadyEnlisted)
          {
              try
              {
  //                getLogger().log("start",LOG_CHANNEL,Logger.DEBUG);
                  // discard changes made outside a tranaction
                  connection.rollback();
              }
              catch (SQLException e)
              {
                  throw new XAException(XAException.XAER_RMERR);
              }
              alreadyEnlisted=true;
          }
      }
  
  
      // ----------------------------------------------- DescriptorsStore Methods
  
  
      /**
       * Retrive an object.
       *
       * @param uri Uri of the object we want to retrieve
       * @exception ServiceAccessException Error accessing the Service
       * @exception ObjectNotFoundException The object to retrieve was not found
       */
      public ObjectNode retrieveObject(Uri uri)
          throws ServiceAccessException, ObjectNotFoundException
      {
  
          ObjectNode result = null;
          PreparedStatement statement = null;
  
          try
          {
  
              statement = connection.prepareStatement
                  ("select * from objects where uri= ?");
              statement.setString(1, uri.toString());
  
              ResultSet res = statement.executeQuery();
  
              // Parsing result set
  
              String className;
  
              if (res.next())
              {
                  // Retrieving and loading the object
                  className = res.getString(OBJECTS_CLASS);
              }
              else
              {
                  // Object was not found ...
                  throw new ObjectNotFoundException(uri);
              }
  
              closeStatement(statement);
  
              // Then, retrieve the children
              statement = connection.prepareStatement
                  ("select * from children where uri= ?");
              statement.setString(1,uri.toString());
              res = statement.executeQuery();
  
              Vector childrenVector = new Vector();
  
              // Parse result set
              while (res.next())
              {
                  // Load each permission
                  childrenVector.addElement(res.getString(CHILDREN_CHILDURI));
              }
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("select * from links where linkto= ?");
              statement.setString(1,uri.toString());
              res = statement.executeQuery();
  
              Vector linksVector = new Vector();
  
              // Parse result set
              while (res.next())
              {
                  // Load each permission
                  linksVector.addElement(res.getString(LINKS_LINKTO));
              }
  
              closeStatement(statement);
  
              if (className.equals("org.apache.slide.structure.LinkNode"))
              {
  
                  String linkTo = new String();
                  statement = connection.prepareStatement
                      ("select * from links where link= ?");
                  statement.setString(1,uri.toString());
                  res = statement.executeQuery();
  
                  if(res.next())
                  {
                      linkTo = res.getString(LINKS_LINKTO);
  				}
  
                  closeStatement(statement);
  
                  result = new LinkNode(uri.toString(), childrenVector,
                                        linksVector, linkTo);
  
              }
              else
              {
  
                  try
                  {
                      Class objclass = Class.forName(className);
  
                      Class[] argClasses =
                      	{
  							Class.forName("java.lang.String"),
                              Class.forName("java.util.Vector"),
                              Class.forName("java.util.Vector")
                          };
                      Object[] arguments =
                      	{
  							uri.toString(),
  							childrenVector,
  							linksVector
  						};
  
                      Constructor constructor =
                          objclass.getConstructor(argClasses);
                      result = (ObjectNode)constructor.newInstance(arguments);
                  }
                  catch(Exception e)
                  {
                      // ClassNotFoundException, NoSuchMethodException, etc.
                      throw new ServiceAccessException(this, e);
                  }
              }
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
          return result;
      }
  
  
      /**
       * Update an object.
       *
       * @param object Object to update
       * @exception ServiceAccessException Error accessing the Service
       * @exception ObjectNotFoundException The object to update was not found
       */
      public void storeObject(Uri uri, ObjectNode object)
          throws ServiceAccessException, ObjectNotFoundException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("select * from objects where uri= ?");
              statement.setString(1, uri.toString());
  
              ResultSet res = statement.executeQuery();
  
              // Parsing result set
  
              if (!res.next())
              {
                  throw new ObjectNotFoundException(uri);
              }
  
              closeStatement(statement);
  
              // Updating children
              statement = connection.prepareStatement
                  ("delete from children where uri= ?");
              statement.setString(1, object.getUri());
              statement.execute();
              closeStatement(statement);
  
              statement = null;
              Enumeration children = object.enumerateChildren();
              while (children.hasMoreElements())
              {
                  if (statement == null)
                  {
                      statement = connection.prepareStatement
                          ("insert into children values(?, ?)");
                  }
                  statement.setString(1, object.getUri());
                  statement.setString(2, (String)children.nextElement());
                  statement.execute();
              }
              closeStatement(statement);
  
              // Updating inbound links
              /*
              s = "delete from links where linkto='" + object.getUri() + "'";
              statement.execute(s);
              Enumeration links = object.enumerateLinks();
              while (children.hasMoreElements()) {
                  s = "insert into links values('"
                      + (String) links.nextElement() + "', '"
                      + object.getUri() + "')";
                  statement.execute(s);
              }
              */
  
              // Updating links
              statement = connection.prepareStatement
                  ("delete from links where link= ?");
              statement.setString(1, object.getUri());
              statement.execute();
              closeStatement(statement);
  
              if (object instanceof LinkNode)
              {
                  statement = connection.prepareStatement
                      ("insert into links values(?,?)");
                  statement.setString(1, object.getUri());
                  statement.setString(2, ((LinkNode) object).getLinkedUri());
                  statement.execute();
                  closeStatement(statement);
              }
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Create a new object.
       *
       * @param object ObjectNode
       * @param uri Uri of the object we want to create
       * @exception ServiceAccessException Error accessing the Service
       * @exception ObjectAlreadyExistsException An object already exists
       * at this Uri
       */
      public void createObject(Uri uri, ObjectNode object)
          throws ServiceAccessException, ObjectAlreadyExistsException
      {
  
          PreparedStatement statement = null;
  
          try
          {
  
              String className = object.getClass().getName();
  
              statement = connection.prepareStatement
                  ("select * from objects where uri= ?");
              statement.setString(1, uri.toString());
  
              ResultSet res = statement.executeQuery();
  
              // Parsing result set
  
              if (res.next())
              {
                  throw new ObjectAlreadyExistsException(uri.toString());
              }
  
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("insert into objects values(?,?)");
              statement.setString(1, uri.toString());
              statement.setString(2, className );
  
              statement.execute();
              closeStatement(statement);
  
              statement = null;
              // Inserting children
              Enumeration children = object.enumerateChildren();
              while (children.hasMoreElements())
              {
                  if (statement == null)
                  {
                      statement = connection.prepareStatement
                          ("insert into children values(?,?)");
                  }
                  statement.setString(1, uri.toString());
                  statement.setString(2, (String) children.nextElement());
                  statement.execute();
              }
              closeStatement(statement);
  
              // Updating inbound links
              /*
              Enumeration links = object.enumerateLinks();
              while (children.hasMoreElements()) {
                  s = "insert into links values('"
                      + (String) links.nextElement() + "', '"
                      + object.getUri() + "')";
                  statement.execute(s);
              }
              */
  
              // If the object is a link, also store the link information
              if (object instanceof LinkNode)
              {
                  statement = connection.prepareStatement
                      ("insert into links values(?,?)");
                  statement.setString(1, uri.toString());
                  statement.setString(2, ((LinkNode) object).getLinkedUri());
                  statement.execute();
                  closeStatement(statement);
              }
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
      }
  
  
      /**
       * Remove an object.
       *
       * @param object Object to remove
       * @exception ServiceAccessException Error accessing the Service
       * @exception ObjectNotFoundException The object to remove was not found
       */
      public void removeObject(Uri uri, ObjectNode object)
          throws ServiceAccessException, ObjectNotFoundException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              // Removing object
              statement = connection.prepareStatement
                  ("delete from objects where uri= ?");
              statement.setString(1,object.getUri());
              statement.execute();
              closeStatement(statement);
  
              // Removing children
              statement = connection.prepareStatement
                  ("delete from children where uri=?");
              statement.setString(1, object.getUri());
              statement.execute();
              closeStatement(statement);
  
              // Removing inbound links
              /*
              s = "delete from links where linkto='" + object.getUri() + "'";
              statement.execute(s);
              */
  
              // Removing links
              statement = connection.prepareStatement
                  ("delete from links where link= ?");
              statement.setString(1, object.getUri());
              statement.execute();
              closeStatement(statement);
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
      }
  
  
      /**
       * Grant a new permission.
       *
       * @param permission Permission we want to create
       * @exception ServiceAccessException Error accessing the Service
       */
      public void grantPermission(Uri uri, NodePermission permission)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              int inheritable = 0;
              if (permission.isInheritable())
              {
                  inheritable = 1;
              }
  
              int negative = 0;
              if (permission.isNegative())
              {
                  negative = 1;
              }
  
              NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
              String revisionNumberStr =
                  (revisionNumber == null) ? null : revisionNumber.toString();
  
              statement = connection.prepareStatement
                  ("insert into permissions values(?,?,?,?,?,?)");
              statement.setString(1, permission.getObjectUri());
              statement.setString(2, revisionNumberStr);
              statement.setString(3, permission.getSubjectUri());
              statement.setString(4, permission.getActionUri());
              statement.setInt(5, inheritable);
              statement.setInt(6, negative);
              statement.execute();
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Revoke a permission.
       *
       * @param permission Permission we want to create
       * @exception ServiceAccessException Error accessing the Service
       */
      public void revokePermission(Uri uri, NodePermission permission)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
  
              if(revisionNumber != null)
              {
                  statement = connection.prepareStatement
                      ("delete from permissions where object= ? and subject = ? and \"ACTION\" = ?  and revisionnumber = ? ");
                  statement.setString(4, revisionNumber.toString());
              }
              else
              {
                  statement = connection.prepareStatement
                      ("delete from permissions where object = ? and subject = ? and \"ACTION\" = ? and revisionnumber is NULL");
              }
  
              statement.setString(1, permission.getObjectUri());
              statement.setString(2, permission.getSubjectUri());
              statement.setString(3, permission.getActionUri());
  
              statement.execute();
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Revoke all the permissions on an object.
       *
       * @param permission Permission we want to create
       * @exception ServiceAccessException Error accessing the Service
       */
      public void revokePermissions(Uri uri)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("delete from permissions where object= ?");
              statement.setString(1, uri.toString());
              statement.execute();
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Enumerate permissions on an object.
       *
       * @param permission Permission we want to create
       * @exception ServiceAccessException Error accessing the Service
       */
      public Enumeration enumeratePermissions(Uri uri)
          throws ServiceAccessException
      {
  
          Vector permissionVector = new Vector();
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("select * from permissions where object= ?");
              statement.setString(1, uri.toString());
              ResultSet res = statement.executeQuery();
  
              while (res.next())
              {
                  String object   = res.getString(PERMISSIONS_OBJECT);
                  String revision = res.getString(PERMISSIONS_REVISION_NUMBER);
                  String subject  = res.getString(PERMISSIONS_SUBJECT);
                  String action   = res.getString(PERMISSIONS_ACTION);
  
                  boolean inheritable = false;
                  if (res.getInt(PERMISSIONS_INHERITABLE) == 1)
                  {
                      inheritable = true;
                  }
                  boolean negative = false;
                  if (res.getInt(PERMISSIONS_NEGATIVE) == 1)
                  {
                      negative = true;
                  }
                  NodePermission permission =
                      new NodePermission(object,revision,subject,
                                         action,inheritable,negative);
                  permissionVector.addElement(permission);
              }
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
          return permissionVector.elements();
      }
  
  
      /**
       * Create a new lock.
       *
       * @param lock Lock token
       * @exception ServiceAccessException Service access error
       */
      public void putLock(Uri uri, NodeLock lock)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              int inheritable = 0;
              if (lock.isInheritable())
              {
                  inheritable = 1;
              }
  
              int exclusive = 0;
              if (lock.isExclusive())
              {
                  exclusive = 1;
              }
  
              statement = connection.prepareStatement
                  ("insert into locks values(?,?,?,?,?,?,?)");
              statement.setString(1, lock.getLockId());
              statement.setString(2, lock.getObjectUri());
              statement.setString(3, lock.getSubjectUri());
              statement.setString(4, lock.getTypeUri());
              statement.setString
                  (5, String.valueOf(lock.getExpirationDate().getTime()));
              statement.setInt(6,inheritable);
              statement.setInt(7, exclusive);
              statement.execute();
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
      }
  
  
      /**
       * Renew a lock.
       *
       * @param lock Token to renew
       * @exception ServiceAccessException Service access error
       * @exception LockTokenNotFoundException Lock token was not found
       */
      public void renewLock(Uri uri, NodeLock lock)
          throws ServiceAccessException, LockTokenNotFoundException
      {
  
          PreparedStatement statement = null;
  
          try
          {
  
              int inheritable = 0;
              if (lock.isInheritable())
              {
                  inheritable = 1;
              }
  
              int exclusive = 0;
              if (lock.isExclusive())
              {
                  exclusive = 1;
              }
  
              statement = connection.prepareStatement
                  ("delete from locks where id=?");
              statement.setString(1, lock.getLockId());
              statement.execute();
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("insert into locks values(?,?,?,?,?,?,?)");
              statement.setString(1, lock.getLockId());
              statement.setString(2, lock.getObjectUri());
              statement.setString(3, lock.getSubjectUri());
              statement.setString(4, lock.getTypeUri());
              statement.setString
                  (5, String.valueOf(lock.getExpirationDate().getTime()));
              statement.setInt(6, inheritable);
              statement.setInt(7, exclusive);
              statement.execute();
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Unlock.
       *
       * @param lock Token to remove
       * @exception ServiceAccessException Service access error
       * @exception LockTokenNotFoundException Lock token was not found
       */
      public void removeLock(Uri uri, NodeLock lock)
          throws ServiceAccessException, LockTokenNotFoundException
      {
  
          Statement statement = null;
  
          try
          {
  
              statement = connection.createStatement();
  
              int inheritable = 0;
              if (lock.isInheritable())
              {
                  inheritable = 1;
              }
  
              String s = null;
  
              s = "delete from locks where id='" + lock.getLockId() + "'";
              statement.execute(s);
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Kill a lock.
       *
       * @param lock Token to remove
       * @exception ServiceAccessException Service access error
       * @exception LockTokenNotFoundException Lock token was not found
       */
      public void killLock(Uri uri, NodeLock lock)
          throws ServiceAccessException, LockTokenNotFoundException
      {
          removeLock(uri, lock);
      }
  
  
      /**
       * Enumerate locks on an object.
       *
       * @param subject Subject
       * @return Enumeration List of locks which have been put on the subject
       * @exception ServiceAccessException Service access error
       */
      public Enumeration enumerateLocks(Uri uri)
          throws ServiceAccessException
      {
  
          Vector lockVector = new Vector();
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("select * from locks where object= ?");
              statement.setString(1, uri.toString());
              statement.execute();
              ResultSet res = statement.getResultSet();
  
              while (res.next())
              {
                  Date expirationDate = null;
                  try
                  {
                      Long timeValue = new Long(res.getString
                                                (LOCKS_EXPIRATIONDATE));
                      expirationDate = new Date(timeValue.longValue());
                  }
                  catch (NumberFormatException e)
                  {
                      expirationDate = new Date();
                  }
                  NodeLock lock =
                      new NodeLock(res.getString(LOCKS_ID),
                                   res.getString(LOCKS_OBJECT),
                                   res.getString(LOCKS_SUBJECT),
                                   res.getString(LOCKS_TYPE),
                                   expirationDate,
                                   (res.getInt(LOCKS_INHERITABLE) == 1),
                                   (res.getInt(LOCKS_EXCLUSIVE) == 1));
                  lockVector.addElement(lock);
              }
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
          return lockVector.elements();
      }
  
  
      /**
       * Retrieve the revisions informations of an object.
       *
       * @param uri Uri
       * @exception ServiceAccessException Service access error
       * @exception RevisionDescriptorNotFoundException Revision descriptor
       * was not found
       */
      public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
          throws ServiceAccessException, RevisionDescriptorNotFoundException
      {
  
          NodeRevisionDescriptors revisionDescriptors = null;
          PreparedStatement statement = null;
          PreparedStatement statement2 = null;
  
          try
          {
              ResultSet res = null;
  
              NodeRevisionNumber initialRevision = new NodeRevisionNumber();
              Hashtable workingRevisions = new Hashtable();
              Hashtable latestRevisionNumbers = new Hashtable();
              Hashtable branches = new Hashtable();
              boolean isVersioned = false;
  
              statement = connection.prepareStatement
                  ("select * from revisions where uri= ?");
              statement.setString(1, uri.toString());
              res = statement.executeQuery();
  
              if (res.next())
              {
                  int isVersionedInt = res.getInt(REVISIONS_ISVERSIONED);
                  if (isVersionedInt == 1)
                  {
                      isVersioned = true;
                  }
              }
              else
              {
                  throw new RevisionDescriptorNotFoundException(uri.toString());
              }
  
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("select * from workingrevision where uri= ?");
              statement.setString(1, uri.toString());
              res = statement.executeQuery();
  
              while(res.next())
              {
                  // TODO : Parse each working revision definition
              }
  
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("select * from latestrevisions where uri=?");
              statement.setString(1, uri.toString());
              res = statement.executeQuery();
  
              while(res.next())
              {
                  latestRevisionNumbers
                      .put(res.getString(LATESTREVISIONS_BRANCHNAME),
                           new NodeRevisionNumber
                               (res.getString(LATESTREVISIONS_NUMBER)));
              }
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("select * from revision where uri= ?");
              statement.setString(1, uri.toString());
              res = statement.executeQuery();
  
              while(res.next())
              {
                  String currentRevisionNumber = res.getString(REVISION_NUMBER);
  
                  // We parse the revision list of the object
                  if (statement2 == null)
                  {
                      statement2 = connection.prepareStatement
                          ("select * from branches where uri = ? and xnumber = ?");
                  }
                  statement2.setString(1, uri.toString());
                  statement2.setString(2, currentRevisionNumber);
                  ResultSet res2 = statement2.executeQuery();
                  Vector childList = new Vector();
  
                  while (res2.next())
                  {
                      childList.addElement(new NodeRevisionNumber
                          (res2.getString(BRANCHES_CHILDNUMBER)));
                  }
  
                  branches.put(new NodeRevisionNumber(currentRevisionNumber),
                               childList);
  
                  res2.close();
              }
              closeStatement(statement2);
  
              revisionDescriptors = new NodeRevisionDescriptors
                  (uri.toString(), initialRevision, workingRevisions,
                   latestRevisionNumbers, branches, isVersioned);
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
              closeStatement(statement2);
          }
          return revisionDescriptors;
      }
  
  
      /**
       * Create a new revision information object.
       *
       * @param uri Uri
       * @param revisionDescriptors Node revision descriptors
       * @exception ServiceAccessException Service access error
       */
      public void createRevisionDescriptors
          (Uri uri, NodeRevisionDescriptors revisionDescriptors)
          throws ServiceAccessException
      {
  
          // TODO : Here, we have the option of "cleaning up" before
          // creating the new records in the database.
  
          PreparedStatement statement = null;
  
          try
          {
              ResultSet res = null;
  
              // Creating record in revisions tables
  
              int isVersioned = 0;
              if (revisionDescriptors.isVersioned())
              {
                  isVersioned = 1;
              }
  
              statement = connection.prepareStatement
                  ("insert into revisions values(?,?,?)");
              statement.setString(1,uri.toString());
              statement.setInt(2, isVersioned);
              statement.setString
                  (3, revisionDescriptors.getInitialRevision().toString());
              statement.execute();
              closeStatement(statement);
  
              // Creating records in working revisions table
              // ... TODO (working revisions are not used for now)
  
              // Creating records in latest revisions table
  
              // For now, only the latest revision from the main branch is stored
              if (revisionDescriptors.getLatestRevision() != null)
              {
                  statement = connection.prepareStatement
                      ("insert into latestrevisions values(?,?,?)");
                  statement.setString(1, uri.toString());
                  statement.setString
                      (2, NodeRevisionDescriptors.MAIN_BRANCH.toString());
                  statement.setString
                      (3, revisionDescriptors.getLatestRevision().toString());
                  statement.execute();
                  closeStatement(statement);
              }
  
              // Creating records in the branches table
              // TODO
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
      }
  
  
      /**
       * Update revision information.
       *
       * @param uri Uri
       * @param revisionDescriptors Node revision descriptors
       * @exception ServiceAccessException Service access error
       * @exception RevisionDescriptorNotFoundException Revision descriptor
       * was not found
       */
      public void storeRevisionDescriptors
          (Uri uri, NodeRevisionDescriptors revisionDescriptors)
          throws ServiceAccessException, RevisionDescriptorNotFoundException
      {
          removeRevisionDescriptors(uri);
          createRevisionDescriptors(uri, revisionDescriptors);
      }
  
  
      /**
       * Remove revision information.
       *
       * @param uri Uri
       * @exception ServiceAccessException Service access error
       */
      public void removeRevisionDescriptors(Uri uri)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("delete from revisions where uri= ?");
              statement.setString(1, uri.toString());
              statement.execute();
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("delete from workingrevision where uri= ?");
              statement.setString(1, uri.toString());
              statement.execute();
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("delete from latestrevisions where uri= ?");
              statement.setString(1, uri.toString());
              statement.execute();
              closeStatement(statement);
  
              statement = connection.prepareStatement
                  ("delete from branches where uri= ?");
              statement.setString(1, uri.toString());
              statement.execute();
              closeStatement(statement);
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Retrieve an individual object's revision descriptor.
       *
       * @param Uri uri
       * @param revisionNumber Node revision number
       */
      public NodeRevisionDescriptor retrieveRevisionDescriptor
          (Uri uri, NodeRevisionNumber revisionNumber)
          throws ServiceAccessException, RevisionDescriptorNotFoundException
      {
  
          NodeRevisionDescriptor revisionDescriptor = null;
          PreparedStatement statement = null;
  
      	if(revisionNumber == null)
      	{
          	throw new RevisionDescriptorNotFoundException(uri.toString());
  		}
  
          try
          {
              ResultSet res = null;
  
              String branchName = null;
              Vector labels = new Vector();
              Hashtable properties = new Hashtable();
  
              // Retrieving branch name (and also check that revision
              // does indeed exist)
  
              statement = connection.prepareStatement
                  ("select * from revision where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, revisionNumber.toString());
              res = statement.executeQuery();
  
              if (res.next())
              {
                  branchName = res.getString(REVISION_BRANCHNAME);
              }
              else
              {
                  throw new RevisionDescriptorNotFoundException(uri.toString());
              }
  
              closeStatement(statement);
  
              // Retrieve labels
  
              statement = connection.prepareStatement
                  ("select * from label where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, revisionNumber.toString());
              res = statement.executeQuery();
  
              while (res.next())
              {
                  labels.addElement(res.getString(LABEL_LABEL));
              }
  
              closeStatement(statement);
  
              // Retrieve properties
  
              statement = connection.prepareStatement
                  ("select * from property where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, revisionNumber.toString());
              res = statement.executeQuery();
  
              while (res.next())
              {
                  String propertyName = res.getString(PROPERTY_NAME);
                  String propertyNamespace = res.getString(PROPERTY_NAMESPACE);
                  NodeProperty property =
                      new NodeProperty(propertyName,
                                       res.getString(PROPERTY_VALUE),
                                       propertyNamespace,
                                       res.getString(PROPERTY_TYPE),
                                       (res.getInt(PROPERTY_PROTECTED) == 1));
                  properties.put(propertyNamespace + propertyName, property);
              }
  
              revisionDescriptor =
                  new NodeRevisionDescriptor(revisionNumber, branchName,
                                             labels, properties);
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
          return revisionDescriptor;
      }
  
  
      /**
       * Create a new revision descriptor.
       *
       * @param uri Uri
       * @param revisionDescriptor Node revision descriptor
       * @exception ServiceAccessException Service access error
       */
      public void createRevisionDescriptor
          (Uri uri, NodeRevisionDescriptor revisionDescriptor)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
  
              ResultSet res = null;
  
              statement = connection.prepareStatement
                  ("insert into revision values(?, ?, ?)");
              statement.setString(1, uri.toString());
              statement.setString
                  (2, revisionDescriptor.getRevisionNumber().toString());
              statement.setString(3, revisionDescriptor.getBranchName());
              statement.execute();
              closeStatement(statement);
  
              // Creating revision labels
              statement = null;
              Enumeration labels = revisionDescriptor.enumerateLabels();
              while (labels.hasMoreElements())
              {
                  if (statement == null)
                  {
                      statement = connection.prepareStatement
                          ("insert into label values(?,?,?)");
                  }
                  statement.setString(1, uri.toString());
                  statement.setString
                      (2, revisionDescriptor.getRevisionNumber().toString());
                  statement.setString(3, (String)labels.nextElement());
                  statement.execute();
              }
              closeStatement(statement);
  
              // Creating associated properties
              statement = null;
              Enumeration properties = revisionDescriptor.enumerateProperties();
              while (properties.hasMoreElements())
              {
                  NodeProperty property =
                      (NodeProperty) properties.nextElement();
                  int protectedProperty = 0;
                  if (property.isProtected())
                  {
                      protectedProperty = 1;
                  }
                  if (statement == null)
                  {
                      statement = connection.prepareStatement
                          ("insert into property values(?,?,?,?,?,?,?)");
                  }
                  statement.setString(1, uri.toString());
                  statement.setString
                      (2, revisionDescriptor.getRevisionNumber().toString());
                  statement.setString(3, property.getName());
                  statement.setString(4, property.getValue().toString());
                  statement.setString(5, property.getNamespace());
                  statement.setString(6, property.getType());
                  statement.setInt(7, protectedProperty);
                  statement.execute();
              }
              closeStatement(statement);
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
      }
  
  
      /**
       * Update a revision descriptor.
       *
       * @param uri Uri
       * @param revisionDescriptors Node revision descriptor
       * @exception ServiceAccessException Service access error
       * @exception RevisionDescriptorNotFoundException Revision descriptor
       * was not found
       */
      public void storeRevisionDescriptor
          (Uri uri, NodeRevisionDescriptor revisionDescriptor)
          throws ServiceAccessException, RevisionDescriptorNotFoundException
      {
          removeRevisionDescriptor(uri, revisionDescriptor.getRevisionNumber());
          createRevisionDescriptor(uri, revisionDescriptor);
      }
  
  
      /**
       * Remove a revision descriptor.
       *
       * @param uri Uri
       * @param revisionNumber Revision number
       * @exception ServiceAccessException Service access error
       */
      public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
          throws ServiceAccessException
      {
  
          PreparedStatement statement = null;
  
          try
          {
              statement = connection.prepareStatement
                  ("delete from revision where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, number.toString());
              statement.execute();
              closeStatement(statement);
  
              // Removing revision labels
  
              statement = connection.prepareStatement
                  ("delete from label where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, number.toString());
              statement.execute();
              closeStatement(statement);
  
              // Removing associated properties
  
              statement = connection.prepareStatement
                  ("delete from property where uri= ? and xnumber = ?");
              statement.setString(1, uri.toString());
              statement.setString(2, number.toString());
              statement.execute();
  
          }
          catch (SQLException e)
          {
              getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
              throw new ServiceAccessException(this, e);
          }
          finally
          {
              closeStatement(statement);
          }
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Close specified statement.
       */
      protected void closeStatement(Statement statement)
      {
          if (statement != null)
          {
              try
              {
                  statement.close();
              }
              catch (SQLException e)
              {
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/repository/slide/JetspeedDescriptorsStore.java
  
  Index: JetspeedDescriptorsStore.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.cms.repository.slide;
  
  //JDK
  import java.lang.reflect.Constructor;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.Vector;
  import java.util.List;
  import java.util.Iterator;
  import java.util.Date;
  
  // Slide
  import org.apache.slide.common.AbstractSimpleService;
  import org.apache.slide.common.ServiceConnectionFailedException;
  import org.apache.slide.common.ServiceDisconnectionFailedException;
  import org.apache.slide.common.NamespaceAccessToken;
  import org.apache.slide.common.ServiceInitializationFailedException;
  import org.apache.slide.common.ServiceResetFailedException;
  import org.apache.slide.common.ServiceAccessException;
  import org.apache.slide.common.Uri;
  import org.apache.slide.common.ServiceParameterErrorException;
  import org.apache.slide.common.ServiceParameterMissingException;
  
  import org.apache.slide.store.LockStore;
  import org.apache.slide.store.NodeStore;
  import org.apache.slide.store.RevisionDescriptorsStore;
  import org.apache.slide.store.RevisionDescriptorStore;
  import org.apache.slide.store.SecurityStore;
  
  import org.apache.slide.structure.ObjectNode;
  import org.apache.slide.structure.ObjectNotFoundException;
  import org.apache.slide.structure.ObjectAlreadyExistsException;
  
  import org.apache.slide.security.NodePermission;
  
  import org.apache.slide.lock.NodeLock;
  import org.apache.slide.lock.LockTokenNotFoundException;
  
  import org.apache.slide.content.NodeRevisionDescriptors;
  import org.apache.slide.content.NodeRevisionDescriptor;
  import org.apache.slide.content.RevisionContentNotFoundException;
  import org.apache.slide.content.RevisionDescriptorNotFoundException;
  import org.apache.slide.content.NodeRevisionNumber;
  
  import javax.transaction.xa.XAException;
  import javax.transaction.xa.Xid;
  
  // Turbine
  
  import org.apache.torque.util.Criteria;
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.util.Log;
  
  
  // Jetspeed
  import org.apache.jetspeed.services.security.JetspeedSecurityService;
  import org.apache.jetspeed.services.security.GroupManagement;
  import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRole;
  import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRolePeer;
  import org.apache.jetspeed.om.security.turbine.TurbineUserPeer;
  import org.apache.jetspeed.om.security.turbine.TurbineUser;
  import org.apache.jetspeed.om.security.turbine.TurbineGroup;
  import org.apache.jetspeed.om.security.turbine.TurbineGroupPeer;
  import org.apache.jetspeed.om.security.Group;
  import org.apache.jetspeed.om.security.JetspeedUser;
  
  
  /**
   * Jetspeed security compliant store implementation.
   *
   * This Slide store is using only to retrieve jetspeed user/group info.
   * It is not used to update a jetspeed user/group. You have to use the  Jetspeed application
   * for doing that
   *
   * TODO :
   *  + This class has to be review. Check if it possible to be more "Turbine independent".
   *    Use in this store the new Jetspeed security stuff.
   *  + Check if the interface NodeStore is not sufficient.
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  public class JetspeedDescriptorsStore
  	extends AbstractSimpleService
  	implements
  		LockStore,
  		NodeStore,
  		RevisionDescriptorsStore,
  		RevisionDescriptorStore,
  		SecurityStore
  {
  
  	// Structure descriptors
  
  	protected static final int OBJECTS_URI = 1;
  	protected static final int OBJECTS_CLASS = 2;
  
  	protected static final int CHILDREN_URI = 1;
  	protected static final int CHILDREN_CHILDURI = 2;
  
  	protected static final int LINKS_LINK = 1;
  	protected static final int LINKS_LINKTO = 2;
  
  	// Security descriptors
  
  	protected static final int PERMISSIONS_OBJECT = 1;
  	protected static final int PERMISSIONS_REVISION_NUMBER = 2;
  	protected static final int PERMISSIONS_SUBJECT = 3;
  	protected static final int PERMISSIONS_ACTION = 4;
  	protected static final int PERMISSIONS_INHERITABLE = 5;
  	protected static final int PERMISSIONS_NEGATIVE = 6;
  
  	// Lock descriptors
  
  	protected static final int LOCKS_ID = 1;
  	protected static final int LOCKS_OBJECT = 2;
  	protected static final int LOCKS_SUBJECT = 3;
  	protected static final int LOCKS_TYPE = 4;
  	protected static final int LOCKS_EXPIRATIONDATE = 5;
  	protected static final int LOCKS_INHERITABLE = 6;
  	protected static final int LOCKS_EXCLUSIVE = 7;
  
  	// Content descriptors
  
  	protected static final int REVISIONS_URI = 1;
  	protected static final int REVISIONS_ISVERSIONED = 2;
  	protected static final int REVISIONS_INITIALREVISION = 3;
  
  	protected static final int WORKINGREVISION_URI = 1;
  	protected static final int WORKINGREVISION_BASEREVISION = 2;
  	protected static final int WORKINGREVISION_NUMBER = 3;
  
  	protected static final int LATESTREVISIONS_URI = 1;
  	protected static final int LATESTREVISIONS_BRANCHNAME = 2;
  	protected static final int LATESTREVISIONS_NUMBER = 3;
  
  	protected static final int BRANCHES_URI = 1;
  	protected static final int BRANCHES_NUMBER = 2;
  	protected static final int BRANCHES_CHILDNUMBER = 3;
  
  	protected static final int REVISION_URI = 1;
  	protected static final int REVISION_NUMBER = 2;
  	protected static final int REVISION_BRANCHNAME = 3;
  
  	protected static final int LABEL_URI = 1;
  	protected static final int LABEL_NUMBER = 2;
  	protected static final int LABEL_LABEL = 3;
  
  	protected static final int PROPERTY_URI = 1;
  	protected static final int PROPERTY_NUMBER = 2;
  	protected static final int PROPERTY_NAME = 3;
  	protected static final int PROPERTY_VALUE = 4;
  	protected static final int PROPERTY_NAMESPACE = 5;
  	protected static final int PROPERTY_TYPE = 6;
  	protected static final int PROPERTY_PROTECTED = 7;
  
  
  	// ----------------------------------------------- DescriptorsStore Methods
  
  	/**
  	 * Retrieve an object.
  	 *
  	 * @param uri Uri of the object we want to retrieve
  	 * @exception ServiceAccessException Error accessing the Service
  	 * @exception ObjectNotFoundException The object to retrieve was not found
  	 */
  	public ObjectNode retrieveObject(Uri uri)
  		throws ServiceAccessException, ObjectNotFoundException
  	{
  
  		ObjectNode result = null;
  
  		try
  		{
  			// Check if parent uri name = the turbine group uri root
  			if (uri.getParentUri()
  				   .toString()
  				   .equals(Utility.getGroupParentUri()))
  			{
  				String groupName = uri.toString().substring(uri.toString().lastIndexOf('/') + 1);
                  GroupManagement groupService = (GroupManagement)TurbineServices.getInstance()
                  									.getService("GroupManagement");
  
  				Criteria criteria = new Criteria();
  				criteria.addJoin(
  					TurbineGroupPeer.GROUP_ID,
  					TurbineUserGroupRolePeer.GROUP_ID);
  				criteria.addJoin(
  					TurbineUserGroupRolePeer.USER_ID,
  					TurbineUserPeer.USER_ID);
  				criteria.add(TurbineGroupPeer.GROUP_NAME, groupName);
  				criteria.setDistinct();
  				List users = TurbineUserPeer.doSelectUsers(criteria);
  
  				if (Log.getLogger().isDebugEnabled())
  				{
  					Log.debug("TurbineDescriptorStore -  Group size : " + users.size());
  				}
  				Vector childrenVector = new Vector();
  				Vector linksVector = new Vector();
  
  				// Get  users from the UserGroupRole info
  				Iterator iterator = users.iterator();
  				while (iterator.hasNext())
  				{
  					JetspeedUser user = (JetspeedUser)iterator.next();
                      childrenVector.addElement(
  						Utility.getUserParentUri() + "/" + user.getUserName());
  				}
  
  				Class objclass =
  					Class.forName("org.apache.slide.structure.GroupNode");
  
  				Class[] argClasses =
  					{
  						Class.forName("java.lang.String"),
  						Class.forName("java.util.Vector"),
  						Class.forName("java.util.Vector")
  					};
  				Object[] arguments =
  					{
  						uri.toString(),
  						childrenVector,
  						linksVector
  					};
  
  				Constructor constructor = objclass.getConstructor(argClasses);
  
  				result = (ObjectNode)constructor.newInstance(arguments);
  
              // Check if parent uri name = the jetspeed user uri root
  			}
  			else if (uri.getParentUri()
  						.toString()
  						.equals(Utility.getUserParentUri()))
  			{
  
                  // Retrieve Jetspeed users
  				String userName =
  					uri.toString().substring(
  						uri.toString().lastIndexOf('/') + 1);
  
                  JetspeedSecurityService service = (JetspeedSecurityService) TurbineServices.getInstance().
                                           getService(JetspeedSecurityService.SERVICE_NAME);
                  JetspeedUser user = service.getUser(userName);
  
                  // Create and populate a Slide ObjectNode for this user
  				Vector childrenVector = new Vector();
  				Vector linksVector = new Vector();
  
  				Class objclass = Class.forName("slideroles.basic.UserRoleImpl");
  
  				Class[] argClasses =
  					{
  						Class.forName("java.lang.String"),
  						Class.forName("java.util.Vector"),
  						Class.forName("java.util.Vector")
  					};
  				Object[] arguments =
  					{
  						uri.toString(),
  						childrenVector,
  						linksVector
  					};
  				Constructor constructor = objclass.getConstructor(argClasses);
  				result = (ObjectNode)constructor.newInstance(arguments);
  			}
  			else
  			{
  				//if (uri.toString().equals(Utility.getUserParentUri())) {
  				// Slide engine ask first information on uri like '/users/turbine/' or
  				// 'users/turbine/users' or '/users/turbine/groups'
  				Vector childrenVector = new Vector();
  				Vector linksVector = new Vector();
  
  				Class objclass = Class.forName("slideroles.basic.UserRoleImpl");
  
  				Class[] argClasses =
  					{
  						Class.forName("java.lang.String"),
  						Class.forName("java.util.Vector"),
  						Class.forName("java.util.Vector")
  					};
  				Object[] arguments =
  					{
  						uri.toString(),
  						childrenVector,
  						linksVector
  					};
  				Constructor constructor = objclass.getConstructor(argClasses);
  				result = (ObjectNode)constructor.newInstance(arguments);
  			}
  		}
  		catch (Exception e)
  		{
  			//Log.debug("TurbineDescriptorStore Exception - retrieveObject : " +
  			//          e.getMessage());
  			e.printStackTrace();
  			throw new ObjectNotFoundException(uri);
  		}
  
  		return result;
  	}
  
  /*********************************************************************************
   *
   *   OTHER METHODE ARE NOT USED IN THIS STORE
   *
   */
  
  
  
  	// -------------------------------------------------------- Service Methods
  
  	/**
  	 * Initializes the data source with a set of parameters.
  	 *
  	 * @param parameters Hashtable containing the parameters' name
  	 * and associated value
  	 * @exception ServiceParameterErrorException Incorrect service parameter
  	 * @exception ServiceParameterMissingException Service parameter missing
  	 */
  	/*
  	   public void setParameters(Hashtable parameters)
  	       throws ServiceParameterErrorException,
  	       ServiceParameterMissingException {
  
  
  	   }
  
  	*/
  	/**
  	 * Connects to JDBC and creates the basic table structure.
  	 *
  	 * @exception ServiceConnectionFailedException Connection to the
  	 * database failed
  	 */
  	public synchronized void connect() throws ServiceConnectionFailedException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - connect");
  		}
  	}
  
  	/**
  	 * Disconnects from data source.
  	 *
  	 * @exception ServiceDisconnectionFailedException Disconnection
  	 * from database failed
  	 */
  	public void disconnect() throws ServiceDisconnectionFailedException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - disconnect");
  		}
  	}
  
  	/**
  	 * Initializes data source.
  	 * <p/>
  	 * Occurs in four steps :
  	 * <li>Driver class is loaded</li>
  	 * <li>Driver is intantiated</li>
  	 * <li>Driver registration in the driver manager</li>
  	 * <li>Creation of the basic tables, if they didn't exist before</li>
  	 *
  	 * @exception ServiceInitializationFailedException Throws an exception
  	 * if the data source has already been initialized before
  	 */
  	public synchronized void initialize(NamespaceAccessToken token)
  		throws ServiceInitializationFailedException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - initialize");
  		}
  	}
  
  	/**
  	 * Deletes data source. Should remove stored data if possible.
  	 *
  	 * @exception ServiceResetFailedException Reset failed
  	 */
  	public synchronized void reset() throws ServiceResetFailedException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - reset");
  		}
  	}
  
  	/**
  	 * This function tells whether or not the data source is connected.
  	 *
  	 * @return boolean true if we are connected
  	 * @exception ServiceAccessException Error accessing DataSource
  	 */
  	public boolean isConnected() throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - isConnected : true");
  		}
  
  		return true;
  	}
  
  	// ----------------------------------------------------- XAResource Methods
  
  	/**
  	 * Commit the global transaction specified by xid.
  	 */
  	public void commit(Xid xid, boolean onePhase) throws XAException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - commit");
  		}
  
  		// No Turbine user info update by using this descriptor store
  		/*
  		        super.commit(xid, onePhase);
  		        try {
  		            // ---------------  Commit the Turbine user info
  
  		            connection.commit();
  		            connection.setAutoCommit(true);
  
  
  		        } catch (SQLException e) {
  		            throw new XAException(XAException.XA_RBCOMMFAIL);
  		        }
  		   */
  	}
  
  	/**
  	 * Inform the resource manager to roll back work done on behalf of a
  	 * transaction branch.
  	 */
  	public void rollback(Xid xid) throws XAException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - rollback");
  		}
  		// No Turbine user info update by using this descriptor store
  		/*
  		       super.rollback(xid);
  		       try {
  		           // ---------------  Commit the Turbine user info
  		           /*
  		           connection.rollback();
  		           connection.setAutoCommit(true);
  
  
  		       } catch (SQLException e) {
  
  		           throw new XAException(XAException.XA_HEURCOM);
  		       }
  		       */
  	}
  
  	/**
  	 * Start work on behalf of a transaction branch specified in xid.
  	 */
  	public void start(Xid xid, int flags) throws XAException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - start");
  		}
  		// No Turbine user info update by using this descriptor store
  		/*
  		        System.out.println("JDBDescriptorStore.start()");
  		        super.start(xid, flags);
  		        try {
  		            connection.setAutoCommit(false);
  		        } catch (SQLException e) {
  		            System.out.println("JDBDescriptorStore.start() hummm begin");
  		            throw new XAException(XAException.XAER_RMERR);
  
  		        }
  		*/
  	}
  
  	/**
  	 * Update an object.
  	 *
  	 * @param object Object to update
  	 * @exception ServiceAccessException Error accessing the Service
  	 * @exception ObjectNotFoundException The object to update was not found
  	 */
  	public void storeObject(Uri uri, ObjectNode object)
  		throws ServiceAccessException, ObjectNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - storeObject :" + uri);
  		}
  	}
  
  	/**
  	 * Create a new object.
  	 *
  	 * @param object ObjectNode
  	 * @param uri Uri of the object we want to create
  	 * @exception ServiceAccessException Error accessing the Service
  	 * @exception ObjectAlreadyExistsException An object already exists
  	 * at this Uri
  	 */
  	public void createObject(Uri uri, ObjectNode object)
  		throws ServiceAccessException, ObjectAlreadyExistsException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - createObject :" + uri);
  		}
  	}
  
  	/**
  	 * Remove an object.
  	 *
  	 * @param object Object to remove
  	 * @exception ServiceAccessException Error accessing the Service
  	 * @exception ObjectNotFoundException The object to remove was not found
  	 */
  	public void removeObject(Uri uri, ObjectNode object)
  		throws ServiceAccessException, ObjectNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - removeObject");
  		}
  	}
  
  	/**
  	 * Grant a new permission.
  	 *
  	 * @param permission Permission we want to create
  	 * @exception ServiceAccessException Error accessing the Service
  	 */
  	public void grantPermission(Uri uri, NodePermission permission)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - grantPermission");
  		}
  	}
  
  	/**
  	 * Revoke a permission.
  	 *
  	 * @param permission Permission we want to create
  	 * @exception ServiceAccessException Error accessing the Service
  	 */
  	public void revokePermission(Uri uri, NodePermission permission)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - revokePermission");
  		}
  	}
  
  	/**
  	 * Revoke all the permissions on an object.
  	 *
  	 * @param permission Permission we want to create
  	 * @exception ServiceAccessException Error accessing the Service
  	 */
  	public void revokePermissions(Uri uri) throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - revokePermission");
  		}
  	}
  
  	/**
  	 * Enumerate permissions on an object.
  	 *
  	 * @param permission Permission we want to create
  	 * @exception ServiceAccessException Error accessing the Service
  	 */
  	public Enumeration enumeratePermissions(Uri uri)
  		throws ServiceAccessException
  	{
  		//Vector permissionVector = new Vector();
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - enumeratePermission : " + uri);
  		}
  		/*NodePermission permission =
  			new NodePermission(
  				uri.toString(),
  				null,
  				"/users/turbine",
  				"/actions/read",
  				true,
  				false);
  		permissionVector.addElement(permission);
  		return permissionVector.elements();
  		*/
          return null;
  	}
  
  	/**
  	 * Create a new lock.
  	 *
  	 * @param lock Lock token
  	 * @exception ServiceAccessException Service access error
  	 */
  	public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - putLock");
  		}
  	}
  
  	/**
  	 * Renew a lock.
  	 *
  	 * @param lock Token to renew
  	 * @exception ServiceAccessException Service access error
  	 * @exception LockTokenNotFoundException Lock token was not found
  	 */
  	public void renewLock(Uri uri, NodeLock lock)
  		throws ServiceAccessException, LockTokenNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - renewLock");
  		}
  	}
  
  	/**
  	 * Unlock.
  	 *
  	 * @param lock Token to remove
  	 * @exception ServiceAccessException Service access error
  	 * @exception LockTokenNotFoundException Lock token was not found
  	 */
  	public void removeLock(Uri uri, NodeLock lock)
  		throws ServiceAccessException, LockTokenNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - removeLock");
  		}
  	}
  
  	/**
  	 * Kill a lock.
  	 *
  	 * @param lock Token to remove
  	 * @exception ServiceAccessException Service access error
  	 * @exception LockTokenNotFoundException Lock token was not found
  	 */
  	public void killLock(Uri uri, NodeLock lock)
  		throws ServiceAccessException, LockTokenNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - KillLock");
  		}
  	}
  
  	/**
  	 * Enumerate locks on an object.
  	 *
  	 * @param subject Subject
  	 * @return Enumeration List of locks which have been put on the subject
  	 * @exception ServiceAccessException Service access error
  	 */
  	public Enumeration enumerateLocks(Uri uri) throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - enumerateLocks : " + uri);
  		}
  
  		return new Vector().elements();
  	}
  
  	/**
  	 * Retrieve the revisions informations of an object.
  	 *
  	 * @param uri Uri
  	 * @exception ServiceAccessException Service access error
  	 * @exception RevisionDescriptorNotFoundException Revision descriptor
  	 * was not found
  	 */
  	public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
  		throws ServiceAccessException, RevisionDescriptorNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - retrieveRevisionDescriptor");
  		}
  
  		return null;
  	}
  
  	/**
  	 * Create a new revision information object.
  	 *
  	 * @param uri Uri
  	 * @param revisionDescriptors Node revision descriptors
  	 * @exception ServiceAccessException Service access error
  	 */
  	public void createRevisionDescriptors(
  		Uri uri,
  		NodeRevisionDescriptors revisionDescriptors)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - createRevisionDescriptors");
  		}
  	}
  
  	/**
  	 * Update revision information.
  	 *
  	 * @param uri Uri
  	 * @param revisionDescriptors Node revision descriptors
  	 * @exception ServiceAccessException Service access error
  	 * @exception RevisionDescriptorNotFoundException Revision descriptor
  	 * was not found
  	 */
  	public void storeRevisionDescriptors(
  		Uri uri,
  		NodeRevisionDescriptors revisionDescriptors)
  		throws ServiceAccessException, RevisionDescriptorNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - storeRevisionDescriptors");
  		}
  	}
  
  	/**
  	 * Remove revision information.
  	 *
  	 * @param uri Uri
  	 * @exception ServiceAccessException Service access error
  	 */
  	public void removeRevisionDescriptors(Uri uri)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - removeRevisionDescriptors");
  		}
  	}
  
  	/**
  	 * Retrieve an individual object's revision descriptor.
  	 *
  	 * @param Uri uri
  	 * @param revisionNumber Node revision number
  	 */
  	public NodeRevisionDescriptor retrieveRevisionDescriptor(
  		Uri uri,
  		NodeRevisionNumber revisionNumber)
  		throws ServiceAccessException, RevisionDescriptorNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - retrieveRevisionDescriptor");
  		}
  
  		return null;
  	}
  
  	/**
  	 * Create a new revision descriptor.
  	 *
  	 * @param uri Uri
  	 * @param revisionDescriptor Node revision descriptor
  	 * @exception ServiceAccessException Service access error
  	 */
  	public void createRevisionDescriptor(
  		Uri uri,
  		NodeRevisionDescriptor revisionDescriptor)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - createRevisionDescriptor");
  		}
  
  		return;
  	}
  
  	/**
  	 * Update a revision descriptor.
  	 *
  	 * @param uri Uri
  	 * @param revisionDescriptors Node revision descriptor
  	 * @exception ServiceAccessException Service access error
  	 * @exception RevisionDescriptorNotFoundException Revision descriptor
  	 * was not found
  	 */
  	public void storeRevisionDescriptor(
  		Uri uri,
  		NodeRevisionDescriptor revisionDescriptor)
  		throws ServiceAccessException, RevisionDescriptorNotFoundException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - storeRevisionDescriptor");
  		}
  	}
  
  	/**
  	 * Remove a revision descriptor.
  	 *
  	 * @param uri Uri
  	 * @param revisionNumber Revision number
  	 * @exception ServiceAccessException Service access error
  	 */
  	public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
  		throws ServiceAccessException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - removeRevisionDescriptor");
  		}
  	}
  
  	/**
  	 * Initializes the data source with a set of parameters.
  	 *
  	 * @param parameters Hashtable containing the parameters' name
  	 * and associated value
  	 * @exception ServiceParameterErrorException Incorrect service parameter
  	 * @exception ServiceParameterMissingException Service parameter missing
  	 */
  	public void setParameters(Hashtable parameters)
  		throws ServiceParameterErrorException, ServiceParameterMissingException
  	{
  		if (Log.getLogger().isDebugEnabled())
  		{
  			Log.debug("TurbineDescriptorStore - setParamters");
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/services/cms/repository/slide/Utility.java
  
  Index: Utility.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jetspeed.services.cms.repository.slide;
  
  import org.apache.turbine.services.resources.TurbineResources;
  
  /**
   *
   * Utility class used in the Slide implementation of the CMS service
   *
   * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
   */
  public class Utility
  {
      /**
       * Returns the complete uri for a turbine/jetspeed user name
       *
       * @param userName Turbine user name.
       *
       * @return the Slide uri
       */
  	static public String getUserUri(String userName)
      {
  
  		if (userName == null)
  		{
  			return "nobody";
  		}
  
          return TurbineResources.getString(
                               "services.CmsService.slide.turbineuser.uri") +
                               '/' + userName ;
      }
  
      /**
       * Get the root uri which contains all Turbine/Jetspeed users.
       *
       * @return the turbine user root uri
       */
      static public String getUserParentUri()
      {
          return TurbineResources.getString("services.CmsService.slide.users")
                 + '/' +
                 TurbineResources.getString(
                                  "services.CmsService.slide.turbineuser.uri");
      }
  
      /**
       * Get the root uri which contains all Turbine/Jetspeed groups
       *
       * @return the turbine group root uri
       */
      static public String getGroupParentUri()
      {
          return TurbineResources.getString("services.CmsService.slide.users")
                 + '/' +
                 TurbineResources.getString(
                                 "services.CmsService.slide.turbinegroup.uri");
      }
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/java/org/apache/jetspeed/util/cms/CMSLink.java
  
  Index: CMSLink.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jetspeed.util.cms;
  
  
  import org.apache.turbine.util.RunData;
  import org.apache.turbine.util.Log;
  import org.apache.turbine.services.pull.ApplicationTool;
  import org.apache.turbine.services.TurbineServices;
  import java.util.Vector;
  
  import org.apache.jetspeed.om.cms.slide.*;
  import org.apache.jetspeed.services.cms.JetspeedCMSException;
  import org.apache.jetspeed.services.cms.repository.slide.Utility;
  import org.apache.jetspeed.services.cms.CmsService;
  import org.apache.jetspeed.services.cms.manager.CmsManager;
  
  /**
   *
   *
   * @author <a href="mailto:clombart@netscape.net">Christophe Lombart</a>
   * @version $Id: CMSLink.java,v 1.1 2002/10/29 16:05:26 raphael Exp $
   */
  public class CMSLink implements ApplicationTool
  {
  
      /**
       * Initialize the CMSManager object.
       *
       * @param data This is null, RunData or User depending upon specified tool scope.
       */
      public void init(Object data)
      {
          if (data == null)
          {
              //Log.debug("CMSManager scope is global");
          }
      }
  
      /**
       * This lets the tool know that it should be
       * refreshed. The tool can perform whatever actions
       * are necessary to refresh itself. This is necessary
       * for sane development where you probably want the
       * tools to refresh themselves on every request.
       */
      public void refresh()
      {
          //Log.debug("Refreshing CMSMmanager : do nothing !");
  
      }
  
      public Catalog getCatalog(RunData data, String catalogName)
      {
  		try
  		{
  			// Read the content from the repository
  			// Get a reference to the Slide Service
  			CmsService service = (CmsService) TurbineServices.getInstance()
  			                                  .getService(CmsService.SERVICE_NAME);
  
  	       	// Retrieve the content from Slide and get its properties
  	       	String userName = Utility.getUserUri(data.getUser().getUserName());
  
  	       	if (Log.getLogger().isDebugEnabled())
  	       	{
  				Log.debug("CMSLink - get Content - username : " + userName);
  			}
  			CmsManager  cmsManager = service.getCmsManager();
  
  			Catalog catalog = (Catalog) cmsManager.getResource(userName, catalogName );
  			cmsManager.populateCatalog(userName, catalog, true, true, 1);
  
  			return catalog;
  		}
  		catch (JetspeedCMSException e)
  		{
  			data.setMessage(e.getMessage());
  			return null;
  		}
  	}
  
      public Vector getCatalogs(RunData data, String fromUri, String toUri)
      {
  		try
  		{
  			CmsService service = (CmsService) TurbineServices.getInstance()
  											.getService(CmsService.SERVICE_NAME);
  
  			String userName = Utility.getUserUri(data.getUser().getUserName());
  			CmsManager  cmsManager = service.getCmsManager();
  			Vector catalogs = cmsManager.getCatalogs(userName, fromUri, toUri);
  			return catalogs;
  		}
  		catch (JetspeedCMSException e)
  		{
  			data.setMessage(e.getMessage());
  			return null;
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/sql/Slide-tables.sql
  
  Index: Slide-tables.sql
  ===================================================================
  create table objects(uri varchar(65536) primary key, classname varchar(4096));
  
  create table children(uri varchar(65536), childuri varchar(65536));
  
  create table links(link varchar(65536), linkto varchar(65536));
  
  create table permissions(object varchar(65536), revisionnumber varchar(20), 
    subject varchar(65536), action varchar(65536), inheritable int, 
    negative int);
  
  create table locks(id varchar(65536), object varchar(4096), 
    subject varchar(4096), type varchar(4096), 
    expirationdate varchar(15), inheritable int, xexclusive int);
  
  create table revisions(uri varchar(65536) primary key, 
    isversioned int, initialrevision varchar(10));
  
  create table workingrevision(uri varchar(65536), 
    baserevision varchar(20), xnumber varchar(20));
  
  create table latestrevisions(uri varchar(65536), 
    branchname varchar(4096), xnumber varchar(20));
  
  create table branches(uri varchar(65536), xnumber varchar(20), 
    childnumber varchar(20));
  
  create table revision(uri varchar(65536), xnumber varchar(20), 
    branchname varchar(4096));
  
  create table label(uri varchar(65536), xnumber varchar(20), 
    label varchar(4096));
  
  create table property(uri varchar(65536), xnumber varchar(20), 
    name varchar(4096), value varchar(65536), namespace varchar(4096), 
    type varchar(100), protected int);
  
  create table revisioncontent(uri varchar(65536), xnumber varchar(20), 
    content longvarbinary);
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/src/sql/reinit_slide.sql
  
  Index: reinit_slide.sql
  ===================================================================
  delete from revisioncontent;
  delete from property;
  delete from label;
  delete from revision;
  delete from branches;
  delete from latestrevisions;
  delete from workingrevision;
  delete from revisions;
  delete from locks;
  delete from permissions;
  delete from links;
  delete from children;
  delete from objects;
  
  insert into objects values('/catalog', 'org.apache.slide.structure.SubjectNode');
  insert into revisions values('/catalog', 0, '1.0');
  
  //  '+/users/turbine/groups/jetspeed' : reference to a group (Slide syntax)
  //  '/users/turbine/users/christophe' : reference to a user (Slide syntax)
  insert into permissions values ('/catalog', null, '+/users/turbine/groups/jetspeed', '/actions', 1, null);
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/conf/CmsResources.properties
  
  Index: CmsResources.properties
  ===================================================================
  # ------------------------------------------------------------------------------------------------
  #
  #  CMS SERVICE 
  #
  # -----------------------------------------------------------------------------------------------
  
  # Service Implementation 
  services.CmsService.classname=org.apache.jetspeed.services.cms.DefaultCmsService
  
  # CmsManager implementation used for the namespace 'Jetspeed'
  services.CmseService.CmsManager.jetspeed.class = org.apache.jetspeed.services.cms.manager.CmsManagerSlideImpl
  services.CmseService.CmsManager.jetspeed.domainfile = D://JavaProjects/jetspeed-cms/webapp/WEB-INF/conf/domain.xml
  
  
  # Root catalog information
  services.CmsService.catalog.root.uri=/catalog
  services.CmsService.catalog.root.logicalname =catalog
  services.CmsService.catalog.root.title = Content Demo
  
  # Application tool
  tool.global.cmslink=org.apache.jetspeed.util.cms.CMSLink
  
  
  #################################################################################################
  #  Specific param used by the Slide implementation
  #################################################################################################
  
  
  # ---------------- Param used only in the TurbineDescriptorsStore.java & JetspeedDescriptorsStore.java
  # Parent uri for retrieve Turbine users, groups
  services.CmsService.slide.users=/users
  services.CmsService.slide.turbinegroup.uri=turbine/groups
  services.CmsService.slide.turbineuser.uri=turbine/users
  
  
  
  
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/conf/Domain.xml
  
  Index: Domain.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <slide logger="org.apache.slide.util.logger.SimpleLogger" logger-level="6"
   default="slide">
    
    <namespace name="jetspeed-content">
      
  
      <definition>
        
        <store name="meta-data">
          
  	<nodestore classname="org.apache.jetspeed.services.cms.repository.slide.JDBCDescriptorsStore">
           <parameter name="driver">org.hsql.jdbcDriver</parameter>
           <parameter name="url">jdbc:HypersonicSQL:D:/MyApplication/Apache Tomcat 4.0/webapps/jetspeed/WEB-INF/db/cms-slide</parameter>
           <parameter name="user">sa</parameter>
           <parameter name="password"></parameter>
          </nodestore>
         
  	<securitystore>
            <reference store="nodestore" />
          </securitystore>
          
  	<lockstore>
            <reference store="nodestore" />
          </lockstore>
          
  	<revisiondescriptorsstore>
            <reference store="nodestore" />
          </revisiondescriptorsstore>
          
  	<revisiondescriptorstore>
            <reference store="nodestore" />
          </revisiondescriptorstore>
          
  	
  	<contentstore classname="slidestore.reference.FileContentStore">
            <parameter name="rootpath">web-inf/slidecontent</parameter>
          </contentstore>
        </store>
  
        <store name="jetspeedSecurity">
          <nodestore classname="org.apache.jetspeed.services.cms.repository.slide.JetspeedDescriptorsStore"/>
        
          <securitystore>
            <reference store="nodestore" />
          </securitystore>
          <lockstore>
            <reference store="nodestore" />
          </lockstore>
          <revisiondescriptorsstore>
            <reference store="nodestore" />
          </revisiondescriptorsstore>
          <revisiondescriptorstore>
            <reference store="nodestore" />
          </revisiondescriptorstore>
        </store>
  
        <store name="memory">
          <contentstore name="file2" 
           classname="slidestore.reference.FileContentStore">
            <parameter name="rootpath">files</parameter>
          </contentstore>
        </store>
  
        <scope match="/" store="memory" />
        <scope match="/catalog" store="meta-data" />
        <scope match="/users/turbine" store="jetspeedSecurity" />
  
      </definition>
      
      <configuration>
  
        <!-- Actions mapping -->
        <default-action>/actions</default-action>
        <read-object>/actions/read</read-object>
        <create-object>/actions/write</create-object>
        <remove-object>/actions/write</remove-object>
        <grant-permission>/actions/manage</grant-permission>
        <revoke-permission>/actions/manage</revoke-permission>
        <read-permissions>/actions/manage</read-permissions>
        <lock-object>/actions/write</lock-object>
        <kill-lock>/actions/manage</kill-lock>
        <read-locks>/actions/read</read-locks>
        <read-revision-metadata>/actions/read</read-revision-metadata>
        <create-revision-metadata>/actions/write</create-revision-metadata>
        <modify-revision-metadata>/actions/write</modify-revision-metadata>
        <remove-revision-metadata>/actions/write</remove-revision-metadata>
        <read-revision-content>/actions/read</read-revision-content>
        <create-revision-content>/actions/write</create-revision-content>
        <modify-revision-content>/actions/write</modify-revision-content>
        <remove-revision-content>/actions/write</remove-revision-content>
  
        <!-- Paths configuration -->
        <userspath>/users</userspath>
        <guestpath>guest</guestpath>
        <filespath>/files</filespath>
        <parameter name="dav">true</parameter>
        <parameter name="standalone">true</parameter>
  
        <!-- Roles definition -->
        <role name="root">slideroles.basic.RootRole</role>
        <role name="user">slideroles.basic.UserRole</role>
        <role name="guest">slideroles.basic.GuestRole</role>
  
        <!-- Users management -->
        <auto-create-users>true</auto-create-users>
  
        <!-- Default properties mapping -->
        <default-property name="foo" namespace="nsfoo/" value="bar"
         role="user"/>
        <default-property name="password" namespace="slide/" value=""
         role="user"/>
  
      </configuration>
      
      <data>
        
        <objectnode classname="org.apache.slide.structure.SubjectNode" uri="/">
                 
          <!-- /users represents the unauthenticated user -->
          
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
           uri="/users">                             
            
          </objectnode>
          
          <objectnode classname="org.apache.slide.structure.ActionNode" 
           uri="/actions" >
            
          
  	       <objectnode classname="org.apache.slide.structure.ActionNode" 
             uri="/actions/read"/>
            
            <objectnode classname="org.apache.slide.structure.ActionNode" 
             uri="/actions/write"/>
            
            <objectnode classname="org.apache.slide.structure.ActionNode" 
             uri="/actions/manage"/>
            
          </objectnode>
          
          <objectnode classname="org.apache.slide.structure.SubjectNode" 
           uri="/files">
           
            
          </objectnode>
        </objectnode>
      </data>
    </namespace>
    
  </slide>
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/conf/TurbineResources.properties
  
  Index: TurbineResources.properties
  ===================================================================
  # -------------------------------------------------------------------
  # $Id: TurbineResources.properties,v 1.1 2002/10/29 16:05:27 raphael Exp $
  #
  # This is the configuration file for Turbine.
  #
  # Note that strings containing "," (comma) characters must backslash
  # escape the comma (i.e. '\,')
  #
  # -------------------------------------------------------------------
  
  # -------------------------------------------------------------------
  #
  #  L O G S
  #
  # -------------------------------------------------------------------
  # This is the configuration for the logging system. In most cases
  # you don't need to modify anything. However, if you wish to add more
  # facilities or modify the existing settings, then you can do so.
  #
  # destination.file: A path relative to the web app root
  # -------------------------------------------------------------------
  services.LoggingService.facilities=system,debug,security,rotation,logforj
  services.LoggingService.default=logforj
  services.LoggingService.loggingConfig=org.apache.turbine.services.logging.PropertiesLoggingConfig
  
  # A facility for system logging.
  services.LoggingService.system.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.system.className=org.apache.turbine.services.logging.FileLogger
  services.LoggingService.system.level=DEBUG
  
  # A facility for the scheduler service
  # To disable started/stopped messages set the level to ERROR
  services.LoggingService.scheduler.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.scheduler.className=org.apache.turbine.services.logging.FileLogger
  services.LoggingService.scheduler.level=DEBUG
  
  # A facility for debugging applications. Messages will go both
  # to the log file and the server console.
  services.LoggingService.debug.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.debug.destination.console=true
  services.LoggingService.debug.className=org.apache.turbine.services.logging.FileLogger
  services.LoggingService.debug.level=DEBUG
  
  # A facility for SQL query logging
  # To enable SQL query logging, set the level to DEBUG
  services.LoggingService.sql.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.sql.className=org.apache.turbine.services.logging.FileLogger
  services.LoggingService.sql.level=DEBUG
  
  # A facility for security audit. NOTE! As of 23 Jan 2001
  # Turbine does not have any standard security auditing
  # functionality. It's up to your application.
  services.LoggingService.security.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.security.className=org.apache.turbine.services.logging.FileLogger
  services.LoggingService.security.level=DEBUG
  
  # An example configuration for using Log4Java, with log4j properties inline
  # The category name - at the end of this line - needs to match the logging facility name - the first log4j.
  # need this rootCategory entry to capture the torque/fulcrum etc logging
  services.LoggingService.logforj.log4j.rootCategory = DEBUG, logforj
  # need this category entry for the actual jetspeed logging (I don't know why it doesn't get covered by the root category!)
  services.LoggingService.logforj.log4j.category.logforj = DEBUG, logforj
  services.LoggingService.logforj.log4j.appender.logforj.file =${webappRoot}/WEB-INF/log/jetspeed.log
  services.LoggingService.logforj.log4j.appender.logforj = org.apache.log4j.FileAppender
  services.LoggingService.logforj.log4j.appender.logforj.layout = org.apache.log4j.PatternLayout
  services.LoggingService.logforj.log4j.appender.logforj.layout.conversionPattern = [%d{ABSOLUTE} %-5p] %m%n
  services.LoggingService.logforj.log4j.appender.logforj.append = false
  services.LoggingService.logforj.className=org.apache.turbine.services.logging.Log4JavaLogger
  services.LoggingService.logforj.level=DEBUG
  
  # An example configuration for automatic log rotation using Log4Java
  # This will keep the log file size under 1MB and save up to 5 backup copies
  services.LoggingService.rotation.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.rotation.file.size=1048576
  services.LoggingService.rotation.file.backups=5
  services.LoggingService.rotation.className=org.apache.turbine.services.logging.Log4JavaLogger
  services.LoggingService.rotation.level=DEBUG
  
  # An example configuration for using *NIX syslogd with Log4Java
  services.LoggingService.syslog.destination.syslogd.host=my.syslog.server.com
  services.LoggingService.syslog.destination.syslogd.facility=LOG_DAEMON
  services.LoggingService.syslog.className=org.apache.turbine.services.logging.Log4JavaLogger
  services.LoggingService.syslog.level=INFO
  
  # An example configuration for using remote Log4Java server
  services.LoggingService.remote.destination.remote.host=my.remote.server.com
  services.LoggingService.remote.destination.remote.port=1099
  services.LoggingService.remote.className=org.apache.turbine.services.logging.Log4JavaLogger
  services.LoggingService.remote.level=INFO
  
  # An example configuration for sending error reports as email with Log4Java
  # notes:
  # * uses 'mail.server' as SMTP server to send mail through
  # * log4j will send the email when an ERROR is logged, with
  #   'buffer.size' previous (non-ERROR) logs included in the email
  # * configured to log to a file as well otherwise stacktraces are lost
  services.LoggingService.email.destination.file=/WEB-INF/log/jetspeed.log
  services.LoggingService.email.destination.email.from=root@localhost
  services.LoggingService.email.destination.email.to=root@localhost
  services.LoggingService.email.destination.email.subject=Jetspeed Error Report
  services.LoggingService.email.destination.email.buffer.size=512
  services.LoggingService.email.className=org.apache.turbine.services.logging.Log4JavaLogger
  services.LoggingService.email.level=INFO
  
  # -------------------------------------------------------------------
  # SMTP-From header for your outgoing messages
  #
  # All failed delivery messages will be returned to this address.
  # If unset, these messages will be sent to the address in the
  # From header (standard behaviour)
  #
  # Default: null
  # -------------------------------------------------------------------
  
  mail.smtp.from=
  
  # -------------------------------------------------------------------
  #
  #  M O D U L E  C A C H I N G
  #
  # -------------------------------------------------------------------
  # This determines whether or not to cache the modules in memory.  For
  # development, turn this off.  For production, turn this on.
  #
  # Default: false
  # -------------------------------------------------------------------
  
  module.cache=false
  
  # If module.cache=true, then how large should we make the hashtables
  # by default.
  
  action.cache.size=20
  layout.cache.size=10
  navigation.cache.size=10
  page.cache.size=5
  screen.cache.size=50
  scheduledjob.cache.size=10
  
  # -------------------------------------------------------------------
  #
  #  M O D U L E  P A C K A G E S
  #
  # -------------------------------------------------------------------
  # This is the "classpath" for Turbine.  In order to locate your own
  # modules, you should add them to this path.  For example, if you have
  # com.company.actions, com.company.screens, com.company.navigations,
  # then this setting would be "com.company,org.apache.turbine.modules".
  # This path is searched in order.  For example, Turbine comes with a
  # screen module named "Login".  If you wanted to have your own screen
  # module named "Login", then you would specify the path to your
  # modules before the others.
  #
  # Default: org.apache.turbine.modules
  # -------------------------------------------------------------------
  
  # These look like mostly ECS modules
  module.packages=org.apache.jetspeed.modules
  module.packages=org.apache.turbine.modules
  
  # -------------------------------------------------------------------
  #
  #  F R A M E W O R K  S E T T I N G S
  #
  # -------------------------------------------------------------------
  # These are settings that control the behaviour of the framework,
  # such as determining whether a template system is in use, what
  # the default templates and screens are and session handling settings.
  # -------------------------------------------------------------------
  
  # Used to set the template homepage if you are using a template
  # layout.
  #
  # Default: /Index.vm
  
  template.homepage=Home
  #template.homepage=/Ecs
  
  # This is the default screen to show to people when they first access
  # the system. Specify one of the template screens such as VelocityScreen
  # to use a template system.
  #
  # Default: Login
  
  #screen.homepage=Home
  
  # This is the template that is shown on an incorrect login attempt.
  # Setting this property will override any value of screen.login specfied
  # below.
  #
  # Default: Login.vm
  
  #dst template.login=/Login.vm
  template.login=Login
  
  # This is the page that is shown on an incorrect login attempt.  It is
  # referenced in the LoginUser action. Note that it will only be used if
  # a login template has not been specified (see template.login above).
  #
  # Default: Login
  
  #dst screen.login=
  #screen.login=Login
  
  # This is the template that is used by the respective Template based
  # ErrorScreen for displaying the error. If you are not using a Template based
  # ErrorScreen, then this is ignored.
  #
  # Default: /Error.vm
  # for JSP templating use: Error.jsp
  # for Velocity templating use: Error.vm
  
  #template.error=Error.jsp
  template.error=ShowError
  
  # This is the default error screen.
  #
  # Default: VelocityErrorScreen
  
  #dst screen.error=VelocityErrorScreen
  screen.error=Error
  
  # This is the screen that is displayed when the user's web page is in
  # an invalid state.
  #
  # Default: error.InvalidState
  
  screen.invalidstate=error.InvalidState
  
  # Set the default Doctype.  The default Doctype can be set by using
  # the single strings: Html40Strict, Html40Transitional, or
  # Html40Frameset.  Additionally the default can be supplied as two
  # strings separated by a comma giving the DTD and URI.
  #
  # Default: ignored if not set to some value.
  
  default.doctype=Html40Transitional
  
  # This is the default action to log a user in.
  
  #dst action.login=LoginUser
  action.login=JLoginUser
  
  # This is the default action to log a user out.
  
  action.logout=JLogoutUser
  
  # This is the default action to validate whether or not a session is
  # valid.  For example, if you want to make sure if a user has already
  # logged in or not.
  #
  # Default: SessionValidator
  
  #dst action.sessionvalidator=sessionvalidator.TemplateSessionValidator
  action.sessionvalidator=JetspeedSessionValidator
  
  # This is the timeout in seconds for sessions. If left commented out, the
  # servlet container's default timeout will be left as is.
  
  # session.timeout=1800
  
  # This is the default action that builds up the AccessControlList for
  # the individual users session.
  
  action.accesscontroller=JetspeedAccessController
  
  # -------------------------------------------------------------------
  #
  #  J N D I  C O N T E X T S
  #
  # -------------------------------------------------------------------
  
  # This indicates whether Turbine should try to create JNDI contexts.
  #
  # Default: false
  #
  # contexts=true
  
  # These are the JNDI context properties.  Each context's properties
  # are defined by the properties beginning with context.name.
  #
  # Default: none
  #
  # Example: The following will create a JNDI context named "name" in
  # the data.contexts Hashtable.  It will point at the RMI registry on
  # localhost running on port 1099, and will use
  # com.sun.jndi.rmi.registry.RegistryContextFactory as the initial
  # context factory:
  #
  # context.name.java.naming.provider.url=rmi://localhost:1099
  # context.name.java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory
  
  # -------------------------------------------------------------------
  #
  #  M E S S A G E S
  #
  # -------------------------------------------------------------------
  # Note that strings containing "," (comma) characters must backslash
  # escape the comma (i.e. '\,')
  
  # The message that can be displayed before a user logs in.
  
  login.message=Please login to Jetspeed
  
  # The message that can be displayed when no screen is defined.
  
  login.message.noscreen=There has been an error. Your session is valid but the screen variable is not defined.
  
  # The message that can be displayed when a user enters an incorrect
  # password or username.
  
  login.error=Sorry your username or password is incorrect!
  
  # The message that can be displayed when a user logs out.
  
  logout.message=Thank you for using the system. Please come back soon.
  
  # -------------------------------------------------------------------
  #
  #  S E C U R E  S O C K E T S  L A Y E R
  #
  # -------------------------------------------------------------------
  # Whether the web server is able to use SSL.  Links in Turbine can
  # check this property to determine if SSL can be used.
  #
  # Default: true
  # -------------------------------------------------------------------
  
  use.ssl=true
  
  # -------------------------------------------------------------------
  #
  #  S E R V I C E S
  #
  # -------------------------------------------------------------------
  # Classes for Turbine Services should be defined here.
  # Format: services.[name].classname=[implementing class]
  #
  # To specify properties of a service use the following syntax:
  # service.[name].[property]=[value]
  #
  # The order that these services is listed is important! The
  # order that is stated here is the order in which the services
  # will be initialized. Keep this is mind if you have services
  # that depend on other services during initialization.
  # -------------------------------------------------------------------
  services.ResourceService.classname=org.apache.turbine.services.resources.TurbineResourceService
  services.LoggingService.classname=org.apache.turbine.services.logging.TurbineLoggingService
  services.FactoryService.classname=org.apache.turbine.services.factory.TurbineFactoryService
  services.PoolService.classname=org.apache.turbine.services.pool.TurbinePoolService
  services.RunDataService.classname=org.apache.jetspeed.services.rundata.JetspeedRunDataService
  services.ServletService.classname=org.apache.turbine.services.servlet.TurbineServletService
  services.AssemblerBrokerService.classname=org.apache.turbine.services.assemblerbroker.TurbineAssemblerBrokerService
  services.LocalizationService.classname=org.apache.turbine.services.localization.TurbineLocalizationService
  services.MimeTypeService.classname=org.apache.turbine.services.mimetype.TurbineMimeTypeService
  services.GlobalCacheService.classname=org.apache.turbine.services.cache.TurbineGlobalCacheService
  services.SchedulerService.classname=org.apache.turbine.services.schedule.TurbineSchedulerService
  #services.XmlRpcService.classname=org.apache.turbine.services.xmlrpc.TurbineXmlRpcService
  services.UniqueIdService.classname=org.apache.turbine.services.uniqueid.TurbineUniqueIdService
  services.UploadService.classname=org.apache.turbine.services.upload.TurbineUploadService
  #services.PoolBrokerService.classname=org.apache.turbine.services.db.TurbinePoolBrokerService
  services.PoolBrokerService.classname=org.apache.jetspeed.services.torquewrapper.TorquePoolServiceAdaptor
  services.MapBrokerService.classname=org.apache.turbine.services.db.TurbineMapBrokerService
  services.PullService.classname=org.apache.turbine.services.pull.TurbinePullService
  #services.IntakeService.classname=org.apache.turbine.services.intake.TurbineIntakeService
  services.TemplateService.classname=org.apache.turbine.services.template.TurbineTemplateService
  #services.XSLTService.classname=org.apache.turbine.services.xslt.TurbineXSLTService
  services.StateManagerService.classname=org.apache.jetspeed.services.statemanager.JetspeedStateManagerService
  
  # Turn on the appropriate template service.
  services.JspService.classname=org.apache.turbine.services.jsp.TurbineJspService
  services.VelocityService.classname=org.apache.turbine.services.velocity.TurbineVelocityService
  
  # -------------------------------------------------------------------
  #
  #  R U N   D A T A   S E R V I C E
  #
  # -------------------------------------------------------------------
  # Default implementations of base interfaces for request processing.
  # Additional configurations can be defined by using other keys
  # in the place of the <default> key.
  # -------------------------------------------------------------------
  
  services.RunDataService.default.run.data=org.apache.jetspeed.services.rundata.DefaultJetspeedRunData
  services.RunDataService.default.parameter.parser=org.apache.turbine.util.parser.DefaultParameterParser
  services.RunDataService.default.cookie.parser=org.apache.turbine.util.parser.DefaultCookieParser
  
  # -------------------------------------------------------------------
  #
  #  C A C H E   S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # Interval at which the cache will be checked. The default is
  # 5000ms or 5 seconds.
  
  services.GlobalCacheService.cache.check.frequency = 5000
  
  # -------------------------------------------------------------------
  #
  #  A S S E M B L E R  B R O K E R  S E R V I C E
  #
  # -------------------------------------------------------------------
  # A list of AssemblerFactory classes that will be registered
  # with TurbineAssemblerBrokerService
  # -------------------------------------------------------------------
  
  services.AssemblerBrokerService.screen=org.apache.turbine.services.assemblerbroker.util.java.JavaScreenFactory
  #services.AssemblerBrokerService.screen=org.apache.turbine.services.assemblerbroker.util.python.PythonScreenFactory
  services.AssemblerBrokerService.action=org.apache.turbine.services.assemblerbroker.util.java.JavaActionFactory
  services.AssemblerBrokerService.layout=org.apache.turbine.services.assemblerbroker.util.java.JavaLayoutFactory
  services.AssemblerBrokerService.page=org.apache.turbine.services.assemblerbroker.util.java.JavaPageFactory
  services.AssemblerBrokerService.navigation=org.apache.turbine.services.assemblerbroker.util.java.JavaNavigationFactory
  services.AssemblerBrokerService.scheduledjob=org.apache.turbine.services.assemblerbroker.util.java.JavaScheduledJobFactory
  
  # -------------------------------------------------------------------
  #
  #  T E M P L A T E  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # Roughly, the number of templates in each category.
  #
  # Defaults: layout=2, navigation=10, screen=50
  
  services.TemplateService.layout.cache.size=2
  services.TemplateService.navigation.cache.size=10
  services.TemplateService.screen.cache.size=50
  services.TemplateService.default.extension=vm
  
  # -------------------------------------------------------------------
  #
  #  P U L L  S E R V I C E
  #
  # -------------------------------------------------------------------
  # These are the properties for the Pull Service, the service
  # that works in conjuction with the Turbine Pull Model API.
  # -------------------------------------------------------------------
  
  # This determines whether the non-request tools are refreshed
  # on each request (request tools aren't ever, because they're
  # instantiated for the request only anyway).
  services.PullService.tools.per.request.refresh=true
  
  # These are tools that are placed in the context by the service
  # These tools will be made available to all your
  # templates. You list the tools in the following way:
  #
  # tool.<scope>.<id> = <classname>
  #
  # <scope>      is the tool scope: global, request, session
  #              or persistent (see below for more details)
  # <id>         is the name of the tool in the context
  #
  # You can configure the tools in this way:
  # tool.<id>.<parameter> = <value>
  #
  # So if you find "global", "request", "session" or "persistent" as second
  # part, it is a configuration to put a tool into the toolbox, else it is a
  # tool specific configuration.
  #
  # For example:
  #
  # tool.global.ui    = org.apache.turbine.util.pull.UIManager
  # tool.global.mm    = org.apache.turbine.util.pull.MessageManager
  # tool.request.link = org.apache.turbine.util.template.TemplateLink
  # tool.request.page = org.apache.turbine.util.template.TemplatePageAttributes
  #
  # Then:
  #
  # tool.ui.skin = default
  #
  # configures the value of "skin" for the "ui" tool.
  #
  # Tools are accessible in all templates by the <id> given
  # to the tool. So for the above listings the UIManager would
  # be available as $ui, the MessageManager as $mm, the TemplateLink
  # as $link and the TemplatePageAttributes as $page.
  #
  # You should avoid using tool names called "global", "request",
  # "session" or "persistent" because of clashes with the possible Scopes.
  #
  # Scopes:
  #
  #   global:     tool is instantiated once and that instance is available
  #               to all templates for all requests. Tool must be threadsafe.
  #
  #   request:    tool is instantiated once for each request (although the
  #               PoolService is used to recycle instances). Tool need not
  #               be threadsafe.
  #
  #   session:    tool is instantiated once for each user session, and is
  #               stored in the user's temporary hashtable. Tool should be
  #               threadsafe.
  #
  #   persistent: tool is instantitated once for each use session, and
  #               is stored in the user's permanent hashtable. This means
  #               for a logged in user the tool will be persisted in the
  #               user's objectdata. Tool should be threadsafe and
  #               Serializable.
  #
  # Defaults: none
  
  tool.request.jslink=org.apache.jetspeed.util.template.BaseJetspeedLink
  
  # link.setAction() has been replace by jslink.setAction()
  # link.setPage() has been replace by jslink.setPage()
  tool.request.link=org.apache.turbine.util.template.TemplateLink
  tool.request.page=org.apache.turbine.util.template.TemplatePageAttributes
  tool.request.content=org.apache.turbine.util.ContentURI
  tool.request.clink=org.apache.jetspeed.util.template.ContentTemplateLink
  # jlink has been replaced by jslink.Template()
  # jlink.ActionKey has been replaced by jslink.ActionKey
  tool.request.jlink=org.apache.jetspeed.util.template.JetspeedTemplateLink
  tool.request.jetspeed=org.apache.jetspeed.util.template.JetspeedTool
  tool.request.l10n=org.apache.turbine.services.localization.LocalizationTool
  #tool.request.jnavigation=org.apache.jetspeed.util.template.JetspeedTemplateNavigation
  tool.request.config=org.apache.jetspeed.services.resources.JetspeedResources
  
  tool.global.ui=org.apache.turbine.services.pull.util.UIManager
  tool.global.config=org.apache.jetspeed.services.resources.JetspeedResources
  
  # The UI Manager will allow you to skin your Turbine
  # application using simple properties files that are
  # located in the WEBAPP/resources/ui/skins/ directory
  # hierarchy.
  
  tool.ui.skin=default
  
  # -------------------------------------------------------------------
  #
  #  V E L O C I T Y  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # The location of Velocity configuration file, relative to webapp root
  # These properties will override the default properties set by Velocity.
  # You should specify the path to the templates directories as well as
  # the path to the log file and they should also be relative to webapp root
  
  #default.page = JetspeedVelocityPage
  
  services.VelocityService.template.extension=vm
  services.VelocityService.default.page = JetspeedVelocityPage
  #services.VelocityService.default.screen=VelocityScreen
  services.VelocityService.default.screen=VelocityDirectScreen
  #services.VelocityService.default.layout = VelocityOnlyLayout
  services.VelocityService.default.layout = VelocityDirectLayout
  services.VelocityService.default.navigation=VelocityNavigation
  services.VelocityService.default.error.screen = VelocityErrorScreen
  services.VelocityService.default.layout.template = /default.vm
  
  services.VelocityService.runtime.log=/WEB-INF/log/velocity.log
  #services.VelocityService.input.encoding=UTF-8
  services.VelocityService.velocimacro.library = GlobalMacros.vm
  
  services.VelocityService.resource.loader = file
  services.VelocityService.file.resource.loader.description = Velocity File Resource Loader
  services.VelocityService.file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
  
  # This parameter supports a comma separated list of directories
  # Each directory is searched in order to find a template.
  # This is useful for example, in defining application specific templates in a separate structure from the jetspeed core templates
  # Note this needs to be set in 3 places - for the jsp loader and vm loader in TR.p and for the template locator in JR.p
  services.VelocityService.file.resource.loader.path = /WEB-INF/templates/vm
  
  services.VelocityService.file.resource.loader.cache = false
  services.VelocityService.file.resource.loader.modificationCheckInterval = 2
  
  services.VelocityService.resource.loader = classpath
  services.VelocityService.classpath.resource.loader.description = Velocity Classpath Resource Loader
  services.VelocityService.classpath.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
  
  # -------------------------------------------------------------------
  #
  #  J S P  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  services.JspService.template.extension=jsp
  services.JspService.default.page = JetspeedJspPage
  services.JspService.default.screen = BaseJspScreen
  services.JspService.default.layout = JetspeedJspLayout
  services.JspService.default.navigation = BaseJspNavigation
  services.JspService.default.error.screen = JspErrorScreen
  services.JspService.default.layout.template = /default.jsp
  
  # This parameter supports a comma separated list of directories
  # Each directory is searched in order to find a template.
  # This is useful for example, in defining application specific templates in a separate structure from the jetspeed core templates
  # Note this needs to be set in 3 places - for the jsp loader and vm loader in TR.p and for the template locator in JR.p
  services.JspService.templates =/WEB-INF/templates/jsp
  
  services.JspService.buffer.size = 8192
  
  # -------------------------------------------------------------------
  #
  #  W E B M A C R O  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  services.WebMacroService.template.extension=wm
  services.WebMacroService.default.page = WebMacroSitePage
  services.WebMacroService.default.screen=WebMacroSiteScreen
  services.WebMacroService.default.layout = WebMacroSiteLayout
  services.WebMacroService.default.navigation=WebMacroSiteNavigation
  services.WebMacroService.default.error.screen = WebMacroSiteErrorScreen
  services.WebMacroService.default.layout.template = /Default.wm
  
  # The location of WebMacro configuration file, relative to webapp
  # root.
  
  services.WebMacroService.properties=/WEB-INF/conf/WebMacro.properties
  
  # The path where WebMacro will look for templates, relative to webapp
  # root.  Use your system's path separator to specify multiple paths.
  
  services.WebMacroService.templates=/templates/app
  
  # The class that will act as a template provider in webmacro.  We can
  # use default class from WebMacro (template path above is pushed into
  # WebMacro configuration mechanism, so that class can pick it up), or
  # some other custom class
  
  services.WebMacroService.templates.provider=org.apache.turbine.services.webmacro.TurbineTemplateProvider
  
  # -------------------------------------------------------------------
  #
  #  F R E E M A R K E R  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # The path where FreeMarker will look for templates, relative to
  # webapp root, if supported by the servlet engine.
  #
  # Default: /templates
  
  services.FreeMarkerService.templates=/templates
  
  # -------------------------------------------------------------------
  #
  #  U P L O A D  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # Whether the files should be automatically picked up by
  # ParameterParser.
  
  services.UploadService.automatic=true
  
  #
  # The directory where files will be temporarily stored.
  #
  services.UploadService.repository=.
  
  #
  # The maximum size of a request that will be processed.
  #
  services.UploadService.size.max=1048576
  
  #
  # The maximum size of a request that will have it's elements cached in
  # memory by TurbineUploadService class.
  #
  services.UploadService.size.threshold=10240
  
  # -------------------------------------------------------------------
  #
  #  L O C A L I Z A T I O N  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # Default ResourceBundle and language/country codes used by the
  # TurbineLocalizationService.
  #
  # this bundle is searched first - so name your override file here
  locale.default.bundle=
  #
  # this is a comma separated list of bundles that are searched to find a resource
  # after the above default bundle has been checked, if its specified
  # should be fine to leave this setting as is
  locale.default.bundles=org.apache.jetspeed.modules.localization.JetspeedLocalization
  locale.default.language=en
  locale.default.country=US
  
  #
  # This will set the charset= portion of the ContentType: header.
  # Leave commented out unless you want to return stuff as a different
  # charset.
  #
  # locale.default.charset=
  
  # -------------------------------------------------------------------
  #
  #  M I M E T Y P E  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # This property specifies a file containing mappings between MIME
  # content types and the corresponding file name extensions. The
  # service itself contains a hardcoded set of most common mappings.
  # The file must use the same syntax as the mime.types file of
  # the Apache Server, i.e.
  # <mimetype> <ext1> <ext2>...
  #
  #services.MimeTypeService.mime.types=/WEB-INF/conf/mime.types
  
  # This property specifies a file containing mappings between locales
  # and the corresponding character encodings. The service itself
  # contains a hardcoded set of most common mappings.
  # The file should use the Java property file syntax, i.e.
  # <lang_country_variant>=<charset>
  #
  #services.MimeTypeService.charsets=/WEB-INF/conf/charset.properties
  
  # -------------------------------------------------------------------
  #
  #  S C H E D U L E R  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  #
  # Set enabled to true to start the scheduler.
  #
  # Default = false
  #
  scheduler.enabled=false
  
  # -------------------------------------------------------------------
  #
  #  X M L R P C  S E R V I C E
  #
  # -------------------------------------------------------------------
  # This property specifies which class should be used to parse
  # xml for XmlRpc functionality.
  #
  # Default: org.apache.xerces.parsers.SAXParser
  
  services.XmlRpcService.parser=org.apache.xerces.parsers.SAXParser
  
  # This property specifies which port the server part of the XmlRpc
  # should listen, if it is active.
  #
  # Default: 12345
  
  services.XmlRpcService.port=12345
  
  # If any classes are specified here, the Service will create an
  # instance of them here and start up a listener on the specified
  # port.
  #
  # Note that the handlers demonstrated are not very useful.  You
  # will have to invent your own services.  They do however
  # illustrate that any class with a default constructor can be
  # added here
  #
  # The handler parameter without further extension determines
  # the default handler for the service
  #
  # Default: no classes are specified by default
  
  #services.XmlRpcService.handler.$default=java.util.Hashtable
  #services.XmlRpcService.handler.stringhandler=java.lang.String
  
  # The following properties allow the transfer of data between
  # separate Turbine applications running on different servers.
  # This allows B2B type behavior such as sending database
  # updates in the form of XML or whatever type of data
  # that needs to be shared between Turbine applications
  # running on separate servers.
  
  services.XmlRpcService.handler.file = org.apache.turbine.services.xmlrpc.util.FileHandler
  services.XmlRpcService.paranoid = false
  services.XmlRpcService.acceptClient = 192.168.1.*
  services.XmlRpcService.denyClient =
  
  # -------------------------------------------------------------------
  #
  #  P O O L  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # Default capacity of pools of the Object pooling service.
  #
  # Default: 128
  services.PoolService.pool.capacity = 128
  
  # Class specific capacities used instead of the default if specified.
  #
  #services.PoolService.pool.capacity.org.apache.turbine.services.rundata.DefaultTurbineRunData=512
  
  # -------------------------------------------------------------------
  #
  #  F A C T O R Y  S E R V I C E
  #
  # -------------------------------------------------------------------
  
  # A comma separated list of classloaders (very optional)
  #
  # Example: org.foo.bar.MyClassLoader, org.ack.joe.YourClassLoader
  #
  #services.FactoryService.class.loaders=
  
  # Customized factories to be used instead of the default factory.
  # E.g. to instantiate XML parsers, SSL sockets, etc., which require
  # specific instantiation not supported by the default factory.
  # The property name is prefixed with "factory" followed by the
  # name of the production class. The value is the class name of
  # the factory implementing the Factory interface. The factory
  # will be instantiated by using the service itself.
  #
  # Examples:
  #
  # services.FactoryService.factory.javax.xml.parsers.DocumentBuilder=org.foo.xml.DomBuilderFactory
  # services.FactoryService.factory.javax.xml.parsers.SAXParser=org.foo.xml.SaxParserFactory
  # services.FactoryService.factory.java.net.ServerSocket=org.foo.net.SslServerSocketFactory
  
  #--------------------------------------------------------------------
  #
  # X S L T  S E R V I C E
  #
  #--------------------------------------------------------------------
  
  services.XSLTService.path = /path/to/stylesheets
  services.XSLTService.cache = false
  
  #--------------------------------------------------------------------
  #
  # P A R A M E T E R  P A R S E R
  #
  #--------------------------------------------------------------------
  #
  # This variable controls the case folding applied to URL variable
  # names.
  #
  # Allowed values: none, lower, upper
  # Default: lower
  #
  
  url.case.folding=lower
  
  # -------------------------------------------------------------------
  #
  #  C O M P O N E N T S
  #
  # -------------------------------------------------------------------
  # Components implementing the lifecycle interfaces can be loaded,
  # configured and initialized by Turbine
  # -------------------------------------------------------------------
  
  component.name = torque
  component.torque.classname = org.apache.torque.Torque
  component.torque.config = ${webappRoot}/WEB-INF/conf/Torque.properties
  component.torque.property.webappRoot = ${webappRoot}
  
  component.name = fulcrum
  component.fulcrum.classname = org.apache.fulcrum.Fulcrum
  component.fulcrum.config = ${webappRoot}/WEB-INF/conf/Fulcrum.properties
  
  
  
  # -------------------------------------------------------------------
  #
  #  A D D I T I O N A L  P R O P E R T I E S
  #
  # -------------------------------------------------------------------
  # The full path name to an additional properties file. Properties in
  # this file will be included in this property set. Duplicate name
  # values will be replaced, so be careful.
  #
  # Default: none
  # -------------------------------------------------------------------
  
  include = JetspeedResources.properties
  include = JetspeedSecurity.properties
  include = CmsResources.properties
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/conf/cms-portlets.xreg
  
  Index: cms-portlets.xreg
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <registry>  
      <portlet-entry name="CMS-VIEWER" hidden="false" type="ref"
          parent="Velocity" application="false">
          <meta-info>
              <title>Content Viewer</title>
              <description>Display contents hierarchy create by the portal users</description>
          </meta-info>
          <parameter name="template" value="cms/content" hidden="true"/>
          <parameter name="catalogName" value="/catalog" hidden="true"/>
          <media-type ref="html"/>
      </portlet-entry>
      
      <portlet-entry name="CMS-ADMINISTRATION" hidden="false" type="ref"
          parent="CustomizerVelocity" application="false">
          <meta-info>
              <title>Content Administration</title>
              <description>Admin contents with their attributes created
                  by the portal users</description>
          </meta-info>
          <parameter name="customize-template" value="cms/content-administration-customize" hidden="true"/>
          <parameter name="template" value="cms/content-administration" hidden="true"/>
          <parameter name="action" value="portlets.CmsAdminAction" hidden="false"/>
          <parameter name="fromuri" value="/catalog" hidden="true"/>
          <media-type ref="html"/>
      </portlet-entry>
  </registry>
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/db/cms-slide.backup
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/db/cms-slide.data
  
  	<<Binary file>>
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/db/cms-slide.properties
  
  Index: cms-slide.properties
  ===================================================================
  #Hypersonic SQL database
  #Sat Oct 19 00:19:36 CEST 2002
  version=1.4
  modified=no
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/db/cms-slide.script
  
  Index: cms-slide.script
  ===================================================================
  CREATE TABLE OBJECTS(URI VARCHAR PRIMARY KEY,CLASSNAME VARCHAR)
  CREATE TABLE CHILDREN(URI VARCHAR,CHILDURI VARCHAR)
  CREATE TABLE LINKS(LINK VARCHAR,LINKTO VARCHAR)
  CREATE TABLE PERMISSIONS(OBJECT VARCHAR,REVISIONNUMBER VARCHAR,SUBJECT VARCHAR,ACTION VARCHAR,INHERITABLE INTEGER,NEGATIVE INTEGER)
  CREATE TABLE LOCKS(ID VARCHAR,OBJECT VARCHAR,SUBJECT VARCHAR,TYPE VARCHAR,EXPIRATIONDATE VARCHAR,INHERITABLE INTEGER,XEXCLUSIVE INTEGER)
  CREATE TABLE REVISIONS(URI VARCHAR PRIMARY KEY,ISVERSIONED INTEGER,INITIALREVISION VARCHAR)
  CREATE TABLE WORKINGREVISION(URI VARCHAR,BASEREVISION VARCHAR,XNUMBER VARCHAR)
  CREATE TABLE LATESTREVISIONS(URI VARCHAR,BRANCHNAME VARCHAR,XNUMBER VARCHAR)
  CREATE TABLE BRANCHES(URI VARCHAR,XNUMBER VARCHAR,CHILDNUMBER VARCHAR)
  CREATE TABLE REVISION(URI VARCHAR,XNUMBER VARCHAR,BRANCHNAME VARCHAR)
  CREATE TABLE LABEL(URI VARCHAR,XNUMBER VARCHAR,LABEL VARCHAR)
  CREATE TABLE PROPERTY(URI VARCHAR,XNUMBER VARCHAR,NAME VARCHAR,VALUE VARCHAR,NAMESPACE VARCHAR,TYPE VARCHAR,PROTECTED INTEGER)
  CREATE TABLE REVISIONCONTENT(URI VARCHAR,XNUMBER VARCHAR,CONTENT LONGVARBINARY)
  GRANT ALL ON CLASS "java.lang.Math" TO PUBLIC
  GRANT ALL ON CLASS "org.hsql.Library" TO PUBLIC
  CREATE USER SA PASSWORD "" ADMIN
  CREATE ALIAS DAYNAME FOR "org.hsql.Library.dayname"
  CREATE ALIAS SPACE FOR "org.hsql.Library.space"
  CREATE ALIAS SUBSTRING FOR "org.hsql.Library.substring"
  CREATE ALIAS SQRT FOR "java.lang.Math.sqrt"
  CREATE ALIAS ABS FOR "java.lang.Math.abs"
  CREATE ALIAS POWER FOR "java.lang.Math.pow"
  CREATE ALIAS CHAR FOR "org.hsql.Library.character"
  CREATE ALIAS CONCAT FOR "org.hsql.Library.concat"
  CREATE ALIAS PI FOR "org.hsql.Library.pi"
  CREATE ALIAS SECOND FOR "org.hsql.Library.second"
  CREATE ALIAS TRUNCATE FOR "org.hsql.Library.truncate"
  CREATE ALIAS MONTH FOR "org.hsql.Library.month"
  CREATE ALIAS LOWER FOR "org.hsql.Library.lcase"
  CREATE ALIAS ATAN2 FOR "java.lang.Math.atan2"
  CREATE ALIAS REPEAT FOR "org.hsql.Library.repeat"
  CREATE ALIAS DAYOFMONTH FOR "org.hsql.Library.dayofmonth"
  CREATE ALIAS TAN FOR "java.lang.Math.tan"
  CREATE ALIAS RADIANS FOR "java.lang.Math.toRadians"
  CREATE ALIAS FLOOR FOR "java.lang.Math.floor"
  CREATE ALIAS NOW FOR "org.hsql.Library.now"
  CREATE ALIAS ACOS FOR "java.lang.Math.acos"
  CREATE ALIAS DAYOFWEEK FOR "org.hsql.Library.dayofweek"
  CREATE ALIAS CEILING FOR "java.lang.Math.ceil"
  CREATE ALIAS DAYOFYEAR FOR "org.hsql.Library.dayofyear"
  CREATE ALIAS LCASE FOR "org.hsql.Library.lcase"
  CREATE ALIAS WEEK FOR "org.hsql.Library.week"
  CREATE ALIAS SOUNDEX FOR "org.hsql.Library.soundex"
  CREATE ALIAS ASIN FOR "java.lang.Math.asin"
  CREATE ALIAS LOCATE FOR "org.hsql.Library.locate"
  CREATE ALIAS EXP FOR "java.lang.Math.exp"
  CREATE ALIAS MONTHNAME FOR "org.hsql.Library.monthname"
  CREATE ALIAS YEAR FOR "org.hsql.Library.year"
  CREATE ALIAS LEFT FOR "org.hsql.Library.left"
  CREATE ALIAS ROUNDMAGIC FOR "org.hsql.Library.roundMagic"
  CREATE ALIAS BITOR FOR "org.hsql.Library.bitor"
  CREATE ALIAS LTRIM FOR "org.hsql.Library.ltrim"
  CREATE ALIAS COT FOR "org.hsql.Library.cot"
  CREATE ALIAS COS FOR "java.lang.Math.cos"
  CREATE ALIAS MOD FOR "org.hsql.Library.mod"
  CREATE ALIAS SIGN FOR "org.hsql.Library.sign"
  CREATE ALIAS DEGREES FOR "java.lang.Math.toDegrees"
  CREATE ALIAS LOG FOR "java.lang.Math.log"
  CREATE ALIAS SIN FOR "java.lang.Math.sin"
  CREATE ALIAS CURTIME FOR "org.hsql.Library.curtime"
  CREATE ALIAS DIFFERENCE FOR "org.hsql.Library.difference"
  CREATE ALIAS INSERT FOR "org.hsql.Library.insert"
  CREATE ALIAS DATABASE FOR "org.hsql.Library.database"
  CREATE ALIAS MINUTE FOR "org.hsql.Library.minute"
  CREATE ALIAS HOUR FOR "org.hsql.Library.hour"
  CREATE ALIAS IDENTITY FOR "org.hsql.Library.identity"
  CREATE ALIAS QUARTER FOR "org.hsql.Library.quarter"
  CREATE ALIAS CURDATE FOR "org.hsql.Library.curdate"
  CREATE ALIAS BITAND FOR "org.hsql.Library.bitand"
  CREATE ALIAS USER FOR "org.hsql.Library.user"
  CREATE ALIAS UCASE FOR "org.hsql.Library.ucase"
  CREATE ALIAS RTRIM FOR "org.hsql.Library.rtrim"
  CREATE ALIAS LOG10 FOR "org.hsql.Library.log10"
  CREATE ALIAS RIGHT FOR "org.hsql.Library.right"
  CREATE ALIAS ATAN FOR "java.lang.Math.atan"
  CREATE ALIAS UPPER FOR "org.hsql.Library.ucase"
  CREATE ALIAS ASCII FOR "org.hsql.Library.ascii"
  CREATE ALIAS RAND FOR "java.lang.Math.random"
  CREATE ALIAS LENGTH FOR "org.hsql.Library.length"
  CREATE ALIAS ROUND FOR "org.hsql.Library.round"
  CREATE ALIAS REPLACE FOR "org.hsql.Library.replace"
  INSERT INTO OBJECTS VALUES('/catalog','org.apache.slide.structure.SubjectNode')
  INSERT INTO PERMISSIONS VALUES('/catalog',NULL,'+/users/turbine/groups/Jetspeed','/actions',1,NULL)
  INSERT INTO REVISIONS VALUES('/catalog',0,'1.0')
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/psml/user/turbine/html/default.psml
  
  Index: default.psml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <portlets id="01">
      <metainfo>
          <title>Default Jetspeed page</title>
      </metainfo>
      <skin name="orange-red"/>
      <layout position="-1" size="-1"/>
      <control name="TabControl"/>
      <controller name="TabController"/>
      <portlets id="02">
          <metainfo>
              <title>Home</title>
          </metainfo>
          <layout position="-1" size="-1"/>
          <controller name="ColumnController"/>
          <entry id="0101" parent="CMS-ADMINISTRATION"/>
      </portlets>
  </portlets>
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/GlobalMacros.vm
  
  Index: GlobalMacros.vm
  ===================================================================
  #* ------------------------------------------------------------------
  #
  # Macros that are used for displaying input forms.
  #
  *# ------------------------------------------------------------------
  
  #macro (text $text)
    <font face="$ui.sansSerifFonts">
      $text
    </font>
  #end
  
  #macro (formLabel $label)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <b>
        <font face="$ui.sansSerifFonts">
          $label
        </font>
      </b>
    </td>
  #end
  
  #macro (formTextField $name $value)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <font face="$ui.sansSerifFonts">
        <input type="text" size="30" name="$name" value="$value">
      </font>
    </td>
  #end
  
  #macro (textField $name $value $size)
    <font face="$ui.sansSerifFonts">
      <input type="text" size="$size" name="$name" value="$value">
    </font>
  #end
  
  #macro (listBox $list)
    <font face="$ui.sansSerifFonts">
      $list
    </font>
  #end
  
  #macro (formPasswordCell $label $name $value)
    #formLabel("$label")
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <font face="$ui.sansSerifFonts">
        <input type="password" size="30" name="$name" value="$value">
      </font>
    </td>
  #end
  
  #macro (formReadOnlyCell $label $name $value)
    #formLabel("$label")
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <font face="$ui.sansSerifFonts">
        <input type="hidden" size="30" name="$name" value="$value">
        $value
      </font>
    </td>
  #end
  
  #macro (formCell $label $name $value)
    #formLabel("$label")
    #formTextField("$name" "$value")
  #end
  
  #macro (fileUploadField $name)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <font face="$ui.sansSerifFonts">
        <input type="file" size="30" name="$name">
      </font>
    </td>
  #end
  
  #macro (fileUpload "$label" "$name")
    #formLabel("$label")
    #fileUploadField("$name")
  #end
  
  #macro (formCheckBox $name $checked)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <input type="checkbox" name="box_$name" #if($checked)checked=1#end/>
    </td>
  #end
  
  #macro (formCheckBox2 $label $name $checked)
    #formLabel("$label")
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <input type="checkbox" name="$name" #if($checked)checked=1#end/>
    </td>
  #end
  
  #macro (formListBox $label $list)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <b>
        <font face="$ui.sansSerifFonts">
          $label
        </font>
      </b>
    </td>
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      $list
    </td>
  #end
  
  #* ------------------------------------------------------------------
  #
  # Macros that are used for displaying information in tables.
  #
  *# ------------------------------------------------------------------
  
  #macro (headerCell $body)
    <td>
      <b>     
          $body
      </b>
    </td>
  #end
  
  #macro (entryCell $body)
    <td>    
        $body &nbsp;    
    </td>
  #end
  
  
  #* ------------------------------------------------------------------
  #
  # Macros added for Nebanum
  #
  *# ------------------------------------------------------------------
  #macro (formTextFieldSize $name $value $size)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <font face="$ui.sansSerifFonts">
        <input type="text" size="$size" name="$name" value="$value">
      </font>
    </td>
  #end
  #macro (formCheckBoxEvent $name $checked $event)
    <td bgcolor="$!{skin.TitleBackgroundColor}">
      <input type="checkbox" name="box_$name" #if($checked)checked=1#end $!{events}  />
    </td>
  #end
  
  #macro (formFlag $name $checked)
    <input type="checkbox" name="$name" #if($checked)checked=1#end/>
  #end
  
  #macro (formSelect $name $list $selectedValue )
    <select name=$name>
    <option value="$selectedValue">$selectedValue</option>  
    #foreach ($item in $list)    
  	 <option value="$item">$item</option>
    #end 
    </select>
  #end
  
  #macro (omListBox $list $selectedPrimaryKey)
    #foreach ($item in $list)
      #if ($selectedPrimaryKey == $item.getPrimaryKey().getValue())
  	 <option value="$item.getPrimaryKey().getValue()" selected>$item.getDisplayValue()</option>
      #else     
  	 <option value="$item.getPrimaryKey().getValue()">$item.getDisplayValue()</option>
      #end
    #end 
  #end
  
  #macro (image $img $w $h)
    #if ($w == "0")
       <img src="$ui.image($img,$data)" >
    #else
       <img src="$ui.image($img,$data)" width="$w" height="$h">
    #end 
  #end
  
  
  #macro (linkwizard $wizardname $step)
    $link.setAction("PullAction").addQueryData("wizard","$wizardname").addQueryData("step","$step")
  #end
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/portlets/html/cms/content-administration-customize.vm
  
  Index: content-administration-customize.vm
  ===================================================================
  Customize me the content<br>
  #set ($fromcatalogName = $conf.getInitParameter("fromuri"))
  #set ($tocatalogName=$data.getParameters().getString("touri"))
  #if (!$tocatalogName) #set ( $tocatalogName = $fromcatalogName ) #end
  
  fromcatalogName : $fromcatalogName
  tocatalogName : $tocatalogName
  
  <br><br>CUSTOMIZE ADMIN<br>
  <A href="$jlink.addQueryData("action","controls.Customize").addQueryData("portlet","$portlet.getName()").addQueryData("touri","$tocatalogName")">Add Content</A>
   
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/portlets/html/cms/content-administration.vm
  
  Index: content-administration.vm
  ===================================================================
  #set ($fromcatalogName = $conf.getInitParameter("fromuri"))
  #set ($tocatalogName=$data.getParameters().getString("touri"))
  #if (!$tocatalogName) #set ( $tocatalogName = $fromcatalogName ) #end
  #set ($catalogs = $cmslink.getCatalogs($data, $fromcatalogName, $tocatalogName) )
  #set ($catalog=$cmslink.getCatalog($data, $tocatalogName))
  #set ($contentCatalog = $catalog.getItems())
  
  #set ($catalogCounter=1)
  
  #set ($catalogList = "<table width='80%' border='0' cellpadding='0' align='center'>")
  #set ($contentList = "<font class=clWinHeading ><u>Content in this folder</u></font><br><br>")
  
  #if ($contentCatalog.size() == 0)
   #set ($contentList="<br><br><br>This folder is empty<br><br><br><br><br>")
  #else
    #foreach ($item in $contentCatalog)
      #if ($item.getType() == "Catalog")
    
      
        #if ($catalogCounter == 1)
           #set ($uri= $item.getUri())
           #set ($catalogList = "$catalogList<tr><td>#image($ui.cms_directory 23 22)  <A class=clWinHeading href='$jlink.addQueryData('touri' , $uri )'>$item.getTitle()</A></td>") 
           #set ($catalogCounter=2)
        #else
           #set ($uri= $item.getUri())
           #set ($catalogList = "$catalogList<td>#image($ui.cms_directory 23 22) <A class=clWinHeading href='$jlink.addQueryData('touri' , $uri )'>$item.getTitle()</A></td></tr>") 
           #set ($catalogCounter=1)
  
        #end
    
    
      #else
         #if ($item.getContentClass() == 'APP') 
              #set ($contentList = "$contentList <table border='0' width='100%'><tr><td width='80%'>#image($ui.cms_application 23 22)")
         #else
              #set ($contentList = "$contentList <table border='0' width='100%'><tr><td width='80%'>#image($ui.cms_document 23 22)")
            
         #end
         #set ($contentList = "$contentList<A class=clWinHeading href='http://www.dhtmlcentral.com/script/script31.asp'>$item.getTitle()</A><SPAN class=clWinBy>( Written by $item.getAuthor() ) </SPAN><BR><FONT class=clWinText>$item.getDescription()</FONT></td><td width='20%' align='right'><A href='http://localhost:8080'>View/Run</A></td></tr></table><SPAN class=clLineDocSeparator></SPAN>")
      #end
    #end
  #end
  
  #set ($catalogList = "$catalogList</table>")
  
  <script>
  // OPENURL
  function openurl(urlid, param) {
     var sList = window.open(urlid, "cmsinfo", param);
  }
  </script>
  <table width='100%' border='0' cellpadding='0' align='center'>
  <tr>
   <td  width="75%">You are in #foreach ($ct in $catalogs) >> <A href="$jlink.addQueryData("touri" , "${ct.getUri()}")">$ct.getTitle()</A>#end</td>
  
   <td  width="25%" align="right"><A href="javascript:openurl('$link.setPage("nebanum,contentadministration,CatalogGeneral").setAction("catalog.CreateCatalog")', 'width=650,height=300,resizable=0,scrollbars=0,status=0')">[Add Catalog] </A> 
                                  <A href="javascript:openurl('$jslink.getTemplate("nebanum.contentadministration.CatalogGeneral").getAction("CreateCatalog")', 'width=800,height=450,resizable=0,scrollbars=0,status=0' )">[Add Content]</A></td>
  </tr>
  </table>
  <SPAN class=clLine></SPAN>
  <SPAN class=clLine></SPAN>
  $catalogList
  <SPAN class=clLine></SPAN>
  $contentList
  <SPAN class=clLine></SPAN>
  
  
  
  
  1.1                  jakarta-jetspeed/scratchpad/jetspeed-cms/webapp/WEB-INF/templates/vm/portlets/html/cms/content.vm
  
  Index: content.vm
  ===================================================================
  
  <script>
  // OPENURL
  function openurl(urlid, param) {
     var sList = window.open(urlid, "list", param);
  }
  </script>
  
  
  #set ($catalogName=$data.getParameters().getString("catalogname"))
  
  #if (!$catalogName) 
       #set ($catalogName = $conf.getInitParameter("catalogName"))
  #end
  
  #set ($catalog=$cmslink.getCatalog($data, "$catalogName")) 
  
  $portlet.setTitle("$catalog.getTitle()")
  #if(!$catalog) 
    <br>No suffisant privileges to display the content<br><br><br><br>
  #else
  
  #set ($contentCatalog = $catalog.getItems()) 
  
  <table width="100%">
    <tr> 
      #if($catalog.getUri() !=  $conf.getInitParameter("catalogName"))
        <td width="100%"> 
           <a href="$jlink.addQueryData("catalogname" , "${catalog.getParentUri()}")">[ Up ] </a>
        </td>
      #end
    </tr>
  </table>
  <br>
    #if($contentCatalog.size()==0) 
      <br>No information to display<br><br><br>
    #else
      #foreach ($item in $contentCatalog) 
         #if ($item.getType() == "ContentItem") 
           #if ($item.getContentClass() == "APP") #image($ui.cms_application 23 22) <A href="$jlink.addQueryData("template", "$item.getContentReference()")" target="_blank">$item.getTitle()</A><br>
           #else 
            #if ($item.contentTypeisURLInternet()) #image($ui.cms_document 23 22) <A href="$item.getContentReference()" target="_blank">$item.getTitle()</A> <br> #end
            #if ($item.contentTypeisURLPortal()) #image($ui.cms_document 23 22) <A href="$jlink.addQueryData("template", "$item.getContentReference()")" target="_blank">$item.getTitle()</A> <br> #end      
  	    #if ($item.contentTypeisUpload()) #image($ui.cms_document 23 22) <A href="$jlink.addQueryData("action", "WebDavAction").addQueryData("contentref","$item.getUri()")" target="_blank">$item.getTitle()</A> <br> #end      
           #end 
         #else 
           #image($ui.cms_directory 23 22) <a href="$jlink.addQueryData("catalogname" , "${item.getUri()}")">$item.getTitle()</a><br>
         #end
      #end 
    #end
  #end
  <br>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>