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