1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formulaparserpool.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "formulaparserpool.hxx"
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/sheet/XFilterFormulaParser.hpp>
41 #include <rtl/instance.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <sfx2/objsh.hxx>
44 #include "document.hxx"
46 using ::rtl::OUString
;
47 using ::rtl::OUStringHash
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::container
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::sheet
;
52 using namespace ::com::sun::star::uno
;
54 // ============================================================================
58 class ScParserFactoryMap
61 explicit ScParserFactoryMap();
63 Reference
< XFormulaParser
> createFormulaParser(
64 const Reference
< XComponent
>& rxComponent
,
65 const OUString
& rNamespace
);
68 typedef ::std::hash_map
<
70 Reference
< XSingleComponentFactory
>,
72 ::std::equal_to
< OUString
> > FactoryMap
;
74 Reference
< XComponentContext
> mxContext
; /// Default context of global process factory.
75 FactoryMap maFactories
; /// All parser factories, mapped by formula namespace.
78 ScParserFactoryMap::ScParserFactoryMap()
82 // get process factory and default component context
83 Reference
< XMultiServiceFactory
> xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW
);
84 Reference
< XPropertySet
> xPropSet( xFactory
, UNO_QUERY_THROW
);
85 mxContext
.set( xPropSet
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), UNO_QUERY_THROW
);
87 // enumerate all implementations of the FormulaParser service
88 Reference
< XContentEnumerationAccess
> xFactoryEA( xFactory
, UNO_QUERY_THROW
);
89 Reference
< XEnumeration
> xEnum( xFactoryEA
->createContentEnumeration( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FilterFormulaParser" ) ) ), UNO_SET_THROW
);
90 while( xEnum
->hasMoreElements() ) try // single try/catch for every element
92 // create an instance of the formula parser implementation
93 Reference
< XSingleComponentFactory
> xCompFactory( xEnum
->nextElement(), UNO_QUERY_THROW
);
94 Reference
< XFilterFormulaParser
> xParser( xCompFactory
->createInstanceWithContext( mxContext
), UNO_QUERY_THROW
);
96 // store factory in the map
97 OUString aNamespace
= xParser
->getSupportedNamespace();
98 if( aNamespace
.getLength() > 0 )
99 maFactories
[ aNamespace
] = xCompFactory
;
110 Reference
< XFormulaParser
> ScParserFactoryMap::createFormulaParser(
111 const Reference
< XComponent
>& rxComponent
, const OUString
& rNamespace
)
113 Reference
< XFormulaParser
> xParser
;
114 FactoryMap::const_iterator aIt
= maFactories
.find( rNamespace
);
115 if( aIt
!= maFactories
.end() ) try
117 Sequence
< Any
> aArgs( 1 );
118 aArgs
[ 0 ] <<= rxComponent
;
119 xParser
.set( aIt
->second
->createInstanceWithArgumentsAndContext( aArgs
, mxContext
), UNO_QUERY_THROW
);
127 struct ScParserFactorySingleton
: public ::rtl::Static
< ScParserFactoryMap
, ScParserFactorySingleton
> {};
131 // ============================================================================
133 ScFormulaParserPool::ScFormulaParserPool( const ScDocument
& rDoc
) :
138 ScFormulaParserPool::~ScFormulaParserPool()
142 bool ScFormulaParserPool::hasFormulaParser( const OUString
& rNamespace
)
144 return getFormulaParser( rNamespace
).is();
147 Reference
< XFormulaParser
> ScFormulaParserPool::getFormulaParser( const OUString
& rNamespace
)
149 // try to find an existing parser entry
150 ParserMap::iterator aIt
= maParsers
.find( rNamespace
);
151 if( aIt
!= maParsers
.end() )
154 // always create a new entry in the map (even if the following initialization fails)
155 Reference
< XFormulaParser
>& rxParser
= maParsers
[ rNamespace
];
157 // try to create a new parser object
158 if( SfxObjectShell
* pDocShell
= mrDoc
.GetDocumentShell() ) try
160 Reference
< XComponent
> xComponent( pDocShell
->GetModel(), UNO_QUERY_THROW
);
161 ScParserFactoryMap
& rFactoryMap
= ScParserFactorySingleton::get();
162 rxParser
= rFactoryMap
.createFormulaParser( xComponent
, rNamespace
);
170 // ============================================================================