Source for javax.xml.xpath.XPathFactory

   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: }