KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > xpointer > ElementPathPart


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.components.xpointer;
17
18 import org.xml.sax.SAXException JavaDoc;
19 import org.xml.sax.Attributes JavaDoc;
20 import org.xml.sax.Locator JavaDoc;
21 import org.apache.cocoon.xml.AbstractXMLPipe;
22 import org.apache.cocoon.components.source.SourceUtil;
23 import org.apache.cocoon.ProcessingException;
24
25 import java.util.StringTokenizer JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.io.IOException JavaDoc;
28
29 /**
30  * A custom XPointer scheme that allows to include the content of a specific element without
31  * building a DOM. The element must be specified using an absolute path reference such as
32  * <tt>/html/body</tt>. Namespace prefixes within these element names are supported.
33  *
34  * <p>This xpointer scheme will always be succesful (thus any further xpointer parts will
35  * never be executed).
36  *
37  * <p>The scheme name for this XPointer scheme is 'elementpath' and its namespace is
38  * http://apache.org/cocoon/xpointer.
39  *
40  * <p>See the samples for a usage example.
41  */

42 public class ElementPathPart implements PointerPart {
43     private String JavaDoc expression;
44
45     public ElementPathPart(String JavaDoc expression) {
46         this.expression = expression;
47     }
48
49     public boolean process(XPointerContext xpointerContext) throws SAXException JavaDoc {
50         PathInclusionPipe pipe = new PathInclusionPipe(expression, xpointerContext);
51         pipe.setConsumer(xpointerContext.getXmlConsumer());
52         try {
53             SourceUtil.toSAX(xpointerContext.getSource(), pipe);
54         } catch (IOException JavaDoc e) {
55             throw new SAXException JavaDoc("Exception while trying to XInclude data: " + e.getMessage(), e);
56         } catch (ProcessingException e) {
57             throw new SAXException JavaDoc("Exception while trying to XInclude data: " + e.getMessage(), e);
58         }
59         return true;
60     }
61
62     public static class PathInclusionPipe extends AbstractXMLPipe {
63         /** The QNames that must be matched before inclusion can start. */
64         private QName[] elementPath;
65         /** The current element nesting level. */
66         private int level;
67         /** Should we currently be including? */
68         private boolean include;
69         /** The element nesting level since we started inclusion, used to know when to stop inclusion. */
70         private int includeLevel;
71
72         /** The element nesting level that should currently be matched. */
73         private int levelToMatch;
74         private boolean done;
75
76         public PathInclusionPipe(String JavaDoc expression, XPointerContext xpointerContext) throws SAXException JavaDoc {
77             // parse the expression to an array of QName objects
78
ArrayList JavaDoc path = new ArrayList JavaDoc();
79             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(expression, "/");
80             while (tokenizer.hasMoreTokens()) {
81                 String JavaDoc token = tokenizer.nextToken();
82                 try {
83                     path.add(QName.parse(token, xpointerContext));
84                 } catch (SAXException JavaDoc e) {
85                     throw new SAXException JavaDoc("Error in element path xpointer expression \"" + expression + "\": " + e.getMessage());
86                 }
87             }
88             if (path.size() < 1)
89                 throw new SAXException JavaDoc("Invalid element path xpointer expression \"" + expression + "\".");
90
91             this.elementPath = (QName[])path.toArray(new QName[path.size()]);
92             this.level = -1;
93             this.include = false;
94             this.levelToMatch = 0;
95             this.done = false;
96         }
97
98         public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc raw, Attributes JavaDoc a)
99                 throws SAXException JavaDoc {
100             level++;
101
102             if (include) {
103                 super.startElement(namespaceURI, localName, raw, a);
104                 return;
105             }
106
107             if (!done && level == levelToMatch && elementPath[level].matches(namespaceURI, localName)) {
108                 levelToMatch++;
109                 if (levelToMatch == elementPath.length) {
110                     include = true;
111                     done = true;
112                     includeLevel = level;
113                 }
114             }
115         }
116
117         public void endElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw)
118                 throws SAXException JavaDoc {
119             if (include && level == includeLevel)
120                 include = false;
121
122             if (include)
123                 super.endElement(uri, loc, raw);
124
125             level--;
126         }
127
128         public void setDocumentLocator(Locator JavaDoc locator) {
129             if (include)
130                 super.setDocumentLocator(locator);
131         }
132
133         public void startDocument()
134                 throws SAXException JavaDoc {
135             if (include)
136                 super.startDocument();
137         }
138
139         public void endDocument()
140                 throws SAXException JavaDoc {
141             if (include)
142                 super.endDocument();
143         }
144
145         public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
146                 throws SAXException JavaDoc {
147             // let namespace prefix alway through
148
super.startPrefixMapping(prefix, uri);
149         }
150
151         public void endPrefixMapping(String JavaDoc prefix)
152                 throws SAXException JavaDoc {
153             // let namespace prefix alway through
154
super.endPrefixMapping(prefix);
155         }
156
157         public void characters(char c[], int start, int len)
158                 throws SAXException JavaDoc {
159             if (include)
160                 super.characters(c, start, len);
161         }
162
163         public void ignorableWhitespace(char c[], int start, int len)
164                 throws SAXException JavaDoc {
165             if (include)
166                 super.ignorableWhitespace(c, start, len);
167         }
168
169         public void processingInstruction(String JavaDoc target, String JavaDoc data)
170                 throws SAXException JavaDoc {
171             if (include)
172                 super.processingInstruction(target, data);
173         }
174
175         public void skippedEntity(String JavaDoc name)
176                 throws SAXException JavaDoc {
177             if (include)
178                 super.skippedEntity(name);
179         }
180
181         public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
182                 throws SAXException JavaDoc {
183             if (include)
184                 super.startDTD(name, publicId, systemId);
185         }
186
187         public void endDTD()
188                 throws SAXException JavaDoc {
189             if (include)
190                 super.endDTD();
191         }
192
193         public void startEntity(String JavaDoc name)
194                 throws SAXException JavaDoc {
195             if (include)
196                 super.startEntity(name);
197         }
198
199         public void endEntity(String JavaDoc name)
200                 throws SAXException JavaDoc {
201             if (include)
202                 super.endEntity(name);
203         }
204
205         public void startCDATA()
206                 throws SAXException JavaDoc {
207             if (include)
208                 super.startCDATA();
209         }
210
211         public void endCDATA()
212                 throws SAXException JavaDoc {
213             if (include)
214                 super.endCDATA();
215         }
216
217         public void comment(char ch[], int start, int len)
218                 throws SAXException JavaDoc {
219             if (include)
220                 super.comment(ch, start, len);
221         }
222
223         public static class QName {
224             private String JavaDoc namespaceURI;
225             private String JavaDoc localName;
226
227             public QName(String JavaDoc namespaceURI, String JavaDoc localName) {
228                 this.namespaceURI = namespaceURI;
229                 this.localName = localName;
230             }
231
232             public static QName parse(String JavaDoc qName, XPointerContext xpointerContext) throws SAXException JavaDoc {
233                 int pos = qName.indexOf(':');
234                 if (pos > 0) {
235                     String JavaDoc prefix = qName.substring(0, pos);
236                     String JavaDoc localName = qName.substring(pos + 1);
237                     String JavaDoc namespaceURI = xpointerContext.prefixToNamespace(prefix);
238                     if (namespaceURI == null)
239                         throw new SAXException JavaDoc("Namespace prefix \"" + prefix + "\" not declared.");
240                     return new QName(prefix, localName);
241                 }
242                 return new QName("", qName);
243             }
244
245             public String JavaDoc getNamespaceURI() {
246                 return namespaceURI;
247             }
248
249             public String JavaDoc getLocalName() {
250                 return localName;
251             }
252
253             public boolean matches(String JavaDoc namespaceURI, String JavaDoc localName) {
254                 return this.localName.equals(localName) && this.namespaceURI.equals(namespaceURI);
255             }
256         }
257     }
258 }
259
Popular Tags