1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. 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,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_forms.hxx"
26
27 #include "pathexpression.hxx"
28 #include "unohelper.hxx"
29 #include "evaluationcontext.hxx"
30 #include "NameContainer.hxx"
31
32 #include <com/sun/star/xml/dom/XNode.hpp>
33 #include <com/sun/star/xml/dom/XNodeList.hpp>
34 #include <com/sun/star/xml/dom/NodeType.hpp>
35 #include <com/sun/star/xml/dom/events/XEventListener.hpp>
36 #include <com/sun/star/xml/dom/events/XEventTarget.hpp>
37 #include <com/sun/star/xml/xpath/XXPathObject.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/uno/Sequence.hxx>
40 #include <rtl/ustrbuf.hxx>
41
42 #include <unotools/textsearch.hxx>
43
44 #include <algorithm>
45 #include <functional>
46
47
48 using rtl::OUString;
49 using rtl::OUStringBuffer;
50 using com::sun::star::uno::Reference;
51 using com::sun::star::uno::Sequence;
52 using com::sun::star::xml::dom::XNode;
53 using com::sun::star::xml::dom::XNodeList;
54 using com::sun::star::xml::dom::events::XEventListener;
55 using com::sun::star::xml::dom::events::XEventTarget;
56 using com::sun::star::container::XNameContainer;
57 using com::sun::star::xml::xpath::XXPathObject;
58 using com::sun::star::uno::RuntimeException;
59 using com::sun::star::uno::UNO_QUERY;
60 using com::sun::star::uno::UNO_QUERY_THROW;
61 using com::sun::star::xml::dom::NodeType_TEXT_NODE;
62 using com::sun::star::xml::xpath::XPathObjectType_XPATH_UNDEFINED;
63 using namespace std;
64
65
66
67
68 namespace xforms
69 {
70
PathExpression()71 PathExpression::PathExpression()
72 : ComputedExpression(),
73 maNodes()
74 {
75 }
76
~PathExpression()77 PathExpression::~PathExpression()
78 {
79 }
80
81
82
setExpression(const OUString & rExpression)83 void PathExpression::setExpression( const OUString& rExpression )
84 {
85 // set new expression, and clear pre-computed results
86 ComputedExpression::setExpression( rExpression );
87
88 // check expression against regular expression to determine
89 // whether it contains only 'simple' (i.e. static) conditions. For
90 // now, we check whether it only contains number positions.
91 // (TODO: Only works for names containing only ASCII letters+digits.)
92 mbIsSimple =
93 _checkExpression( "( */@?[a-zA-Z0-9:]+( *\\[ *[0-9 ]+ *\\] *)?)+" );
94
95 maNodes.clear();
96 }
97
_getExpressionForEvaluation() const98 const rtl::OUString PathExpression::_getExpressionForEvaluation() const
99 {
100 OUString sExpr = ComputedExpression::_getExpressionForEvaluation();
101 if( sExpr.getLength() == 0 )
102 sExpr = OUSTRING(".");
103 return sExpr;
104 }
105
evaluate(const EvaluationContext & rContext)106 bool PathExpression::evaluate( const EvaluationContext& rContext )
107 {
108 // for simple expression we don't need to re-bind (if we were bound before)
109 // (we will evaluate empty expressions, since they are interpreted as ".")
110 if( mxResult.is() && isSimpleExpression() )
111 return true;
112
113 bool bResult = _evaluate( rContext, _getExpressionForEvaluation() );
114
115 // clear old result, and copy new
116 maNodes.clear();
117 if( mxResult.is() )
118 {
119 // copy node list
120 Reference<XNodeList> xNodeList = mxResult->getNodeList();
121 OSL_ENSURE( xNodeList.is(), "empty object (instead of empty list)" );
122 sal_Int32 nLength = xNodeList.is() ? xNodeList->getLength() : 0;
123 for( sal_Int32 n = 0; n < nLength; n++ )
124 maNodes.push_back( xNodeList->item( n ) );
125 }
126
127 return bResult;
128 }
129
130
getNode() const131 Reference<XNode> PathExpression::getNode() const
132 {
133 Reference<XNode> xResult;
134 if( ! maNodes.empty() )
135 xResult = *maNodes.begin();
136 return xResult;
137 }
138
getNodeList() const139 const PathExpression::NodeVector_t PathExpression::getNodeList() const
140 {
141 return maNodes;
142 }
143
getXNodeList() const144 Reference<XNodeList> PathExpression::getXNodeList() const
145 {
146 return mxResult.is() ? mxResult->getNodeList() : Reference<XNodeList>();
147 }
148
149
150 } // namespace xforms
151