LibreOffice Module forms (master) 1
computedexpression.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22#include "evaluationcontext.hxx"
23
24#include <com/sun/star/uno/Sequence.hxx>
25#include <com/sun/star/xml/xpath/XPathAPI.hpp>
26#include <com/sun/star/xml/xpath/XPathExtension.hpp>
27#include <com/sun/star/util/SearchAlgorithms2.hpp>
28
29#include <osl/diagnose.h>
30
34
35using namespace com::sun::star::uno;
36using com::sun::star::xml::xpath::XPathAPI;
37using com::sun::star::xml::xpath::XXPathAPI;
38using com::sun::star::xml::xpath::XPathExtension;
39using com::sun::star::xml::xpath::XXPathExtension;
40using com::sun::star::xml::xpath::XPathObjectType_XPATH_UNDEFINED;
41
42
43namespace xforms
44{
45
47 : mbIsEmpty( true ),
48 mbIsSimple( true )
49{
50}
51
53{
54}
55
56
57void ComputedExpression::setExpression( const OUString& rExpression )
58{
59 // set new expression, and clear pre-computed results
60 msExpression = rExpression;
62 mbIsSimple = false;
63 mxResult.clear();
64}
65
66
67bool ComputedExpression::_checkExpression( const char* pExpression ) const
68{
69 assert(pExpression && "no expression?");
70
71 // call RegExp engine
72 i18nutil::SearchOptions2 aSearchOptions;
73 aSearchOptions.AlgorithmType2 = css::util::SearchAlgorithms2::REGEXP;
74 aSearchOptions.searchString = OUString( pExpression, strlen(pExpression), RTL_TEXTENCODING_ASCII_US );
75 utl::TextSearch aTextSearch( aSearchOptions );
76
77 sal_Int32 nLength = msExpression.getLength();
78 sal_Int32 nStart = 0;
79 sal_Int32 nEnd = nLength;
80 bool bSearch = aTextSearch.SearchForward( msExpression, &nStart, &nEnd );
81
82 // our expression is static only if 1) we found our regexp, and 2)
83 // the regexp goes from beginning to end.
84 return ( nLength == 0 || bSearch )
85 && ( nStart == 0 && nEnd == nLength );
86}
87
89{
90 // actual work is done by setExpression
91 return mbIsEmpty || mbIsSimple;
92}
93
94
96 const xforms::EvaluationContext& rContext,
97 const OUString& sExpression )
98{
99 OSL_ENSURE( rContext.mxContextNode.is(), "no context node in context" );
100
101 // obtain value by evaluating XPath expression
102 mxResult.clear();
103 try
104 {
105 mxResult = _getXPathAPI(rContext)->eval( rContext.mxContextNode,
106 sExpression );
107 }
108 catch( const Exception& )
109 {
110 ; // ignore exception -> mxResult will be empty
111 }
112
113 return hasValue();
114}
115
117{
118 // for simple expression we don't need to re-evaluate (if we have
119 // an older result); neither for empty expressions
120 if( mbIsEmpty || (mxResult.is() && mbIsSimple) )
121 return true;
122
123 return _evaluate( rContext, _getExpressionForEvaluation() );
124}
125
126
128{
129 return mxResult.is() &&
130 mxResult->getObjectType() != XPathObjectType_XPATH_UNDEFINED;
131}
132
134{
135 mxResult.clear();
136}
137
138
140{
141 return mxResult.is() ? mxResult->getString() : OUString();
142}
143
144bool ComputedExpression::getBool( bool bDefault ) const
145{
146 return mxResult.is() ? mxResult->getBoolean() : bDefault;
147}
148
149
151{
152 // create XPath API, then register namespaces
153 Reference<XXPathAPI> xXPath( XPathAPI::create( comphelper::getProcessComponentContext() ) );
154
155 // register xforms extension#
157 Reference< XXPathExtension > aExtension = XPathExtension::createWithModel(aComponentContext, aContext.mxModel, aContext.mxContextNode);
158 xXPath->registerExtensionInstance(aExtension);
159
160 // register namespaces
161 if( aContext.mxNamespaces.is() )
162 {
163 Sequence<OUString> aPrefixes =aContext.mxNamespaces->getElementNames();
164 sal_Int32 nCount = aPrefixes.getLength();
165 const OUString* pPrefixes = aPrefixes.getConstArray();
166 for( sal_Int32 i = 0; i < nCount; i++ )
167 {
168 const OUString* pNamePrefix = &pPrefixes[i];
169 OUString sNameURL;
170 aContext.mxNamespaces->getByName( *pNamePrefix ) >>= sNameURL;
171 xXPath->registerNS( *pNamePrefix, sNameURL );
172 }
173 }
174
175 // done, so return xXPath-object
176 return xXPath;
177}
178
179
180} // namespace xforms
181
182/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
bool isSimpleExpression() const
heuristically determine whether this expression is 'simple', i.e.
css::uno::Reference< css::xml::xpath::XXPathObject > mxResult
the result from the last bind
OUString msExpression
the expression string
bool getBool(bool bDefault=false) const
bool mbIsEmpty
is msExpression empty?
static css::uno::Reference< css::xml::xpath::XXPathAPI > _getXPathAPI(const xforms::EvaluationContext &aContext)
obtain a (suitable) XPathAPI implementation
const OUString & _getExpressionForEvaluation() const
allow manipulation of the expression before it is evaluated
bool hasValue() const
does this expression have a value?
bool _checkExpression(const char *pExpression) const
implementation of isSimpleExpression
bool mbIsSimple
is msExpression a simple expression?
void clear()
remove value/evaluate results
bool evaluate(const xforms::EvaluationContext &rContext)
evaluate the expression relative to the content node.
bool _evaluate(const xforms::EvaluationContext &rContext, const OUString &sExpression)
evaluate the expression relative to the content node.
void setExpression(const OUString &rExpression)
set a new expression string
define the context for the evaluation of an XPath expression
css::uno::Reference< css::xforms::XModel > mxModel
css::uno::Reference< css::xml::dom::XNode > mxContextNode
css::uno::Reference< css::container::XNameContainer > mxNamespaces
int nCount
@ Exception
Reference< XComponentContext > getProcessComponentContext()
int i
sal_Int32 nLength