bump product version to 4.1.6.2
[LibreOffice.git] / forms / source / xforms / computedexpression.cxx
blob184d91c61d962482a1224c36ec16e16153994972
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "computedexpression.hxx"
22 #include "unohelper.hxx"
23 #include "evaluationcontext.hxx"
24 #include "NameContainer.hxx"
26 #include <com/sun/star/container/XNameContainer.hpp>
27 #include <com/sun/star/uno/Sequence.hxx>
28 #include <com/sun/star/xml/dom/NodeType.hpp>
29 #include <com/sun/star/xml/dom/XNode.hpp>
30 #include <com/sun/star/xml/xpath/XPathAPI.hpp>
31 #include <com/sun/star/xml/xpath/XXPathObject.hpp>
32 #include <com/sun/star/xml/xpath/XPathExtension.hpp>
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <com/sun/star/lang/XInitialization.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/util/SearchAlgorithms.hpp>
38 #include <unotools/textsearch.hxx>
39 #include <comphelper/processfactory.hxx>
41 using com::sun::star::beans::NamedValue;
42 using namespace com::sun::star::uno;
43 using com::sun::star::lang::XInitialization;
44 using com::sun::star::lang::XMultiServiceFactory;
45 using com::sun::star::xml::dom::XNode;
46 using com::sun::star::container::XNameContainer;
47 using com::sun::star::xml::xpath::XPathAPI;
48 using com::sun::star::xml::xpath::XXPathAPI;
49 using com::sun::star::xml::xpath::XPathExtension;
50 using com::sun::star::xml::xpath::XXPathExtension;
51 using com::sun::star::xml::xpath::XXPathObject;
52 using com::sun::star::xml::xpath::XPathObjectType_XPATH_UNDEFINED;
53 using com::sun::star::util::SearchOptions;
54 using com::sun::star::util::SearchAlgorithms_REGEXP;
57 namespace xforms
60 ComputedExpression::ComputedExpression()
61 : msExpression(),
62 mbIsEmpty( true ),
63 mbIsSimple( true ),
64 mxResult()
68 ComputedExpression::~ComputedExpression()
73 OUString ComputedExpression::getExpression() const
75 return msExpression;
78 void ComputedExpression::setExpression( const OUString& rExpression )
80 // set new expression, and clear pre-computed results
81 msExpression = rExpression;
82 mbIsEmpty = _checkExpression( " *" );
83 mbIsSimple = false;
84 mxResult.clear();
88 bool ComputedExpression::_checkExpression( const sal_Char* pExpression ) const
90 OSL_ENSURE( pExpression != NULL, "no expression?" );
92 // call RegExp engine
93 SearchOptions aSearchOptions;
94 aSearchOptions.algorithmType = SearchAlgorithms_REGEXP;
95 aSearchOptions.searchString = String( pExpression, RTL_TEXTENCODING_ASCII_US );
96 utl::TextSearch aTextSearch( aSearchOptions );
98 xub_StrLen nLength =
99 static_cast<xub_StrLen>( msExpression.getLength() );
100 xub_StrLen nStart = 0;
101 xub_StrLen nEnd = nLength;
102 int nSearch = aTextSearch.SearchFrwrd( msExpression, &nStart, &nEnd );
104 // our expression is static only if 1) we found our regexp, and 2)
105 // the regexp goes from beginning to end.
106 return ( nLength == 0 || nSearch != 0 )
107 && ( nStart == 0 && nEnd == nLength );
110 /// do we have an actual expression?
111 bool ComputedExpression::isEmptyExpression() const
113 return mbIsEmpty;
116 bool ComputedExpression::isSimpleExpression() const
118 // actual work is done by setExpression
119 return mbIsEmpty || mbIsSimple;
123 const OUString ComputedExpression::_getExpressionForEvaluation() const
125 // the default implementation is to do nothing...
126 return msExpression;
129 bool ComputedExpression::_evaluate(
130 const xforms::EvaluationContext& rContext,
131 const OUString& sExpression )
133 OSL_ENSURE( rContext.mxContextNode.is(), "no context node in context" );
135 // obtain value by evaluating XPath expression
136 mxResult.clear();
139 mxResult = _getXPathAPI(rContext)->eval( rContext.mxContextNode,
140 sExpression );
142 catch( const Exception& )
144 ; // ignore exception -> mxResult will be empty
147 return hasValue();
150 bool ComputedExpression::evaluate( const EvaluationContext& rContext )
152 // for simple expression we don't need to re-evaluate (if we have
153 // an older result); neither for empty expressions
154 if( mbIsEmpty || (mxResult.is() && mbIsSimple) )
155 return true;
157 return _evaluate( rContext, _getExpressionForEvaluation() );
161 bool ComputedExpression::hasValue() const
163 return mxResult.is() &&
164 mxResult->getObjectType() != XPathObjectType_XPATH_UNDEFINED;
167 void ComputedExpression::clear()
169 mxResult.clear();
172 Reference<XXPathObject> ComputedExpression::getXPath() const
174 return mxResult;
177 OUString ComputedExpression::getString( const OUString& rDefault ) const
179 return mxResult.is() ? mxResult->getString() : rDefault;
182 bool ComputedExpression::getBool( bool bDefault ) const
184 return mxResult.is() ? mxResult->getBoolean() : bDefault;
190 Reference<XXPathAPI> ComputedExpression::_getXPathAPI(const xforms::EvaluationContext& aContext)
192 // create XPath API, then register namespaces
193 Reference<XXPathAPI> xXPath( XPathAPI::create( comphelper::getProcessComponentContext() ) );
195 // register xforms extension#
196 Reference< XComponentContext > aComponentContext = comphelper::getProcessComponentContext();
197 Reference< XXPathExtension > aExtension = XPathExtension::createWithModel(aComponentContext, aContext.mxModel, aContext.mxContextNode);
198 xXPath->registerExtensionInstance(aExtension);
200 // register namespaces
201 if( aContext.mxNamespaces.is() )
203 Sequence<OUString> aPrefixes =aContext.mxNamespaces->getElementNames();
204 sal_Int32 nCount = aPrefixes.getLength();
205 const OUString* pPrefixes = aPrefixes.getConstArray();
206 for( sal_Int32 i = 0; i < nCount; i++ )
208 const OUString* pNamePrefix = &pPrefixes[i];
209 OUString sNameURL;
210 aContext.mxNamespaces->getByName( *pNamePrefix ) >>= sNameURL;
211 xXPath->registerNS( *pNamePrefix, sNameURL );
215 // done, so return xXPath-object
216 return xXPath;
220 } // namespace xforms
222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */