1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "oox/xls/ooxformulaparser.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp> 31*cdf0e10cSrcweir #include "oox/xls/formulaparser.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir namespace oox { 34*cdf0e10cSrcweir namespace xls { 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir // ============================================================================ 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 39*cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 40*cdf0e10cSrcweir using namespace ::com::sun::star::table; 41*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir using ::rtl::OUString; 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir // ============================================================================ 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir class OOXMLFormulaParserImpl : private FormulaFinalizer 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir public: 50*cdf0e10cSrcweir explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos ); 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir protected: 55*cdf0e10cSrcweir virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const; 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir private: 58*cdf0e10cSrcweir ApiParserWrapper maApiParser; 59*cdf0e10cSrcweir }; 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : 64*cdf0e10cSrcweir FormulaFinalizer( OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ), 65*cdf0e10cSrcweir maApiParser( rxModelFactory, *this ) 66*cdf0e10cSrcweir { 67*cdf0e10cSrcweir } 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir Sequence< FormulaToken > OOXMLFormulaParserImpl::parseFormula( const OUString& rFormula, const CellAddress& rReferencePos ) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir return finalizeTokenArray( maApiParser.parseFormula( rFormula, rReferencePos ) ); 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir /* Try to parse calls to library functions. The format of such a function 77*cdf0e10cSrcweir call is assumed to be 78*cdf0e10cSrcweir "'<path-to-office-install>\Library\<libname>'!<funcname>". */ 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir // the string has to start with an apostroph (followed by the library URL) 81*cdf0e10cSrcweir if( (rTokenData.getLength() >= 6) && (rTokenData[ 0 ] == '\'') ) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir // library URL and function name are separated by an exclamation mark 84*cdf0e10cSrcweir sal_Int32 nExclamPos = rTokenData.lastIndexOf( '!' ); 85*cdf0e10cSrcweir if( (1 < nExclamPos) && (nExclamPos + 1 < rTokenData.getLength()) && (rTokenData[ nExclamPos - 1 ] == '\'') ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir // find the last backslash that separates library path and name 88*cdf0e10cSrcweir sal_Int32 nFileSep = rTokenData.lastIndexOf( '\\', nExclamPos - 2 ); 89*cdf0e10cSrcweir if( nFileSep > 1 ) 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir // find preceding backslash that separates the last directory name 92*cdf0e10cSrcweir sal_Int32 nDirSep = rTokenData.lastIndexOf( '\\', nFileSep - 1 ); 93*cdf0e10cSrcweir // function library is located in a directory called 'library' 94*cdf0e10cSrcweir if( (nDirSep > 0) && rTokenData.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "\\LIBRARY\\" ), nDirSep ) ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir // try to find a function info for the function name 97*cdf0e10cSrcweir OUString aFuncName = rTokenData.copy( nExclamPos + 1 ).toAsciiUpperCase(); 98*cdf0e10cSrcweir const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName ); 99*cdf0e10cSrcweir if( pFuncInfo && (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) ) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir // check that the name of the library matches 102*cdf0e10cSrcweir OUString aLibName = rTokenData.copy( nFileSep + 1, nExclamPos - nFileSep - 2 ); 103*cdf0e10cSrcweir if( pFuncInfo->meFuncLibType == getFuncLibTypeFromLibraryName( aLibName ) ) 104*cdf0e10cSrcweir return pFuncInfo; 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir } 110*cdf0e10cSrcweir return 0; 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // ============================================================================ 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir class OOXMLFormulaPrinterImpl : public OpCodeProvider 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir public: 118*cdf0e10cSrcweir explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir private: 121*cdf0e10cSrcweir ApiParserWrapper maApiParser; 122*cdf0e10cSrcweir }; 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : 127*cdf0e10cSrcweir OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, false ), 128*cdf0e10cSrcweir maApiParser( rxModelFactory, *this ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir // ============================================================================ 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir Sequence< OUString > OOXMLFormulaParser_getSupportedServiceNames() 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir Sequence< OUString > aServiceNames( 1 ); 137*cdf0e10cSrcweir aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.sheet.FilterFormulaParser" ); 138*cdf0e10cSrcweir return aServiceNames; 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir OUString OOXMLFormulaParser_getImplementationName() 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.FormulaParser" ); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir Reference< XInterface > SAL_CALL OOXMLFormulaParser_createInstance( const Reference< XComponentContext >& ) throw( Exception ) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir return static_cast< ::cppu::OWeakObject* >( new OOXMLFormulaParser ); 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // ============================================================================ 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir OOXMLFormulaParser::OOXMLFormulaParser() 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir OOXMLFormulaParser::~OOXMLFormulaParser() 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir // com.sun.star.lang.XServiceInfo interface ----------------------------------- 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir OUString SAL_CALL OOXMLFormulaParser::getImplementationName() throw( RuntimeException ) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir return OOXMLFormulaParser_getImplementationName(); 166*cdf0e10cSrcweir } 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir sal_Bool SAL_CALL OOXMLFormulaParser::supportsService( const OUString& rService ) throw( RuntimeException ) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir const Sequence< OUString > aServices( OOXMLFormulaParser_getSupportedServiceNames() ); 171*cdf0e10cSrcweir const OUString* pArray = aServices.getConstArray(); 172*cdf0e10cSrcweir const OUString* pArrayEnd = pArray + aServices.getLength(); 173*cdf0e10cSrcweir return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd; 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir Sequence< OUString > SAL_CALL OOXMLFormulaParser::getSupportedServiceNames() throw( RuntimeException ) 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir return OOXMLFormulaParser_getSupportedServiceNames(); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir // com.sun.star.lang.XInitialization interface -------------------------------- 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir void SAL_CALL OOXMLFormulaParser::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException ) 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir OSL_ENSURE( rArgs.hasElements(), "OOXMLFormulaParser::initialize - missing arguments" ); 186*cdf0e10cSrcweir if( !rArgs.hasElements() ) 187*cdf0e10cSrcweir throw RuntimeException(); 188*cdf0e10cSrcweir mxComponent.set( rArgs[ 0 ], UNO_QUERY_THROW ); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir // com.sun.star.sheet.XFilterFormulaParser interface -------------------------- 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir OUString SAL_CALL OOXMLFormulaParser::getSupportedNamespace() throw( RuntimeException ) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir return CREATE_OUSTRING( "http://schemas.microsoft.com/office/excel/formula" ); 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir // com.sun.star.sheet.XFormulaParser interface -------------------------------- 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula( 201*cdf0e10cSrcweir const OUString& rFormula, const CellAddress& rReferencePos ) throw( RuntimeException ) 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir if( !mxParserImpl ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir Reference< XMultiServiceFactory > xModelFactory( mxComponent, UNO_QUERY_THROW ); 206*cdf0e10cSrcweir mxParserImpl.reset( new OOXMLFormulaParserImpl( xModelFactory ) ); 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir return mxParserImpl->parseFormula( rFormula, rReferencePos ); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir OUString SAL_CALL OOXMLFormulaParser::printFormula( 212*cdf0e10cSrcweir const Sequence< FormulaToken >& /*rTokens*/, const CellAddress& /*rReferencePos*/ ) throw( RuntimeException ) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir // not implemented 215*cdf0e10cSrcweir throw RuntimeException(); 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir // ============================================================================ 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir } // namespace xls 221*cdf0e10cSrcweir } // namespace oox 222