1 /*
   2  * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Copyright 1999-2004 The Apache Software Foundation.
   6  *
   7  * Licensed under the Apache License, Version 2.0 (the "License");
   8  * you may not use this file except in compliance with the License.
   9  * You may obtain a copy of the License at
  10  *
  11  *     http://www.apache.org/licenses/LICENSE-2.0
  12  *
  13  * Unless required by applicable law or agreed to in writing, software
  14  * distributed under the License is distributed on an "AS IS" BASIS,
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16  * See the License for the specific language governing permissions and
  17  * limitations under the License.
  18  */
  19 // $Id: XPathFactoryImpl.java,v 1.2 2005/08/16 22:41:13 jeffsuttor Exp $
  20 
  21 package com.sun.org.apache.xpath.internal.jaxp;
  22 
  23 import com.sun.org.apache.xalan.internal.XalanConstants;
  24 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
  25 import com.sun.org.apache.xalan.internal.res.XSLMessages;
  26 
  27 import javax.xml.XMLConstants;
  28 import javax.xml.xpath.XPathFactory;
  29 import javax.xml.xpath.XPathFactoryConfigurationException;
  30 import javax.xml.xpath.XPathFunctionResolver;
  31 import javax.xml.xpath.XPathVariableResolver;
  32 import jdk.xml.internal.JdkXmlFeatures;
  33 
  34 /**
  35  * The XPathFactory builds XPaths.
  36  *
  37  * @version $Revision: 1.11 $
  38  * @author  Ramesh Mandava
  39  */
  40 public  class XPathFactoryImpl extends XPathFactory {
  41 
  42         /**
  43          * <p>Name of class as a constant to use for debugging.</p>
  44          */
  45         private static final String CLASS_NAME = "XPathFactoryImpl";
  46 
  47         /**
  48          *<p>XPathFunctionResolver for this XPathFactory and created XPaths.</p>
  49          */
  50         private XPathFunctionResolver xPathFunctionResolver = null;
  51 
  52         /**
  53          * <p>XPathVariableResolver for this XPathFactory and created XPaths</p>
  54          */
  55         private XPathVariableResolver xPathVariableResolver = null;
  56 
  57         /**
  58          * <p>State of secure processing feature.</p>
  59          */
  60         private boolean _isNotSecureProcessing = true;
  61         /**
  62          * <p>State of secure mode.</p>
  63          */
  64         private boolean _isSecureMode = false;
  65 
  66         /**
  67          * XML Features manager
  68          */
  69         private final JdkXmlFeatures _featureManager;
  70 
  71         /**
  72          * javax.xml.xpath.XPathFactory implementation.
  73          */
  74 
  75         public XPathFactoryImpl() {
  76             if (System.getSecurityManager() != null) {
  77                 _isSecureMode = true;
  78                 _isNotSecureProcessing = false;
  79             }
  80             _featureManager = new JdkXmlFeatures(!_isNotSecureProcessing);
  81         }
  82         /**
  83          * <p>Is specified object model supported by this
  84          * <code>XPathFactory</code>?</p>
  85          *
  86          * @param objectModel Specifies the object model which the returned
  87          * <code>XPathFactory</code> will understand.
  88          *
  89          * @return <code>true</code> if <code>XPathFactory</code> supports
  90          * <code>objectModel</code>, else <code>false</code>.
  91          *
  92          * @throws NullPointerException If <code>objectModel</code> is <code>null</code>.
  93          * @throws IllegalArgumentException If <code>objectModel.length() == 0</code>.
  94          */
  95         public boolean isObjectModelSupported(String objectModel) {
  96 
  97             if (objectModel == null) {
  98                 String fmsg = XSLMessages.createXPATHMessage(
  99                         XPATHErrorResources.ER_OBJECT_MODEL_NULL,
 100                         new Object[] { this.getClass().getName() } );
 101 
 102                 throw new NullPointerException( fmsg );
 103             }
 104 
 105             if (objectModel.length() == 0) {
 106                 String fmsg = XSLMessages.createXPATHMessage(
 107                         XPATHErrorResources.ER_OBJECT_MODEL_EMPTY,
 108                         new Object[] { this.getClass().getName() } );
 109                 throw new IllegalArgumentException( fmsg );
 110             }
 111 
 112             // know how to support default object model, W3C DOM
 113             if (objectModel.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) {
 114                 return true;
 115             }
 116 
 117             // don't know how to support anything else
 118             return false;
 119         }
 120 
 121         /**
 122          * <p>Returns a new <code>XPath</code> object using the underlying
 123          * object model determined when the factory was instantiated.</p>
 124          *
 125          * @return New <code>XPath</code>
 126          */
 127         public javax.xml.xpath.XPath newXPath() {
 128             return new com.sun.org.apache.xpath.internal.jaxp.XPathImpl(
 129                     xPathVariableResolver, xPathFunctionResolver,
 130                     !_isNotSecureProcessing, _featureManager );
 131         }
 132 
 133         /**
 134          * <p>Set a feature for this <code>XPathFactory</code> and
 135          * <code>XPath</code>s created by this factory.</p>
 136          *
 137          * <p>
 138          * Feature names are fully qualified {@link java.net.URI}s.
 139          * Implementations may define their own features.
 140          * An {@link XPathFactoryConfigurationException} is thrown if this
 141          * <code>XPathFactory</code> or the <code>XPath</code>s
 142          *  it creates cannot support the feature.
 143          * It is possible for an <code>XPathFactory</code> to expose a feature
 144          * value but be unable to change its state.
 145          * </p>
 146          *
 147          * <p>See {@link javax.xml.xpath.XPathFactory} for full documentation
 148          * of specific features.</p>
 149          *
 150          * @param name Feature name.
 151          * @param value Is feature state <code>true</code> or <code>false</code>.
 152          *
 153          * @throws XPathFactoryConfigurationException if this
 154          * <code>XPathFactory</code> or the <code>XPath</code>s
 155          *   it creates cannot support this feature.
 156          * @throws NullPointerException if <code>name</code> is
 157          * <code>null</code>.
 158          */
 159         public void setFeature(String name, boolean value)
 160                 throws XPathFactoryConfigurationException {
 161 
 162             // feature name cannot be null
 163             if (name == null) {
 164                 String fmsg = XSLMessages.createXPATHMessage(
 165                         XPATHErrorResources.ER_FEATURE_NAME_NULL,
 166                         new Object[] { CLASS_NAME, new Boolean( value) } );
 167                 throw new NullPointerException( fmsg );
 168              }
 169 
 170             // secure processing?
 171             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 172                 if ((_isSecureMode) && (!value)) {
 173                     String fmsg = XSLMessages.createXPATHMessage(
 174                             XPATHErrorResources.ER_SECUREPROCESSING_FEATURE,
 175                             new Object[] { name, CLASS_NAME, new Boolean(value) } );
 176                     throw new XPathFactoryConfigurationException( fmsg );
 177                 }
 178 
 179                 _isNotSecureProcessing = !value;
 180                 if (value && _featureManager != null) {
 181                     _featureManager.setFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION,
 182                             JdkXmlFeatures.State.FSP, false);
 183                 }
 184 
 185                 // all done processing feature
 186                 return;
 187             }
 188             if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
 189                 // for compatibility, in secure mode, useServicesMechanism is determined by the constructor
 190                 if (_isSecureMode)
 191                     return;
 192             }
 193 
 194             if (_featureManager != null &&
 195                     _featureManager.setFeature(name, JdkXmlFeatures.State.APIPROPERTY, value)) {
 196                 return;
 197             }
 198 
 199             // unknown feature
 200             String fmsg = XSLMessages.createXPATHMessage(
 201                     XPATHErrorResources.ER_FEATURE_UNKNOWN,
 202                     new Object[] { name, CLASS_NAME, value} );
 203             throw new XPathFactoryConfigurationException( fmsg );
 204         }
 205 
 206         /**
 207          * <p>Get the state of the named feature.</p>
 208          *
 209          * <p>
 210          * Feature names are fully qualified {@link java.net.URI}s.
 211          * Implementations may define their own features.
 212          * An {@link XPathFactoryConfigurationException} is thrown if this
 213          * <code>XPathFactory</code> or the <code>XPath</code>s
 214          * it creates cannot support the feature.
 215          * It is possible for an <code>XPathFactory</code> to expose a feature
 216          * value but be unable to change its state.
 217          * </p>
 218          *
 219          * @param name Feature name.
 220          *
 221          * @return State of the named feature.
 222          *
 223          * @throws XPathFactoryConfigurationException if this
 224          * <code>XPathFactory</code> or the <code>XPath</code>s
 225          *   it creates cannot support this feature.
 226          * @throws NullPointerException if <code>name</code> is
 227          * <code>null</code>.
 228          */
 229         public boolean getFeature(String name)
 230                 throws XPathFactoryConfigurationException {
 231 
 232             // feature name cannot be null
 233             if (name == null) {
 234                 String fmsg = XSLMessages.createXPATHMessage(
 235                         XPATHErrorResources.ER_GETTING_NULL_FEATURE,
 236                         new Object[] { CLASS_NAME } );
 237                 throw new NullPointerException( fmsg );
 238             }
 239 
 240             // secure processing?
 241             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 242                 return !_isNotSecureProcessing;
 243             }
 244 
 245             /** Check to see if the property is managed by the feature manager **/
 246             int index = _featureManager.getIndex(name);
 247             if (index > -1) {
 248                 return _featureManager.getFeature(index);
 249             }
 250 
 251             // unknown feature
 252             String fmsg = XSLMessages.createXPATHMessage(
 253                     XPATHErrorResources.ER_GETTING_UNKNOWN_FEATURE,
 254                     new Object[] { name, CLASS_NAME } );
 255 
 256             throw new XPathFactoryConfigurationException( fmsg );
 257         }
 258 
 259         /**
 260          * <p>Establish a default function resolver.</p>
 261          *
 262          * <p>Any <code>XPath</code> objects constructed from this factory will use
 263          * the specified resolver by default.</p>
 264          *
 265          * <p>A <code>NullPointerException</code> is thrown if
 266          * <code>resolver</code> is <code>null</code>.</p>
 267          *
 268          * @param resolver XPath function resolver.
 269          *
 270          * @throws NullPointerException If <code>resolver</code> is
 271          * <code>null</code>.
 272          */
 273         public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
 274 
 275             // resolver cannot be null
 276             if (resolver == null) {
 277                 String fmsg = XSLMessages.createXPATHMessage(
 278                         XPATHErrorResources.ER_NULL_XPATH_FUNCTION_RESOLVER,
 279                         new Object[] {  CLASS_NAME } );
 280                 throw new NullPointerException( fmsg );
 281             }
 282 
 283             xPathFunctionResolver = resolver;
 284         }
 285 
 286         /**
 287          * <p>Establish a default variable resolver.</p>
 288          *
 289          * <p>Any <code>XPath</code> objects constructed from this factory will use
 290          * the specified resolver by default.</p>
 291          *
 292          * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
 293          *
 294          * @param resolver Variable resolver.
 295          *
 296          *  @throws NullPointerException If <code>resolver</code> is
 297          * <code>null</code>.
 298          */
 299         public void setXPathVariableResolver(XPathVariableResolver resolver) {
 300 
 301                 // resolver cannot be null
 302                 if (resolver == null) {
 303                     String fmsg = XSLMessages.createXPATHMessage(
 304                             XPATHErrorResources.ER_NULL_XPATH_VARIABLE_RESOLVER,
 305                             new Object[] {  CLASS_NAME } );
 306                     throw new NullPointerException( fmsg );
 307                 }
 308 
 309                 xPathVariableResolver = resolver;
 310         }
 311 }