1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_forms.hxx" 30 31 #include "pathexpression.hxx" 32 #include "unohelper.hxx" 33 #include "evaluationcontext.hxx" 34 #include "NameContainer.hxx" 35 36 #include <com/sun/star/xml/dom/XNode.hpp> 37 #include <com/sun/star/xml/dom/XNodeList.hpp> 38 #include <com/sun/star/xml/dom/NodeType.hpp> 39 #include <com/sun/star/xml/dom/events/XEventListener.hpp> 40 #include <com/sun/star/xml/dom/events/XEventTarget.hpp> 41 #include <com/sun/star/xml/xpath/XXPathObject.hpp> 42 #include <com/sun/star/container/XNameContainer.hpp> 43 #include <com/sun/star/uno/Sequence.hxx> 44 #include <rtl/ustrbuf.hxx> 45 46 #include <unotools/textsearch.hxx> 47 48 #include <algorithm> 49 #include <functional> 50 51 52 using rtl::OUString; 53 using rtl::OUStringBuffer; 54 using com::sun::star::uno::Reference; 55 using com::sun::star::uno::Sequence; 56 using com::sun::star::xml::dom::XNode; 57 using com::sun::star::xml::dom::XNodeList; 58 using com::sun::star::xml::dom::events::XEventListener; 59 using com::sun::star::xml::dom::events::XEventTarget; 60 using com::sun::star::container::XNameContainer; 61 using com::sun::star::xml::xpath::XXPathObject; 62 using com::sun::star::uno::RuntimeException; 63 using com::sun::star::uno::UNO_QUERY; 64 using com::sun::star::uno::UNO_QUERY_THROW; 65 using com::sun::star::xml::dom::NodeType_TEXT_NODE; 66 using com::sun::star::xml::xpath::XPathObjectType_XPATH_UNDEFINED; 67 using namespace std; 68 69 70 71 72 namespace xforms 73 { 74 75 PathExpression::PathExpression() 76 : ComputedExpression(), 77 maNodes() 78 { 79 } 80 81 PathExpression::~PathExpression() 82 { 83 } 84 85 86 87 void PathExpression::setExpression( const OUString& rExpression ) 88 { 89 // set new expression, and clear pre-computed results 90 ComputedExpression::setExpression( rExpression ); 91 92 // check expression against regular expression to determine 93 // whether it contains only 'simple' (i.e. static) conditions. For 94 // now, we check whether it only contains number positions. 95 // (TODO: Only works for names containing only ASCII letters+digits.) 96 mbIsSimple = 97 _checkExpression( "( */@?[a-zA-Z0-9:]+( *\\[ *[0-9 ]+ *\\] *)?)+" ); 98 99 maNodes.clear(); 100 } 101 102 const rtl::OUString PathExpression::_getExpressionForEvaluation() const 103 { 104 OUString sExpr = ComputedExpression::_getExpressionForEvaluation(); 105 if( sExpr.getLength() == 0 ) 106 sExpr = OUSTRING("."); 107 return sExpr; 108 } 109 110 bool PathExpression::evaluate( const EvaluationContext& rContext ) 111 { 112 // for simple expression we don't need to re-bind (if we were bound before) 113 // (we will evaluate empty expressions, since they are interpreted as ".") 114 if( mxResult.is() && isSimpleExpression() ) 115 return true; 116 117 bool bResult = _evaluate( rContext, _getExpressionForEvaluation() ); 118 119 // clear old result, and copy new 120 maNodes.clear(); 121 if( mxResult.is() ) 122 { 123 // copy node list 124 Reference<XNodeList> xNodeList = mxResult->getNodeList(); 125 OSL_ENSURE( xNodeList.is(), "empty object (instead of empty list)" ); 126 sal_Int32 nLength = xNodeList.is() ? xNodeList->getLength() : 0; 127 for( sal_Int32 n = 0; n < nLength; n++ ) 128 maNodes.push_back( xNodeList->item( n ) ); 129 } 130 131 return bResult; 132 } 133 134 135 Reference<XNode> PathExpression::getNode() const 136 { 137 Reference<XNode> xResult; 138 if( ! maNodes.empty() ) 139 xResult = *maNodes.begin(); 140 return xResult; 141 } 142 143 const PathExpression::NodeVector_t PathExpression::getNodeList() const 144 { 145 return maNodes; 146 } 147 148 Reference<XNodeList> PathExpression::getXNodeList() const 149 { 150 return mxResult.is() ? mxResult->getNodeList() : Reference<XNodeList>(); 151 } 152 153 154 } // namespace xforms 155