KickJava   Java API By Example, From Geeks To Geeks.

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


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.transformation;
17
18 import java.io.IOException JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.avalon.framework.parameters.Parameters;
24
25 import org.apache.cocoon.ProcessingException;
26 import org.apache.cocoon.environment.SourceResolver;
27 import org.apache.cocoon.xml.dom.DOMBuilder;
28
29 import org.w3c.dom.Document JavaDoc;
30 import org.xml.sax.Attributes JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32
33
34 /**
35  * This transformer sieves an incoming stream of xml
36  * and feeds a DOMBuilder with it.
37  *
38  * @author <a HREF="mailto:paul@luminas.co.uk">Paul Russell</a>
39  * @author <a HREF="mailto:haul@apache.org">Christian Haul</a>
40  * @version CVS $Id: AbstractExtractionTransformer.java 30932 2004-07-29 17:35:38Z vgritsenko $
41  */

42 abstract public class AbstractExtractionTransformer extends AbstractTransformer {
43
44     protected DOMBuilder currentBuilder;
45
46     private Map JavaDoc prefixMap;
47
48     protected int extractLevel;
49
50
51     /** Setup the transformer. */
52     public void setup(SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src, Parameters parameters)
53             throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
54         extractLevel = 0;
55         prefixMap = new HashMap JavaDoc();
56     }
57
58     public void recycle() {
59         this.extractLevel = 0;
60         this.currentBuilder = null;
61         this.prefixMap = null;
62         super.recycle();
63     }
64
65
66     /**
67      * Begin the scope of a prefix-URI Namespace mapping.
68      *
69      * @param prefix The Namespace prefix being declared.
70      * @param uri The Namespace URI the prefix is mapped to.
71      */

72     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
73     throws SAXException JavaDoc {
74         if (extractLevel == 0) {
75             super.startPrefixMapping(prefix,uri);
76             prefixMap.put(prefix,uri);
77         } else {
78             this.currentBuilder.startPrefixMapping(prefix,uri);
79         }
80     }
81
82     /**
83      * End the scope of a prefix-URI mapping.
84      *
85      * @param prefix The prefix that was being mapping.
86      */

87     public void endPrefixMapping(String JavaDoc prefix)
88     throws SAXException JavaDoc {
89         if (extractLevel == 0) {
90             super.endPrefixMapping(prefix);
91             prefixMap.remove(prefix);
92         } else {
93             this.currentBuilder.endPrefixMapping(prefix);
94         }
95     }
96
97
98     /**
99      * Receive notification of the beginning of an element. Uses
100      * startExtraction to determine whether to start
101      * extracting. Nested triggering tags result in only one document.
102      * * startExtractedDocument with the first node of the extracted
103      * Document.
104      *
105      * @param uri The Namespace URI, or the empty string if the element has no
106      * Namespace URI or if Namespace
107      * processing is not being performed.
108      * @param loc The local name (without prefix), or the empty string if
109      * Namespace processing is not being performed.
110      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
111      * raw names are not available.
112      * @param a The attributes attached to the element. If there are no
113      * attributes, it shall be an empty Attributes object.
114      */

115     public void startElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw, Attributes JavaDoc a) throws SAXException JavaDoc {
116         if (!startExtracting(uri, loc, raw, a)) {
117
118             if (extractLevel == 0) {
119                 super.startElement(uri,loc,raw,a);
120             } else {
121                 this.currentBuilder.startElement(uri,loc,raw,a);
122             }
123
124         } else {
125
126             extractLevel++;
127             if (this.getLogger().isDebugEnabled()) {
128                 getLogger().debug("extractLevel now " + extractLevel + ".");
129             }
130
131             if (extractLevel != 1) {
132                 this.currentBuilder.startElement(uri,loc,raw,a);
133             } else {
134
135                 // setup new document
136
this.currentBuilder = new DOMBuilder();
137                 this.currentBuilder.startDocument();
138                 // setup namespaces
139
Iterator JavaDoc itt = prefixMap.entrySet().iterator();
140                 while (itt.hasNext()) {
141                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc)itt.next();
142                     this.currentBuilder.startPrefixMapping(
143                         (String JavaDoc)entry.getKey(),
144                         (String JavaDoc)entry.getValue()
145                     );
146                 }
147                 // start root node
148
startExtractingDocument(uri, loc, raw, a);
149
150             }
151
152         }
153     }
154
155
156     /**
157      * Receive notification of the end of an element. Uses
158      * endExtraction to determine whether to stop extracting or
159      * not. Calls endExtractedDocument with the extracted document.
160      *
161      * @param uri The Namespace URI, or the empty string if the element has no
162      * Namespace URI or if Namespace
163      * processing is not being performed.
164      * @param loc The local name (without prefix), or the empty string if
165      * Namespace processing is not being performed.
166      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
167      * raw names are not available.
168      */

169     public void endElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw)
170     throws SAXException JavaDoc {
171         if (extractLevel == 0) {
172             super.endElement(uri,loc,raw);
173         } else {
174             if (endExtracting(uri, loc, raw)) {
175                 extractLevel--;
176                 if (this.getLogger().isDebugEnabled()) {
177                     getLogger().debug("extractLevel now " + extractLevel + ".");
178                 }
179
180                 if (extractLevel != 0) {
181                     this.currentBuilder.endElement(uri,loc,raw);
182                 } else {
183
184                     // end root element
185
endExtractingDocument(uri, loc, raw);
186                     // finish building the document. remove existing prefix mappings.
187
Iterator JavaDoc itt = prefixMap.entrySet().iterator();
188                     while (itt.hasNext()) {
189                         Map.Entry JavaDoc entry = (Map.Entry JavaDoc) itt.next();
190                         this.currentBuilder.endPrefixMapping(
191                             (String JavaDoc)entry.getKey()
192                         );
193                     }
194                     this.currentBuilder.endDocument();
195
196                     handleExtractedDocument(this.currentBuilder.getDocument());
197
198                     if (this.getLogger().isDebugEnabled()) {
199                         getLogger().debug("Stored document.");
200                     }
201
202                 }
203             } else {
204                 this.currentBuilder.endElement(uri, loc, raw);
205             }
206         }
207     }
208
209     /**
210      * Receive notification of character data.
211      *
212      * @param c The characters from the XML document.
213      * @param start The start position in the array.
214      * @param len The number of characters to read from the array.
215      */

216     public void characters(char c[], int start, int len)
217     throws SAXException JavaDoc {
218         if (extractLevel == 0) {
219             super.characters(c,start,len);
220         } else {
221             this.currentBuilder.characters(c,start,len);
222         }
223     }
224
225     /**
226      * Receive notification of ignorable whitespace in element content.
227      *
228      * @param c The characters from the XML document.
229      * @param start The start position in the array.
230      * @param len The number of characters to read from the array.
231      */

232     public void ignorableWhitespace(char c[], int start, int len)
233     throws SAXException JavaDoc {
234         if (extractLevel == 0) {
235             super.ignorableWhitespace(c,start,len);
236         } else {
237             this.currentBuilder.ignorableWhitespace(c,start,len);
238         }
239     }
240
241     /**
242      * Receive notification of a processing instruction.
243      *
244      * @param target The processing instruction target.
245      * @param data The processing instruction data, or null if none was
246      * supplied.
247      */

248     public void processingInstruction(String JavaDoc target, String JavaDoc data)
249     throws SAXException JavaDoc {
250         if (extractLevel == 0) {
251             super.processingInstruction(target,data);
252         } else {
253             this.currentBuilder.processingInstruction(target,data);
254         }
255     }
256
257     /**
258      * Receive notification of a skipped entity.
259      *
260      * @param name The name of the skipped entity. If it is a parameter
261      * entity, the name will begin with '%'.
262      */

263     public void skippedEntity(String JavaDoc name)
264     throws SAXException JavaDoc {
265         if (extractLevel == 0) {
266             super.skippedEntity(name);
267         } else {
268             this.currentBuilder.skippedEntity(name);
269         }
270     }
271
272     /**
273      * Report the start of DTD declarations, if any.
274      *
275      * @param name The document type name.
276      * @param publicId The declared public identifier for the external DTD
277      * subset, or null if none was declared.
278      * @param systemId The declared system identifier for the external DTD
279      * subset, or null if none was declared.
280      */

281     public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
282     throws SAXException JavaDoc {
283         if (extractLevel == 0) {
284             super.startDTD(name,publicId,systemId);
285         } else {
286             throw new SAXException JavaDoc(
287                 "Recieved startDTD after beginning fragment extraction process."
288             );
289         }
290     }
291
292     /**
293      * Report the end of DTD declarations.
294      */

295     public void endDTD()
296     throws SAXException JavaDoc {
297         if (extractLevel == 0) {
298             super.endDTD();
299         } else {
300             throw new SAXException JavaDoc(
301                 "Recieved endDTD after beginning fragment extraction process."
302             );
303         }
304     }
305
306     /**
307      * Report the beginning of an entity.
308      *
309      * @param name The name of the entity. If it is a parameter entity, the
310      * name will begin with '%'.
311      */

312     public void startEntity(String JavaDoc name)
313     throws SAXException JavaDoc {
314         if (extractLevel == 0) {
315             super.startEntity(name);
316         } else {
317             this.currentBuilder.startEntity(name);
318         }
319     }
320
321     /**
322      * Report the end of an entity.
323      *
324      * @param name The name of the entity that is ending.
325      */

326     public void endEntity(String JavaDoc name)
327     throws SAXException JavaDoc {
328         if (extractLevel == 0) {
329             super.endEntity(name);
330         } else {
331             this.currentBuilder.endEntity(name);
332         }
333     }
334
335     /**
336      * Report the start of a CDATA section.
337      */

338     public void startCDATA()
339     throws SAXException JavaDoc {
340         if (extractLevel == 0) {
341             super.startCDATA();
342         } else {
343             this.currentBuilder.startCDATA();
344         }
345     }
346
347     /**
348      * Report the end of a CDATA section.
349      */

350     public void endCDATA()
351     throws SAXException JavaDoc {
352         if (extractLevel == 0) {
353             super.endCDATA();
354         } else {
355             this.currentBuilder.endCDATA();
356         }
357     }
358
359     /**
360      * Report an XML comment anywhere in the document.
361      *
362      * @param ch An array holding the characters in the comment.
363      * @param start The starting position in the array.
364      * @param len The number of characters to use from the array.
365      */

366     public void comment(char ch[], int start, int len)
367     throws SAXException JavaDoc {
368         if (extractLevel == 0) {
369             super.comment(ch,start,len);
370         } else {
371             this.currentBuilder.comment(ch,start,len);
372         }
373     }
374
375
376
377     /**
378      * Receive notification of the beginning of an element and signal extraction start.
379      *
380      * @param uri The Namespace URI, or the empty string if the element has no
381      * Namespace URI or if Namespace
382      * processing is not being performed.
383      * @param loc The local name (without prefix), or the empty string if
384      * Namespace processing is not being performed.
385      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
386      * raw names are not available.
387      * @param a The attributes attached to the element. If there are no
388      * attributes, it shall be an empty Attributes object.
389      * @return a <code>boolean</code> value to signal to start extracting
390      */

391     abstract boolean startExtracting(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw, Attributes JavaDoc a);
392
393     /**
394      * Receive notification of the beginning of the extracted Document. Per default send
395      * startElement message to document builder. Override if necessary. Must override
396      * {@link #endExtractingDocument(String, String, String)} as well.
397      *
398      * @param uri The Namespace URI, or the empty string if the element has no
399      * Namespace URI or if Namespace
400      * processing is not being performed.
401      * @param loc The local name (without prefix), or the empty string if
402      * Namespace processing is not being performed.
403      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
404      * raw names are not available.
405      * @param a The attributes attached to the element. If there are no
406      * attributes, it shall be an empty Attributes object.
407      */

408     public void startExtractingDocument(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw, Attributes JavaDoc a) throws SAXException JavaDoc{
409         this.currentBuilder.startElement(uri,loc,raw,a);
410     }
411
412     /**
413      * Receive notification of the end of an element and signal extraction end.
414      *
415      * @param uri The Namespace URI, or the empty string if the element has no
416      * Namespace URI or if Namespace
417      * processing is not being performed.
418      * @param loc The local name (without prefix), or the empty string if
419      * Namespace processing is not being performed.
420      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
421      * @return a <code>boolean</code> value to signal to stop extracting
422      */

423     abstract boolean endExtracting(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw);
424
425     /**
426      * Receive notification of the end of the extracted Document. Per default,
427      * send endElement message to document builder. Override if necessary.
428      * Must override
429      * {@link #startExtractingDocument(String, String, String, Attributes)}
430      * as well.
431      *
432      * @param uri The Namespace URI, or the empty string if the element has no
433      * Namespace URI or if Namespace
434      * processing is not being performed.
435      * @param loc The local name (without prefix), or the empty string if
436      * Namespace processing is not being performed.
437      * @param raw The raw XML 1.0 name (with prefix), or the empty string if
438      * raw names are not available.
439      */

440     public void endExtractingDocument(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw) throws SAXException JavaDoc{
441         this.currentBuilder.endElement(uri,loc,raw);
442     }
443
444     /**
445      * Receive notification of the end of the extracted Document.
446      *
447      * @param doc a <code>Document</code> value
448      */

449     abstract void handleExtractedDocument(Document JavaDoc doc);
450     
451
452 }
453
Popular Tags