KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > cms > cocoon > generation > SitetreeFragmentGenerator


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 /* @version $Id$*/
19
20 package org.apache.lenya.cms.cocoon.generation;
21
22 import java.io.IOException JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.avalon.framework.parameters.Parameters;
26 import org.apache.cocoon.ProcessingException;
27 import org.apache.cocoon.environment.ObjectModelHelper;
28 import org.apache.cocoon.environment.Request;
29 import org.apache.cocoon.environment.SourceResolver;
30 import org.apache.cocoon.generation.AbstractGenerator;
31 import org.apache.lenya.cms.publication.Label;
32 import org.apache.lenya.cms.publication.PageEnvelope;
33 import org.apache.lenya.cms.publication.PageEnvelopeFactory;
34 import org.apache.lenya.cms.publication.Publication;
35 import org.apache.lenya.cms.publication.SiteTree;
36 import org.apache.lenya.cms.publication.SiteTreeException;
37 import org.apache.lenya.cms.publication.SiteTreeNode;
38 import org.xml.sax.SAXException JavaDoc;
39 import org.xml.sax.helpers.AttributesImpl JavaDoc;
40
41 /**
42  * Generates a fragment of the XML from the sitetree, corresponding to a given
43  * node. The node is specified by the sitemap parameters area/documentid. If the
44  * sitemap parameter initialTree is true, the top nodes of the tree will be
45  * generated and the node given by the sitemap parameters area/documentid will
46  * be unfolded. If initialTree is false, only the children of the selected node
47  * will be generated.
48  *
49  */

50 public class SitetreeFragmentGenerator extends AbstractGenerator {
51
52     protected Publication publication;
53
54     /** Parameter which denotes the documentid of the clicked node */
55     protected String JavaDoc documentid;
56
57     /** Parameter which denotes the area of the clicked node */
58     protected String JavaDoc area;
59
60     /**
61      * Parameter which decides if the initial tree with the root nodes is
62      * generated
63      */

64     protected boolean initialTree;
65
66     /**
67      * Parameter which denotes a comma-separated list of areas, for which the
68      * xml will be generated.
69      */

70     protected String JavaDoc[] areas = null;
71
72     /**
73      * Convenience object, so we don't need to create an AttributesImpl for
74      * every element.
75      */

76     protected AttributesImpl JavaDoc attributes;
77
78     protected static final String JavaDoc PARAM_AREA = "area";
79
80     protected static final String JavaDoc PARAM_DOCUMENTID = "documentid";
81
82     protected static final String JavaDoc PARAM_INITIAL = "initial";
83
84     protected static final String JavaDoc PARAM_AREAS = "areas";
85
86     /** The URI of the namespace of this generator. */
87     protected static final String JavaDoc URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
88
89     protected static final String JavaDoc XML_URI = "http://www.w3.org/XML/1998/namespace";
90
91     /** The namespace prefix for this namespace. */
92     protected static final String JavaDoc PREFIX = "site";
93
94     protected static final String JavaDoc XML_PREFIX = "xml";
95
96     protected static final String JavaDoc NODE_NODE = "node";
97
98     protected static final String JavaDoc NODE_LABEL = "label";
99
100     protected static final String JavaDoc NODE_SITE = "site";
101
102     protected static final String JavaDoc NODE_FRAGMENT = "fragment";
103
104     protected static final String JavaDoc ATTR_ID = "id";
105
106     protected static final String JavaDoc ATTR_FOLDER = "folder";
107
108     protected static final String JavaDoc ATTR_AREA = "area";
109
110     protected static final String JavaDoc ATTR_LABEL = "label";
111
112     protected static final String JavaDoc ATTR_VISIBLEINNAV = "visibleinnav";
113
114     protected static final String JavaDoc ATTR_LINK = "link";
115
116     protected static final String JavaDoc ATTR_BASE = "base";
117
118     protected static final String JavaDoc ATTR_SUFFIX = "suffix";
119
120     protected static final String JavaDoc ATTR_HREF = "href";
121
122     protected static final String JavaDoc ATTR_LANG = "lang";
123
124     /**
125      * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
126      * java.util.Map, java.lang.String,
127      * org.apache.avalon.framework.parameters.Parameters)
128      */

129     public void setup(SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src,
130             Parameters par) throws ProcessingException, SAXException JavaDoc,
131             IOException JavaDoc {
132         super.setup(resolver, objectModel, src, par);
133
134         PageEnvelope envelope = null;
135
136         if (getLogger().isDebugEnabled()) {
137             Request request = ObjectModelHelper.getRequest(objectModel);
138             getLogger().debug(
139                     "Resolving page envelope for URL ["
140                             + request.getRequestURI() + "]");
141         }
142
143         this.area = par.getParameter(PARAM_AREA, null);
144         this.documentid = par.getParameter(PARAM_DOCUMENTID, null);
145
146         if (par.isParameter(PARAM_INITIAL)) {
147             this.initialTree = Boolean.valueOf(
148                     par.getParameter(PARAM_INITIAL, null)).booleanValue();
149         } else {
150             this.initialTree = false;
151         }
152
153         if (par.isParameter(PARAM_AREAS)) {
154             String JavaDoc parAreas = par.getParameter(PARAM_AREAS, null);
155             this.areas = parAreas.split(",");
156         } else {
157             String JavaDoc temp[] = { "authoring", "archive", "trash" };
158             this.areas = temp;
159         }
160
161         if (this.getLogger().isDebugEnabled()) {
162             this.getLogger().debug("Parameter area: " + this.area);
163             this.getLogger().debug("Parameter documentid: " + this.documentid);
164             this.getLogger()
165                     .debug("Parameter initialTree: " + this.initialTree);
166             String JavaDoc areasStr = "";
167             for (int i = 0; i < this.areas.length; i++)
168                 areasStr += this.areas[i] + " ";
169             this.getLogger().debug("Parameter areas: " + areasStr);
170         }
171
172         try {
173             envelope = PageEnvelopeFactory.getInstance().getPageEnvelope(
174                     objectModel);
175         } catch (Exception JavaDoc e) {
176             throw new ProcessingException("Resolving page envelope failed: ", e);
177         }
178
179         this.publication = envelope.getPublication();
180         this.attributes = new AttributesImpl JavaDoc();
181
182     }
183
184     /**
185      * @see org.apache.cocoon.generation.Generator#generate()
186      */

187     public void generate() throws IOException JavaDoc, SAXException JavaDoc,
188             ProcessingException {
189
190         try {
191
192             this.contentHandler.startDocument();
193             this.contentHandler.startPrefixMapping(PREFIX, URI);
194
195             attributes.clear();
196             if (!initialTree) {
197                 attributes.addAttribute("", ATTR_AREA, ATTR_AREA, "CDATA",
198                         this.area);
199                 attributes.addAttribute("", ATTR_BASE, ATTR_BASE, "CDATA",
200                         this.documentid);
201             }
202
203             this.contentHandler.startElement(URI, NODE_FRAGMENT, PREFIX + ':'
204                     + NODE_FRAGMENT, this.attributes);
205
206             if (this.initialTree) {
207                 for (int i = 0; i < this.areas.length; i++) {
208                     generateFragmentInitial(this.areas[i]);
209                 }
210             } else {
211                 generateFragment();
212             }
213
214             this.contentHandler.endElement(URI, NODE_FRAGMENT, PREFIX + ':'
215                     + NODE_FRAGMENT);
216
217             this.contentHandler.endPrefixMapping(PREFIX);
218             this.contentHandler.endDocument();
219
220         } catch (SAXException JavaDoc e) {
221             throw new ProcessingException(e);
222         } catch (SiteTreeException e) {
223             throw new ProcessingException(e);
224         }
225
226     }
227
228     /**
229      * Generates a fragment of the tree which contains the children of a given
230      * node.
231      *
232      * @throws SiteTreeException
233      * @throws SAXException
234      * @throws ProcessingException
235      */

236     protected void generateFragment() throws SiteTreeException, SAXException JavaDoc,
237             ProcessingException {
238
239         SiteTree siteTree = null;
240         if (!this.area.equals(Publication.AUTHORING_AREA)
241                 && !this.area.equals(Publication.ARCHIVE_AREA)
242                 && !this.area.equals(Publication.TRASH_AREA)
243                 && !this.area.equals(Publication.STAGING_AREA)
244                 && !this.area.equals(Publication.LIVE_AREA)) {
245             throw new ProcessingException("Invalid area: " + this.area);
246         }
247         siteTree = publication.getTree(this.area);
248
249         SiteTreeNode node = siteTree.getNode(this.documentid);
250         if (this.getLogger().isDebugEnabled()) {
251             this.getLogger().debug(
252                     "Node with documentid " + documentid + " found.");
253         }
254         if (node == null)
255             throw new SiteTreeException("Node with documentid " + documentid
256                     + " not found.");
257
258         SiteTreeNode[] children = node.getChildren();
259
260         for (int i = 0; i < children.length; i++) {
261             startNode(NODE_NODE, children[i]);
262             addLabels(children[i]);
263             endNode(NODE_NODE);
264         }
265     }
266
267     /**
268      * Generates the top node of the given area and then calls a recursive
269      * method to traverse the tree, if the node given by area/documentid is in
270      * this area.
271      *
272      * @param siteArea
273      * @throws SiteTreeException
274      * @throws SAXException
275      * @throws ProcessingException
276      */

277     protected void generateFragmentInitial(String JavaDoc siteArea)
278             throws SiteTreeException, SAXException JavaDoc, ProcessingException {
279
280         SiteTree siteTree = publication.getTree(siteArea);
281
282         String JavaDoc label = "";
283         String JavaDoc isFolder = "";
284
285         // FIXME: don't hardcode area label
286
if (siteArea.equals(Publication.AUTHORING_AREA))
287             label = "Authoring";
288         if (siteArea.equals(Publication.ARCHIVE_AREA))
289             label = "Archive";
290         if (siteArea.equals(Publication.TRASH_AREA))
291             label = "Trash";
292         if (siteArea.equals(Publication.LIVE_AREA))
293             label = "Live";
294         if (siteArea.equals(Publication.STAGING_AREA))
295             label = "Staging";
296
297         if (siteTree.getTopNodes().length > 0)
298             isFolder = "true";
299         else
300             isFolder = "false";
301
302         this.attributes.clear();
303         this.attributes.addAttribute("", ATTR_AREA, ATTR_AREA, "CDATA",
304                 siteArea);
305         this.attributes.addAttribute("", ATTR_FOLDER, ATTR_FOLDER, "CDATA",
306                 isFolder);
307         this.attributes
308                 .addAttribute("", ATTR_LABEL, ATTR_LABEL, "CDATA", label);
309
310         startNode(NODE_SITE);
311
312         if (area.equals(siteArea)) {
313             generateFragmentRecursive(siteTree.getTopNodes(), this.documentid);
314         }
315
316         endNode(NODE_SITE);
317     }
318
319     /**
320      * Follows the documentid to find the way in the sitetree to the specified
321      * node and opens all folders on its way.
322      *
323      * @param nodes
324      * @param docid
325      * @throws SiteTreeException
326      * @throws SAXException
327      */

328     protected void generateFragmentRecursive(SiteTreeNode[] nodes, String JavaDoc docid)
329             throws SiteTreeException, SAXException JavaDoc {
330         String JavaDoc nodeid;
331         String JavaDoc childid;
332
333         if (nodes == null)
334             return;
335         if (docid.startsWith("/"))
336             docid = docid.substring(1);
337         if (docid.indexOf("/") != -1) {
338             nodeid = docid.substring(0, docid.indexOf("/"));
339             childid = docid.substring(docid.indexOf("/") + 1);
340         } else {
341             nodeid = docid;
342             childid = "";
343         }
344
345         for (int i = 0; i < nodes.length; i++) {
346             startNode(NODE_NODE, nodes[i]);
347             addLabels(nodes[i]);
348             if (nodes[i].getId().equals(nodeid)) {
349                 generateFragmentRecursive(nodes[i].getChildren(), childid);
350             }
351             endNode(NODE_NODE);
352         }
353     }
354
355     /**
356      * Begins a named node and calls setNodeAttributes to set its attributes.
357      *
358      * @param nodeName
359      * the name of the new node
360      * @throws SAXException
361      * if an error occurs while creating the node
362      */

363     protected void startNode(String JavaDoc nodeName) throws SAXException JavaDoc {
364         this.contentHandler.startElement(URI, nodeName,
365                 PREFIX + ':' + nodeName, this.attributes);
366     }
367
368     /**
369      * Begins a named node and calls setNodeAttributes to set its attributes.
370      *
371      * @param nodeName
372      * the name of the new node
373      * @param node
374      * The attributes are taken from this node
375      * @throws SAXException
376      * if an error occurs while creating the node
377      */

378     protected void startNode(String JavaDoc nodeName, SiteTreeNode node)
379             throws SAXException JavaDoc {
380         setNodeAttributes(node);
381         this.contentHandler.startElement(URI, nodeName,
382                 PREFIX + ':' + nodeName, this.attributes);
383     }
384
385     /**
386      * Sets the attributes for a given node. Sets attributes id, href, folder,
387      * suffix, basic-url, language-suffix.
388      *
389      * @param node
390      * @throws SAXException
391      * if an error occurs while setting the attributes
392      */

393     protected void setNodeAttributes(SiteTreeNode node) throws SAXException JavaDoc {
394         this.attributes.clear();
395
396         String JavaDoc id = node.getId();
397         String JavaDoc isVisible = Boolean.toString(node.visibleInNav());
398         String JavaDoc hasLink = Boolean.toString(node.hasLink());
399         String JavaDoc href = node.getHref();
400         String JavaDoc suffix = node.getSuffix();
401         String JavaDoc isFolder = isFolder(node);
402
403         if (this.getLogger().isDebugEnabled()) {
404             this.getLogger().debug("adding attribute id: " + id);
405             this.getLogger().debug(
406                     "adding attribute visibleinnav: " + isVisible);
407             this.getLogger().debug("adding attribute link: " + hasLink);
408             if (href != null)
409                 this.getLogger().debug("adding attribute href: " + href);
410             if (suffix != null)
411                 this.getLogger().debug("adding attribute suffix: " + suffix);
412             this.getLogger().debug("adding attribute folder: " + isFolder);
413         }
414         this.attributes.addAttribute("", ATTR_ID, ATTR_ID, "CDATA", id);
415         this.attributes.addAttribute("", ATTR_VISIBLEINNAV, ATTR_VISIBLEINNAV,
416                 "CDATA", isVisible);
417         this.attributes
418                 .addAttribute("", ATTR_LINK, ATTR_LINK, "CDATA", hasLink);
419         if (href != null)
420             this.attributes.addAttribute("", ATTR_HREF, ATTR_HREF, "CDATA",
421                     href);
422         if (suffix != null)
423             this.attributes.addAttribute("", ATTR_SUFFIX, ATTR_SUFFIX, "CDATA",
424                     suffix);
425         this.attributes.addAttribute("", ATTR_FOLDER, ATTR_FOLDER, "CDATA",
426                 isFolder);
427     }
428
429     /**
430      * Returns a value to indicate whether a node is a folder (contains
431      * subnodes). With the incremental sitetree loading, we sometimes load nodes
432      * which are folders, but we don't load their children. But we still have to
433      * know if it's a folder or not, i.e. if it can be opened.
434      *
435      * @param node
436      * @return "true" or "false"
437      */

438     protected String JavaDoc isFolder(SiteTreeNode node) {
439         if (node.getChildren().length > 0)
440             return "true";
441         else
442             return "false";
443     }
444
445     /**
446      * Ends the named node.
447      *
448      * @param nodeName
449      * the name of the new node
450      * @throws SAXException
451      * if an error occurs while closing the node
452      */

453     protected void endNode(String JavaDoc nodeName) throws SAXException JavaDoc {
454         this.contentHandler.endElement(URI, nodeName, PREFIX + ':' + nodeName);
455     }
456
457     /**
458      * Finds all the label children of a node and adds them to the nav xml.
459      *
460      * @param node
461      * @throws SAXException
462      */

463     protected void addLabels(SiteTreeNode node) throws SAXException JavaDoc {
464         Label[] labels = node.getLabels();
465
466         for (int i = 0; i < labels.length; i++) {
467             String JavaDoc lang = labels[i].getLanguage();
468             if (lang == null)
469                 lang = "";
470             addLabel(labels[i].getLabel(), lang);
471         }
472     }
473
474     /**
475      * Adds a label element of a given language.
476      *
477      * @param label
478      * the value of the label
479      * @param language
480      * the language of the label
481      * @throws SAXException
482      */

483     protected void addLabel(String JavaDoc label, String JavaDoc language) throws SAXException JavaDoc {
484         this.attributes.clear();
485         this.attributes.addAttribute(XML_URI, ATTR_LANG, XML_PREFIX + ":"
486                 + ATTR_LANG, "CDATA", language);
487
488         this.contentHandler.startElement(URI, NODE_LABEL, PREFIX + ':'
489                 + NODE_LABEL, this.attributes);
490         char[] labelArray = label.toCharArray();
491         this.contentHandler.characters(labelArray, 0, labelArray.length);
492         this.contentHandler.endElement(URI, NODE_LABEL, PREFIX + ':'
493                 + NODE_LABEL);
494     }
495
496 }
497
Popular Tags