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_sc.hxx" 30 31 #include "formulaparserpool.hxx" 32 #include <com/sun/star/beans/XPropertySet.hpp> 33 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 34 #include <com/sun/star/lang/XComponent.hpp> 35 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 36 #include <com/sun/star/sheet/XFilterFormulaParser.hpp> 37 #include <rtl/instance.hxx> 38 #include <comphelper/processfactory.hxx> 39 #include <sfx2/objsh.hxx> 40 #include "document.hxx" 41 42 using ::rtl::OUString; 43 using ::rtl::OUStringHash; 44 using namespace ::com::sun::star::beans; 45 using namespace ::com::sun::star::container; 46 using namespace ::com::sun::star::lang; 47 using namespace ::com::sun::star::sheet; 48 using namespace ::com::sun::star::uno; 49 50 // ============================================================================ 51 52 namespace { 53 54 class ScParserFactoryMap 55 { 56 public: 57 explicit ScParserFactoryMap(); 58 59 Reference< XFormulaParser > createFormulaParser( 60 const Reference< XComponent >& rxComponent, 61 const OUString& rNamespace ); 62 63 private: 64 typedef ::std::hash_map< OUString, Reference< XSingleComponentFactory >, OUStringHash > FactoryMap; 65 66 Reference< XComponentContext > mxContext; /// Global component context. 67 FactoryMap maFactories; /// All parser factories, mapped by formula namespace. 68 }; 69 70 ScParserFactoryMap::ScParserFactoryMap() : 71 mxContext( ::comphelper::getProcessComponentContext() ) 72 { 73 if( mxContext.is() ) try 74 { 75 // enumerate all implementations of the FormulaParser service 76 Reference< XContentEnumerationAccess > xFactoryEA( mxContext->getServiceManager(), UNO_QUERY_THROW ); 77 Reference< XEnumeration > xEnum( xFactoryEA->createContentEnumeration( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FilterFormulaParser" ) ) ), UNO_SET_THROW ); 78 while( xEnum->hasMoreElements() ) try // single try/catch for every element 79 { 80 // create an instance of the formula parser implementation 81 Reference< XSingleComponentFactory > xCompFactory( xEnum->nextElement(), UNO_QUERY_THROW ); 82 Reference< XFilterFormulaParser > xParser( xCompFactory->createInstanceWithContext( mxContext ), UNO_QUERY_THROW ); 83 84 // store factory in the map 85 OUString aNamespace = xParser->getSupportedNamespace(); 86 if( aNamespace.getLength() > 0 ) 87 maFactories[ aNamespace ] = xCompFactory; 88 } 89 catch( Exception& ) 90 { 91 } 92 } 93 catch( Exception& ) 94 { 95 } 96 } 97 98 Reference< XFormulaParser > ScParserFactoryMap::createFormulaParser( 99 const Reference< XComponent >& rxComponent, const OUString& rNamespace ) 100 { 101 Reference< XFormulaParser > xParser; 102 FactoryMap::const_iterator aIt = maFactories.find( rNamespace ); 103 if( aIt != maFactories.end() ) try 104 { 105 Sequence< Any > aArgs( 1 ); 106 aArgs[ 0 ] <<= rxComponent; 107 xParser.set( aIt->second->createInstanceWithArgumentsAndContext( aArgs, mxContext ), UNO_QUERY_THROW ); 108 } 109 catch( Exception& ) 110 { 111 } 112 return xParser; 113 } 114 115 struct ScParserFactorySingleton : public ::rtl::Static< ScParserFactoryMap, ScParserFactorySingleton > {}; 116 117 } // namespace 118 119 // ============================================================================ 120 121 ScFormulaParserPool::ScFormulaParserPool( const ScDocument& rDoc ) : 122 mrDoc( rDoc ) 123 { 124 } 125 126 ScFormulaParserPool::~ScFormulaParserPool() 127 { 128 } 129 130 bool ScFormulaParserPool::hasFormulaParser( const OUString& rNamespace ) 131 { 132 return getFormulaParser( rNamespace ).is(); 133 } 134 135 Reference< XFormulaParser > ScFormulaParserPool::getFormulaParser( const OUString& rNamespace ) 136 { 137 // try to find an existing parser entry 138 ParserMap::iterator aIt = maParsers.find( rNamespace ); 139 if( aIt != maParsers.end() ) 140 return aIt->second; 141 142 // always create a new entry in the map (even if the following initialization fails) 143 Reference< XFormulaParser >& rxParser = maParsers[ rNamespace ]; 144 145 // try to create a new parser object 146 if( SfxObjectShell* pDocShell = mrDoc.GetDocumentShell() ) try 147 { 148 Reference< XComponent > xComponent( pDocShell->GetModel(), UNO_QUERY_THROW ); 149 ScParserFactoryMap& rFactoryMap = ScParserFactorySingleton::get(); 150 rxParser = rFactoryMap.createFormulaParser( xComponent, rNamespace ); 151 } 152 catch( Exception& ) 153 { 154 } 155 return rxParser; 156 } 157 158 // ============================================================================ 159 160