KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > webapps > session > context > SimpleSessionContext


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 package org.apache.cocoon.webapps.session.context;
17
18 import java.io.IOException JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.cocoon.ProcessingException;
23 import org.apache.cocoon.components.source.SourceUtil;
24 import org.apache.cocoon.xml.IncludeXMLConsumer;
25 import org.apache.cocoon.xml.dom.DOMUtil;
26 import org.apache.excalibur.source.Source;
27 import org.apache.excalibur.source.SourceException;
28 import org.apache.excalibur.source.SourceParameters;
29 import org.apache.excalibur.source.SourceResolver;
30 import org.apache.excalibur.xml.xpath.NodeListImpl;
31 import org.apache.excalibur.xml.xpath.XPathProcessor;
32 import org.w3c.dom.Attr JavaDoc;
33 import org.w3c.dom.Document JavaDoc;
34 import org.w3c.dom.DocumentFragment JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.NodeList JavaDoc;
37 import org.xml.sax.ContentHandler JavaDoc;
38 import org.xml.sax.SAXException JavaDoc;
39 import org.xml.sax.ext.LexicalHandler JavaDoc;
40
41 /**
42  * This is a simple implementation of the session context.
43  *
44  * @author <a HREF="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
45  * @version CVS $Id: SimpleSessionContext.java 30932 2004-07-29 17:35:38Z vgritsenko $
46 */

47 public final class SimpleSessionContext
48 implements SessionContext {
49
50     /** Context name */
51     private String JavaDoc name;
52
53     /** The content of the context */
54     private Document JavaDoc data;
55
56     /** The attributes */
57     private Map JavaDoc attributes = new HashMap JavaDoc();
58
59     /** load resource */
60     private String JavaDoc loadResource;
61     
62     /** save resource */
63     private String JavaDoc saveResource;
64
65     /** The XPath Processor */
66     private XPathProcessor xpathProcessor;
67
68     /** The source resolver */
69     private SourceResolver resolver;
70     
71     /**
72      * Constructor
73      */

74     public SimpleSessionContext(XPathProcessor xPathProcessor, SourceResolver resolver)
75     throws ProcessingException {
76         this.data = DOMUtil.createDocument();
77         this.data.appendChild(data.createElementNS(null, "context"));
78         this.xpathProcessor = xPathProcessor;
79         this.resolver = resolver;
80     }
81
82     /**
83      * Get the name of the context
84      */

85     public String JavaDoc getName() {
86         return this.name;
87     }
88
89     /* (non-Javadoc)
90      * @see org.apache.cocoon.webapps.session.context.SessionContext#setup(java.lang.String, java.lang.String, java.lang.String)
91      */

92     public void setup(String JavaDoc value, String JavaDoc loadResource, String JavaDoc saveResource) {
93         this.name = value;
94         this.loadResource = loadResource;
95         this.saveResource = saveResource;
96     }
97
98     public synchronized DocumentFragment JavaDoc getXML(String JavaDoc path)
99     throws ProcessingException {
100         DocumentFragment JavaDoc result = null;
101         NodeList JavaDoc list;
102         path = this.createPath(path);
103
104         String JavaDoc[] pathComponents = DOMUtil.buildPathArray(path);
105         if (pathComponents == null) {
106             list = this.xpathProcessor.selectNodeList(this.data, path);
107         } else {
108             list = DOMUtil.getNodeListFromPath(data, pathComponents);
109         }
110
111         if (list != null && list.getLength() > 0) {
112             Document JavaDoc doc = DOMUtil.createDocument();
113             result = doc.createDocumentFragment();
114
115             for(int i = 0; i < list.getLength(); i++) {
116
117                 // the found node is either an attribute or an element
118
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
119                     // if it is an attribute simple create a new text node with the value of the attribute
120
result.appendChild(doc.createTextNode(list.item(i).getNodeValue()));
121                 } else {
122                     // now we have an element
123
// copy all children of this element in the resulting tree
124
NodeList JavaDoc childs = list.item(i).getChildNodes();
125                     if (childs != null) {
126                         for(int m = 0; m < childs.getLength(); m++) {
127                             result.appendChild(doc.importNode(childs.item(m), true));
128                         }
129                     }
130                 }
131             }
132         }
133
134         return result;
135     }
136
137
138     public synchronized void setXML(String JavaDoc path, DocumentFragment JavaDoc fragment)
139     throws ProcessingException {
140         path = this.createPath(path);
141         Node JavaDoc node = DOMUtil.selectSingleNode(data, path, this.xpathProcessor);
142         if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
143             // now we have to serialize the fragment to a string and insert this
144
Attr JavaDoc attr = (Attr JavaDoc)node;
145             attr.setNodeValue(DOMUtil.getValueOfNode(fragment));
146
147         } else {
148
149             // remove old childs
150
while (node.hasChildNodes() == true) {
151                 node.removeChild(node.getFirstChild());
152             }
153
154             // Insert new childs
155
NodeList JavaDoc childs = fragment.getChildNodes();
156             if (childs != null && childs.getLength() > 0) {
157                 for(int i = 0; i < childs.getLength(); i++) {
158                     Node JavaDoc n = data.importNode(childs.item(i), true);
159                     node.appendChild(n);
160                 }
161             }
162         }
163     }
164
165     /**
166      * Append a document fragment at the given path. The implementation of this
167      * method is context specific.
168      * Usually the children of the fragment are appended as new children of the
169      * node specified by the path.
170      * If the path is not existent it is created.
171      */

172     public synchronized void appendXML(String JavaDoc path, DocumentFragment JavaDoc fragment)
173     throws ProcessingException {
174         path = this.createPath(path);
175         Node JavaDoc node = DOMUtil.selectSingleNode(data, path, this.xpathProcessor);
176         if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
177             Attr JavaDoc attr;
178
179             if (node.getNodeValue() != null || node.getNodeValue().trim().length() > 0) {
180                 // this is an existing attr, create a new one
181
attr = node.getOwnerDocument().createAttributeNS(null, node.getNodeName());
182                 node.getParentNode().appendChild(attr);
183             } else {
184                 attr = (Attr JavaDoc)node;
185             }
186
187             // now we have to serialize the fragment to a string and insert this
188
attr.setNodeValue(DOMUtil.getValueOfNode(fragment));
189         } else {
190
191             // Insert new childs
192
NodeList JavaDoc childs = fragment.getChildNodes();
193             if (childs != null && childs.getLength() > 0) {
194                 for(int i = 0; i < childs.getLength(); i++) {
195                     Node JavaDoc n = data.importNode(childs.item(i), true);
196                     node.appendChild(n);
197                 }
198             }
199         }
200     }
201
202     /**
203      * Build path
204      */

205     private String JavaDoc createPath(String JavaDoc path) {
206         if (path == null) path ="/";
207         if (!path.startsWith("/") ) path = "/" + path;
208         path = "context" + path;
209         if (path.endsWith("/")) path = path.substring(0, path.length() - 1);
210         return path;
211     }
212
213     /**
214      * Remove nodes
215      */

216     public synchronized void removeXML(String JavaDoc path)
217     throws ProcessingException {
218         NodeList JavaDoc list;
219         path = this.createPath(path);
220
221         String JavaDoc[] pathComponents = DOMUtil.buildPathArray(path);
222         if (pathComponents == null) {
223             list = this.xpathProcessor.selectNodeList(this.data, path);
224         } else {
225             list = DOMUtil.getNodeListFromPath(data, pathComponents);
226         }
227         if (list != null && list.getLength() > 0) {
228             int len = list.getLength();
229             Node JavaDoc child;
230             for(int i = 0; i < len; i++) {
231                 child = list.item(len - 1 -i);
232                 child.getParentNode().removeChild(child);
233             }
234         }
235     }
236
237     /**
238      * Get a copy the first node specified by the path.
239      */

240     public synchronized Node JavaDoc getSingleNode(String JavaDoc path)
241     throws ProcessingException {
242         Node JavaDoc result = null;
243
244         path = this.createPath(path);
245
246         try {
247             result = DOMUtil.getSingleNode(data, path, this.xpathProcessor);
248             if (result != null) result = result.cloneNode(true);
249         } catch (javax.xml.transform.TransformerException JavaDoc localException) {
250             throw new ProcessingException("TransformerException: " + localException, localException);
251         }
252
253         return result;
254     }
255
256     /**
257      * Get a copy all the nodes specified by the path.
258      */

259     public synchronized NodeList JavaDoc getNodeList(String JavaDoc path)
260     throws ProcessingException {
261         NodeList JavaDoc result = null;
262
263         path = this.createPath(path);
264
265         String JavaDoc[] pathComponents = DOMUtil.buildPathArray(path);
266         if (pathComponents == null) {
267             result = this.xpathProcessor.selectNodeList(this.data, path);
268         } else {
269             result = DOMUtil.getNodeListFromPath(data, pathComponents);
270         }
271         // clone list
272
if (result != null) {
273             result = new NodeListImpl(result);
274         }
275
276         return result;
277     }
278
279     /**
280      * Set the value of a node. The node is copied before insertion.
281      */

282     public synchronized void setNode(String JavaDoc path, Node JavaDoc node)
283     throws ProcessingException {
284         if ( path == null || path.equals("/")) {
285             data = DOMUtil.createDocument();
286             data.appendChild(data.createElementNS(null, "context"));
287             data.getFirstChild().appendChild(data.importNode(node, true));
288         } else {
289             path = this.createPath(path);
290             Node JavaDoc removeNode = DOMUtil.selectSingleNode(data, path, this.xpathProcessor);
291             removeNode.getParentNode().replaceChild(data.importNode(node, true), removeNode);
292         }
293     }
294
295
296     /**
297      * Set a context attribute. If value is null the attribute is removed.
298      */

299     public synchronized void setAttribute(String JavaDoc key, Object JavaDoc value) {
300         if (value == null) {
301             attributes.remove(key);
302         } else {
303             attributes.put(key, value);
304         }
305     }
306
307     /**
308      * Get a context attribute. If the attribute is not available return null
309      */

310     public synchronized Object JavaDoc getAttribute(String JavaDoc key) {
311         return attributes.get(key);
312     }
313
314     /**
315      * Get a context attribute. If the attribute is not available the defaultObject is returned
316      */

317     public synchronized Object JavaDoc getAttribute(String JavaDoc key, Object JavaDoc defaultObject) {
318         Object JavaDoc value = attributes.get(key);
319         if (value == null) value = defaultObject;
320         return value;
321     }
322
323     /**
324      * Get the value of this node. This is similiar to the xsl:value-of
325      * function. If the node does not exist, <code>null</code> is returned.
326      */

327     public synchronized String JavaDoc getValueOfNode(String JavaDoc path)
328     throws ProcessingException {
329         String JavaDoc value = null;
330
331         path = this.createPath(path); // correct path
332
value = DOMUtil.getValueOf(data, path, this.xpathProcessor);
333
334         return value;
335     }
336
337     /**
338      * Set the value of a node.
339      */

340     public synchronized void setValueOfNode(String JavaDoc path, String JavaDoc value)
341     throws ProcessingException {
342         path = this.createPath(path); // correct path
343

344         Node JavaDoc node = DOMUtil.selectSingleNode(data, path, this.xpathProcessor);
345         if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
346             Attr JavaDoc attr = (Attr JavaDoc)node;
347             attr.setNodeValue(value);
348
349         } else {
350
351             // remove old childs
352
while (node.hasChildNodes() == true) {
353                 node.removeChild(node.getFirstChild());
354             }
355
356             node.appendChild(node.getOwnerDocument().createTextNode(value));
357         }
358     }
359
360     /**
361      * Stream the XML directly to the handler. This streams the contents of getXML()
362      * to the given handler without creating a DocumentFragment containing a copy
363      * of the data
364      */

365     public synchronized boolean streamXML(String JavaDoc path, ContentHandler JavaDoc contentHandler,
366                            LexicalHandler JavaDoc lexicalHandler)
367     throws SAXException JavaDoc, ProcessingException {
368         NodeList JavaDoc list;
369         boolean streamed = false;
370         path = this.createPath(path);
371
372         String JavaDoc[] pathComponents = DOMUtil.buildPathArray(path);
373         if (pathComponents == null) {
374             list = this.xpathProcessor.selectNodeList(this.data, path);
375         } else {
376             list = DOMUtil.getNodeListFromPath(data, pathComponents);
377         }
378         if (list != null && list.getLength() > 0) {
379             streamed = true;
380             for(int i = 0; i < list.getLength(); i++) {
381
382                 // the found node is either an attribute or an element
383
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
384                     // if it is an attribute simple create a new text node with the value of the attribute
385
String JavaDoc value = list.item(i).getNodeValue();
386                     contentHandler.characters(value.toCharArray(), 0, value.length());
387                 } else {
388                     // now we have an element
389
// stream all children of this element to the resulting tree
390
NodeList JavaDoc childs = list.item(i).getChildNodes();
391                     if (childs != null) {
392                         for(int m = 0; m < childs.getLength(); m++) {
393                             IncludeXMLConsumer.includeNode(childs.item(m), contentHandler, lexicalHandler);
394                         }
395                     }
396                 }
397             }
398          }
399
400         return streamed;
401     }
402
403     /**
404      * Try to load XML into the context.
405      * If the context does not provide the ability of loading,
406      * an exception is thrown.
407      */

408     public void loadXML(String JavaDoc path,
409                         SourceParameters parameters)
410     throws SAXException JavaDoc, ProcessingException, IOException JavaDoc {
411         if (this.loadResource == null) {
412             throw new ProcessingException("The context " + this.name + " does not support loading.");
413         }
414         Source source = null;
415         try {
416             source = SourceUtil.getSource(this.loadResource, null, parameters, this.resolver);
417             Document JavaDoc doc = SourceUtil.toDOM(source);
418             DocumentFragment JavaDoc df = doc.createDocumentFragment();
419             df.appendChild(doc.getDocumentElement());
420             this.setXML(path, df);
421         } catch (SourceException se) {
422             throw SourceUtil.handle(se);
423         } finally {
424             resolver.release(source);
425         }
426     }
427
428     /**
429      * Try to save XML from the context.
430      * If the context does not provide the ability of saving,
431      * an exception is thrown.
432      */

433     public void saveXML(String JavaDoc path,
434                         SourceParameters parameters)
435     throws SAXException JavaDoc, ProcessingException, IOException JavaDoc {
436         if (this.saveResource == null) {
437             throw new ProcessingException("The context " + this.name + " does not support saving.");
438         }
439         DocumentFragment JavaDoc frag = this.getXML(path);
440         if (frag == null) {
441             // create empty fake document
442
frag = DOMUtil.createDocument().createDocumentFragment();
443         }
444
445         SourceUtil.writeDOM(this.saveResource,
446                             null,
447                             parameters,
448                             frag,
449                             this.resolver,
450                             "xml");
451     }
452
453 }
454
455
Popular Tags