You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2005/07/05 18:19:23 UTC

svn commit: r209293 [1/3] - in /lenya/trunk/src: java/org/apache/lenya/cms/cocoon/components/modules/input/ java/org/apache/lenya/cms/cocoon/generation/ java/org/apache/lenya/cms/cocoon/transformation/ java/org/apache/lenya/cms/site/tree/ java/org/apac...

Author: andreas
Date: Tue Jul  5 09:19:18 2005
New Revision: 209293

URL: http://svn.apache.org/viewcvs?rev=209293&view=rev
Log:
Extracted sitetree to separate publet

Added:
    lenya/trunk/src/publets/sitetree/
    lenya/trunk/src/publets/sitetree/config/
    lenya/trunk/src/publets/sitetree/config/modules.xconf
    lenya/trunk/src/publets/sitetree/config/publet.xconf
    lenya/trunk/src/publets/sitetree/config/usecases.xconf
    lenya/trunk/src/publets/sitetree/java/
    lenya/trunk/src/publets/sitetree/java/src/
    lenya/trunk/src/publets/sitetree/java/src/org/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/DefaultSiteTree.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTree.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeFactory.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNode.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNodeImpl.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNodeVisitor.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/TreeSiteManager.java
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/usecases/
    lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/usecases/Nudge.java
    lenya/trunk/src/publets/sitetree/resources/
    lenya/trunk/src/publets/sitetree/resources/javascript/
    lenya/trunk/src/publets/sitetree/resources/javascript/tree.js
    lenya/trunk/src/publets/sitetree/resources/javascript/ua.js
    lenya/trunk/src/publets/sitetree/resources/schemas/
    lenya/trunk/src/publets/sitetree/resources/schemas/sitetree.xsd
    lenya/trunk/src/publets/sitetree/sitemap.xmap
    lenya/trunk/src/publets/sitetree/xslt/
    lenya/trunk/src/publets/sitetree/xslt/info/
    lenya/trunk/src/publets/sitetree/xslt/info/sitetree2areatree.xsl
    lenya/trunk/src/publets/sitetree/xslt/info/sitetree2tree.xsl
    lenya/trunk/src/publets/sitetree/xslt/navigation/
    lenya/trunk/src/publets/sitetree/xslt/navigation/breadcrumb.xsl
    lenya/trunk/src/publets/sitetree/xslt/navigation/menu.xsl
    lenya/trunk/src/publets/sitetree/xslt/navigation/search.xsl
    lenya/trunk/src/publets/sitetree/xslt/navigation/sitetree2nav.xsl
    lenya/trunk/src/publets/sitetree/xslt/navigation/tabs.xsl
    lenya/trunk/src/webapp/lenya/pubs/default/lenya/publets/sitetree/
    lenya/trunk/src/webapp/lenya/pubs/default/lenya/publets/sitetree/xslt/
    lenya/trunk/src/webapp/lenya/pubs/default/lenya/publets/sitetree/xslt/navigation/
    lenya/trunk/src/webapp/lenya/pubs/default/lenya/publets/sitetree/xslt/navigation/tabs.xsl
    lenya/trunk/src/webapp/lenya/pubs/default/publets/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/config/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/config/menus/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/config/menus/homepage.xsp
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/config/publet.xconf
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/menus.xmap
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/samples/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/samples/homepage.xml
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/sitemap.xmap
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/xslt/
    lenya/trunk/src/webapp/lenya/pubs/default/publets/homepage/xslt/homepage2xhtml.xsl
Removed:
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/DefaultSiteTree.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/SiteTree.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/SiteTreeFactory.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/SiteTreeNode.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/SiteTreeNodeImpl.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/SiteTreeNodeVisitor.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/tree/TreeSiteManager.java
    lenya/trunk/src/java/org/apache/lenya/cms/site/usecases/Nudge.java
    lenya/trunk/src/webapp/lenya/info.xmap
    lenya/trunk/src/webapp/lenya/navigation.xmap
    lenya/trunk/src/webapp/lenya/resources/entities/sitetree.xsd
    lenya/trunk/src/webapp/lenya/resources/javascript/tree.js
    lenya/trunk/src/webapp/lenya/resources/javascript/ua.js
    lenya/trunk/src/webapp/lenya/xslt/info/sitetree2areatree.xsl
    lenya/trunk/src/webapp/lenya/xslt/info/sitetree2tree.xsl
    lenya/trunk/src/webapp/lenya/xslt/navigation/
Modified:
    lenya/trunk/src/resources/dev/eclipse/checkstyle-plugin.cfg
    lenya/trunk/src/resources/dev/eclipse/make-classpath.xsl
    lenya/trunk/src/targets/test-build.xml
    lenya/trunk/src/webapp/WEB-INF/cocoon-xconf.xsl
    lenya/trunk/src/webapp/global-sitemap.xmap
    lenya/trunk/src/webapp/lenya/pubs/default/sitemap.xmap
    lenya/trunk/src/webapp/lenya/pubs/default/work/search/lucene/index/live/index/_1.prx
    lenya/trunk/src/webapp/lenya/usecases/tab/head.jx

Added: lenya/trunk/src/publets/sitetree/config/modules.xconf
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/config/modules.xconf?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/config/modules.xconf (added)
+++ lenya/trunk/src/publets/sitetree/config/modules.xconf Tue Jul  5 09:19:18 2005
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+  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: doctypes.xconf 164635 2005-04-25 20:01:43Z tschlabach $ -->
+
+<xconf xpath="/cocoon/input-modules" unless="/cocoon/input-modules/component-instance[@name = 'sitetree']">
+
+  <component-instance logger="core.modules.input.sitetree" name="sitetree"
+    class="org.apache.lenya.cms.cocoon.components.modules.input.SitetreeModule"/>
+  
+</xconf>

Added: lenya/trunk/src/publets/sitetree/config/publet.xconf
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/config/publet.xconf?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/config/publet.xconf (added)
+++ lenya/trunk/src/publets/sitetree/config/publet.xconf Tue Jul  5 09:19:18 2005
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+  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: doctypes.xconf 164635 2005-04-25 20:01:43Z tschlabach $ -->
+
+<xconf xpath="/cocoon/site-managers" unless="/cocoon/site-managers/component-instance[@name = 'tree']">
+
+  <component-instance name="tree" logger="lenya.site"
+    class="org.apache.lenya.cms.site.tree.TreeSiteManager"/>
+  
+</xconf>

Added: lenya/trunk/src/publets/sitetree/config/usecases.xconf
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/config/usecases.xconf?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/config/usecases.xconf (added)
+++ lenya/trunk/src/publets/sitetree/config/usecases.xconf Tue Jul  5 09:19:18 2005
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+  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: doctypes.xconf 164635 2005-04-25 20:01:43Z tschlabach $ -->
+
+<xconf xpath="/cocoon/usecases" unless="/cocoon/usecases/component-instance[@name = 'nudge']">
+
+  <component-instance name="site.nudge" logger="lenya.site" class="org.apache.lenya.cms.site.usecases.Nudge"/>
+  
+</xconf>

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/components/modules/input/SitetreeModule.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.lenya.cms.cocoon.components.modules.input;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.lenya.cms.publication.DocumentIdentityMap;
+import org.apache.lenya.cms.publication.PageEnvelope;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.site.SiteManager;
+import org.apache.lenya.cms.site.tree.SiteTree;
+import org.apache.lenya.cms.site.tree.TreeSiteManager;
+
+/**
+ * Module for sitetree access.
+ * 
+ * @version $Id: SitetreeModule.java 159584 2005-03-31 12:49:41Z andreas $
+ */
+public class SitetreeModule extends AbstractPageEnvelopeModule {
+
+    /**
+     * <code>AUTHORING_NODE</code> The authoring node
+     */
+    public static final String AUTHORING_NODE = "authoring-node";
+    /**
+     * <code>LIVE_NODE</code> The live node
+     */
+    public static final String LIVE_NODE = "live-node";
+    /**
+     * <code>TRASH_NODE</code> The trash node
+     */
+    public static final String TRASH_NODE = "trash-node";
+    /**
+     * <code>ARCHIVE_NODE</code> The archive node
+     */
+    public static final String ARCHIVE_NODE = "archive-node";
+
+    protected static final String[] PARAMETER_NAMES = { AUTHORING_NODE, LIVE_NODE, TRASH_NODE,
+            ARCHIVE_NODE };
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String,
+     *      org.apache.avalon.framework.configuration.Configuration,
+     *      java.util.Map)
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+            throws ConfigurationException {
+
+        Object value = null;
+        ServiceSelector selector = null;
+        TreeSiteManager _manager = null;
+
+        try {
+            PageEnvelope envelope = getEnvelope(objectModel, name);
+            Publication publication = envelope.getPublication();
+            
+            selector = (ServiceSelector) this.manager.lookup(SiteManager.ROLE + "Selector");
+            _manager = (TreeSiteManager) selector.select(publication.getSiteManagerHint());
+            
+            DocumentIdentityMap map = new DocumentIdentityMap(this.manager, getLogger());
+
+            if (name.equals(AUTHORING_NODE)) {
+                SiteTree authoringTree = _manager.getTree(map,
+                        publication,
+                        Publication.AUTHORING_AREA);
+                value = authoringTree.getNode(envelope.getDocument().getId());
+            }
+
+            if (name.equals(LIVE_NODE)) {
+                SiteTree liveTree = _manager.getTree(map, publication, Publication.LIVE_AREA);
+                value = liveTree.getNode(envelope.getDocument().getId());
+            }
+
+            if (name.equals(TRASH_NODE)) {
+                SiteTree trashTree = _manager.getTree(map, publication, Publication.TRASH_AREA);
+                value = trashTree.getNode(envelope.getDocument().getId());
+            }
+
+            if (name.equals(ARCHIVE_NODE)) {
+                SiteTree archiveTree = _manager.getTree(map, publication, Publication.ARCHIVE_AREA);
+                value = archiveTree.getNode(envelope.getDocument().getId());
+            }
+        } catch (Exception e) {
+            throw new ConfigurationException("Obtaining value for [" + name + "] failed: ", e);
+        }
+        finally {
+            if (selector != null) {
+                if (_manager != null) {
+                    selector.release(_manager);
+                }
+                this.manager.release(selector);
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration,
+     *      java.util.Map)
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+            throws ConfigurationException {
+        return Arrays.asList(PARAMETER_NAMES).iterator();
+    }
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String,
+     *      org.apache.avalon.framework.configuration.Configuration,
+     *      java.util.Map)
+     */
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+            throws ConfigurationException {
+        Object[] objects = { getAttribute(name, modeConf, objectModel) };
+        return objects;
+    }
+
+}
\ No newline at end of file

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,472 @@
+/*
+ * 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: SitetreeFragmentGenerator.java 159584 2005-03-31 12:49:41Z andreas $*/
+
+package org.apache.lenya.cms.cocoon.generation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.lenya.cms.publication.PageEnvelope;
+import org.apache.lenya.cms.publication.PageEnvelopeException;
+import org.apache.lenya.cms.publication.PageEnvelopeFactory;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.publication.DocumentIdentityMap;
+import org.apache.lenya.cms.site.Label;
+import org.apache.lenya.cms.site.SiteManager;
+import org.apache.lenya.cms.site.tree.SiteTree;
+import org.apache.lenya.cms.site.tree.TreeSiteManager;
+import org.apache.lenya.cms.site.SiteException;
+import org.apache.lenya.cms.site.tree.SiteTreeNode;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Generates a fragment of the navigation XML from the sitetree, corresponding to a given node. The
+ * node is specified by the sitemap parameters area/documentid. If the sitemap parameter initialTree
+ * is true, the top nodes of the tree will be generated and the node given by the sitemap parameters
+ * area/documentid will be unfolded. If initialTree is false, only the children of the selected node
+ * will be generated.
+ */
+public class SitetreeFragmentGenerator extends ServiceableGenerator {
+
+    protected Publication publication;
+    private DocumentIdentityMap identityMap;
+
+    /** Parameter which denotes the documentid of the clicked node */
+    protected String documentid;
+
+    /** Parameter which denotes the area of the clicked node */
+    protected String area;
+
+    /**
+     * Parameter which decides if the initial tree with the root nodes is generated
+     */
+    protected boolean initialTree;
+
+    /** FIXME: should pass this as a parameter */
+    protected String[] areas = null;
+
+    /**
+     * Convenience object, so we don't need to create an AttributesImpl for every element.
+     */
+    protected AttributesImpl attributes;
+
+    protected static final String PARAM_AREA = "area";
+    protected static final String PARAM_DOCUMENTID = "documentid";
+    protected static final String PARAM_INITIAL = "initial";
+    protected static final String PARAM_AREAS = "areas";
+
+    /** The URI of the namespace of this generator. */
+    protected static final String URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
+    protected static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
+
+    /** The namespace prefix for this namespace. */
+    protected static final String PREFIX = "site";
+    protected static final String XML_PREFIX = "xml";
+
+    protected static final String NODE_NODE = "node";
+    protected static final String NODE_LABEL = "label";
+    protected static final String NODE_SITE = "site";
+    protected static final String NODE_FRAGMENT = "fragment";
+
+    protected static final String ATTR_ID = "id";
+    protected static final String ATTR_FOLDER = "folder";
+    protected static final String ATTR_AREA = "area";
+    protected static final String ATTR_LABEL = "label";
+    protected static final String ATTR_VISIBLEINNAV = "visibleinnav";
+    protected static final String ATTR_LINK = "link";
+    protected static final String ATTR_BASE = "base";
+    protected static final String ATTR_SUFFIX = "suffix";
+    protected static final String ATTR_HREF = "href";
+    protected static final String ATTR_LANG = "lang";
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
+     *      java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver _resolver, Map _objectModel, String src, Parameters par)
+            throws ProcessingException, SAXException, IOException {
+        super.setup(_resolver, _objectModel, src, par);
+
+        PageEnvelope envelope = null;
+
+        if (getLogger().isDebugEnabled()) {
+            Request request = ObjectModelHelper.getRequest(_objectModel);
+            getLogger().debug("Resolving page envelope for URL [" + request.getRequestURI() + "]");
+        }
+
+        this.area = par.getParameter(PARAM_AREA, null);
+        this.documentid = par.getParameter(PARAM_DOCUMENTID, null);
+
+        if (par.isParameter(PARAM_INITIAL)) {
+            this.initialTree = Boolean.valueOf(par.getParameter(PARAM_INITIAL, null))
+                    .booleanValue();
+        } else {
+            this.initialTree = false;
+        }
+
+        if (par.isParameter(PARAM_AREAS)) {
+            String parAreas = par.getParameter(PARAM_AREAS, null);
+            this.areas = parAreas.split(",");
+        } else {
+            String temp[] = { "authoring", "archive", "trash" };
+            this.areas = temp;
+        }
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Parameter area: " + this.area);
+            this.getLogger().debug("Parameter documentid: " + this.documentid);
+            this.getLogger().debug("Parameter initialTree: " + this.initialTree);
+            String areasStr = "";
+            for (int i = 0; i < this.areas.length; i++) {
+                areasStr += this.areas[i] + " ";
+            }
+            this.getLogger().debug("Parameter areas: " + areasStr);
+        }
+
+        try {
+            this.identityMap = new DocumentIdentityMap(this.manager, getLogger());
+            envelope = PageEnvelopeFactory.getInstance().getPageEnvelope(this.identityMap,
+                    _objectModel);
+        } catch (final PageEnvelopeException e) {
+            throw new ProcessingException("Resolving page envelope failed: ", e);
+        }
+
+        this.publication = envelope.getPublication();
+        this.attributes = new AttributesImpl();
+
+    }
+
+    /**
+     * @see org.apache.cocoon.generation.Generator#generate()
+     */
+    public void generate() throws IOException, SAXException, ProcessingException {
+
+        try {
+
+            this.contentHandler.startDocument();
+            this.contentHandler.startPrefixMapping(PREFIX, URI);
+
+            this.attributes.clear();
+            if (!this.initialTree) {
+                this.attributes.addAttribute("", ATTR_AREA, ATTR_AREA, "CDATA", this.area);
+                this.attributes.addAttribute("", ATTR_BASE, ATTR_BASE, "CDATA", this.documentid);
+            }
+
+            this.contentHandler.startElement(URI,
+                    NODE_FRAGMENT,
+                    PREFIX + ':' + NODE_FRAGMENT,
+                    this.attributes);
+
+            if (this.initialTree) {
+                for (int i = 0; i < this.areas.length; i++) {
+                    generateFragmentInitial(this.areas[i]);
+                }
+            } else {
+                generateFragment();
+            }
+
+            this.contentHandler.endElement(URI, NODE_FRAGMENT, PREFIX + ':' + NODE_FRAGMENT);
+
+            this.contentHandler.endPrefixMapping(PREFIX);
+            this.contentHandler.endDocument();
+
+        } catch (final SAXException e) {
+            throw new ProcessingException(e);
+        } catch (final SiteException e) {
+            throw new ProcessingException(e);
+        }
+
+    }
+
+    /**
+     * Generates a fragment of the tree which contains the children of a given node.
+     * @throws SiteException
+     * @throws SAXException
+     * @throws ProcessingException
+     */
+    protected void generateFragment() throws SiteException, SAXException, ProcessingException {
+
+        if (!this.area.equals(Publication.AUTHORING_AREA)
+                && !this.area.equals(Publication.ARCHIVE_AREA)
+                && !this.area.equals(Publication.TRASH_AREA)
+                && !this.area.equals(Publication.LIVE_AREA)
+                && !this.area.equals(Publication.STAGING_AREA)) {
+            throw new ProcessingException("Invalid area: " + this.area);
+        }
+
+        ServiceSelector selector = null;
+        TreeSiteManager siteManager = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup(SiteManager.ROLE + "Selector");
+            siteManager = (TreeSiteManager) selector.select(this.publication.getSiteManagerHint());
+
+            SiteTree siteTree = siteManager.getTree(this.identityMap, this.publication, this.area);
+
+            SiteTreeNode node = siteTree.getNode(this.documentid);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("Node with documentid " + this.documentid + " found.");
+            }
+            if (node == null)
+                throw new SiteException("Node with documentid " + this.documentid + " not found.");
+
+            SiteTreeNode[] children = node.getChildren();
+
+            for (int i = 0; i < children.length; i++) {
+                startNode(NODE_NODE, children[i]);
+                addLabels(children[i]);
+                endNode(NODE_NODE);
+            }
+        } catch (ServiceException e) {
+            throw new ProcessingException(e);
+        } finally {
+            if (selector != null) {
+                if (siteManager != null) {
+                    selector.release(siteManager);
+                }
+                this.manager.release(selector);
+            }
+        }
+    }
+
+    /**
+     * Generates the top node of the given area and then calls a recursive method to traverse the
+     * tree, if the node given by area/documentid is in this area.
+     * @param siteArea
+     * @throws SiteException
+     * @throws SAXException
+     * @throws ProcessingException
+     */
+    protected void generateFragmentInitial(String siteArea) throws SiteException, SAXException,
+            ProcessingException {
+
+        ServiceSelector selector = null;
+        TreeSiteManager siteManager = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup(SiteManager.ROLE + "Selector");
+            siteManager = (TreeSiteManager) selector.select(this.publication.getSiteManagerHint());
+            SiteTree siteTree = siteManager.getTree(this.identityMap, this.publication, siteArea);
+
+            String label = "";
+            String isFolder = "";
+
+            // FIXME: don't hardcode area label
+            if (siteArea.equals(Publication.AUTHORING_AREA))
+                label = "Authoring";
+            if (siteArea.equals(Publication.ARCHIVE_AREA))
+                label = "Archive";
+            if (siteArea.equals(Publication.TRASH_AREA))
+                label = "Trash";
+            if (siteArea.equals(Publication.LIVE_AREA))
+                label = "Live";
+            if (siteArea.equals(Publication.STAGING_AREA))
+                label = "Staging";
+
+            if (siteTree.getTopNodes().length > 0)
+                isFolder = "true";
+            else
+                isFolder = "false";
+
+            this.attributes.clear();
+            this.attributes.addAttribute("", ATTR_AREA, ATTR_AREA, "CDATA", siteArea);
+            this.attributes.addAttribute("", ATTR_FOLDER, ATTR_FOLDER, "CDATA", isFolder);
+            this.attributes.addAttribute("", ATTR_LABEL, ATTR_LABEL, "CDATA", label);
+
+            startNode(NODE_SITE);
+
+            if (this.area.equals(siteArea)) {
+                generateFragmentRecursive(siteTree.getTopNodes(), this.documentid);
+            }
+
+            endNode(NODE_SITE);
+        } catch (ServiceException e) {
+            throw new ProcessingException(e);
+        } finally {
+            if (selector != null) {
+                if (siteManager != null) {
+                    selector.release(siteManager);
+                }
+                this.manager.release(selector);
+            }
+        }
+    }
+
+    /**
+     * Follows the documentid to find the way in the sitetree to the specified node and opens all
+     * folders on its way.
+     * @param nodes
+     * @param docid
+     * @throws SiteException
+     * @throws SAXException
+     */
+    protected void generateFragmentRecursive(SiteTreeNode[] nodes, String docid)
+            throws SiteException, SAXException {
+        String nodeid;
+        String childid;
+
+        if (nodes == null)
+            return;
+        if (docid.startsWith("/"))
+            docid = docid.substring(1);
+        if (docid.indexOf("/") != -1) {
+            nodeid = docid.substring(0, docid.indexOf("/"));
+            childid = docid.substring(docid.indexOf("/") + 1);
+        } else {
+            nodeid = docid;
+            childid = "";
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            startNode(NODE_NODE, nodes[i]);
+            addLabels(nodes[i]);
+            if (nodes[i].getId().equals(nodeid)) {
+                generateFragmentRecursive(nodes[i].getChildren(), childid);
+            }
+            endNode(NODE_NODE);
+        }
+    }
+
+    /**
+     * Begins a named node and calls setNodeAttributes to set its attributes.
+     * @param nodeName the name of the new node
+     * @throws SAXException if an error occurs while creating the node
+     */
+    protected void startNode(String nodeName) throws SAXException {
+        this.contentHandler.startElement(URI, nodeName, PREFIX + ':' + nodeName, this.attributes);
+    }
+
+    /**
+     * Begins a named node and calls setNodeAttributes to set its attributes.
+     * @param nodeName the name of the new node
+     * @param node The attributes are taken from this node
+     * @throws SAXException if an error occurs while creating the node
+     */
+    protected void startNode(String nodeName, SiteTreeNode node) throws SAXException {
+        setNodeAttributes(node);
+        this.contentHandler.startElement(URI, nodeName, PREFIX + ':' + nodeName, this.attributes);
+    }
+
+    /**
+     * Sets the attributes for a given node. Sets attributes id, href, folder, suffix, basic-url,
+     * language-suffix.
+     * @param node
+     * @throws SAXException if an error occurs while setting the attributes
+     */
+    protected void setNodeAttributes(SiteTreeNode node) throws SAXException {
+        this.attributes.clear();
+
+        String id = node.getId();
+        //String isVisible = Boolean.toString(node.visibleInNav());
+        String hasLink = Boolean.toString(node.hasLink());
+        String href = node.getHref();
+        String suffix = node.getSuffix();
+        String isFolder = isFolder(node);
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("adding attribute id: " + id);
+            //this.getLogger().debug("adding attribute visibleinnav: " +
+            // isVisible);
+            this.getLogger().debug("adding attribute link: " + hasLink);
+            if (href != null)
+                this.getLogger().debug("adding attribute href: " + href);
+            if (suffix != null)
+                this.getLogger().debug("adding attribute suffix: " + suffix);
+            this.getLogger().debug("adding attribute folder: " + isFolder);
+        }
+        this.attributes.addAttribute("", ATTR_ID, ATTR_ID, "CDATA", id);
+        //attributes.addAttribute("", ATTR_VISIBLEINNAV, ATTR_VISIBLEINNAV,
+        // "CDATA", isVisible);
+        this.attributes.addAttribute("", ATTR_LINK, ATTR_LINK, "CDATA", hasLink);
+        if (href != null)
+            this.attributes.addAttribute("", ATTR_HREF, ATTR_HREF, "CDATA", href);
+        if (suffix != null)
+            this.attributes.addAttribute("", ATTR_SUFFIX, ATTR_SUFFIX, "CDATA", suffix);
+        this.attributes.addAttribute("", ATTR_FOLDER, ATTR_FOLDER, "CDATA", isFolder);
+    }
+
+    /**
+     * Returns a value to indicate whether a node is a folder (contains subnodes). With the
+     * incremental sitetree loading, we sometimes load nodes which are folders, but we don't load
+     * their children. But we still have to know if it's a folder or not, i.e. if it can be opened.
+     * @param node
+     * @return "true" or "false"
+     */
+    protected String isFolder(SiteTreeNode node) {
+        if (node.getChildren().length > 0)
+            return "true";
+        return "false";
+    }
+
+    /**
+     * Ends the named node.
+     * @param nodeName the name of the new node
+     * @throws SAXException if an error occurs while closing the node
+     */
+    protected void endNode(String nodeName) throws SAXException {
+        this.contentHandler.endElement(URI, nodeName, PREFIX + ':' + nodeName);
+    }
+
+    /**
+     * Finds all the label children of a node and adds them to the nav xml.
+     * @param node
+     * @throws SAXException
+     */
+    protected void addLabels(SiteTreeNode node) throws SAXException {
+        Label[] labels = node.getLabels();
+
+        for (int i = 0; i < labels.length; i++) {
+            String lang = labels[i].getLanguage();
+            if (lang == null)
+                lang = "";
+            addLabel(labels[i].getLabel(), lang);
+        }
+    }
+
+    /**
+     * Adds a label element of a given language.
+     * @param label the value of the label
+     * @param language the language of the label
+     * @throws SAXException
+     */
+    protected void addLabel(String label, String language) throws SAXException {
+        this.attributes.clear();
+        this.attributes.addAttribute(XML_URI,
+                ATTR_LANG,
+                XML_PREFIX + ":" + ATTR_LANG,
+                "CDATA",
+                language);
+
+        this.contentHandler.startElement(URI,
+                NODE_LABEL,
+                PREFIX + ':' + NODE_LABEL,
+                this.attributes);
+        char[] labelArray = label.toCharArray();
+        this.contentHandler.characters(labelArray, 0, labelArray.length);
+        this.contentHandler.endElement(URI, NODE_LABEL, PREFIX + ':' + NODE_LABEL);
+    }
+
+}
\ No newline at end of file

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,263 @@
+/*
+ * 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: AccessControlSitetreeTransformer.java 153561 2005-02-12 21:49:18Z gregor $  */
+
+package org.apache.lenya.cms.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.AbstractSAXTransformer;
+import org.apache.lenya.ac.AccessControlException;
+import org.apache.lenya.ac.AccessController;
+import org.apache.lenya.ac.AccessControllerResolver;
+import org.apache.lenya.ac.AccreditableManager;
+import org.apache.lenya.ac.Authorizer;
+import org.apache.lenya.ac.Identity;
+import org.apache.lenya.ac.Policy;
+import org.apache.lenya.ac.PolicyManager;
+import org.apache.lenya.ac.Role;
+import org.apache.lenya.ac.impl.DefaultAccessController;
+import org.apache.lenya.ac.impl.PolicyAuthorizer;
+import org.apache.lenya.cms.site.tree.DefaultSiteTree;
+import org.apache.lenya.cms.site.tree.SiteTreeNodeImpl;
+import org.apache.lenya.util.ServletHelper;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This transformer is applied to the sitetree.
+ * It marks the site element and all node elements the
+ * current identity is not allowed to access 
+ * with a <code>protected="true"</code> attribute.
+ */
+public class AccessControlSitetreeTransformer
+    extends AbstractSAXTransformer
+    implements Disposable {
+
+    /**
+     * <code>ATTRIBUTE_PROTECTED</code> The attribute for protected
+     */
+    public static final String ATTRIBUTE_PROTECTED = "protected";
+    /**
+     * <code>PARAMETER_PUBLICATION_ID</code> The publication id parameter
+     */
+    public static final String PARAMETER_PUBLICATION_ID = "publication-id";
+    /**
+     * <code>PARAMETER_AREA</code> The area parameter
+     */
+    public static final String PARAMETER_AREA = "area";
+
+    private String documentId;
+    private ServiceSelector serviceSelector;
+    private PolicyManager policyManager;
+    private AccessControllerResolver acResolver;
+    private AccreditableManager accreditableManager;
+    private Identity identity;
+    private String urlPrefix;
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver _resolver, Map _objectModel, String src, Parameters par)
+        throws ProcessingException, SAXException, IOException {
+        super.setup(_resolver, _objectModel, src, par);
+
+        this.serviceSelector = null;
+        this.acResolver = null;
+        this.policyManager = null;
+
+        this.identity = Identity.getIdentity(this.request.getSession(false));
+
+        try {
+            String publicationId = par.getParameter(PARAMETER_PUBLICATION_ID);
+            String area = par.getParameter(PARAMETER_AREA);
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Setting up transformer");
+                getLogger().debug("    Identity:       [" + this.identity + "]");
+                getLogger().debug("    Publication ID: [" + publicationId + "]");
+                getLogger().debug("    Area:           [" + area + "]");
+            }
+
+            this.urlPrefix = "/" + publicationId + "/" + area;
+
+            Request _request = ObjectModelHelper.getRequest(_objectModel);
+
+            this.serviceSelector =
+                (ServiceSelector) this.manager.lookup(AccessControllerResolver.ROLE + "Selector");
+
+            this.acResolver =
+                (AccessControllerResolver) this.serviceSelector.select(
+                    AccessControllerResolver.DEFAULT_RESOLVER);
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("    Resolved AC resolver [" + this.acResolver + "]");
+            }
+
+            String webappUrl = ServletHelper.getWebappURI(_request);
+            AccessController accessController = this.acResolver.resolveAccessController(webappUrl);
+
+            if (accessController instanceof DefaultAccessController) {
+                DefaultAccessController defaultAccessController =
+                    (DefaultAccessController) accessController;
+
+                this.accreditableManager = defaultAccessController.getAccreditableManager();
+
+                Authorizer[] authorizers = defaultAccessController.getAuthorizers();
+                for (int i = 0; i < authorizers.length; i++) {
+                    if (authorizers[i] instanceof PolicyAuthorizer) {
+                        PolicyAuthorizer policyAuthorizer = (PolicyAuthorizer) authorizers[i];
+                        this.policyManager = policyAuthorizer.getPolicyManager();
+                    }
+                }
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("    Using policy manager [" + this.policyManager + "]");
+            }
+        } catch (final ParameterException e) {
+            throw new ProcessingException(e);
+        } catch (final ServiceException e) {
+            throw new ProcessingException(e);
+        } catch (final AccessControlException e) {
+            throw new ProcessingException(e);
+        }
+
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Disposing transformer");
+        }
+        if (this.serviceSelector != null) {
+            if (this.acResolver != null) {
+                this.serviceSelector.release(this.acResolver);
+            }
+            this.manager.release(this.serviceSelector);
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        super.startDocument();
+        this.documentId = "";
+    }
+
+    /** (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startElement(String uri, String localName, String raw, Attributes attr)
+        throws SAXException {
+
+        Attributes attributes = attr;
+
+        if (isFragmentNode(uri, localName)) {
+            String area = attr.getValue("area"); // FIXME: don't hardcode
+            String base = attr.getValue("base");
+            if (area!=null && base!=null) {
+                this.documentId = "/"+area+base;
+            }
+        }
+        if (isNode(uri, localName)) {
+            String id = attr.getValue(SiteTreeNodeImpl.ID_ATTRIBUTE_NAME);
+            if (id != null) {
+                this.documentId += "/" + id;
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Checking node");
+                getLogger().debug("    Document ID: [" + this.documentId + "]");
+                getLogger().debug("    URL:         [" + this.urlPrefix + this.documentId + "]");
+            }
+
+            try {
+                String url = this.urlPrefix + this.documentId;
+                Policy policy = this.policyManager.getPolicy(this.accreditableManager, url);
+                Role[] roles = policy.getRoles(this.identity);
+
+                getLogger().debug("    Roles:       [" + roles.length + "]");
+
+                if (roles.length == 0) {
+                    getLogger().debug("    Adding attribute [protected='true']");
+
+                    AttributesImpl attributesImpl = new AttributesImpl(attributes);
+                    attributesImpl.addAttribute(
+                        "",
+                        ATTRIBUTE_PROTECTED,
+                        ATTRIBUTE_PROTECTED,
+                        "",
+                        Boolean.toString(true));
+                    attributes = attributesImpl;
+                }
+            } catch (AccessControlException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        super.startElement(uri, localName, raw, attributes);
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endElement(String uri, String localName, String raw) throws SAXException {
+        super.endElement(uri, localName, raw);
+        if (isNode(uri, localName) && this.documentId.length() > 0) {
+            this.documentId = this.documentId.substring(0, this.documentId.lastIndexOf("/"));
+        }
+    }
+
+    /**
+     * Returns if an element represents a sitetree node.
+     * @param uri The namespace URI.
+     * @param localName The local name.
+     * @return A boolean value.
+     */
+    protected boolean isNode(String uri, String localName) {
+        return uri.equals(DefaultSiteTree.NAMESPACE_URI)
+            && (localName.equals(SiteTreeNodeImpl.NODE_NAME) || localName.equals("site"));
+    }
+
+   /**
+     * Returns if an element represents a fragment node.
+     * @param uri The namespace URI.
+     * @param localName The local name.
+     * @return A boolean value.
+     */
+    protected boolean isFragmentNode(String uri, String localName) {
+        return uri.equals(DefaultSiteTree.NAMESPACE_URI)
+            && (localName.equals("fragment"));
+    }
+
+}

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/DefaultSiteTree.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/DefaultSiteTree.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/DefaultSiteTree.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/DefaultSiteTree.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,571 @@
+/*
+ * 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.site.tree;
+
+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.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.lenya.cms.cocoon.source.RepositorySource;
+import org.apache.lenya.cms.cocoon.source.SourceUtil;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.site.Label;
+import org.apache.lenya.cms.site.SiteException;
+import org.apache.lenya.xml.DocumentHelper;
+import org.apache.lenya.xml.NamespaceHelper;
+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;
+
+/**
+ * Default sitetree implementation.
+ * 
+ * @version $Id: DefaultSiteTree.java 208764 2005-07-01 15:57:21Z andreas $
+ */
+public class DefaultSiteTree extends AbstractLogEnabled implements SiteTree {
+
+    /**
+     * The sitetree namespace.
+     */
+    public static final String NAMESPACE_URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
+
+    /**
+     * The name of the sitetree file.
+     */
+    public static final String SITE_TREE_FILENAME = "sitetree.xml";
+
+    private String sourceUri;
+    // the area is only retained to provide some more info when raising an
+    // exception.
+    private String area = "";
+    protected ServiceManager manager;
+    private Document document;
+
+    /**
+     * Create a DefaultSiteTree
+     * @param publication The publication.
+     * @param _area The area.
+     * @param manager The service manager.
+     * @throws SiteException if an error occurs.
+     */
+    protected DefaultSiteTree(Publication publication, String _area, ServiceManager manager)
+            throws SiteException {
+        this.sourceUri = publication.getSourceURI() + "/content/" + _area + "/"
+                + SITE_TREE_FILENAME;
+        this.area = _area;
+        this.manager = manager;
+        try {
+            this.document = SourceUtil.readDOM(this.sourceUri, this.manager);
+            if (this.document == null) {
+                this.document = createDocument();
+            }
+        } catch (Exception e) {
+            throw new SiteException(e);
+        }
+    }
+
+    protected void saveDocument() throws SiteException {
+        try {
+            SourceUtil.writeDOM(this.document, this.sourceUri, this.manager);
+        } catch (Exception e) {
+            throw new SiteException(e);
+        }
+    }
+
+    /**
+     * Checks if the tree file has been modified externally and reloads the site tree. protected
+     * synchronized void checkModified() { if (this.area.equals(Publication.LIVE_AREA) &&
+     * this.treefile.lastModified() > this.lastModified) {
+     * 
+     * if (getLogger().isDebugEnabled()) { getLogger().debug("Sitetree [" + this.treefile + "] has
+     * changed: reloading."); }
+     * 
+     * try { this.document = DocumentHelper.readDocument(this.treefile); } catch (Exception e) {
+     * throw new IllegalStateException(e.getMessage()); } this.lastModified =
+     * this.treefile.lastModified(); } }
+     */
+
+    /**
+     * Create a new DefaultSiteTree xml document.
+     * @return the new site document
+     * @throws ParserConfigurationException if an error occurs
+     */
+    public synchronized Document createDocument() throws ParserConfigurationException {
+        Document 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 synchronized Node findNode(Node node, List ids) {
+
+        if (ids.size() < 1) {
+            return node;
+        }
+        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;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(org.apache.lenya.cms.site.tree.SiteTreeNode,
+     *      java.lang.String)
+     */
+    public synchronized void addNode(SiteTreeNode node, String refDocumentId) throws SiteException {
+        addNode(node.getParent().getAbsoluteId(),
+                node.getId(),
+                node.getLabels(),
+                node.getHref(),
+                node.getSuffix(),
+                node.hasLink(),
+                refDocumentId);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(java.lang.String, java.lang.String,
+     *      org.apache.lenya.cms.site.Label[])
+     */
+    public synchronized void addNode(String parentid, String id, Label[] labels)
+            throws SiteException {
+        addNode(parentid, id, labels, null, null, false);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(org.apache.lenya.cms.site.tree.SiteTreeNode)
+     */
+    public synchronized void addNode(SiteTreeNode node) throws SiteException {
+        addNode(node, null);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(java.lang.String,
+     *      org.apache.lenya.cms.site.Label[], java.lang.String, java.lang.String, boolean,
+     *      java.lang.String)
+     */
+    public synchronized void addNode(String documentid, Label[] labels, String href, String suffix,
+            boolean link, String refDocumentId) throws SiteException {
+        StringBuffer buf = new StringBuffer();
+        StringTokenizer st = new StringTokenizer(documentid, "/");
+        int length = st.countTokens();
+
+        for (int i = 0; i < (length - 1); i++) {
+            buf.append("/" + st.nextToken());
+        }
+        String parentid = buf.toString();
+        String id = st.nextToken();
+        addNode(parentid, id, labels, href, suffix, link, refDocumentId);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(java.lang.String,
+     *      org.apache.lenya.cms.site.Label[], java.lang.String, java.lang.String, boolean)
+     */
+    public synchronized void addNode(String documentid, Label[] labels, String href, String suffix,
+            boolean link) throws SiteException {
+        addNode(documentid, labels, href, suffix, link, null);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(java.lang.String, java.lang.String,
+     *      org.apache.lenya.cms.site.Label[], java.lang.String, java.lang.String, boolean)
+     */
+    public synchronized void addNode(String parentid, String id, Label[] labels, String href,
+            String suffix, boolean link) throws SiteException {
+        addNode(parentid, id, labels, href, suffix, link, null);
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addNode(java.lang.String, java.lang.String,
+     *      org.apache.lenya.cms.site.Label[], java.lang.String, java.lang.String, boolean,
+     *      java.lang.String)
+     */
+    public synchronized void addNode(String parentid, String id, Label[] labels, String href,
+            String suffix, boolean link, String refDocumentId) throws SiteException {
+
+        Node parentNode = getNodeInternal(parentid);
+
+        if (parentNode == null) {
+            throw new SiteException("Parentid: " + parentid + " in " + this.area
+                    + " tree not found");
+        }
+
+        getLogger().debug("PARENT ELEMENT: " + parentNode);
+
+        // Check if child already exists
+        Node childNode = getNodeInternal(parentid + "/" + id);
+
+        if (childNode != null) {
+            getLogger().info("This node: " + parentid + "/" + id + " has already been inserted");
+
+            return;
+        }
+
+        // Create node
+        NamespaceHelper helper = new NamespaceHelper(NAMESPACE_URI, "", this.document);
+        Element child = helper.createElement(SiteTreeNodeImpl.NODE_NAME);
+        child.setAttribute(SiteTreeNodeImpl.ID_ATTRIBUTE_NAME, id);
+
+        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);
+        }
+        getLogger().debug("Tree has been modified: " + document.getDocumentElement());
+        saveDocument();
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#addLabel(java.lang.String,
+     *      org.apache.lenya.cms.site.Label)
+     */
+    public synchronized void addLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.addLabel(label);
+        }
+        try {
+            saveDocument();
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#removeLabel(java.lang.String,
+     *      org.apache.lenya.cms.site.Label)
+     */
+    public synchronized void removeLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.removeLabel(label);
+        }
+        try {
+            saveDocument();
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#removeNode(java.lang.String)
+     */
+    public synchronized SiteTreeNode removeNode(String documentId) {
+        assert documentId != null;
+
+        Node node;
+        try {
+            node = removeNodeInternal(documentId);
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+        if (node == null) {
+            return null;
+        }
+
+        SiteTreeNode newNode = new SiteTreeNodeImpl(node);
+        ContainerUtil.enableLogging(newNode, getLogger());
+        return newNode;
+    }
+
+    /**
+     * 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
+     * @throws SiteException
+     */
+    private synchronized Node removeNodeInternal(String documentId) throws SiteException {
+        Node node = this.getNodeInternal(documentId);
+        Node parentNode = node.getParentNode();
+        Node newNode = parentNode.removeChild(node);
+        try {
+            saveDocument();
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+        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
+     * @throws SiteException
+     */
+    private synchronized Node getNodeInternal(String documentId) throws SiteException {
+        StringTokenizer st = new StringTokenizer(documentId, "/");
+        ArrayList ids = new ArrayList();
+
+        while (st.hasMoreTokens()) {
+            ids.add(st.nextToken());
+        }
+
+        Node node = findNode(this.document.getDocumentElement(), ids);
+        return node;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#getNode(java.lang.String)
+     */
+    public synchronized SiteTreeNode getNode(String documentId) {
+        assert documentId != null;
+
+        SiteTreeNode treeNode = null;
+
+        Node node;
+        try {
+            node = getNodeInternal(documentId);
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+        if (node != null) {
+            treeNode = new SiteTreeNodeImpl(node);
+            ContainerUtil.enableLogging(treeNode, getLogger());
+        }
+
+        return treeNode;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#getTopNodes()
+     */
+    public SiteTreeNode[] getTopNodes() {
+        List childElements = new ArrayList();
+
+        NamespaceHelper helper = new NamespaceHelper(NAMESPACE_URI, "", this.document);
+
+        Element[] elements = helper.getChildren(this.document.getDocumentElement(),
+                SiteTreeNodeImpl.NODE_NAME);
+
+        for (int i = 0; i < elements.length; i++) {
+            SiteTreeNode newNode = new SiteTreeNodeImpl(elements[i]);
+            childElements.add(newNode);
+        }
+
+        return (SiteTreeNode[]) childElements.toArray(new SiteTreeNode[childElements.size()]);
+    }
+
+    /**
+     * Move up the node amongst its siblings.
+     * @param documentid The document id for the node.
+     * @throws SiteException if the moving failed.
+     */
+    public synchronized void moveUp(String documentid) throws SiteException {
+        Node node = this.getNodeInternal(documentid);
+        if (node == null) {
+            throw new SiteException("Node to move: " + documentid + " not found");
+        }
+        Node parentNode = node.getParentNode();
+        if (parentNode == null) {
+            throw new SiteException("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 SiteException(e);
+        }
+
+        if (previousNode == null) {
+            getLogger().warn("Couldn't found a preceding sibling");
+            return;
+        }
+        Node insertNode = parentNode.removeChild(node);
+        parentNode.insertBefore(insertNode, previousNode);
+        saveDocument();
+    }
+
+    /**
+     * Move down the node amongst its siblings.
+     * 
+     * @param documentid The document id for the node.
+     * @throws SiteException if the moving failed.
+     */
+    public synchronized void moveDown(String documentid) throws SiteException {
+        Node node = this.getNodeInternal(documentid);
+        if (node == null) {
+            throw new SiteException("Node to move: " + documentid + " not found");
+        }
+        Node parentNode = node.getParentNode();
+        if (parentNode == null) {
+            throw new SiteException("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 SiteException(e);
+        }
+
+        Node insertNode = parentNode.removeChild(node);
+
+        if (nextNode == null) {
+            getLogger().warn("Couldn't found the second following sibling");
+            parentNode.appendChild(insertNode);
+        } else {
+            parentNode.insertBefore(insertNode, nextNode);
+        }
+        saveDocument();
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#importSubtree(org.apache.lenya.cms.site.tree.SiteTreeNode,
+     *      org.apache.lenya.cms.site.tree.SiteTreeNode, java.lang.String, java.lang.String)
+     */
+    public synchronized void importSubtree(SiteTreeNode newParent, SiteTreeNode subtreeRoot,
+            String newid, String refDocumentId) throws SiteException {
+        assert subtreeRoot != null;
+        assert newParent != null;
+        String parentId = newParent.getAbsoluteId();
+        String id = newid;
+
+        this.addNode(parentId, id, subtreeRoot.getLabels(), subtreeRoot.getHref(), subtreeRoot
+                .getSuffix(), subtreeRoot.hasLink(), refDocumentId);
+        newParent = this.getNode(parentId + "/" + id);
+        if (newParent == null) {
+            throw new SiteException("The added node was not found.");
+        }
+        SiteTreeNode[] children = subtreeRoot.getChildren();
+        if (children == null) {
+            getLogger().info("The node " + subtreeRoot.toString() + " has no children");
+            return;
+        }
+        for (int i = 0; i < children.length; i++) {
+            importSubtree(newParent, children[i], children[i].getId(), null);
+        }
+        saveDocument();
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.tree.SiteTree#setLabel(java.lang.String,
+     *      org.apache.lenya.cms.site.Label)
+     */
+    public synchronized void setLabel(String documentId, Label label) {
+        SiteTreeNode node = getNode(documentId);
+        if (node != null) {
+            node.setLabel(label);
+        }
+        try {
+            saveDocument();
+        } catch (SiteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @see org.apache.lenya.transaction.Identifiable#getIdentifiableType()
+     */
+    public String getIdentifiableType() {
+        return SiteTree.IDENTIFIABLE_TYPE;
+    }
+
+    /**
+     * @see org.apache.lenya.cms.site.SiteStructure#getRepositoryNode()
+     */
+    public org.apache.lenya.cms.repository.Node getRepositoryNode() {
+        SourceResolver resolver = null;
+        RepositorySource source = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            source = (RepositorySource) resolver.resolveURI(this.sourceUri);
+            return source.getNode();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                this.manager.release(resolver);
+            }
+        }
+    }
+
+}

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTree.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTree.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTree.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTree.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.lenya.cms.site.tree;
+
+import org.apache.lenya.cms.site.Label;
+import org.apache.lenya.cms.site.SiteException;
+import org.apache.lenya.cms.site.SiteStructure;
+
+/**
+ * A sitetree.
+ * 
+ * @version $Id: SiteTree.java 177923 2005-05-23 05:15:51Z gregor $
+ */
+public interface SiteTree extends SiteStructure {
+
+    /**
+     * The type of sitetree identifiable objects.
+     */
+    String IDENTIFIABLE_TYPE = "site";
+
+    /**
+     * Add a node.
+     * 
+     * @param parentid where the node is to be added
+     * @param id e.g. "concepts"
+     * @param labels the labels of the node that is to be added
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(String parentid, String id, Label[] labels) throws SiteException;
+
+    /**
+     * Add a node. TODO: Lenya 1.2.X supports argument visibleInNav
+     * 
+     * @param parentid the node where the new node is to be inserted
+     * @param id the node id
+     * @param labels the labels
+     * @param href the href of the new node (internal and external references)
+     * @param suffix the suffix of the new node
+     * @param link Visibility of link respectively href. It is meant to support "grouping" nodes in the navigation which do not relate to a document (internal) or external link (www).
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(String parentid, String id, Label[] labels, String href, String suffix,
+            boolean link) throws SiteException;
+
+    /**
+     * Insert a node before a given node
+     * 
+     * @param parentid the node where the new node is to be inserted
+     * @param id the node id
+     * @param labels the labels
+     * @param href the href of the new node
+     * @param suffix the suffix of the new node
+     * @param link the link
+     * @param refDocumentId document-id of the node, before which the new node will be inserted.
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(String parentid, String id, Label[] labels, String href, String suffix,
+            boolean link, String refDocumentId) throws SiteException;
+
+    /**
+     * Add a node. Compute the parent id and the id of the node from the document-id
+     * 
+     * @param documentid the document-id of the new node. From this the parent-id and the id are
+     *            computed
+     * @param labels the labels
+     * @param href the href
+     * @param suffix the suffix
+     * @param link the link
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(String documentid, Label[] labels, String href, String suffix, boolean link)
+            throws SiteException;
+
+    /**
+     * Insert a node before a given node Compute the parent id and the id of the node from the
+     * document-id
+     * 
+     * @param documentid the document-id of the new node. From this the parent-id and the id are
+     *            computed
+     * @param labels the labels
+     * @param href the href
+     * @param suffix the suffix
+     * @param link the link
+     * @param refDocumentId document-id of the node, before which the new node will be inserted.
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(String documentid, Label[] labels, String href, String suffix, boolean link,
+            String refDocumentId) throws SiteException;
+
+    /**
+     * Add a node. This method is typically used when publishing, i.e. when copying a node from the
+     * authoring tree to the live tree. The existing node already has a parent node (in the
+     * authoring tree). The node that is added will be a copy of the original node and will be
+     * inserted at the same parentid as the original node.
+     * 
+     * @param node the <code>SiteTreeNode</code> that is to be added
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(SiteTreeNode node) throws SiteException;
+
+    /**
+     * Add a node. This method is typically used when publishing, i.e. when copying a node from the
+     * authoring tree to the live tree. The existing node already has a parent node (in the
+     * authoring tree). The node that is added will be a copy of the original node and will be
+     * inserted at the same parentid as the original node.
+     * 
+     * @param node the <code>SiteTreeNode</code> that is to be added
+     * @param refDocumentId document-id of the node, before which the new node will be inserted.
+     * 
+     * @throws SiteException if the addition failed
+     */
+    void addNode(SiteTreeNode node, String refDocumentId) throws SiteException;
+
+    /**
+     * Add a label to an existing node
+     * 
+     * @param documentId the document-id to which the label is to be added.
+     * @param label the label to add
+     */
+    void addLabel(String documentId, Label label);
+
+    /**
+     * Sets a label of an existing node. If the label does not exist, it is added. Otherwise, the
+     * existing label is replaced.
+     * 
+     * @param documentId the document-id to which the label is to be added.
+     * @param label the label to add
+     */
+    void setLabel(String documentId, Label label);
+
+    /**
+     * Remove a label from a node
+     * 
+     * @param documentId the document-id from which the label is to be removed.
+     * @param label the label to remove
+     */
+    void removeLabel(String documentId, Label label);
+
+    /**
+     * Removes the node corresponding to the given document-id from the tree, and returns it.
+     * 
+     * @param documentId the document-id of the node that is to be removed
+     * 
+     * @return the removed node
+     */
+    SiteTreeNode removeNode(String documentId);
+
+    /**
+     * Return the Node for a given document-id.
+     * 
+     * @param documentId the document-id of the node that is requested
+     * 
+     * @return a <code>SiteTreeNode</code> if there is a node for the given document-id, null
+     *         otherwise.
+     */
+    SiteTreeNode getNode(String documentId);
+
+    /**
+     * Return the top level nodes in the sitetree.
+     * @return the top nodes in the sitetree, or empty array if there are none
+     */
+    SiteTreeNode[] getTopNodes();
+
+    /**
+     * Move up the node amongst its siblings.
+     * 
+     * @param documentid The document id of the node.
+     * @throws SiteException if the moving failed.
+     */
+    void moveUp(String documentid) throws SiteException;
+
+    /**
+     * Move down the node amongst its siblings.
+     * @param documentid The document id of the node.
+     * @throws SiteException if the moving failed.
+     */
+    void moveDown(String documentid) throws SiteException;
+
+    /**
+     * Imports a subtree (from this or from another tree) at a certain position.
+     * @param subtreeRoot The root of the subtree to import.
+     * @param newParent The node where the subtree shall be inserted.
+     * @param newid The new id of the inserted subtreeRoot node (to not overwrite
+     * @param refDocumentId The document-id corresponding to the reference node, before which the
+     *            subtree should be inserted. If null, the subtree is inserted at the end. in case
+     *            there is already a node with the same id in the tree).
+     * @throws SiteException when an error occurs.
+     */
+    void importSubtree(SiteTreeNode subtreeRoot, SiteTreeNode newParent, String newid,
+            String refDocumentId) throws SiteException;
+
+}

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeFactory.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeFactory.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeFactory.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeFactory.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.lenya.cms.site.tree;
+
+import java.io.File;
+
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceUtil;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.publication.PublicationFactory;
+import org.apache.lenya.transaction.Identifiable;
+import org.apache.lenya.transaction.IdentityMap;
+import org.apache.lenya.transaction.IdentifiableFactory;
+
+/**
+ * Factory for sitetree objects.
+ * 
+ * @version $Id: SiteTreeFactory.java 179568 2005-06-02 09:27:26Z jwkaltz $
+ */
+public class SiteTreeFactory extends AbstractLogEnabled implements IdentifiableFactory {
+
+    protected ServiceManager manager;
+
+    /**
+     * Ctor.
+     * @param manager The service manager.
+     */
+    public SiteTreeFactory(ServiceManager manager) {
+        this.manager = manager;
+    }
+
+    /**
+     * @see org.apache.lenya.transaction.IdentifiableFactory#build(org.apache.lenya.transaction.IdentityMap,
+     *      java.lang.String)
+     */
+    public Identifiable build(IdentityMap map, String key) throws Exception {
+        String[] snippets = key.split(":");
+        String publicationId = snippets[0];
+        String area = snippets[1];
+
+        SourceResolver resolver = null;
+        Source source = null;
+        DefaultSiteTree tree;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI("context://");
+            File servletContext = SourceUtil.getFile(source);
+
+            PublicationFactory factory = PublicationFactory.getInstance(getLogger());
+            Publication publication = factory.getPublication(publicationId, servletContext
+                    .getAbsolutePath());
+           
+            tree = new DefaultSiteTree(publication, area, this.manager);
+            ContainerUtil.enableLogging(tree, getLogger());
+            
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                this.manager.release(resolver);
+            }
+        }
+        return tree;
+    }
+
+}
\ No newline at end of file

Added: lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNode.java
URL: http://svn.apache.org/viewcvs/lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNode.java?rev=209293&view=auto
==============================================================================
--- lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNode.java (added)
+++ lenya/trunk/src/publets/sitetree/java/src/org/apache/lenya/cms/site/tree/SiteTreeNode.java Tue Jul  5 09:19:18 2005
@@ -0,0 +1,202 @@
+/*
+ * 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: SiteTreeNode.java 155270 2005-02-24 22:43:34Z andreas $  */
+
+package org.apache.lenya.cms.site.tree;
+
+import java.util.List;
+
+import org.apache.lenya.cms.publication.DocumentException;
+import org.apache.lenya.cms.site.Label;
+
+/**
+ * This interface is a wrapper around the more general w3c.Node which
+ * hides some details which are irrelevant for site tree nodes. It basically
+ * delegates everything to the Node.
+ */
+public interface SiteTreeNode {
+
+    /**
+     * Returns the parent node of this node.
+     * @return A sitetree node.
+     */
+    SiteTreeNode getParent();
+
+    /**
+     * Returns the parent node of this node or null if the parent has no label for the given language.
+     * @param language A language string.
+     * @return A sitetree node.
+     */
+    SiteTreeNode getParent(String language);
+
+    /**
+     * Get the absolute id of this node.
+     * 
+     * @return  the absolute id.
+     */
+    String getAbsoluteId();
+
+    /**
+     * Get the id of this node.
+     * 
+     * @return the node id.
+     */
+    String getId();
+
+    /**
+     * Get all labels for this node (independent of their language attribute).
+     * 
+     * @return an <code>Array</code> of labels.
+     */
+    Label[] getLabels();
+
+    /**
+     * Get the label for a specific language.
+     * 
+     * @param xmlLanguage the language for which the label is requested.
+     * 
+     * @return a <code>Label</code> if there is one for the given language, 
+     * null otherwise. 
+     */
+    Label getLabel(String xmlLanguage);
+
+    /**
+     * Add a label to this node iff the node does not have this label already.
+     * 
+     * @param label the label to be added.
+     */
+    void addLabel(Label label);
+
+    /**
+     * Remove a label from this node.
+     * 
+     * @param label the label to be removed.
+     */
+    void removeLabel(Label label);
+
+    /**
+     * Get the href of this node.
+     * 
+     * @return the href.
+     */
+    String getHref();
+
+    /**
+     * Get the suffix of this node.
+     * 
+     * @return the suffix.
+     */
+    String getSuffix();
+
+    /**
+     * Check whether this node has a link.
+     * 
+     * @return true if this node has a link.
+     */
+    boolean hasLink();
+
+    /**
+     * Get the sitetreenodes, which are children of this node
+     * 
+     * @return the children.
+     */
+    SiteTreeNode[] getChildren();
+
+    /**
+     * Get the sitetreenodes, which are children of this node
+     * and contain a label for the given language.
+     * 
+     * @param language A language string.
+     * @return the children.
+     */
+    SiteTreeNode[] getChildren(String language);
+
+    /**
+     * Remove the children of the node
+     * 
+     * @return the removed node
+     */
+    SiteTreeNode[] removeChildren();
+
+    /**
+     * Get the sitetreenodes, which are the siblings preceding this node
+     * 
+     * @return the children.
+     */
+    SiteTreeNode[] getPrecedingSiblings();
+
+	/**
+	 * Get the sitetreenodes, which are the siblings following this node
+	 * 
+	 * @return the children.
+	 */
+	SiteTreeNode[] getNextSiblings();
+
+    /**
+	 * @return string. The document-id corresponding to the next sibling node.
+	 */
+	String getNextSiblingDocumentId();
+
+    /**
+     * Call the visit method of the visitor, that mean
+     * the operation that shall be perfoemed on this node
+     * (Visitor pattern)
+     * @param visitor The visitor.
+     * 
+     * @throws DocumentException if an error occurs
+     */
+    void accept(SiteTreeNodeVisitor visitor) throws DocumentException;
+
+    /**
+     * Traverse the node ant its children and call the
+     * accept method.
+     * @param visitor The visitor.
+     * 
+     * @throws DocumentException if an error occurs
+     */
+    void acceptSubtree(SiteTreeNodeVisitor visitor) throws DocumentException;
+
+    /**
+     * Traverse in a reverse way the node ant its children and call the
+     * accept method.
+     * @param visitor The visitor.
+     * 
+     * @throws DocumentException if an error occurs
+	 */
+	void acceptReverseSubtree(SiteTreeNodeVisitor visitor) throws DocumentException; 
+    /**
+     * Sets a label of an this node. If the label does not exist, it is added.
+     * Otherwise, the existing label is replaced.
+     * 
+     * @param label the label to add
+     */
+    void setLabel(Label label);
+
+    /**
+     * Give a list of the children and this node in a pre order way
+     * @return The list
+     */
+    List preOrder();
+    
+	/**
+     * Give a list of the children and this node in a post order way
+	 * @return The list
+	 */
+	List postOrder();
+    
+}



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