001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    // $Id: XPathFactoryImpl.java 1225277 2011-12-28 18:50:56Z mrglavas $
019    
020    package org.apache.xpath.jaxp;
021    
022    import org.apache.xpath.res.XPATHErrorResources;
023    import org.apache.xalan.res.XSLMessages;
024    
025    import javax.xml.XMLConstants;
026    import javax.xml.xpath.XPathFactory;
027    import javax.xml.xpath.XPathFactoryConfigurationException;
028    import javax.xml.xpath.XPathFunctionResolver;
029    import javax.xml.xpath.XPathVariableResolver;
030    
031    /**
032     * The XPathFactory builds XPaths.
033     *
034     * @version $Revision: 1225277 $
035     * @author  Ramesh Mandava
036     */
037    public class XPathFactoryImpl extends XPathFactory {
038            
039            /**
040             * <p>Name of class as a constant to use for debugging.</p>
041             */
042            private static final String CLASS_NAME = "XPathFactoryImpl";
043            
044            /**
045             *<p>XPathFunctionResolver for this XPathFactory and created XPaths.</p>
046             */
047            private XPathFunctionResolver xPathFunctionResolver = null;
048            
049            /**
050             * <p>XPathVariableResolver for this XPathFactory and created XPaths</p>
051             */
052            private XPathVariableResolver xPathVariableResolver = null;
053    
054            /**
055             * <p>State of secure processing feature.</p>
056             */
057            private boolean featureSecureProcessing = false;
058                    
059            /**
060             * <p>Is specified object model supported by this 
061             * <code>XPathFactory</code>?</p>
062             * 
063             * @param objectModel Specifies the object model which the returned
064             * <code>XPathFactory</code> will understand.
065             *  
066             * @return <code>true</code> if <code>XPathFactory</code> supports 
067             * <code>objectModel</code>, else <code>false</code>.
068             * 
069             * @throws NullPointerException If <code>objectModel</code> is <code>null</code>.
070             * @throws IllegalArgumentException If <code>objectModel.length() == 0</code>.
071             */
072            public boolean isObjectModelSupported(String objectModel) {
073                    
074                if (objectModel == null) {
075                    String fmsg = XSLMessages.createXPATHMessage(
076                            XPATHErrorResources.ER_OBJECT_MODEL_NULL,
077                            new Object[] { this.getClass().getName() } );
078    
079                    throw new NullPointerException( fmsg );
080                }
081                    
082                if (objectModel.length() == 0) {
083                    String fmsg = XSLMessages.createXPATHMessage(
084                            XPATHErrorResources.ER_OBJECT_MODEL_EMPTY,
085                            new Object[] { this.getClass().getName() } );
086                    throw new IllegalArgumentException( fmsg );
087                }
088                    
089                // know how to support default object model, W3C DOM
090                if (objectModel.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) {
091                    return true;
092                }
093                    
094                // don't know how to support anything else
095                return false;
096            }
097    
098            /**
099             * <p>Returns a new <code>XPath</code> object using the underlying
100             * object model determined when the factory was instantiated.</p>
101             * 
102             * @return New <code>XPath</code>
103             */
104            public javax.xml.xpath.XPath newXPath() {
105                return new org.apache.xpath.jaxp.XPathImpl(
106                        xPathVariableResolver, xPathFunctionResolver,
107                        featureSecureProcessing );
108            }
109                
110            /**
111             * <p>Set a feature for this <code>XPathFactory</code> and 
112             * <code>XPath</code>s created by this factory.</p>
113             * 
114             * <p>
115             * Feature names are fully qualified {@link java.net.URI}s.
116             * Implementations may define their own features.
117             * An {@link XPathFactoryConfigurationException} is thrown if this
118             * <code>XPathFactory</code> or the <code>XPath</code>s
119             *  it creates cannot support the feature.
120             * It is possible for an <code>XPathFactory</code> to expose a feature
121             * value but be unable to change its state.
122             * </p>
123             * 
124             * <p>See {@link javax.xml.xpath.XPathFactory} for full documentation
125             * of specific features.</p>
126             * 
127             * @param name Feature name.
128             * @param value Is feature state <code>true</code> or <code>false</code>.
129             *  
130             * @throws XPathFactoryConfigurationException if this 
131             * <code>XPathFactory</code> or the <code>XPath</code>s
132             *   it creates cannot support this feature.
133             * @throws NullPointerException if <code>name</code> is 
134             * <code>null</code>.
135             */
136            public void setFeature(String name, boolean value)
137                    throws XPathFactoryConfigurationException {
138                            
139                // feature name cannot be null
140                if (name == null) {
141                    String fmsg = XSLMessages.createXPATHMessage(
142                            XPATHErrorResources.ER_FEATURE_NAME_NULL,
143                            new Object[] { CLASS_NAME, value ? Boolean.TRUE : Boolean.FALSE } );
144                    throw new NullPointerException( fmsg );
145                 }
146                    
147                // secure processing?
148                if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
149    
150                    featureSecureProcessing = value;
151                                                    
152                    // all done processing feature
153                    return;
154                }
155                    
156                // unknown feature
157                String fmsg = XSLMessages.createXPATHMessage(
158                        XPATHErrorResources.ER_FEATURE_UNKNOWN,
159                        new Object[] { name, CLASS_NAME, value ? Boolean.TRUE : Boolean.FALSE } );
160                throw new XPathFactoryConfigurationException( fmsg );
161            }
162    
163            /**
164             * <p>Get the state of the named feature.</p>
165             * 
166             * <p>
167             * Feature names are fully qualified {@link java.net.URI}s.
168             * Implementations may define their own features.
169             * An {@link XPathFactoryConfigurationException} is thrown if this
170             * <code>XPathFactory</code> or the <code>XPath</code>s
171             * it creates cannot support the feature.
172             * It is possible for an <code>XPathFactory</code> to expose a feature 
173             * value but be unable to change its state.
174             * </p>
175             * 
176             * @param name Feature name.
177             * 
178             * @return State of the named feature.
179             * 
180             * @throws XPathFactoryConfigurationException if this 
181             * <code>XPathFactory</code> or the <code>XPath</code>s
182             *   it creates cannot support this feature.
183             * @throws NullPointerException if <code>name</code> is 
184             * <code>null</code>.
185             */
186            public boolean getFeature(String name)
187                    throws XPathFactoryConfigurationException {
188    
189                // feature name cannot be null
190                if (name == null) {
191                    String fmsg = XSLMessages.createXPATHMessage(
192                            XPATHErrorResources.ER_GETTING_NULL_FEATURE,
193                            new Object[] { CLASS_NAME } );
194                    throw new NullPointerException( fmsg );
195                }
196                    
197                // secure processing?
198                if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
199                    return featureSecureProcessing;
200                }
201                    
202                // unknown feature
203                String fmsg = XSLMessages.createXPATHMessage(
204                        XPATHErrorResources.ER_GETTING_UNKNOWN_FEATURE,
205                        new Object[] { name, CLASS_NAME } );
206    
207                throw new XPathFactoryConfigurationException( fmsg );
208            }
209                    
210            /**
211             * <p>Establish a default function resolver.</p>
212             * 
213             * <p>Any <code>XPath</code> objects constructed from this factory will use
214             * the specified resolver by default.</p>
215             *
216             * <p>A <code>NullPointerException</code> is thrown if 
217             * <code>resolver</code> is <code>null</code>.</p>
218             * 
219             * @param resolver XPath function resolver.
220             * 
221             * @throws NullPointerException If <code>resolver</code> is 
222             * <code>null</code>.
223             */
224            public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
225                            
226                // resolver cannot be null
227                if (resolver == null) {
228                    String fmsg = XSLMessages.createXPATHMessage(
229                            XPATHErrorResources.ER_NULL_XPATH_FUNCTION_RESOLVER,
230                            new Object[] {  CLASS_NAME } );
231                    throw new NullPointerException( fmsg );
232                }
233                            
234                xPathFunctionResolver = resolver;
235            }
236                    
237            /**
238             * <p>Establish a default variable resolver.</p>
239             *
240             * <p>Any <code>XPath</code> objects constructed from this factory will use
241             * the specified resolver by default.</p>
242             * 
243             * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
244             * 
245             * @param resolver Variable resolver.
246             * 
247             *  @throws NullPointerException If <code>resolver</code> is 
248             * <code>null</code>.
249             */
250            public void setXPathVariableResolver(XPathVariableResolver resolver) {
251    
252                    // resolver cannot be null
253                    if (resolver == null) {
254                        String fmsg = XSLMessages.createXPATHMessage(
255                                XPATHErrorResources.ER_NULL_XPATH_VARIABLE_RESOLVER,
256                                new Object[] {  CLASS_NAME } );
257                        throw new NullPointerException( fmsg );
258                    }
259                            
260                    xPathVariableResolver = resolver;
261            }
262    }
263    
264    
265