KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xpath > SourceTreeManager


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  * $Id: SourceTreeManager.java,v 1.34 2004/02/17 04:30:02 minchau Exp $
18  */

19 package org.apache.xpath;
20
21 import java.io.IOException JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 import javax.xml.transform.Source JavaDoc;
25 import javax.xml.transform.SourceLocator JavaDoc;
26 import javax.xml.transform.TransformerException JavaDoc;
27 import javax.xml.transform.URIResolver JavaDoc;
28 import javax.xml.transform.sax.SAXSource JavaDoc;
29 import javax.xml.transform.stream.StreamSource JavaDoc;
30
31 import org.apache.xml.dtm.DTM;
32 import org.apache.xml.utils.SystemIDResolver;
33
34 import org.xml.sax.XMLReader JavaDoc;
35 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
36
37 /**
38  * This class bottlenecks all management of source trees. The methods
39  * in this class should allow easy garbage collection of source
40  * trees (not yet!), and should centralize parsing for those source trees.
41  */

42 public class SourceTreeManager
43 {
44
45   /** Vector of SourceTree objects that this manager manages. */
46   private Vector JavaDoc m_sourceTree = new Vector JavaDoc();
47
48   /**
49    * Reset the list of SourceTree objects that this manager manages.
50    *
51    */

52   public void reset()
53   {
54     m_sourceTree = new Vector JavaDoc();
55   }
56
57   /** The TrAX URI resolver used to obtain source trees. */
58   URIResolver JavaDoc m_uriResolver;
59
60   /**
61    * Set an object that will be used to resolve URIs used in
62    * document(), etc.
63    * @param resolver An object that implements the URIResolver interface,
64    * or null.
65    */

66   public void setURIResolver(URIResolver JavaDoc resolver)
67   {
68     m_uriResolver = resolver;
69   }
70
71   /**
72    * Get the object that will be used to resolve URIs used in
73    * document(), etc.
74    * @return An object that implements the URIResolver interface,
75    * or null.
76    */

77   public URIResolver JavaDoc getURIResolver()
78   {
79     return m_uriResolver;
80   }
81
82   /**
83    * Given a document, find the URL associated with that document.
84    * @param owner Document that was previously processed by this liaison.
85    *
86    * @return The base URI of the owner argument.
87    */

88   public String JavaDoc findURIFromDoc(int owner)
89   {
90     int n = m_sourceTree.size();
91
92     for (int i = 0; i < n; i++)
93     {
94       SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);
95
96       if (owner == sTree.m_root)
97         return sTree.m_url;
98     }
99
100     return null;
101   }
102
103   /**
104    * This will be called by the processor when it encounters
105    * an xsl:include, xsl:import, or document() function.
106    *
107    * @param base The base URI that should be used.
108    * @param urlString Value from an xsl:import or xsl:include's href attribute,
109    * or a URI specified in the document() function.
110    *
111    * @return a Source that can be used to process the resource.
112    *
113    * @throws IOException
114    * @throws TransformerException
115    */

116   public Source JavaDoc resolveURI(
117           String JavaDoc base, String JavaDoc urlString, SourceLocator JavaDoc locator)
118             throws TransformerException JavaDoc, IOException JavaDoc
119   {
120
121     Source JavaDoc source = null;
122
123     if (null != m_uriResolver)
124     {
125       source = m_uriResolver.resolve(urlString, base);
126     }
127
128     if (null == source)
129     {
130       String JavaDoc uri = SystemIDResolver.getAbsoluteURI(urlString, base);
131
132       source = new StreamSource JavaDoc(uri);
133     }
134
135     return source;
136   }
137
138   /** JJK: Support <?xalan:doc_cache_off?> kluge in ElemForEach.
139    * TODO: This function is highly dangerous. Cache management must be improved.
140    *
141    * @param n The node to remove.
142    */

143   public void removeDocumentFromCache(int n)
144   {
145     if(DTM.NULL ==n)
146       return;
147     for(int i=m_sourceTree.size()-1;i>=0;--i)
148     {
149       SourceTree st=(SourceTree)m_sourceTree.elementAt(i);
150       if(st!=null && st.m_root==n)
151       {
152     m_sourceTree.removeElementAt(i);
153     return;
154       }
155     }
156   }
157   
158
159
160   /**
161    * Put the source tree root node in the document cache.
162    * TODO: This function needs to be a LOT more sophisticated.
163    *
164    * @param n The node to cache.
165    * @param source The Source object to cache.
166    */

167   public void putDocumentInCache(int n, Source JavaDoc source)
168   {
169
170     int cachedNode = getNode(source);
171
172     if (DTM.NULL != cachedNode)
173     {
174       if (!(cachedNode == n))
175         throw new RuntimeException JavaDoc(
176           "Programmer's Error! "
177           + "putDocumentInCache found reparse of doc: "
178           + source.getSystemId());
179       return;
180     }
181     if (null != source.getSystemId())
182     {
183       m_sourceTree.addElement(new SourceTree(n, source.getSystemId()));
184     }
185   }
186
187   /**
188    * Given a Source object, find the node associated with it.
189    *
190    * @param source The Source object to act as the key.
191    *
192    * @return The node that is associated with the Source, or null if not found.
193    */

194   public int getNode(Source JavaDoc source)
195   {
196
197 // if (source instanceof DOMSource)
198
// return ((DOMSource) source).getNode();
199

200     // TODO: Not sure if the BaseID is really the same thing as the ID.
201
String JavaDoc url = source.getSystemId();
202
203     if (null == url)
204       return DTM.NULL;
205
206     int n = m_sourceTree.size();
207
208     // System.out.println("getNode: "+n);
209
for (int i = 0; i < n; i++)
210     {
211       SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);
212
213       // System.out.println("getNode - url: "+url);
214
// System.out.println("getNode - sTree.m_url: "+sTree.m_url);
215
if (url.equals(sTree.m_url))
216         return sTree.m_root;
217     }
218
219     // System.out.println("getNode - returning: "+node);
220
return DTM.NULL;
221   }
222
223   /**
224    * Get the source tree from the a base URL and a URL string.
225    *
226    * @param base The base URI to use if the urlString is relative.
227    * @param urlString An absolute or relative URL string.
228    * @param locator The location of the caller, for diagnostic purposes.
229    *
230    * @return should be a non-null reference to the node identified by the
231    * base and urlString.
232    *
233    * @throws TransformerException If the URL can not resolve to a node.
234    */

235   public int getSourceTree(
236           String JavaDoc base, String JavaDoc urlString, SourceLocator JavaDoc locator, XPathContext xctxt)
237             throws TransformerException JavaDoc
238   {
239
240     // System.out.println("getSourceTree");
241
try
242     {
243       Source JavaDoc source = this.resolveURI(base, urlString, locator);
244
245       // System.out.println("getSourceTree - base: "+base+", urlString: "+urlString+", source: "+source.getSystemId());
246
return getSourceTree(source, locator, xctxt);
247     }
248     catch (IOException JavaDoc ioe)
249     {
250       throw new TransformerException JavaDoc(ioe.getMessage(), locator, ioe);
251     }
252
253     /* catch (TransformerException te)
254      {
255        throw new TransformerException(te.getMessage(), locator, te);
256      }*/

257   }
258
259   /**
260    * Get the source tree from the input source.
261    *
262    * @param source The Source object that should identify the desired node.
263    * @param locator The location of the caller, for diagnostic purposes.
264    *
265    * @return non-null reference to a node.
266    *
267    * @throws TransformerException if the Source argument can't be resolved to
268    * a node.
269    */

270   public int getSourceTree(Source JavaDoc source, SourceLocator JavaDoc locator, XPathContext xctxt)
271           throws TransformerException JavaDoc
272   {
273
274     int n = getNode(source);
275
276     if (DTM.NULL != n)
277       return n;
278
279     n = parseToNode(source, locator, xctxt);
280
281     if (DTM.NULL != n)
282       putDocumentInCache(n, source);
283
284     return n;
285   }
286
287   /**
288    * Try to create a DOM source tree from the input source.
289    *
290    * @param source The Source object that identifies the source node.
291    * @param locator The location of the caller, for diagnostic purposes.
292    *
293    * @return non-null reference to node identified by the source argument.
294    *
295    * @throws TransformerException if the source argument can not be resolved
296    * to a source node.
297    */

298   public int parseToNode(Source JavaDoc source, SourceLocator JavaDoc locator, XPathContext xctxt)
299           throws TransformerException JavaDoc
300   {
301
302     try
303     {
304       Object JavaDoc xowner = xctxt.getOwnerObject();
305       DTM dtm;
306       if(null != xowner && xowner instanceof org.apache.xml.dtm.DTMWSFilter)
307       {
308         dtm = xctxt.getDTM(source, false,
309                           (org.apache.xml.dtm.DTMWSFilter)xowner, false, true);
310       }
311       else
312       {
313         dtm = xctxt.getDTM(source, false, null, false, true);
314       }
315       return dtm.getDocument();
316     }
317     catch (Exception JavaDoc e)
318     {
319       //e.printStackTrace();
320
throw new TransformerException JavaDoc(e.getMessage(), locator, e);
321     }
322
323   }
324
325   /**
326    * This method returns the SAX2 parser to use with the InputSource
327    * obtained from this URI.
328    * It may return null if any SAX2-conformant XML parser can be used,
329    * or if getInputSource() will also return null. The parser must
330    * be free for use (i.e.
331    * not currently in use for another parse().
332    *
333    * @param inputSource The value returned from the URIResolver.
334    * @returns a SAX2 XMLReader to use to resolve the inputSource argument.
335    * @param locator The location of the original caller, for diagnostic purposes.
336    *
337    * @return non-null XMLReader reference ready to parse.
338    *
339    * @throws TransformerException if the reader can not be created.
340    */

341   public static XMLReader JavaDoc getXMLReader(Source JavaDoc inputSource, SourceLocator JavaDoc locator)
342           throws TransformerException JavaDoc
343   {
344
345     try
346     {
347       XMLReader JavaDoc reader = (inputSource instanceof SAXSource JavaDoc)
348                          ? ((SAXSource JavaDoc) inputSource).getXMLReader() : null;
349                          
350       if (null == reader)
351       {
352         try {
353           javax.xml.parsers.SAXParserFactory JavaDoc factory=
354               javax.xml.parsers.SAXParserFactory.newInstance();
355           factory.setNamespaceAware( true );
356           javax.xml.parsers.SAXParser JavaDoc jaxpParser=
357               factory.newSAXParser();
358           reader=jaxpParser.getXMLReader();
359           
360         } catch( javax.xml.parsers.ParserConfigurationException JavaDoc ex ) {
361           throw new org.xml.sax.SAXException JavaDoc( ex );
362         } catch( javax.xml.parsers.FactoryConfigurationError JavaDoc ex1 ) {
363             throw new org.xml.sax.SAXException JavaDoc( ex1.toString() );
364         } catch( NoSuchMethodError JavaDoc ex2 ) {
365         }
366         catch (AbstractMethodError JavaDoc ame){}
367         if(null == reader)
368           reader = XMLReaderFactory.createXMLReader();
369       }
370
371       try
372       {
373         reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
374                           true);
375       }
376       catch (org.xml.sax.SAXException JavaDoc se)
377       {
378
379         // What can we do?
380
// TODO: User diagnostics.
381
}
382
383       return reader;
384     }
385     catch (org.xml.sax.SAXException JavaDoc se)
386     {
387       throw new TransformerException JavaDoc(se.getMessage(), locator, se);
388     }
389   }
390 }
391
Popular Tags