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