OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / xml / xpath / XPathFactory.java
1 /* XPathFactory.java -- 
2    Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package javax.xml.xpath;
39
40 import java.io.BufferedReader;
41 import java.io.File;
42 import java.io.FileInputStream;
43 import java.io.InputStream;
44 import java.io.InputStreamReader;
45 import java.io.IOException;
46 import java.util.Properties;
47
48 /**
49  * Factory for creating XPath environments.
50  *
51  * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
52  * @since 1.3
53  */
54 public abstract class XPathFactory
55 {
56
57   /**
58    * The default property name according to the JAXP specification.
59    */
60   public static final String DEFAULT_PROPERTY_NAME =
61                 "javax.xml.xpath.XPathFactory";
62
63   /**
64    * The default object model URI.
65    */
66   public static final String DEFAULT_OBJECT_MODEL_URI =
67     XPathConstants.DOM_OBJECT_MODEL;
68
69   protected XPathFactory()
70   {
71   }
72
73   /**
74    * Returns a new factory for the default (DOM) object model.
75    */
76   public static final XPathFactory newInstance()
77   {
78     try
79       {
80         return newInstance(DEFAULT_OBJECT_MODEL_URI);
81       }
82     catch (XPathFactoryConfigurationException e)
83       {
84         throw new RuntimeException(e.getMessage());
85       }
86   }
87
88   /**
89    * Returns a new factory for the given object model URI.
90    * The implementation class to load is the first found in the following
91    * locations that advertises support for the given model URI:
92    * <ol>
93    * <li>the <code>javax.xml.xpath.XPathFactory</code> system property</li>
94    * <li>the above named property value in the
95    * <code><i>$JAVA_HOME</i>/lib/jaxp.properties</code> file</li>
96    * <li>the class name specified in the
97    * <code>META-INF/services/javax.xml.xpath.XPathFactory</code> system
98    * resource</li>
99    * <li>the default factory class</li>
100    * </ol>
101    * @param uri the object model URI
102    */
103   public static final XPathFactory newInstance(String uri)
104     throws XPathFactoryConfigurationException
105   {
106     ClassLoader loader = Thread.currentThread().getContextClassLoader();
107     if (loader == null)
108       {
109         loader = XPathFactory.class.getClassLoader();
110       }
111     String className = null;
112     int count = 0;
113     do
114       {
115         className = getFactoryClassName(loader, count++);
116         if (className != null)
117           {
118             try
119               {
120                 Class<?> t = (loader != null) ? loader.loadClass(className) :
121                   Class.forName(className);
122                 XPathFactory ret = (XPathFactory) t.newInstance();
123                 if (ret.isObjectModelSupported(uri))
124                   {
125                     return ret;
126                   }
127                 className = null;
128               }
129             catch (ClassNotFoundException e)
130               {
131                 className = null;
132               }
133             catch (Exception e)
134               {
135                 throw new XPathFactoryConfigurationException(e);
136               }
137           }
138       }
139     while (className == null && count < 4);
140     String msg = "no factories with support for " + uri;
141     throw new XPathFactoryConfigurationException(msg);
142   }
143
144   private static String getFactoryClassName(ClassLoader loader, int attempt)
145   {
146     final String propertyName = DEFAULT_PROPERTY_NAME;
147     switch (attempt)
148       {
149         case 0:
150           return System.getProperty(propertyName);
151         case 1:
152           try
153             {
154               File file = new File(System.getProperty("java.home"));
155               file = new File(file, "lib");
156               file = new File(file, "jaxp.properties");
157               InputStream in = new FileInputStream(file);
158               Properties props = new Properties();
159               props.load(in);
160               in.close();
161               return props.getProperty(propertyName);
162             }
163           catch (IOException e)
164             {
165               return null;
166             }
167         case 2:
168           try
169             {
170               String serviceKey = "/META-INF/services/" + propertyName;
171               InputStream in = (loader != null) ?
172                 loader.getResourceAsStream(serviceKey) :
173                 XPathFactory.class.getResourceAsStream(serviceKey);
174               if (in != null)
175                 {
176                   BufferedReader r =
177                     new BufferedReader(new InputStreamReader(in));
178                   String ret = r.readLine();
179                   r.close();
180                   return ret;
181                 }
182             }
183           catch (IOException e)
184             {
185             }
186           return null;
187         case 3:
188           return "gnu.xml.xpath.XPathFactoryImpl";
189         default:
190           return null;
191       }
192   }
193
194   /**
195    * Indicates whether the specified object model URI is supported by
196    * this factory.
197    */
198   public abstract boolean isObjectModelSupported(String objectModel);
199
200   /**
201    * Sets the state of the named feature.
202    */
203   public abstract void setFeature(String name, boolean value)
204     throws XPathFactoryConfigurationException;
205
206   /**
207    * Returns the state of the named feature.
208    */
209   public abstract boolean getFeature(String name)
210     throws XPathFactoryConfigurationException;
211
212   /**
213    * Sets the XPath variable resolver calback.
214    */
215   public abstract void setXPathVariableResolver(XPathVariableResolver resolver);
216
217   /**
218    * Sets the XPath extension function resolver calback.
219    */
220   public abstract void setXPathFunctionResolver(XPathFunctionResolver resolver);
221
222   /**
223    * Returns a new XPath evaluation environment.
224    */
225   public abstract XPath newXPath();
226   
227 }