You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by mi...@apache.org on 2005/03/09 23:57:12 UTC

svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Author: michi
Date: Wed Mar  9 14:57:06 2005
New Revision: 156703

URL: http://svn.apache.org/viewcvs?view=rev&rev=156703
Log:
JCRSiteTree implementation added

Added:
    lenya/sandbox/jcrsitetree/
    lenya/sandbox/jcrsitetree/build.properties
    lenya/sandbox/jcrsitetree/build.xml
    lenya/sandbox/jcrsitetree/legal/
    lenya/sandbox/jcrsitetree/legal/jackrabbit.LICENSE.txt
    lenya/sandbox/jcrsitetree/lib/
    lenya/sandbox/jcrsitetree/lib/core/
    lenya/sandbox/jcrsitetree/lib/core/jackrabbit-0.16.2-dev.jar   (with props)
    lenya/sandbox/jcrsitetree/lib/extra/
    lenya/sandbox/jcrsitetree/src/
    lenya/sandbox/jcrsitetree/src/data/
    lenya/sandbox/jcrsitetree/src/data/pubs/
    lenya/sandbox/jcrsitetree/src/data/pubs/default/
    lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/
    lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/
    lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/repository.xml
    lenya/sandbox/jcrsitetree/src/java/
    lenya/sandbox/jcrsitetree/src/java/org/
    lenya/sandbox/jcrsitetree/src/java/org/apache/
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/AbstractPublication.java
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/ImportSiteTree.java
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/JCRSiteTree.java
    lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/Publication.java
    lenya/sandbox/jcrsitetree/src/targets/

Added: lenya/sandbox/jcrsitetree/build.properties
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/build.properties?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/build.properties (added)
+++ lenya/sandbox/jcrsitetree/build.properties Wed Mar  9 14:57:06 2005
@@ -0,0 +1,3 @@
+# Apache Lenya source directory
+
+lenya.source.dir=../../branches/BRANCH_1_2_X

Added: lenya/sandbox/jcrsitetree/build.xml
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/build.xml?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/build.xml (added)
+++ lenya/sandbox/jcrsitetree/build.xml Wed Mar  9 14:57:06 2005
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+
+<project name="patch" default="patch">
+
+  <description>
+    Patch files within Lenya build dir
+  </description>
+
+  <target name="init">
+    <property file="local.build.properties"/>
+    <property file="build.properties"/>
+
+    <echo>Apache Lenya source Dir: ${lenya.source.dir}</echo>
+  </target>
+
+  <target name="patch" depends="init" description="Patch files">
+    <echo>Patch files</echo>
+
+    <copy todir="${lenya.source.dir}/build/lenya/src">
+      <fileset dir="src/java"/>
+    </copy>
+
+    <copy todir="${lenya.source.dir}/build/lenya/webapp/WEB-INF/lib">
+      <fileset dir="lib/core"/>
+    </copy>
+
+    <copy todir="${lenya.source.dir}/build/lenya/webapp/WEB-INF/lib">
+      <fileset dir="lib/extra"/>
+    </copy>
+
+    <copy todir="${lenya.source.dir}/build/lenya/webapp/lenya/pubs/default">
+      <fileset dir="src/data/pubs/default"/>
+    </copy>
+  </target>
+
+  <target name="import-sitetree" depends="init" description="Import Authoring and Live sitetree">
+    <property name="default.pub.dir" value="${lenya.source.dir}/build/lenya/webapp/lenya/pubs/default"/>
+    <property name="repo.dir" value="${default.pub.dir}/repos/repo-sitetree"/>
+
+    <path id="classpath">
+      <fileset dir="${lenya.source.dir}/build/lenya/webapp/WEB-INF/lib">
+        <include name="*.jar"/>
+      </fileset>
+      <pathelement path="${lenya.source.dir}/build/lenya/webapp/WEB-INF/classes"/>
+    </path>
+
+    <echo>Import Authoring and Live Sitetree from ${default.pub.dir} into ${repo.dir}</echo>
+
+    <java classname="org.apache.lenya.cms.publication.ImportSiteTree">
+      <arg value="${repo.dir}"/>
+      <arg value="${default.pub.dir}"/>
+      <classpath refid="classpath"/>
+    </java>
+  </target>
+
+</project>

Added: lenya/sandbox/jcrsitetree/legal/jackrabbit.LICENSE.txt
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/legal/jackrabbit.LICENSE.txt?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/legal/jackrabbit.LICENSE.txt (added)
+++ lenya/sandbox/jcrsitetree/legal/jackrabbit.LICENSE.txt Wed Mar  9 14:57:06 2005
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Added: lenya/sandbox/jcrsitetree/lib/core/jackrabbit-0.16.2-dev.jar
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/lib/core/jackrabbit-0.16.2-dev.jar?view=auto&rev=156703
==============================================================================
Binary file - no diff available.

Propchange: lenya/sandbox/jcrsitetree/lib/core/jackrabbit-0.16.2-dev.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/repository.xml
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/repository.xml?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/repository.xml (added)
+++ lenya/sandbox/jcrsitetree/src/data/pubs/default/repos/repo-sitetree/repository.xml Wed Mar  9 14:57:06 2005
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- <!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Repository//EN" "file://config.dtd"> -->
+<!DOCTYPE Repository [
+    <!--
+        the Repository element configures a repository instance;
+        individual workspaces of the repository are configured through
+        separate configuration files called workspace.xml which are
+        located in a subfolder of the workspaces root directory
+        (see Workspaces element).
+
+        it consists of
+
+            a FileSystem element (the virtual file system
+            used by the repository to persist global state such as
+            registered namespaces, custom node types, etc..
+
+            a Workspaces element that specifies to the location of
+            workspaces root directory and the name of default workspace
+
+            a Workspace element that is used as a workspace configuration
+            template; it is used to create the initial workspace if there's
+            no workspace yet and for creating additional workspaces through
+            the api
+
+            a SearchIndex element that is used for configuring per workspace
+            Indexing-related settings
+
+            a Versioning element that is used for configuring 
+            versioning-related settings
+    -->
+    <!ELEMENT Repository (FileSystem,Workspaces,Workspace,Versioning)>
+
+    <!--
+        a virtual file system
+    -->
+    <!ELEMENT FileSystem (param*)>
+    <!ATTLIST FileSystem
+      class CDATA #REQUIRED>
+
+    <!--
+        generic parameter (name/value pair)
+    -->
+    <!ELEMENT param EMPTY>
+    <!ATTLIST param
+      name CDATA #REQUIRED
+      value CDATA #REQUIRED>
+
+    <!--
+        the Workspaces element specifies the workspaces root directory
+        (rootPath attribute) and the name of the default workspace
+        (defaultWorkspace attribute).
+
+        individual workspaces are configured through individual workspace.xml
+        files located in a subfolder each of the workspaces root directory.
+    -->
+    <!ELEMENT Workspaces EMPTY>
+    <!ATTLIST Workspaces
+      rootPath CDATA #REQUIRED
+      defaultWorkspace CDATA #REQUIRED>
+
+    <!--
+        the Workspace element serves as a workspace configuration template;
+        it is used to create the initial workspace if there's no workspace yet
+        and for creating additional workspaces through the api
+    -->
+    <!ELEMENT Workspace (FileSystem,PersistenceManager,SearchIndex?)>
+    <!ATTLIST Workspace
+      name CDATA #REQUIRED>
+
+    <!--
+        the PersistenceManager element configures the persistence manager
+        to be used for the workspace; the class attribute specifies the
+        FQN of the class implementing PersistenceManager interface
+    -->
+    <!ELEMENT PersistenceManager (param*)>
+    <!ATTLIST PersistenceManager
+      class CDATA #REQUIRED>
+
+    <!--
+        the SearchIndex element specifies the locaction of the search index
+        (used by the QueryHandler); the class attribute specifies the
+        FQN of the class implementing the QueryHandler interface.
+    -->
+    <!ELEMENT SearchIndex (param*,FileSystem)>
+    <!ATTLIST SearchIndex
+      class CDATA #REQUIRED>
+
+    <!--
+        the Versioning element configures the persistence manager
+        to be used for persisting version state
+    -->
+    <!ELEMENT Versioning (FileSystem, PersistenceManager)>
+    <!ATTLIST Versioning
+      rootPath CDATA #REQUIRED
+    >
+]>
+<Repository>
+    <!--
+        virtual file system where the repository stores global state
+        (e.g. registered namespaces, custom node types, etc.)
+    -->
+    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+        <param name="path" value="${rep.home}/repository"/>
+    </FileSystem>
+    <!--
+        location of workspaces root directory and name of default workspace
+    -->
+    <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
+    <!--
+        workspace configuration template:
+        used to create the initial workspace if there's no workspace yet
+    -->
+    <Workspace name="${wsp.name}">
+        <!--
+            virtual file system of the workspace:
+            class: FQN of class implementing FileSystem interface
+        -->
+        <FileSystem class="com.day.jackrabbit.fs.cq.CQFileSystem">
+            <param name="path" value="${wsp.home}/wspStore.dat"/>
+            <param name="autoRepair" value="false"/>
+            <param name="blockSize" value="128"/>
+            <param name="autoSync" value="false"/>
+        </FileSystem>
+        <!--
+            persistence of the workspace:
+            class: FQN of class implementing PersistenceManager interface
+        -->
+        <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
+        <!--
+            Search index and the file system it uses.
+        -->
+        <SearchIndex class="org.apache.jackrabbit.core.search.lucene.SearchIndex">
+            <param name="useCompoundFile" value="true"/>
+            <param name="minMergeDocs" value="1000"/>
+            <param name="maxMergeDocs" value="10000"/>
+            <param name="mergeFactor" value="10"/>
+            
+            <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+                <param name="path" value="${wsp.home}/index"/>
+            </FileSystem>
+        </SearchIndex>
+    </Workspace>
+
+    <!--
+        Configures the versioning
+    -->
+    <Versioning rootPath="${rep.home}/version">
+        <!--
+            Configures the filesystem to use for versioning for the respective
+            persistence manager
+        -->
+        <FileSystem class="com.day.jackrabbit.fs.cq.CQFileSystem">
+            <param name="path" value="${rep.home}/version/version.dat"/>
+            <param name="autoRepair" value="false"/>
+            <param name="blockSize" value="128"/>
+            <param name="autoSync" value="false"/>
+        </FileSystem>
+
+        <!--
+            Configures the persistence manager to be used for persisting version state.
+            Please note that the current versioning implementation is based on
+            a 'normal' persistence manager, but this could change in future
+            implementations.
+        -->
+        <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
+
+    </Versioning>
+
+</Repository>

Added: lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/AbstractPublication.java
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/AbstractPublication.java?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/AbstractPublication.java (added)
+++ lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/AbstractPublication.java Wed Mar  9 14:57:06 2005
@@ -0,0 +1,608 @@
+/*
+ * Copyright  1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/* $Id: AbstractPublication.java 154050 2005-02-16 17:20:29Z andreas $  */
+
+package org.apache.lenya.cms.publication;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.lenya.cms.publishing.PublishingEnvironment;
+import org.apache.log4j.Category;
+
+/**
+ * A publication.
+ */
+public abstract class AbstractPublication implements Publication {
+    private static Category log = Category.getInstance(AbstractPublication.class);
+
+    private static final String[] areas = { AUTHORING_AREA, STAGING_AREA, LIVE_AREA, ADMIN_AREA,
+            ARCHIVE_AREA, TRASH_AREA, INFO_AREA_PREFIX + AUTHORING_AREA,
+            INFO_AREA_PREFIX + STAGING_AREA, INFO_AREA_PREFIX + LIVE_AREA,
+            INFO_AREA_PREFIX + ARCHIVE_AREA, INFO_AREA_PREFIX + TRASH_AREA };
+
+    private String id;
+    private PublishingEnvironment environment;
+    private File servletContext;
+    private DocumentIdToPathMapper mapper = null;
+    private ArrayList languages = new ArrayList();
+    private String defaultLanguage = null;
+    private String breadcrumbprefix = null;
+    private String sslprefix = null;
+    private String livemountpoint = null;
+    private HashMap siteTrees = new HashMap();
+    private String[] rewriteAttributeXPaths = { };
+    private boolean hasSitetree = true;
+
+    private static final String ELEMENT_PROXY = "proxy";
+    private static final String ATTRIBUTE_AREA = "area";
+    private static final String ATTRIBUTE_URL = "url";
+    private static final String ATTRIBUTE_SSL = "ssl";
+    private static final String ELEMENT_REWRITE_ATTRIBUTE = "link-attribute";
+    private static final String ATTRIBUTE_XPATH = "xpath";
+
+    /**
+     * Creates a new instance of Publication
+     * 
+     * @param id the publication id
+     * @param servletContextPath the servlet context of this publication
+     * 
+     * @throws PublicationException if there was a problem reading the config file
+     */
+    protected AbstractPublication(String id, String servletContextPath) throws PublicationException {
+        assert id != null;
+        this.id = id;
+
+        assert servletContextPath != null;
+
+        File servletContext = new File(servletContextPath);
+        assert servletContext.exists();
+        this.servletContext = servletContext;
+
+        // FIXME: remove PublishingEnvironment from publication
+        environment = new PublishingEnvironment(servletContextPath, id);
+
+        File configFile = new File(getDirectory(), CONFIGURATION_FILE);
+        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+
+        Configuration config;
+
+        String pathMapperClassName = null;
+        String documentBuilderClassName = null;
+
+        try {
+            config = builder.buildFromFile(configFile);
+
+            try {
+                pathMapperClassName = config.getChild(ELEMENT_PATH_MAPPER).getValue();
+                Class pathMapperClass = Class.forName(pathMapperClassName);
+                this.mapper = (DocumentIdToPathMapper) pathMapperClass.newInstance();
+            } catch (ClassNotFoundException e) {
+                throw new PublicationException("Cannot instantiate documentToPathMapper: ["
+                        + pathMapperClassName + "]", e);
+            }
+
+            try {
+                Configuration documentBuilderConfiguration = config.getChild(
+                        ELEMENT_DOCUMENT_BUILDER, false);
+                if (documentBuilderConfiguration != null) {
+                    documentBuilderClassName = documentBuilderConfiguration.getValue();
+                    Class documentBuilderClass = Class.forName(documentBuilderClassName);
+                    this.documentBuilder = (DocumentBuilder) documentBuilderClass.newInstance();
+                }
+            } catch (ClassNotFoundException e) {
+                throw new PublicationException("Cannot instantiate document builder: ["
+                        + pathMapperClassName + "]", e);
+            }
+
+            Configuration[] languages = config.getChild(LANGUAGES).getChildren();
+            for (int i = 0; i < languages.length; i++) {
+                Configuration languageConfig = languages[i];
+                String language = languageConfig.getValue();
+                this.languages.add(language);
+                if (languageConfig.getAttribute(DEFAULT_LANGUAGE_ATTR, null) != null) {
+                    defaultLanguage = language;
+                }
+            }
+
+            Configuration siteStructureConfiguration = config.getChild(ELEMENT_SITE_STRUCTURE,
+                    false);
+            if (siteStructureConfiguration != null) {
+                String siteStructureType = siteStructureConfiguration.getAttribute(ATTRIBUTE_TYPE);
+                if (!siteStructureType.equals("sitetree")) {
+                    hasSitetree = false;
+                }
+            }
+
+            Configuration[] proxyConfigs = config.getChildren(ELEMENT_PROXY);
+            for (int i = 0; i < proxyConfigs.length; i++) {
+                String url = proxyConfigs[i].getAttribute(ATTRIBUTE_URL);
+                String ssl = proxyConfigs[i].getAttribute(ATTRIBUTE_SSL);
+                String area = proxyConfigs[i].getAttribute(ATTRIBUTE_AREA);
+
+                Proxy proxy = new Proxy();
+                proxy.setUrl(url);
+
+                Object key = getProxyKey(area, Boolean.valueOf(ssl).booleanValue());
+                this.areaSsl2proxy.put(key, proxy);
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding proxy: [" + proxy + "] for area=[" + area + "] SSL=[" + ssl
+                            + "]");
+                }
+            }
+            
+            Configuration[] rewriteAttributeConfigs = config.getChildren(ELEMENT_REWRITE_ATTRIBUTE);
+            List xPaths = new ArrayList();
+            for (int i = 0; i < rewriteAttributeConfigs.length; i++) {
+                String xPath = rewriteAttributeConfigs[i].getAttribute(ATTRIBUTE_XPATH);
+                xPaths.add(xPath);
+            }
+            this.rewriteAttributeXPaths = (String[]) xPaths.toArray(new String[xPaths.size()]);
+
+        } catch (PublicationException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error(e);
+            throw new PublicationException("Problem with config file: "
+                    + configFile.getAbsolutePath(), e);
+        }
+
+        breadcrumbprefix = config.getChild(BREADCRUMB_PREFIX).getValue("");
+
+        sslprefix = config.getChild(SSL_PREFIX).getValue("");
+
+        livemountpoint = config.getChild(LIVE_MOUNT_POINT).getValue("");
+
+    }
+
+    /**
+     * Returns the publication ID.
+     * @return A string value.
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Returns the publishing environment of this publication.
+     * @return A {@link PublishingEnvironment}object.
+     * @deprecated It is planned to decouple the environments from the publication.
+     */
+    public PublishingEnvironment getEnvironment() {
+        return environment;
+    }
+
+    /**
+     * Returns the servlet context this publication belongs to (usually, the
+     * <code>webapps/lenya</code> directory).
+     * @return A <code>File</code> object.
+     */
+    public File getServletContext() {
+        return servletContext;
+    }
+
+    /**
+     * Returns the publication directory.
+     * @return A <code>File</code> object.
+     */
+    public File getDirectory() {
+        return new File(getServletContext(), PUBLICATION_PREFIX + File.separator + getId());
+    }
+
+    /**
+     * Return the directory of a specific area.
+     * 
+     * @param area a <code>File</code> representing the root of the area content directory.
+     * 
+     * @return the directory of the given content area.
+     */
+    public File getContentDirectory(String area) {
+        return new File(getDirectory(), CONTENT_PATH + File.separator + area);
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param mapper DOCUMENT ME!
+     */
+    public void setPathMapper(DefaultDocumentIdToPathMapper mapper) {
+        assert mapper != null;
+        this.mapper = mapper;
+    }
+
+    /**
+     * Returns the path mapper.
+     * 
+     * @return a <code>DocumentIdToPathMapper</code>
+     */
+    public DocumentIdToPathMapper getPathMapper() {
+        return mapper;
+    }
+
+    /**
+     * Returns if a given string is a valid area name.
+     * @param area The area string to test.
+     * @return A boolean value.
+     */
+    public static boolean isValidArea(String area) {
+        return area != null && Arrays.asList(areas).contains(area);
+    }
+
+    /**
+     * Get the default language
+     * 
+     * @return the default language
+     */
+    public String getDefaultLanguage() {
+        return defaultLanguage;
+    }
+
+    /**
+     * Set the default language
+     * 
+     * @param language the default language
+     */
+    public void setDefaultLanguage(String language) {
+        defaultLanguage = language;
+    }
+
+    /**
+     * Get all available languages for this publication
+     * 
+     * @return an <code>Array</code> of languages
+     */
+    public String[] getLanguages() {
+        return (String[]) languages.toArray(new String[languages.size()]);
+    }
+
+    /**
+     * Get the breadcrumb prefix. It can be used as a prefix if a publication is part of a larger
+     * site
+     * 
+     * @return the breadcrumb prefix
+     */
+    public String getBreadcrumbPrefix() {
+        return breadcrumbprefix;
+    }
+
+    /**
+     * Get the SSL prefix. If you want to serve SSL-protected pages through a special site, use this
+     * prefix. This can come in handy if you have multiple sites that need SSL protection and you
+     * want to share one SSL certificate.
+     * 
+     * @return the SSL prefix
+     */
+    public String getSSLPrefix() {
+        return sslprefix;
+    }
+
+    /**
+     * Get the Live mount point. The live mount point is used to rewrite links that are of the form
+     * /contextprefix/publication/area/documentid to /livemountpoint/documentid
+     * 
+     * This is useful if you serve your live area through mod_proxy. to enable this functionality,
+     * set the Live mount point to / or something else. An empty mount point disables the feature.
+     * 
+     * @return the Live mount point
+     */
+    public String getLiveMountPoint() {
+        return livemountpoint;
+    }
+
+    /**
+     * Get the sitetree for a specific area of this publication. Sitetrees are created on demand and
+     * are cached.
+     * 
+     * @param area the area
+     * @return the sitetree for the specified area
+     * 
+     * @throws SiteTreeException if an error occurs
+     */
+    public JCRSiteTree getSiteTree(String area) throws SiteTreeException {
+
+        JCRSiteTree sitetree = null;
+
+        if (hasSitetree) {
+            if (siteTrees.containsKey(area)) {
+                log.error("Load sitetree from MEMORY (" + area + ")");
+                sitetree = (JCRSiteTree) siteTrees.get(area);
+            } else {
+                log.error("Load sitetree from FILESYSTEM (" + area + ")");
+                sitetree = new JCRSiteTree(getDirectory(), area);
+                siteTrees.put(area, sitetree);
+            }
+        }
+        return sitetree;
+    }
+
+    private DocumentBuilder documentBuilder;
+
+    /**
+     * Returns the document builder of this instance.
+     * @return A document builder.
+     */
+    public DocumentBuilder getDocumentBuilder() {
+
+        if (documentBuilder == null) {
+            throw new IllegalStateException(
+                    "The document builder was not defined in publication.xconf!");
+        }
+
+        return documentBuilder;
+    }
+
+    /**
+     * Creates a version of the document object in another area.
+     * @param document The document to clone.
+     * @param area The destination area.
+     * @return A document.
+     * @throws PublicationException when an error occurs.
+     */
+    public Document getAreaVersion(Document document, String area) throws PublicationException {
+        DocumentBuilder builder = getDocumentBuilder();
+        String url = builder
+                .buildCanonicalUrl(this, area, document.getId(), document.getLanguage());
+        Document destinationDocument = builder.buildDocument(this, url);
+        return destinationDocument;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object object) {
+        boolean equals = false;
+
+        if (getClass().isInstance(object)) {
+            Publication publication = (Publication) object;
+            equals = getId().equals(publication.getId())
+                    && getServletContext().equals(publication.getServletContext());
+        }
+
+        return equals;
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        String key = getServletContext() + ":" + getId();
+        return key.hashCode();
+    }
+
+    /**
+     * Template method to copy a document. Override {@link #copyDocumentSource(Document, Document)}
+     * to implement access to a custom repository.
+     * @see org.apache.lenya.cms.publication.Publication#copyDocument(org.apache.lenya.cms.publication.Document,
+     *      org.apache.lenya.cms.publication.Document)
+     */
+    public void copyDocument(Document sourceDocument, Document destinationDocument)
+            throws PublicationException {
+
+        copyDocumentSource(sourceDocument, destinationDocument);
+
+        copySiteStructure(sourceDocument, destinationDocument);
+    }
+
+    /**
+     * Copies a document in the site structure.
+     * @param sourceDocument The source document.
+     * @param destinationDocument The destination document.
+     * @throws PublicationException when something went wrong.
+     */
+    protected void copySiteStructure(Document sourceDocument, Document destinationDocument)
+            throws PublicationException {
+        if (hasSitetree) {
+            try {
+                SiteTree sourceTree = getSiteTree(sourceDocument.getArea());
+                SiteTree destinationTree = getSiteTree(destinationDocument.getArea());
+
+                SiteTreeNode sourceNode = sourceTree.getNode(sourceDocument.getId());
+                if (sourceNode == null) {
+                    throw new PublicationException("The node for source document ["
+                            + sourceDocument.getId() + "] doesn't exist!");
+                } else {
+
+                    SiteTreeNode[] siblings = sourceNode.getNextSiblings();
+                    String parentId = sourceNode.getAbsoluteParentId();
+                    SiteTreeNode sibling = null;
+                    String siblingDocId = null;
+
+                    // same document ID -> insert at the same position
+                    if (sourceDocument.getId().equals(destinationDocument.getId())) {
+                        for (int i = 0; i < siblings.length; i++) {
+                            String docId = parentId + "/" + siblings[i].getId();
+                            sibling = destinationTree.getNode(docId);
+                            if (sibling != null) {
+                                siblingDocId = docId;
+                                break;
+                            }
+                        }
+                    }
+                    
+           
+                    Label label = sourceNode.getLabel(sourceDocument.getLanguage());
+                    if (label == null) {
+                        // the node that we're trying to publish
+                        // doesn't have this language
+                        throw new PublicationException("The node " + sourceDocument.getId()
+                                + " doesn't contain a label for language "
+                                + sourceDocument.getLanguage());
+                    } else {
+                        SiteTreeNode destinationNode = destinationTree.getNode(destinationDocument
+                                .getId());
+                        if (destinationNode == null) {
+                            Label[] labels = { label };
+
+                            if (siblingDocId == null) {
+                                destinationTree.addNode(destinationDocument.getId(), labels,
+                                		sourceNode.visibleInNav(), sourceNode.getHref(), sourceNode.getSuffix(), sourceNode
+                                                .hasLink());
+                            } else {
+                                destinationTree.addNode(destinationDocument.getId(), labels, sourceNode.visibleInNav(),
+                                        sourceNode.getHref(), sourceNode.getSuffix(), sourceNode
+                                                .hasLink(), siblingDocId);
+                            }
+
+                        } else {
+                            // if the node already exists in the live
+                            // tree simply insert the label in the
+                            // live tree
+                            destinationTree.setLabel(destinationDocument.getId(), label);
+                            //and synchronize visibilityinnav attribute with the one in the source area 
+                            String visibility ="true";
+                            if (!sourceNode.visibleInNav()) visibility = "false";
+                            destinationNode.setNodeAttribute(SiteTreeNodeImpl.VISIBLEINNAV_ATTRIBUTE_NAME,
+                                    visibility);
+
+                        }
+                    }
+                }
+
+                destinationTree.save();
+            } catch (SiteTreeException e) {
+                throw new PublicationException(e);
+            }
+        }
+    }
+
+    /**
+     * Copies a document source.
+     * @param sourceDocument The source document.
+     * @param destinationDocument The destination document.
+     * @throws PublicationException when something went wrong.
+     */
+    protected abstract void copyDocumentSource(Document sourceDocument, Document destinationDocument)
+            throws PublicationException;
+
+    /**
+     * @see org.apache.lenya.cms.publication.Publication#deleteDocument(org.apache.lenya.cms.publication.Document)
+     */
+    public void deleteDocument(Document document) throws PublicationException {
+        if (!document.exists()) {
+            throw new PublicationException("Document [" + document + "] does not exist!");
+        }
+        deleteFromSiteStructure(document);
+        deleteDocumentSource(document);
+    }
+
+    /**
+     * Deletes a document from the site structure.
+     * @param document The document to remove.
+     * @throws PublicationException when something went wrong.
+     */
+    protected void deleteFromSiteStructure(Document document) throws PublicationException {
+        if (hasSitetree) {
+            SiteTree tree;
+            try {
+                tree = getSiteTree(document.getArea());
+            } catch (SiteTreeException e) {
+                throw new PublicationException(e);
+            }
+
+            SiteTreeNode node = tree.getNode(document.getId());
+
+            if (node == null) {
+                throw new PublicationException("Sitetree node for document [" + document
+                        + "] does not exist!");
+            }
+
+            Label label = node.getLabel(document.getLanguage());
+
+            if (label == null) {
+                throw new PublicationException("Sitetree label for document [" + document
+                        + "] in language [" + document.getLanguage() + "]does not exist!");
+            }
+
+            if (node.getLabels().length == 1 && node.getChildren().length > 0) {
+                throw new PublicationException("Cannot delete last language version of document ["
+                        + document + "] because this node has children.");
+            }
+
+            node.removeLabel(label);
+
+            if (node.getLabels().length == 0) {
+                tree.removeNode(document.getId());
+            }
+
+            try {
+                tree.save();
+            } catch (SiteTreeException e) {
+                throw new PublicationException(e);
+            }
+        }
+    }
+
+    /**
+     * Deletes the source of a document.
+     * @param document The document to delete.
+     * @throws PublicationException when something went wrong.
+     */
+    protected abstract void deleteDocumentSource(Document document) throws PublicationException;
+
+    /**
+     * @see org.apache.lenya.cms.publication.Publication#moveDocument(org.apache.lenya.cms.publication.Document,
+     *      org.apache.lenya.cms.publication.Document)
+     */
+    public void moveDocument(Document sourceDocument, Document destinationDocument)
+            throws PublicationException {
+        copyDocument(sourceDocument, destinationDocument);
+        deleteDocument(sourceDocument);
+    }
+
+    private Map areaSsl2proxy = new HashMap();
+
+    /**
+     * Generates a hash key for a area-SSL combination.
+     * @param area The area.
+     * @param isSslProtected If the proxy is assigned for SSL-protected pages.
+     * @return An object.
+     */
+    protected Object getProxyKey(String area, boolean isSslProtected) {
+        return area + ":" + isSslProtected;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.publication.Publication#getProxy(org.apache.lenya.cms.publication.Document,
+     *      boolean)
+     */
+    public Proxy getProxy(Document document, boolean isSslProtected) {
+
+        Object key = getProxyKey(document.getArea(), isSslProtected);
+        Proxy proxy = (Proxy) this.areaSsl2proxy.get(key);
+
+        if (log.isDebugEnabled()) {
+            log.debug("Resolving proxy for [" + document + "] SSL=[" + isSslProtected + "]");
+            log.debug("Resolved proxy: [" + proxy + "]");
+        }
+
+        return proxy;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.publication.Publication#getRewriteAttributeXPaths()
+     */
+    public String[] getRewriteAttributeXPaths() {
+        return this.rewriteAttributeXPaths;
+    }
+}

Added: lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/ImportSiteTree.java
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/ImportSiteTree.java?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/ImportSiteTree.java (added)
+++ lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/ImportSiteTree.java Wed Mar  9 14:57:06 2005
@@ -0,0 +1,84 @@
+/*
+ * Copyright  1999-2005 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.lenya.cms.publication;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Hashtable;
+
+import javax.jcr.*;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.apache.jackrabbit.core.jndi.RegistryHelper;
+
+/**
+ *
+ */
+public class ImportSiteTree {
+
+    /**
+     *
+     */
+    public static void main(String[] args) {
+        String repoHomeDir = args[0];
+        String defaultPubDir = args[1];
+
+        new ImportSiteTree().importSitetree(repoHomeDir, defaultPubDir);
+    }
+
+    /**
+     *
+     */
+    public void importSitetree(String repoHomeDir, String defaultPubDir) {
+        System.out.println("Import Authoring and Live Sitetree from " + defaultPubDir + " into " + repoHomeDir);
+
+        try {
+            Repository repo = getRepository(repoHomeDir);
+
+            Session session = repo.login(new SimpleCredentials("anonymous", "".toCharArray()), null);
+            Node rootNode = session.getRootNode();
+
+            Node authoringNode = rootNode.addNode("authoring", "nt:unstructured");
+            session.importXML("/authoring", new FileInputStream(defaultPubDir + "/content/authoring/sitetree.xml"));
+
+            Node liveNode = rootNode.addNode("live", "nt:unstructured");
+            session.importXML("/live", new FileInputStream(defaultPubDir + "/content/live/sitetree.xml"));
+
+            session.save();
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+    }
+
+    /**
+     *
+     */
+    private Repository getRepository(String repHomeDir) throws Exception {
+        String configFile = repHomeDir + File.separator + "repository.xml";
+
+        Hashtable env = new Hashtable();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
+        env.put(Context.PROVIDER_URL, "localhost");
+        InitialContext ctx = new InitialContext(env);
+
+        RegistryHelper.registerRepository(ctx, "repo", configFile, repHomeDir, true);
+        return (Repository) ctx.lookup("repo");
+    }
+}

Added: lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/JCRSiteTree.java
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/JCRSiteTree.java?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/JCRSiteTree.java (added)
+++ lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/JCRSiteTree.java Wed Mar  9 14:57:06 2005
@@ -0,0 +1,593 @@
+/*
+ * Copyright  1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/* @version $Id: JCRSiteTree.java 155287 2005-02-25 01:17:05Z gregor $ */
+
+package org.apache.lenya.cms.publication;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.lenya.xml.DocumentHelper;
+import org.apache.lenya.xml.NamespaceHelper;
+import org.apache.log4j.Category;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * DOCUMENT ME!
+ */
+public class JCRSiteTree implements SiteTree {
+    private static Category log = Category.getInstance(JCRSiteTree.class);
+
+    public static final String NAMESPACE_URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
+    public static final String SITE_TREE_FILENAME = "sitetree.xml";
+
+    private Document document = null;
+    private File treefile = null;
+    // the area is only retained to provide some more info when raising an exception.
+    private String area = "";
+
+    /**
+     * Create a JCRSiteTree
+     * 
+     * @param pubDir the publication directory
+     * @param area the area
+     * 
+     * @throws SiteTreeException if an error occurs
+     */
+    protected JCRSiteTree(File pubDir, String area) throws SiteTreeException {
+        this(
+            new File(
+                pubDir,
+                Publication.CONTENT_PATH
+                    + File.separator
+                    + area
+                    + File.separator
+                    + SITE_TREE_FILENAME));
+        log.error("Load sitetree: " + pubDir + " " + area);
+        this.area = area;
+    }
+
+    /**
+     * Create a JCRSiteTree from a filename.
+     *
+     * @param treefilename file name of the tree
+     *
+     * @throws SiteTreeException if an error occurs
+     *  
+     * @deprecated use the JCRSiteTree(File pubDir, String area) constructor instead.
+     */
+    public JCRSiteTree(String treefilename) throws SiteTreeException {
+        this(new File(treefilename));
+    }
+
+    /**
+     * Create a JCRSiteTree from a file.
+     *
+     * @param treefile the file containing the tree
+     * 
+     * @throws SiteTreeException if an error occurs
+     * 
+     * @deprecated this constructor will be private in the future
+     */
+    public JCRSiteTree(File treefile) throws SiteTreeException {
+        this.treefile = treefile;
+
+        try {
+            if (!treefile.isFile()) {
+                //the treefile doesn't exist, so create it
+
+                document = createDocument();
+            } else {
+                // Read tree
+                document = DocumentHelper.readDocument(treefile);
+            }
+        } catch (ParserConfigurationException e) {
+            throw new SiteTreeException(e);
+        } catch (SAXException e) {
+            throw new SiteTreeException(e);
+        } catch (IOException e) {
+            throw new SiteTreeException(e);
+        }
+
+    }
+
+    private long lastModified = 0;
+
+    /**
+     * Checks if the tree file has been modified externally and reloads the site tree.
+     * @throws SiteTreeException when something went wrong.
+     */
+    protected void checkModified() {
+        if (area.equals(Publication.LIVE_AREA)
+            && treefile.isFile()
+            && treefile.lastModified() > lastModified) {
+                
+            if (log.isDebugEnabled()) {
+                log.debug("Sitetree [" + treefile + "] has changed: reloading.");
+            }
+                
+            try {
+                document = DocumentHelper.readDocument(treefile);
+            } catch (Exception e) {
+                throw new IllegalStateException(e.getMessage());
+            }
+            lastModified = treefile.lastModified();
+        }
+    }
+
+    /**
+     * Create a new JCRSiteTree xml document.
+     *
+     * @return the new site document
+     * 
+     * @throws ParserConfigurationException if an error occurs
+     */
+    public Document createDocument() throws ParserConfigurationException {
+        document = DocumentHelper.createDocument(NAMESPACE_URI, "site", null);
+
+        Element root = document.getDocumentElement();
+        root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        root.setAttribute(
+            "xsi:schemaLocation",
+            "http://apache.org/cocoon/lenya/sitetree/1.0  ../../../../resources/entities/sitetree.xsd");
+
+        return document;
+    }
+
+    /**
+     * Find a node in a subtree. The search is started at the
+     * given node. The list of ids contains the document-id
+     * split by "/".
+     *
+     * @param node where to start the search
+     * @param ids list of node ids
+     * 
+     * @return the node that matches the path given in the list of ids
+     */
+    protected Node findNode(Node node, List ids) {
+
+        checkModified();
+
+        if (ids.size() < 1) {
+            return node;
+        } else {
+            NodeList nodes = node.getChildNodes();
+
+            for (int i = 0; i < nodes.getLength(); i++) {
+                NamedNodeMap attributes = nodes.item(i).getAttributes();
+
+                if (attributes != null) {
+                    Node idAttribute = attributes.getNamedItem("id");
+
+                    if (idAttribute != null
+                        && !"".equals(idAttribute.getNodeValue())
+                        && idAttribute.getNodeValue().equals(ids.get(0))) {
+                        return findNode(nodes.item(i), ids.subList(1, ids.size()));
+                    }
+                }
+            }
+        }
+
+        // node wasn't found
+        return null;
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(org.apache.lenya.cms.publication.SiteTreeNode, java.lang.String)
+     */
+    public synchronized void addNode(SiteTreeNode node, String refDocumentId) throws SiteTreeException {
+        this.addNode(
+            node.getAbsoluteParentId(),
+            node.getId(),
+            node.getLabels(),
+            node.visibleInNav(),
+            node.getHref(),
+            node.getSuffix(),
+            node.hasLink(),
+            refDocumentId);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, java.lang.String, org.apache.lenya.cms.publication.Label[])
+     */
+    public synchronized void addNode(String parentid, String id, Label[] labels, boolean visibleInNav ) throws SiteTreeException {
+        addNode(parentid, id, labels, visibleInNav, null, null, false);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, java.lang.String, org.apache.lenya.cms.publication.Label[], boolean)
+     */
+    public synchronized void addNode(String parentid, String id, Label[] labels) throws SiteTreeException {
+        addNode(parentid, id, labels, true);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(org.apache.lenya.cms.publication.SiteTreeNode)
+     */
+    public synchronized void addNode(SiteTreeNode node) throws SiteTreeException {
+        this.addNode(node, null);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, org.apache.lenya.cms.publication.Label[], java.lang.String, java.lang.String, boolean, java.lang.String)
+     */
+    public synchronized void addNode(
+        String documentid,
+        Label[] labels,
+        boolean visibleInNav,
+        String href,
+        String suffix,
+        boolean link,
+        String refDocumentId)
+        throws SiteTreeException {
+        String parentid = "";
+        StringTokenizer st = new StringTokenizer(documentid, "/");
+        int length = st.countTokens();
+
+        for (int i = 0; i < (length - 1); i++) {
+            parentid = parentid + "/" + st.nextToken();
+        }
+
+        String id = st.nextToken();
+        this.addNode(parentid, id, labels, visibleInNav, href, suffix, link, refDocumentId);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, org.apache.lenya.cms.publication.Label[], java.lang.String, java.lang.String, boolean)
+     */
+    public synchronized void addNode(
+        String documentid,
+        Label[] labels,
+        boolean visibleInNav,
+        String href,
+        String suffix,
+        boolean link)
+        throws SiteTreeException {
+        this.addNode(documentid, labels, visibleInNav, href, suffix, link, null);
+    }
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, java.lang.String, org.apache.lenya.cms.publication.Label[], java.lang.String, java.lang.String, boolean)
+     */
+    public synchronized void addNode(
+        String parentid,
+        String id,
+        Label[] labels,
+        boolean visibleInNav,
+        String href,
+        String suffix,
+        boolean link)
+        throws SiteTreeException {
+        this.addNode(parentid, id, labels, visibleInNav, href, suffix, link, null);
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addNode(java.lang.String, java.lang.String, org.apache.lenya.cms.publication.Label[], java.lang.String, java.lang.String, boolean)
+     */
+    public synchronized void addNode(
+        String parentid,
+        String id,
+        Label[] labels,
+        boolean visibleInNav,
+        String href,
+        String suffix,
+        boolean link,
+        String refDocumentId)
+        throws SiteTreeException {
+
+        Node parentNode = getNodeInternal(parentid);
+
+        if (parentNode == null) {
+            throw new SiteTreeException(
+                "Parentid: " + parentid + " in " + area + " tree not found");
+        }
+
+        log.debug("PARENT ELEMENT: " + parentNode);
+
+        // Check if child already exists
+        Node childNode = getNodeInternal(parentid + "/" + id);
+
+        if (childNode != null) {
+            log.info("This node: " + parentid + "/" + id + " has already been inserted");
+
+            return;
+        }
+
+        // Create node
+        NamespaceHelper helper = new NamespaceHelper(NAMESPACE_URI, "", document);
+        Element child = helper.createElement(SiteTreeNodeImpl.NODE_NAME);
+        child.setAttribute(SiteTreeNodeImpl.ID_ATTRIBUTE_NAME, id);
+        
+        if (visibleInNav) {
+            child.setAttribute(SiteTreeNodeImpl.VISIBLEINNAV_ATTRIBUTE_NAME, "true");
+        } else {
+            child.setAttribute(SiteTreeNodeImpl.VISIBLEINNAV_ATTRIBUTE_NAME, "false");
+        }
+
+        if ((href != null) && (href.length() > 0)) {
+            child.setAttribute(SiteTreeNodeImpl.HREF_ATTRIBUTE_NAME, href);
+        }
+
+        if ((suffix != null) && (suffix.length() > 0)) {
+            child.setAttribute(SiteTreeNodeImpl.SUFFIX_ATTRIBUTE_NAME, suffix);
+        }
+
+        if (link) {
+            child.setAttribute(SiteTreeNodeImpl.LINK_ATTRIBUTE_NAME, "true");
+        }
+
+        for (int i = 0; i < labels.length; i++) {
+            String labelName = labels[i].getLabel();
+            Element label = helper.createElement(SiteTreeNodeImpl.LABEL_NAME, labelName);
+            String labelLanguage = labels[i].getLanguage();
+
+            if ((labelLanguage != null) && (labelLanguage.length() > 0)) {
+                label.setAttribute(SiteTreeNodeImpl.LANGUAGE_ATTRIBUTE_NAME, labelLanguage);
+            }
+
+            child.appendChild(label);
+        }
+
+        // Add Node 
+        if (refDocumentId != null && !refDocumentId.equals("")) {
+            Node nextSibling = getNodeInternal(refDocumentId);
+            if (nextSibling != null) {
+                parentNode.insertBefore(child, nextSibling);
+            } else {
+                parentNode.appendChild(child);
+            }
+        } else {
+            parentNode.appendChild(child);
+        }
+        log.debug("Tree has been modified: " + document.getDocumentElement());
+
+    }
+    /**
+     *  (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#addLabel(java.lang.String, org.apache.lenya.cms.publication.Label)
+     */
+    public synchronized void addLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.addLabel(label);
+        }
+    }
+
+    /**
+     *  (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#removeLabel(java.lang.String, org.apache.lenya.cms.publication.Label)
+     */
+    public synchronized void removeLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.removeLabel(label);
+        }
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#removeNode(java.lang.String)
+     */
+    public synchronized SiteTreeNode removeNode(String documentId) {
+        assert documentId != null;
+
+        Node node = removeNodeInternal(documentId);
+
+        if (node == null) {
+            return null;
+        }
+
+        return new SiteTreeNodeImpl(node);
+    }
+
+    /**
+     * removes the node corresponding to the given document-id
+     * and returns it
+     * 
+     * @param documentId the document-id of the Node to be removed
+     * 
+     * @return the <code>Node</code> that was removed
+     */
+    private synchronized Node removeNodeInternal(String documentId) {
+        Node node = this.getNodeInternal(documentId);
+        Node parentNode = node.getParentNode();
+        Node newNode = parentNode.removeChild(node);
+
+        return newNode;
+    }
+
+    /**
+     * Find a node for a given document-id
+     *
+     * @param documentId the document-id of the Node that we're trying to get
+     * 
+     * @return the Node if there is a Node for the given document-id, null otherwise
+     */
+    private Node getNodeInternal(String documentId) {
+        StringTokenizer st = new StringTokenizer(documentId, "/");
+        ArrayList ids = new ArrayList();
+
+        while (st.hasMoreTokens()) {
+            ids.add(st.nextToken());
+        }
+
+        Node node = findNode(document.getDocumentElement(), ids);
+        return node;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.publication.SiteTree#getNode(java.lang.String)
+     */
+    public SiteTreeNode getNode(String documentId) {
+        assert documentId != null;
+
+        SiteTreeNode treeNode = null;
+
+        Node node = getNodeInternal(documentId);
+        if (node != null) {
+            treeNode = new SiteTreeNodeImpl(node);
+        }
+
+        return treeNode;
+    }
+
+    /**
+     * Move up the node amongst its siblings.
+     * 
+     * @param documentid The document id for the node.
+     * @throws SiteTreeException if the moving failed.
+     */
+    public synchronized void moveUp(String documentid) throws SiteTreeException {
+        Node node = this.getNodeInternal(documentid);
+        if (node == null) {
+            throw new SiteTreeException("Node to move: " + documentid + " not found");
+        }
+        Node parentNode = node.getParentNode();
+        if (parentNode == null) {
+            throw new SiteTreeException(
+                "Parentid of node with documentid: " + documentid + " not found");
+        }
+
+        Node previousNode;
+        try {
+            previousNode =
+                XPathAPI.selectSingleNode(
+                    node,
+                    "(preceding-sibling::*[local-name() = 'node'])[last()]");
+        } catch (TransformerException e) {
+            throw new SiteTreeException(e);
+        }
+
+        if (previousNode == null) {
+            log.warn("Couldn't found a preceding sibling");
+            return;
+        }
+        Node insertNode = parentNode.removeChild(node);
+        parentNode.insertBefore(insertNode, previousNode);
+    }
+
+    /**
+     * Move down the node amongst its siblings.
+     * 
+     * @param documentid The document id for the node.
+     * @throws SiteTreeException if the moving failed.
+     */
+    public synchronized void moveDown(String documentid) throws SiteTreeException {
+        Node node = this.getNodeInternal(documentid);
+        if (node == null) {
+            throw new SiteTreeException("Node to move: " + documentid + " not found");
+        }
+        Node parentNode = node.getParentNode();
+        if (parentNode == null) {
+            throw new SiteTreeException(
+                "Parentid of node with documentid: " + documentid + " not found");
+        }
+        Node nextNode;
+        try {
+            nextNode =
+                XPathAPI.selectSingleNode(
+                    node,
+                    "following-sibling::*[local-name() = 'node'][position()=2]");
+        } catch (TransformerException e) {
+            throw new SiteTreeException(e);
+        }
+
+        Node insertNode = parentNode.removeChild(node);
+
+        if (nextNode == null) {
+            log.warn("Couldn't found the second following sibling");
+            parentNode.appendChild(insertNode);
+        } else {
+            parentNode.insertBefore(insertNode, nextNode);
+        }
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#importSubtree(org.apache.lenya.cms.publication.SiteTreeNode, org.apache.lenya.cms.publication.SiteTreeNode, java.lang.String)
+     */
+    public synchronized void importSubtree(
+        SiteTreeNode newParent,
+        SiteTreeNode subtreeRoot,
+        String newid,
+        String refDocumentId)
+        throws SiteTreeException {
+        assert subtreeRoot != null;
+        assert newParent != null;
+        String parentId = newParent.getAbsoluteId();
+        String id = newid;
+
+        this.addNode(
+            parentId,
+            id,
+            subtreeRoot.getLabels(),
+            subtreeRoot.visibleInNav(),
+            subtreeRoot.getHref(),
+            subtreeRoot.getSuffix(),
+            subtreeRoot.hasLink(),
+            refDocumentId);
+        newParent = this.getNode(parentId + "/" + id);
+        if (newParent == null) {
+            throw new SiteTreeException("The added node was not found.");
+        }
+        SiteTreeNode[] children = subtreeRoot.getChildren();
+        if (children == null) {
+            log.info("The node " + subtreeRoot.toString() + " has no children");
+            return;
+        } else {
+            for (int i = 0; i < children.length; i++) {
+                importSubtree(newParent, children[i], children[i].getId(), null);
+            }
+        }
+    }
+
+    /** (non-Javadoc)
+     * @see org.apache.lenya.cms.publication.SiteTree#save()
+     */
+    public synchronized void save() throws SiteTreeException {
+        try {
+            DocumentHelper.writeDocument(document, treefile);
+        } catch (TransformerException e) {
+            throw new SiteTreeException(
+                "The document [" + document.getLocalName() + "] could not be transformed");
+        } catch (IOException e) {
+            throw new SiteTreeException(
+                "The saving of document [" + document.getLocalName() + "] failed");
+        }
+    }
+
+    /**
+     * @see org.apache.lenya.cms.publication.SiteTree#setLabel(java.lang.String, org.apache.lenya.cms.publication.Label)
+     */
+    public synchronized void setLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.setLabel(label);
+        }
+    }
+
+}

Added: lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/Publication.java
URL: http://svn.apache.org/viewcvs/lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/Publication.java?view=auto&rev=156703
==============================================================================
--- lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/Publication.java (added)
+++ lenya/sandbox/jcrsitetree/src/java/org/apache/lenya/cms/publication/Publication.java Wed Mar  9 14:57:06 2005
@@ -0,0 +1,242 @@
+/*
+ * Copyright  1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/* $Id: Publication.java 154050 2005-02-16 17:20:29Z andreas $  */
+
+package org.apache.lenya.cms.publication;
+
+import java.io.File;
+
+import org.apache.lenya.cms.publishing.PublishingEnvironment;
+
+/**
+ * A Lenya publication.
+ */
+public interface Publication {
+
+    String AUTHORING_AREA = "authoring";
+    String STAGING_AREA = "staging";
+    String LIVE_AREA = "live";
+    String ADMIN_AREA = "admin";
+    String ARCHIVE_AREA = "archive";
+    String TRASH_AREA = "trash";
+    String ELEMENT_PATH_MAPPER = "path-mapper";
+    String ELEMENT_DOCUMENT_BUILDER = "document-builder";
+    String ELEMENT_SITE_STRUCTURE = "site-structure";
+    String ATTRIBUTE_TYPE = "type";
+    String LANGUAGES = "languages";
+    String LANGUAGE = "language";
+    String DEFAULT_LANGUAGE_ATTR = "default";
+    String BREADCRUMB_PREFIX = "breadcrumb-prefix";
+    String SSL_PREFIX = "ssl-prefix";
+    String LIVE_MOUNT_POINT = "live-mount-point";
+    String PUBLICATION_PREFIX = "lenya" + File.separator + "pubs";
+    String PUBLICATION_PREFIX_URI = "lenya/pubs";
+    String CONFIGURATION_PATH = "config";
+    String CONTENT_PATH = "content";
+    String PENDING_PATH = "pending";    
+    String DELETE_PATH = "delete";
+    String INFO_AREA_PREFIX = "info-";
+    String SEARCH_AREA_PREFIX = "search-";
+    String CONFIGURATION_FILE = CONFIGURATION_PATH + File.separator + "publication.xconf";
+
+    /**
+     * Returns the publication ID.
+     * @return A string value.
+     */
+    String getId();
+
+    /**
+     * Returns the publishing environment of this publication.
+     * @return A {@link PublishingEnvironment} object.
+     * @deprecated It is planned to decouple the environments from the publication.
+     */
+    PublishingEnvironment getEnvironment();
+
+    /**
+     * Returns the servlet context this publication belongs to
+     * (usually, the <code>webapps/lenya</code> directory).
+     * @return A <code>File</code> object.
+     */
+    File getServletContext();
+
+    /**
+     * Returns the publication directory.
+     * @return A <code>File</code> object.
+     */
+    File getDirectory();
+
+    /**
+     * Return the directory of a specific area.
+     * 
+     * @param area a <code>File</code> representing the root of the area content directory.
+     * 
+     * @return the directory of the given content area. 
+     */
+    File getContentDirectory(String area);
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param mapper DOCUMENT ME!
+     */
+    void setPathMapper(DefaultDocumentIdToPathMapper mapper);
+
+    /**
+     * Returns the path mapper.
+     * 
+     * @return a <code>DocumentIdToPathMapper</code>
+     */
+    DocumentIdToPathMapper getPathMapper();
+
+    /**
+     * Get the default language
+     * 
+     * @return the default language
+     */
+    String getDefaultLanguage();
+
+    /**
+     * Set the default language
+     * 
+     * @param language the default language
+     */
+    void setDefaultLanguage(String language);
+
+    /**
+     * Get all available languages for this publication
+     * 
+     * @return an <code>Array</code> of languages
+     */
+    String[] getLanguages();
+
+    /**
+     * Get the breadcrumb prefix. It can be used as a prefix if a publication is part of a larger site
+     * 
+     * @return the breadcrumb prefix
+     */
+    String getBreadcrumbPrefix();
+
+    /**
+     * Get the SSL prefix. If you want to serve SSL-protected pages through a special site, use this
+     * prefix. This can come in handy if you have multiple sites that need SSL protection and you want
+     * to share one SSL certificate.
+     * 
+     * @return the SSL prefix
+     */
+    String getSSLPrefix();
+
+    /**
+     * Get the Live mount point. The live mount point is used to rewrite links that are of the form 
+     * /contextprefix/publication/area/documentid to /livemountpoint/documentid
+     * 
+     * This is useful if you serve your live area through mod_proxy. to enable this functionality, set
+     * the Live mount point to / or something else. An empty mount point disables the feature.
+     * 
+     * @return the Live mount point
+     */
+    String getLiveMountPoint();
+
+    /**
+     * Get the sitetree for a specific area of this publication. 
+     * Sitetrees are created on demand and are cached.
+     * 
+     * @param area the area
+     * @return the sitetree for the specified area
+     * 
+     * @throws SiteTreeException if an error occurs 
+     */
+    JCRSiteTree getSiteTree(String area) throws SiteTreeException;
+
+    /**
+     * Returns the document builder of this instance.
+     * @return A document builder.
+     */
+    DocumentBuilder getDocumentBuilder();
+
+    /**
+     * Copies a document from one location to another location.
+     * @param sourceDocument The document to copy.
+     * @param destinationDocument The destination document.
+     * @throws PublicationException if a document which destinationDocument depends on
+     * does not exist.
+     */
+    void copyDocument(Document sourceDocument, Document destinationDocument)
+        throws PublicationException;
+
+    /**
+     * Copies a document to another area.
+     * @param sourceDocument The document to copy.
+     * @param destinationArea The destination area.
+     * @throws PublicationException if a document which the
+     * destination document depends on does not exist.
+     */
+    void copyDocumentToArea(Document sourceDocument, String destinationArea)
+        throws PublicationException;
+
+    /**
+     * Copies a document set to another area.
+     * @param documentSet The document set to copy.
+     * @param destinationArea The destination area.
+     * @throws PublicationException if a document which one of the
+     * destination documents depends on does not exist.
+     */
+    void copyDocumentSetToArea(DocumentSet documentSet, String destinationArea)
+        throws PublicationException;
+        
+    /**
+     * Deletes a document.
+     * @param document The document to delete.
+     * @throws PublicationException when something went wrong.
+     */
+    void deleteDocument(Document document) throws PublicationException;
+    
+    /**
+     * Moves a document from one location to another.
+     * @param sourceDocument The source document.
+     * @param destinationDocument The destination document.
+     * @throws PublicationException if a document which the
+     * destination document depends on does not exist.
+     */
+    void moveDocument(Document sourceDocument, Document destinationDocument) throws PublicationException;
+
+    /**
+     * Creates a version of the document object in another area.
+     * @param document The document to clone.
+     * @param area The destination area.
+     * @return A document.
+     * @throws PublicationException when an error occurs.
+     */
+    Document getAreaVersion(Document document, String area) throws PublicationException;
+
+    /**
+     * Returns the proxy which is used for a particular document. 
+     * @param document The document.
+     * @param isSslProtected A boolean value.
+     * @return A proxy or <code>null</code> if no proxy is defined
+     * for this version.
+     */
+    Proxy getProxy(Document document, boolean isSslProtected);
+    
+    /**
+     * Returns an array of XPaths representing attributes to be rewritten
+     * when a document URL has changed.
+     * @return An array of strings.
+     */
+    String[] getRewriteAttributeXPaths();
+    
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by "Gregor J. Rothfuss" <gr...@apache.org>.
Michael Wechner wrote:

>> IIRC the original purpose of hasSitetree was to support non-sitetree
>> publications, which was a desired constraint when the sitetree was
>> introduced.
> 
> oh right, and I think this is still very necessary

this needs to be reevaluated in trunk.

-- 
Gregor J. Rothfuss
COO, Wyona       Content Management Solutions    http://wyona.com
Apache Lenya                              http://lenya.apache.org
gregor.rothfuss@wyona.com                       gregor@apache.org

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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by Michael Wechner <mi...@wyona.com>.
Andreas Hartmann wrote:

>
> IIRC the original purpose of hasSitetree was to support non-sitetree
> publications, which was a desired constraint when the sitetree was
> introduced.


oh right, and I think this is still very necessary

Thanks

Michi

>
> -- Andreas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
> For additional commands, e-mail: dev-help@lenya.apache.org
>
>


-- 
Michael Wechner
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
michael.wechner@wyona.com                        michi@apache.org


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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by Andreas Hartmann <an...@apache.org>.
Michael Wechner wrote:

[...]

>> what is the purpose of hasSitetree in light of trying to have a 
>> consistent API without backdoors?
> 
> 
> 
> this is just a copy of the existing class from 1.2.X, whereas I have 
> replaced Default by JCR. Take a look at it ;-)
> 
> I don't think that I have created this code in the first place, whereas 
> I don't want
> to blame anyone here.

IIRC the original purpose of hasSitetree was to support non-sitetree
publications, which was a desired constraint when the sitetree was
introduced.

-- Andreas


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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by "Gregor J. Rothfuss" <gr...@apache.org>.
Michael Wechner wrote:

>> what is the purpose of hasSitetree in light of trying to have a 
>> consistent API without backdoors?
> 
> this is just a copy of the existing class from 1.2.X, whereas I have 
> replaced Default by JCR. Take a look at it ;-)
> 
> I don't think that I have created this code in the first place, whereas 
> I don't want
> to blame anyone here.

you are right :) in that case, let me ask the crowd: what is the purpose 
of it?


-- 
Gregor J. Rothfuss
COO, Wyona       Content Management Solutions    http://wyona.com
Apache Lenya                              http://lenya.apache.org
gregor.rothfuss@wyona.com                       gregor@apache.org

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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by Michael Wechner <mi...@wyona.com>.
Gregor J. Rothfuss wrote:

> Michael Wechner wrote:
>
>> Gregor J. Rothfuss wrote:
>>
>>> michi@apache.org wrote:
>>>
>>>> +                }
>>>> +            }
>>>
>>>
>>>
>>>
>>> can you explain this a bit more? we need to focus on creating more 
>>> site tree implementations, not try to work around them. (see recent 
>>> discussion about backdoors)
>>
>>
>>
>>
>> hm?
>
>
> what is the purpose of hasSitetree in light of trying to have a 
> consistent API without backdoors?


this is just a copy of the existing class from 1.2.X, whereas I have 
replaced Default by JCR. Take a look at it ;-)

I don't think that I have created this code in the first place, whereas 
I don't want
to blame anyone here.

Michi


-- 
Michael Wechner
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
michael.wechner@wyona.com                        michi@apache.org


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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by "Gregor J. Rothfuss" <gr...@apache.org>.
Michael Wechner wrote:
> Gregor J. Rothfuss wrote:
> 
>> michi@apache.org wrote:
>>
>>> +                }
>>> +            }
>>
>>
>>
>> can you explain this a bit more? we need to focus on creating more 
>> site tree implementations, not try to work around them. (see recent 
>> discussion about backdoors)
> 
> 
> 
> hm?

what is the purpose of hasSitetree in light of trying to have a 
consistent API without backdoors?

-- 
Gregor J. Rothfuss
COO, Wyona       Content Management Solutions    http://wyona.com
Apache Lenya                              http://lenya.apache.org
gregor.rothfuss@wyona.com                       gregor@apache.org

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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by Michael Wechner <mi...@wyona.com>.
Gregor J. Rothfuss wrote:

> michi@apache.org wrote:
>
>> +                }
>> +            }
>
>
> can you explain this a bit more? we need to focus on creating more 
> site tree implementations, not try to work around them. (see recent 
> discussion about backdoors)


hm?

>
>
>> +    public JCRSiteTree getSiteTree(String area) throws 
>> SiteTreeException {
>> +
>> +        JCRSiteTree sitetree = null;
>> +
>> +        if (hasSitetree) {
>> +            if (siteTrees.containsKey(area)) {
>> +                log.error("Load sitetree from MEMORY (" + area + ")");
>> +                sitetree = (JCRSiteTree) siteTrees.get(area);
>> +            } else {
>> +                log.error("Load sitetree from FILESYSTEM (" + area + 
>> ")");
>> +                sitetree = new JCRSiteTree(getDirectory(), area);
>> +                siteTrees.put(area, sitetree);
>> +            }
>> +        }
>> +        return sitetree;
>
>
> don't debug with log.error


I am aware of this, but this is not thought to be used in production 
yet, just for the ones who want help on implementing the JCRSiteTree and 
the very early adopters.

Michi



-- 
Michael Wechner
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
michael.wechner@wyona.com                        michi@apache.org


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


Re: svn commit: r156703 - in lenya/sandbox/jcrsitetree: ./ legal/ lib/ lib/core/ lib/extra/ src/ src/data/ src/data/pubs/ src/data/pubs/default/ src/data/pubs/default/repos/ src/data/pubs/default/repos/repo-sitetree/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/lenya/ src/java/org/apache/lenya/cms/ src/java/org/apache/lenya/cms/publication/ src/targets/

Posted by "Gregor J. Rothfuss" <gr...@apache.org>.
michi@apache.org wrote:

> +public abstract class AbstractPublication implements Publication {

> +            Configuration siteStructureConfiguration = config.getChild(ELEMENT_SITE_STRUCTURE,
> +                    false);
> +            if (siteStructureConfiguration != null) {
> +                String siteStructureType = siteStructureConfiguration.getAttribute(ATTRIBUTE_TYPE);
> +                if (!siteStructureType.equals("sitetree")) {
> +                    hasSitetree = false;
> +                }
> +            }

can you explain this a bit more? we need to focus on creating more site 
tree implementations, not try to work around them. (see recent 
discussion about backdoors)


> +    public JCRSiteTree getSiteTree(String area) throws SiteTreeException {
> +
> +        JCRSiteTree sitetree = null;
> +
> +        if (hasSitetree) {
> +            if (siteTrees.containsKey(area)) {
> +                log.error("Load sitetree from MEMORY (" + area + ")");
> +                sitetree = (JCRSiteTree) siteTrees.get(area);
> +            } else {
> +                log.error("Load sitetree from FILESYSTEM (" + area + ")");
> +                sitetree = new JCRSiteTree(getDirectory(), area);
> +                siteTrees.put(area, sitetree);
> +            }
> +        }
> +        return sitetree;

don't debug with log.error

> +public class ImportSiteTree {
> +
> +    /**
> +     *
> +     */
> +    public static void main(String[] args) {
> +        String repoHomeDir = args[0];
> +        String defaultPubDir = args[1];
> +
> +        new ImportSiteTree().importSitetree(repoHomeDir, defaultPubDir);
> +    }
> +
> +    /**
> +     *
> +     */
> +    public void importSitetree(String repoHomeDir, String defaultPubDir) {

please add javadocs

> +    protected JCRSiteTree(File pubDir, String area) throws SiteTreeException {
> +        this(
> +            new File(
> +                pubDir,
> +                Publication.CONTENT_PATH
> +                    + File.separator
> +                    + area
> +                    + File.separator
> +                    + SITE_TREE_FILENAME));
> +        log.error("Load sitetree: " + pubDir + " " + area);

don't debug with log.error


-- 
Gregor J. Rothfuss
COO, Wyona       Content Management Solutions    http://wyona.com
Apache Lenya                              http://lenya.apache.org
gregor.rothfuss@wyona.com                       gregor@apache.org

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