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