KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > transformation > CIncludeTransformer


1 /*
2  * Copyright 1999-2005 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.transformation;
17
18 import org.apache.avalon.framework.activity.Disposable;
19 import org.apache.avalon.framework.parameters.Parameters;
20 import org.apache.avalon.framework.service.ServiceException;
21 import org.apache.avalon.framework.service.ServiceManager;
22
23 import org.apache.cocoon.ProcessingException;
24 import org.apache.cocoon.caching.CacheableProcessingComponent;
25 import org.apache.cocoon.components.sax.XMLDeserializer;
26 import org.apache.cocoon.components.sax.XMLSerializer;
27 import org.apache.cocoon.components.source.SourceUtil;
28 import org.apache.cocoon.environment.SourceResolver;
29 import org.apache.cocoon.transformation.helpers.IncludeCacheManager;
30 import org.apache.cocoon.transformation.helpers.IncludeCacheManagerSession;
31 import org.apache.cocoon.xml.IncludeXMLConsumer;
32 import org.apache.cocoon.xml.XMLConsumer;
33 import org.apache.cocoon.xml.XMLUtils;
34
35 import org.apache.commons.lang.BooleanUtils;
36 import org.apache.commons.lang.StringUtils;
37 import org.apache.excalibur.source.Source;
38 import org.apache.excalibur.source.SourceException;
39 import org.apache.excalibur.source.SourceParameters;
40 import org.apache.excalibur.source.SourceValidity;
41 import org.apache.excalibur.xml.dom.DOMParser;
42 import org.apache.excalibur.xml.xpath.XPathProcessor;
43 import org.w3c.dom.Document JavaDoc;
44 import org.w3c.dom.NodeList JavaDoc;
45 import org.xml.sax.Attributes JavaDoc;
46 import org.xml.sax.InputSource JavaDoc;
47 import org.xml.sax.SAXException JavaDoc;
48 import org.xml.sax.helpers.AttributesImpl JavaDoc;
49
50 import java.io.IOException JavaDoc;
51 import java.io.Serializable JavaDoc;
52 import java.util.Map JavaDoc;
53
54 /**
55  * @cocoon.sitemap.component.documentation
56  * This transformer triggers for the element <code>include</code> in the
57  * namespace "http://apache.org/cocoon/include/1.0".
58  * The <code>src</code> attribute contains the url which points to
59  * an xml resource which is include instead of the element.
60  * With the attributes <code>element</code>, <code>ns</code> and
61  * <code>prefix</code> it is possible to specify an element
62  * which surrounds the included content.
63  *
64  * @cocoon.sitemap.component.name cinclude
65  * @cocoon.sitemap.component.logger sitemap.transformer.cinclude
66  * @cocoon.sitemap.component.documentation.caching
67  * See documentation for further information.
68  *
69  * @cocoon.sitemap.component.pooling.max 16
70  *
71  * This transformer also supports a more verbose but flexible version:
72  * <cinclude:includexml xmlns:cinclude="http://apache.org/cocoon/include/1.0" ignoreErrors="false">
73  * <cinclude:src>THE SRC URI</cinclude:src>
74  * <!-- This is an optional configuration block -->
75  * <cinclude:configuration>
76  * <!-- For example if you want to make a HTTP POST -->
77  * <cinclude:parameter>
78  * <cinclude:name>method</cinclude:name>
79  * <cinclude:value>POST</cinclude:value>
80  * </cinclude:parameter>
81  * </cinclude:configuration>
82  * <!-- The following are optional parameters appended to the URI -->
83  * <cinclude:parameters>
84  * <cinclude:parameter>
85  * <cinclude:name>a name</cinclude:name>
86  * <cinclude:value>a value</cinclude:value>
87  * </cinclude:parameter>
88  * <!-- more can follow -->
89  * </cinclude:parameters>
90  * </cinclude:includexml>
91  *
92  *
93  * This transformer also supports caching of the included content.
94  * Therefore it triggers for the element <code>cached-include</code> in the
95  * namespace "http://apache.org/cocoon/include/1.0".
96  * The <code>src</code> attribute contains the url which points to
97  * an xml resource which is include instead of the element.
98  * First, it works like the usual include command. But it can be
99  * configured with various parameters:
100  * The most important one is the <code>expires</code> parameter.
101  * If (and only if) this is set to a value greater than zero,
102  * all included content is cached for the given period of time.
103  * So if any other request includes the same URI, the content
104  * is fetched from the cache. The expires value is in seconds.
105  * Usually the content is cached in the usual store, but you
106  * can also define a writeable source with the <code>source</code> parameter,
107  * e.g. "file:/c:/temp". Then the cached content is written into this
108  * directory.
109  * With the optional <code>purge</code> set to <code>true</code>
110  * the cache is purged which means the cached content is regarded as
111  * invalid nevertheless if it has expired or not.
112  * With the optional parameter <code>parallel</code> the various
113  * included contents are processed (included) in parallel rather than
114  * in a series.
115  * With the optional parameter <code>preemptive</code> set to <code>true</code>
116  * a pre-emptive caching is activated. When a resource is requested with
117  * pre-emptive caching, this transformer always attempts to get the
118  * content from the cache. If the content is not in the cache, it is
119  * of course retrieved from the original source and cached.
120  * If the cached resource has expired, it is still provided. The cache
121  * is updated by a background task. This task has to be started
122  * beforehand.
123  *
124  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
125  * @author <a HREF="mailto:acoliver@apache.org">Andrew C. Oliver</a>
126  * @version $Id: CIncludeTransformer.java 265735 2005-09-01 14:04:30Z cziegeler $
127  */

128 public class CIncludeTransformer extends AbstractSAXTransformer
129                                  implements Disposable, CacheableProcessingComponent {
130
131     public static final String JavaDoc CINCLUDE_NAMESPACE_URI = "http://apache.org/cocoon/include/1.0";
132     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT = "include";
133     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE = "src";
134     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE = "element";
135     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE = "select";
136     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE = "ns";
137     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE = "prefix";
138     public static final String JavaDoc CINCLUDE_INCLUDE_ELEMENT_STRIP_ROOT_ATTRIBUTE = "strip-root";
139
140     public static final String JavaDoc CINCLUDE_INCLUDEXML_ELEMENT = "includexml";
141     public static final String JavaDoc CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE = "ignoreErrors";
142     public static final String JavaDoc CINCLUDE_SRC_ELEMENT = "src";
143     public static final String JavaDoc CINCLUDE_CONFIGURATION_ELEMENT = "configuration";
144     public static final String JavaDoc CINCLUDE_PARAMETERS_ELEMENT = "parameters";
145     public static final String JavaDoc CINCLUDE_PARAMETER_ELEMENT = "parameter";
146     public static final String JavaDoc CINCLUDE_NAME_ELEMENT = "name";
147     public static final String JavaDoc CINCLUDE_VALUE_ELEMENT = "value";
148
149     public static final String JavaDoc CINCLUDE_CACHED_INCLUDE_ELEMENT = "cached-include";
150     protected static final String JavaDoc CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT = "cached-includep";
151
152     private static final int STATE_OUTSIDE = 0;
153     private static final int STATE_INCLUDE = 1;
154
155     /** The configuration of includexml */
156     protected Parameters configurationParameters;
157
158     /** The parameters for includexml */
159     protected SourceParameters resourceParameters;
160
161     /** The current state: STATE_ */
162     protected int state;
163
164     protected IncludeCacheManager cacheManager;
165
166     protected IncludeCacheManagerSession cachingSession;
167
168     protected boolean compiling;
169
170     protected IncludeXMLConsumer filter;
171
172     protected XMLSerializer recorder;
173
174     protected AttributesImpl JavaDoc srcAttributes = new AttributesImpl JavaDoc();
175
176     protected boolean supportCaching;
177
178     /** Remember the start time of the request for profiling */
179     protected long startTime;
180
181    /**
182      * Constructor
183      * Set the namespace
184      */

185     public CIncludeTransformer() {
186         this.defaultNamespaceURI = CINCLUDE_NAMESPACE_URI;
187     }
188
189     /**
190      * Setup the component.
191      */

192     public void setup(SourceResolver resolver, Map JavaDoc objectModel,
193                       String JavaDoc source, Parameters parameters)
194     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
195         super.setup(resolver, objectModel, source, parameters);
196         this.state = STATE_OUTSIDE;
197         if ( null != this.cacheManager ) {
198             this.cachingSession = this.cacheManager.getSession( this.parameters );
199         }
200         this.compiling = false;
201         this.supportCaching = parameters.getParameterAsBoolean("support-caching", false);
202         if (getLogger().isDebugEnabled()) {
203             getLogger().debug("Starting, session " + this.cachingSession);
204             this.startTime = System.currentTimeMillis();
205         }
206     }
207
208     /**
209      * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
210      */

211     public void service(ServiceManager manager) throws ServiceException {
212         super.service(manager);
213         if (this.manager.hasService(IncludeCacheManager.ROLE)) {
214             this.cacheManager = (IncludeCacheManager) this.manager.lookup(IncludeCacheManager.ROLE);
215         } else {
216             getLogger().warn("The cinclude transformer cannot find the IncludeCacheManager. " +
217                              "Therefore caching is turned off for the include transformer.");
218         }
219     }
220
221     /**
222      * @see org.apache.avalon.framework.activity.Disposable#dispose()
223      */

224     public void dispose() {
225         if (null != this.manager) {
226             this.manager.release(this.cacheManager);
227             this.manager = null;
228         }
229         super.dispose();
230     }
231
232     /**
233      * Recycle the component
234      */

235     public void recycle() {
236         if ( null != this.cachingSession ) {
237             this.cacheManager.terminateSession( this.cachingSession );
238         }
239         this.cachingSession = null;
240         if ( null != this.recorder) {
241             this.manager.release( this.recorder );
242             this.recorder = null;
243         }
244
245         this.configurationParameters = null;
246         this.resourceParameters = null;
247         if (getLogger().isDebugEnabled()) {
248             getLogger().debug("Finishing, time: " +
249                               (System.currentTimeMillis() - this.startTime));
250             this.startTime = 0;
251         }
252         this.filter = null;
253
254         super.recycle();
255     }
256
257     public void startTransformingElement(String JavaDoc uri, String JavaDoc name, String JavaDoc raw, Attributes JavaDoc attr)
258     throws ProcessingException ,IOException JavaDoc, SAXException JavaDoc {
259         // Element: include
260
if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
261             String JavaDoc stripRootValue = attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_STRIP_ROOT_ATTRIBUTE);
262             boolean stripRoot = StringUtils.equals(stripRootValue, "true");
263
264             processCIncludeElement(attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE),
265                                    attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE),
266                                    attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE),
267                                    attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE),
268                                    attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE),
269                                    stripRoot,
270                                    false);
271
272         // Element: includexml
273
} else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT)
274                    && this.state == STATE_OUTSIDE) {
275             this.state = STATE_INCLUDE;
276             String JavaDoc ignoreErrors = attr.getValue("", CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE);
277             if (ignoreErrors == null || ignoreErrors.length() == 0) {
278                 ignoreErrors = "false";
279             }
280             this.stack.push(BooleanUtils.toBooleanObject(this.ignoreEmptyCharacters));
281             this.stack.push(BooleanUtils.toBooleanObject(this.ignoreWhitespaces));
282             this.stack.push(ignoreErrors);
283
284             this.ignoreEmptyCharacters = false;
285             this.ignoreWhitespaces = true;
286
287         // target
288
} else if (name.equals(CINCLUDE_SRC_ELEMENT)
289                    && this.state == STATE_INCLUDE) {
290             this.startTextRecording();
291
292         // configparameters
293
} else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT)
294                    && this.state == STATE_INCLUDE) {
295             stack.push("end");
296
297         // parameters
298
} else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT)
299                    && this.state == STATE_INCLUDE) {
300             stack.push("end");
301
302         // parameter
303
} else if (name.equals(CINCLUDE_PARAMETER_ELEMENT)
304                    && this.state == STATE_INCLUDE) {
305
306         // parameter name
307
} else if (name.equals(CINCLUDE_NAME_ELEMENT)
308                    && this.state == STATE_INCLUDE) {
309             this.startTextRecording();
310
311         // parameter value
312
} else if (name.equals(CINCLUDE_VALUE_ELEMENT)
313                    && this.state == STATE_INCLUDE) {
314             this.startSerializedXMLRecording(XMLUtils.createPropertiesForXML(true));
315
316        } else if (name.equals(CINCLUDE_CACHED_INCLUDE_ELEMENT)) {
317
318            String JavaDoc src = processCIncludeElement(attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE),
319                                                null,
320                                                null,
321                                                null,
322                                                null,
323                                                false,
324                                                this.cacheManager != null);
325            if (this.compiling) {
326                this.srcAttributes.addAttribute("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE, CINCLUDE_SRC_ELEMENT, "CDATA", src);
327                super.startTransformingElement(uri,
328                                               CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT,
329                                               raw + "p",
330                                               this.srcAttributes);
331                this.srcAttributes.clear();
332            }
333         } else {
334             super.startTransformingElement(uri, name, raw, attr);
335         }
336     }
337
338     public void endTransformingElement(String JavaDoc uri, String JavaDoc name, String JavaDoc raw)
339     throws ProcessingException, IOException JavaDoc, SAXException JavaDoc {
340         if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
341             // do nothing
342
return;
343
344         } else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT)
345                    && this.state == STATE_INCLUDE) {
346             // Element: includexml
347

348             this.state = STATE_OUTSIDE;
349
350             final String JavaDoc resource = (String JavaDoc)stack.pop();
351
352             final boolean ignoreErrors = stack.pop().equals("true");
353
354             if (getLogger().isDebugEnabled()) {
355                 getLogger().debug("Processing includexml element: SRC=" + resource
356                               + ", ignoreErrors=" + ignoreErrors
357                               + ", configuration=" + this.configurationParameters
358                               + ", parameters=" + this.resourceParameters);
359             }
360             Source source = null;
361
362             try {
363                 source = SourceUtil.getSource(resource,
364                                               this.configurationParameters,
365                                               this.resourceParameters,
366                                               this.resolver);
367
368                 XMLSerializer serializer = null;
369                 XMLDeserializer deserializer = null;
370                 try {
371                     if ( ignoreErrors ) {
372                         serializer = (XMLSerializer) this.manager.lookup(XMLSerializer.ROLE);
373                         deserializer = (XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
374                         SourceUtil.toSAX(source, serializer, this.configurationParameters, true);
375                         deserializer.setConsumer( this.xmlConsumer );
376                         deserializer.deserialize( serializer.getSAXFragment() );
377                     } else {
378                         SourceUtil.toSAX(source, this.xmlConsumer, this.configurationParameters, true);
379                     }
380                 } catch (ProcessingException pe) {
381                     if (!ignoreErrors) throw pe;
382                 } catch (ServiceException ignore) {
383                 } finally {
384                     this.manager.release( serializer );
385                     this.manager.release( deserializer );
386                 }
387             } catch (SourceException se) {
388                 if (!ignoreErrors) throw SourceUtil.handle(se);
389             } catch (SAXException JavaDoc se) {
390                 if (!ignoreErrors) throw se;
391             } catch (IOException JavaDoc ioe) {
392                 if (!ignoreErrors) throw ioe;
393             } finally {
394                 this.resolver.release(source);
395             }
396
397             // restore values
398
this.ignoreWhitespaces = ((Boolean JavaDoc)stack.pop()).booleanValue();
399             this.ignoreEmptyCharacters = ((Boolean JavaDoc)stack.pop()).booleanValue();
400
401         // src element
402
} else if (name.equals(CINCLUDE_SRC_ELEMENT)
403                    && this.state == STATE_INCLUDE) {
404
405             this.stack.push(this.endTextRecording());
406
407         } else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT)
408                    && this.state == STATE_INCLUDE) {
409             this.resourceParameters = new SourceParameters();
410             // Now get the parameters off the stack
411
String JavaDoc label = (String JavaDoc)stack.pop();
412             String JavaDoc key = null;
413             String JavaDoc value = null;
414             while (!label.equals("end")) {
415                 if (label.equals("name")) key = (String JavaDoc)stack.pop();
416                 if (label.equals("value")) value = (String JavaDoc)stack.pop();
417                 if (key != null && value != null) {
418                     this.resourceParameters.setParameter(key, value);
419                     key = null;
420                     value = null;
421                 }
422                 label = (String JavaDoc)stack.pop();
423             }
424
425         } else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT) == true
426                  && this.state == STATE_INCLUDE) {
427             this.configurationParameters = new Parameters();
428             // Now get the parameters off the stack
429
String JavaDoc label = (String JavaDoc)stack.pop();
430             String JavaDoc key = null;
431             String JavaDoc value = null;
432             while (!label.equals("end")) {
433                 if (label.equals("name")) key = (String JavaDoc)stack.pop();
434                 if (label.equals("value")) value = (String JavaDoc)stack.pop();
435                 if (key != null && value != null) {
436                     this.configurationParameters.setParameter(key, value);
437                     key = null;
438                     value = null;
439                 }
440                 label = (String JavaDoc)stack.pop();
441             }
442
443         } else if (name.equals(CINCLUDE_PARAMETER_ELEMENT) == true
444                    && this.state == STATE_INCLUDE) {
445
446         } else if (name.equals(CINCLUDE_NAME_ELEMENT) == true
447                    && this.state == STATE_INCLUDE) {
448             stack.push(this.endTextRecording());
449             stack.push("name");
450
451         // parameter value
452
} else if (name.equals(CINCLUDE_VALUE_ELEMENT) == true
453                    && this.state == STATE_INCLUDE) {
454             stack.push(this.endSerializedXMLRecording());
455             stack.push("value");
456
457         } else if (name.equals(CINCLUDE_CACHED_INCLUDE_ELEMENT)) {
458             if (this.compiling) {
459                super.endTransformingElement(uri,
460                                             CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT,
461                                             raw + "p");
462             }
463             // do nothing else
464
} else {
465             super.endTransformingElement(uri, name, raw);
466         }
467     }
468
469     protected String JavaDoc processCIncludeElement(String JavaDoc src, String JavaDoc element,
470                                             String JavaDoc select, String JavaDoc ns, String JavaDoc prefix,
471                                             boolean stripRoot,
472                                             boolean cache)
473     throws SAXException JavaDoc, IOException JavaDoc {
474
475         if (src == null) {
476             throw new SAXException JavaDoc("Missing 'src' attribute on cinclude:include element");
477         }
478
479         if (element == null) element="";
480         if (select == null) select="";
481         if (ns == null) ns="";
482         if (prefix == null) prefix="";
483
484         if (getLogger().isDebugEnabled()) {
485             getLogger().debug("Processing include element: SRC=" + src
486                           + ", element=" + element
487                           + ", select=" + select
488                           + ", ns=" + ns
489                           + ", prefix=" + prefix
490                           + ", stripRoot=" + stripRoot
491                           + ", caching=" + cache);
492         }
493
494         if (cache) {
495             src = this.cacheManager.load(src, this.cachingSession);
496
497             if (this.cachingSession.isParallel() && !this.cachingSession.isPreemptive()) {
498                 if (!this.compiling) {
499                     this.compiling = true;
500                     this.startCompiledXMLRecording();
501                 }
502             } else {
503                 this.cacheManager.stream(src, this.cachingSession, this.filter);
504             }
505
506             return src;
507         }
508
509         // usual no caching stuff
510
if (!"".equals(element)) {
511             if (!ns.equals("")) {
512                 super.startPrefixMapping(prefix, ns);
513             }
514             super.startElement(ns,
515                                element,
516                                (!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element),
517                                XMLUtils.EMPTY_ATTRIBUTES);
518         }
519
520         Source source = null;
521         try {
522             source = this.resolver.resolveURI(src);
523
524             if (!"".equals(select)) {
525
526
527                 DOMParser parser = null;
528                 XPathProcessor processor = null;
529
530                 try {
531                     parser = (DOMParser)this.manager.lookup(DOMParser.ROLE);
532                     processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
533
534                     InputSource JavaDoc input = SourceUtil.getInputSource(source);
535
536                     Document JavaDoc document = parser.parseDocument(input);
537                     NodeList JavaDoc list = processor.selectNodeList(document, select);
538                     int length = list.getLength();
539                     for (int i=0; i<length; i++) {
540                           IncludeXMLConsumer.includeNode(list.item(i),
541                                                this.filter,
542                                                this.filter);
543                     }
544                 } finally {
545                     this.manager.release(parser);
546                     this.manager.release(processor);
547                 }
548             } else {
549                 String JavaDoc mimeType = null;
550                 if (null != this.configurationParameters) {
551                     mimeType = this.configurationParameters.getParameter("mime-type", mimeType);
552                 }
553                 if (this.compiling) {
554                     SourceUtil.toSAX(source, mimeType, new IncludeXMLConsumer(this.contentHandler, this.lexicalHandler));
555                 } else {
556                     this.filter.setIgnoreRootElement(stripRoot);
557                     SourceUtil.toSAX(source, mimeType, this.filter);
558                 }
559             }
560
561         } catch (SourceException se) {
562             throw new SAXException JavaDoc("Exception in CIncludeTransformer",se);
563         } catch (IOException JavaDoc e) {
564             throw new SAXException JavaDoc("CIncludeTransformer could not read resource", e);
565         } catch (ProcessingException e){
566             throw new SAXException JavaDoc("Exception in CIncludeTransformer",e);
567         } catch(ServiceException e) {
568             throw new SAXException JavaDoc(e);
569         } finally {
570             this.resolver.release(source);
571         }
572
573         if (!"".equals(element)) {
574             super.endElement(ns, element, (!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element));
575             if (!ns.equals("")) {
576                 super.endPrefixMapping(prefix);
577             }
578         }
579         return src;
580     }
581
582     /**
583      * Start recording of compiled xml.
584      * The incomming SAX events are recorded and a compiled representation
585      * is created. These events are not forwarded to the next component in
586      * the pipeline.
587      */

588     protected void startCompiledXMLRecording()
589     throws SAXException JavaDoc {
590         if (this.getLogger().isDebugEnabled()) {
591             this.getLogger().debug("BEGIN startCompiledXMLRecording");
592         }
593
594         try {
595             this.recorder = (XMLSerializer)this.manager.lookup(XMLSerializer.ROLE);
596
597             this.addRecorder(recorder);
598
599         } catch (ServiceException ce) {
600             throw new SAXException JavaDoc("Unable to lookup xml serializer for compiling xml.", ce);
601         }
602         if (this.getLogger().isDebugEnabled()) {
603            this.getLogger().debug("END startCompiledXMLRecording");
604         }
605     }
606
607     /**
608      * Stop recording of compiled XML.
609      * @return The compiled XML.
610      */

611     protected Object JavaDoc endCompiledXMLRecording()
612     throws SAXException JavaDoc {
613         if (this.getLogger().isDebugEnabled()) {
614             this.getLogger().debug("BEGIN endCompiledXMLRecording");
615         }
616
617         XMLSerializer recorder = (XMLSerializer)this.removeRecorder();
618         Object JavaDoc text = recorder.getSAXFragment();
619
620         if (this.getLogger().isDebugEnabled()) {
621             this.getLogger().debug("END endCompiledXMLRecording text="+text);
622         }
623         return text;
624     }
625
626     /**
627      * @see org.xml.sax.ContentHandler#startDocument()
628      */

629     public void startDocument() throws SAXException JavaDoc {
630         this.filter = new MyFilter(this.xmlConsumer,
631                                    this);
632         super.startDocument();
633     }
634
635     /**
636      * @see org.xml.sax.ContentHandler#endDocument()
637      */

638     public void endDocument() throws SAXException JavaDoc {
639         if ( this.compiling ) {
640             Object JavaDoc compiledXML = this.endCompiledXMLRecording();
641             XMLDeserializer deserializer = null;
642             try {
643                 deserializer = (XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
644                 deserializer.setConsumer(this.filter);
645                 deserializer.deserialize(compiledXML);
646             } catch (ServiceException ce) {
647                 throw new SAXException JavaDoc("Unable to lookup xml deserializer.", ce);
648             } finally {
649                 this.manager.release( deserializer );
650             }
651         }
652         super.endDocument();
653     }
654
655     /**
656      * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
657      */

658     public Serializable JavaDoc getKey() {
659         if (this.supportCaching
660             && null != this.cacheManager
661             && this.cachingSession.getExpires() > 0) {
662             return "1";
663         }
664         return null;
665     }
666
667     /**
668      * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
669      */

670     public SourceValidity getValidity() {
671         if (this.supportCaching
672             && null != this.cacheManager
673             && this.cachingSession.getExpires() > 0
674             && !this.cachingSession.isPurging()) {
675             return this.cachingSession.getExpiresValidity();
676         }
677         return null;
678     }
679
680 }
681
682 final class MyFilter extends IncludeXMLConsumer {
683
684     private final CIncludeTransformer transformer;
685
686     /**
687      * This filter class post-processes the parallel fetching
688      * @param consumer
689      */

690     public MyFilter(XMLConsumer consumer,
691                     CIncludeTransformer transformer) {
692         super(consumer);
693         this.transformer = transformer;
694     }
695
696     /**
697      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
698      */

699     public void endElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qName)
700     throws SAXException JavaDoc {
701         if (uri != null
702             && uri.equals(CIncludeTransformer.CINCLUDE_NAMESPACE_URI)
703             && local.equals(CIncludeTransformer.CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT)) {
704             // this is the placeholder element: do nothing
705
} else {
706             super.endElement(uri, local, qName);
707         }
708     }
709
710     /**
711      * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
712      */

713     public void startElement(String JavaDoc uri,
714                              String JavaDoc local,
715                              String JavaDoc qName,
716                              Attributes JavaDoc attr)
717     throws SAXException JavaDoc {
718         if (uri != null
719             && uri.equals(CIncludeTransformer.CINCLUDE_NAMESPACE_URI)
720             && local.equals(CIncludeTransformer.CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT)) {
721             // this is a placeholder
722
try {
723                 final String JavaDoc src = attr.getValue("",CIncludeTransformer.CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE);
724                 this.transformer.cacheManager.stream(src, this.transformer.cachingSession, this);
725             } catch (IOException JavaDoc ioe) {
726                 throw new SAXException JavaDoc("IOException", ioe);
727             }
728         } else {
729             super.startElement(uri, local, qName, attr);
730         }
731     }
732
733 }
734
Popular Tags