Back to index

lightning-sunbird  0.9+nobinonly
nsXPathEvaluator.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is TransforMiiX XSLT processor code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Peter Van der Beken <peterv@propagandism.org>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsXPathEvaluator.h"
00040 #include "nsCOMPtr.h"
00041 #include "nsIAtom.h"
00042 #include "nsIDOMClassInfo.h"
00043 #include "nsXPathException.h"
00044 #include "nsXPathExpression.h"
00045 #include "nsXPathNSResolver.h"
00046 #include "nsXPathResult.h"
00047 #include "nsContentCID.h"
00048 #include "Expr.h"
00049 #include "ExprParser.h"
00050 #include "nsDOMError.h"
00051 #include "txURIUtils.h"
00052 #include "nsIDocument.h"
00053 #include "nsIDOMDocument.h"
00054 #include "nsDOMString.h"
00055 #include "nsINameSpaceManager.h"
00056 #include "txError.h"
00057 
00058 extern nsINameSpaceManager* gTxNameSpaceManager;
00059 
00060 NS_IMPL_ADDREF(nsXPathEvaluator)
00061 NS_IMPL_RELEASE(nsXPathEvaluator)
00062 NS_INTERFACE_MAP_BEGIN(nsXPathEvaluator)
00063   NS_INTERFACE_MAP_ENTRY(nsIDOMXPathEvaluator)
00064   NS_INTERFACE_MAP_ENTRY(nsIXPathEvaluatorInternal)
00065   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathEvaluator)
00066   NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XPathEvaluator)
00067 NS_INTERFACE_MAP_END
00068 
00069 nsXPathEvaluator::nsXPathEvaluator()
00070 {
00071 }
00072 
00073 nsXPathEvaluator::~nsXPathEvaluator()
00074 {
00075 }
00076 
00077 NS_IMETHODIMP
00078 nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
00079                                    nsIDOMXPathNSResolver *aResolver,
00080                                    nsIDOMXPathExpression **aResult)
00081 {
00082     nsresult rv = NS_OK;
00083     if (!mRecycler) {
00084         nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
00085         NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
00086         
00087         rv = recycler->init();
00088         NS_ENSURE_SUCCESS(rv, rv);
00089         
00090         mRecycler = recycler;
00091     }
00092 
00093     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
00094     ParseContextImpl pContext(aResolver, !doc || doc->IsCaseSensitive());
00095     nsAutoPtr<Expr> expression;
00096     rv = txExprParser::createExpr(PromiseFlatString(aExpression), &pContext,
00097                                   getter_Transfers(expression));
00098     if (NS_FAILED(rv)) {
00099         if (rv == NS_ERROR_DOM_NAMESPACE_ERR) {
00100             return NS_ERROR_DOM_NAMESPACE_ERR;
00101         }
00102 
00103         return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
00104     }
00105 
00106     *aResult = new nsXPathExpression(expression, mRecycler);
00107     if (!*aResult) {
00108         return NS_ERROR_OUT_OF_MEMORY;
00109     }
00110 
00111     NS_ADDREF(*aResult);
00112     return NS_OK;
00113 }
00114 
00115 NS_IMETHODIMP
00116 nsXPathEvaluator::CreateNSResolver(nsIDOMNode *aNodeResolver,
00117                                    nsIDOMXPathNSResolver **aResult)
00118 {
00119     NS_ENSURE_ARG(aNodeResolver);
00120     if (!URIUtils::CanCallerAccess(aNodeResolver))
00121         return NS_ERROR_DOM_SECURITY_ERR;
00122 
00123     *aResult = new nsXPathNSResolver(aNodeResolver);
00124     NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
00125 
00126     NS_ADDREF(*aResult);
00127     return NS_OK;
00128 }
00129 
00130 NS_IMETHODIMP
00131 nsXPathEvaluator::Evaluate(const nsAString & aExpression,
00132                            nsIDOMNode *aContextNode,
00133                            nsIDOMXPathNSResolver *aResolver,
00134                            PRUint16 aType,
00135                            nsISupports *aInResult,
00136                            nsISupports **aResult)
00137 {
00138     // XXX Need to check document of aContextNode if created by
00139     //     QI'ing a document.
00140 
00141     nsCOMPtr<nsIDOMXPathExpression> expression;
00142     nsresult rv = CreateExpression(aExpression, aResolver,
00143                                    getter_AddRefs(expression));
00144     NS_ENSURE_SUCCESS(rv, rv);
00145 
00146     return expression->Evaluate(aContextNode, aType, aInResult, aResult);
00147 }
00148 
00149 
00150 NS_IMETHODIMP
00151 nsXPathEvaluator::SetDocument(nsIDOMDocument* aDocument)
00152 {
00153     mDocument = do_GetWeakReference(aDocument);
00154     return NS_OK;
00155 }
00156 
00157 /*
00158  * Implementation of txIParseContext private to nsXPathEvaluator
00159  * ParseContextImpl bases on a nsIDOMXPathNSResolver
00160  */
00161 
00162 nsresult nsXPathEvaluator::ParseContextImpl::resolveNamespacePrefix
00163     (nsIAtom* aPrefix, PRInt32& aID)
00164 {
00165     aID = kNameSpaceID_Unknown;
00166 
00167     if (!mResolver) {
00168         return NS_ERROR_DOM_NAMESPACE_ERR;
00169     }
00170 
00171     nsAutoString prefix;
00172     if (aPrefix) {
00173         aPrefix->ToString(prefix);
00174     }
00175 
00176     nsVoidableString ns;
00177     nsresult rv = mResolver->LookupNamespaceURI(prefix, ns);
00178     NS_ENSURE_SUCCESS(rv, rv);
00179 
00180     if (DOMStringIsNull(ns)) {
00181         return NS_ERROR_DOM_NAMESPACE_ERR;
00182     }
00183 
00184     if (ns.IsEmpty()) {
00185         aID = kNameSpaceID_None;
00186 
00187         return NS_OK;
00188     }
00189 
00190     // get the namespaceID for the URI
00191     return gTxNameSpaceManager->RegisterNameSpace(ns, aID);
00192 }
00193 
00194 nsresult
00195 nsXPathEvaluator::ParseContextImpl::resolveFunctionCall(nsIAtom* aName,
00196                                                         PRInt32 aID,
00197                                                         FunctionCall*& aFn)
00198 {
00199     return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
00200 }
00201 
00202 PRBool nsXPathEvaluator::ParseContextImpl::caseInsensitiveNameTests()
00203 {
00204     return !mIsCaseSensitive;
00205 }
00206 
00207 void
00208 nsXPathEvaluator::ParseContextImpl::SetErrorOffset(PRUint32 aOffset)
00209 {
00210 }