1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 #include "vbahelper/vbaglobalbase.hxx"
24
25 #include <cppuhelper/component_context.hxx>
26 #include <comphelper/processfactory.hxx>
27 #include <com/sun/star/container/XNameContainer.hpp>
28
29 using namespace com::sun::star;
30 using namespace ooo::vba;
31
32 rtl::OUString sApplication( RTL_CONSTASCII_USTRINGPARAM("Application") );
33
34 // special key to return the Application
35 rtl::OUString sAppService( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.Application") );
36
VbaGlobalsBase(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const rtl::OUString & sDocCtxName)37 VbaGlobalsBase::VbaGlobalsBase(
38 const uno::Reference< ov::XHelperInterface >& xParent,
39 const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sDocCtxName )
40 : Globals_BASE( xParent, xContext ), msDocCtxName( sDocCtxName )
41 {
42 // overwrite context with custom one ( that contains the application )
43 // wrap the service manager as we don't want the disposing context to tear down the 'normal' ServiceManager ( or at least thats what the code appears like it wants to do )
44 uno::Any aSrvMgr;
45 if ( xContext.is() && xContext->getServiceManager().is() )
46 {
47 aSrvMgr = uno::makeAny( xContext->getServiceManager()->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.OServiceManagerWrapper") ), xContext ) );
48 }
49
50 ::cppu::ContextEntry_Init aHandlerContextInfo[] =
51 {
52 ::cppu::ContextEntry_Init( sApplication, uno::Any() ),
53 ::cppu::ContextEntry_Init( sDocCtxName, uno::Any() ),
54 ::cppu::ContextEntry_Init( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.lang.theServiceManager" ) ), aSrvMgr )
55 };
56 // don't pass a delegate, this seems to introduce yet another cyclic dependency ( and
57 // some strange behavior
58 mxContext = ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), NULL );
59 }
60
~VbaGlobalsBase()61 VbaGlobalsBase::~VbaGlobalsBase()
62 {
63 try
64 {
65 uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY );
66 if ( xNameContainer.is() )
67 {
68 // release document reference ( we don't wan't the component context trying to dispose that )
69 xNameContainer->removeByName( msDocCtxName );
70 // release application reference, as it is holding onto the context
71 xNameContainer->removeByName( sApplication );
72 }
73 }
74 catch ( const uno::Exception& )
75 {
76 }
77 }
78
79 void
init(const uno::Sequence<beans::PropertyValue> & aInitArgs)80 VbaGlobalsBase::init( const uno::Sequence< beans::PropertyValue >& aInitArgs )
81 {
82 sal_Int32 nLen = aInitArgs.getLength();
83 for ( sal_Int32 nIndex = 0; nIndex < nLen; ++nIndex )
84 {
85 uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY_THROW );
86 if ( aInitArgs[ nIndex ].Name.equals( sApplication ) )
87 {
88 xNameContainer->replaceByName( sApplication, aInitArgs[ nIndex ].Value );
89 uno::Reference< XHelperInterface > xParent( aInitArgs[ nIndex ].Value, uno::UNO_QUERY );
90 mxParent = xParent;
91 }
92 else
93 xNameContainer->replaceByName( aInitArgs[ nIndex ].Name, aInitArgs[ nIndex ].Value );
94 }
95 }
96
97 uno::Reference< uno::XInterface > SAL_CALL
createInstance(const::rtl::OUString & aServiceSpecifier)98 VbaGlobalsBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (uno::Exception, uno::RuntimeException)
99 {
100 uno::Reference< uno::XInterface > xReturn;
101 if ( aServiceSpecifier.equals( sAppService ) )
102 {
103 // try to extract the Application from the context
104 uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY );
105 xNameContainer->getByName( sApplication ) >>= xReturn;
106 }
107 else if ( hasServiceName( aServiceSpecifier ) )
108 xReturn = mxContext->getServiceManager()->createInstanceWithContext( aServiceSpecifier, mxContext );
109 return xReturn;
110 }
111
112 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const::rtl::OUString & aServiceSpecifier,const uno::Sequence<uno::Any> & Arguments)113 VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException)
114 {
115
116 uno::Reference< uno::XInterface > xReturn;
117 if ( aServiceSpecifier.equals( sAppService ) )
118 {
119 // try to extract the Application from the context
120 uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY );
121 xNameContainer->getByName( sApplication ) >>= xReturn;
122 }
123 else if ( hasServiceName( aServiceSpecifier ) )
124 xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceSpecifier, Arguments, mxContext );
125 return xReturn;
126 }
127
128 uno::Sequence< ::rtl::OUString > SAL_CALL
getAvailableServiceNames()129 VbaGlobalsBase::getAvailableServiceNames( ) throw (uno::RuntimeException)
130 {
131 static const rtl::OUString names[] = {
132 // common
133 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.msforms.UserForm" ) ),
134 };
135 static uno::Sequence< rtl::OUString > serviceNames( names, sizeof( names )/ sizeof( names[0] ) );
136 return serviceNames;
137 }
138
139 bool
hasServiceName(const rtl::OUString & serviceName)140 VbaGlobalsBase::hasServiceName( const rtl::OUString& serviceName )
141 {
142 uno::Sequence< rtl::OUString > sServiceNames( getAvailableServiceNames() );
143 sal_Int32 nLen = sServiceNames.getLength();
144 for ( sal_Int32 index = 0; index < nLen; ++index )
145 {
146 if ( sServiceNames[ index ].equals( serviceName ) )
147 return true;
148 }
149 return false;
150 }
151
152
153