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