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 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include <uifactory/uicontrollerfactory.hxx>
28 #include <uifactory/factoryconfiguration.hxx>
29 #include <threadhelp/resetableguard.hxx>
30 #include "services.h"
31 
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/container/XNameContainer.hpp>
36 #include <com/sun/star/container/XContainer.hpp>
37 
38 #include <rtl/ustrbuf.hxx>
39 #include <cppuhelper/weak.hxx>
40 
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::beans;
44 using namespace com::sun::star::container;
45 using namespace ::com::sun::star::frame;
46 
47 namespace framework
48 {
49 
UIControllerFactory(const Reference<XMultiServiceFactory> & xServiceManager,const rtl::OUString & rConfigurationNode)50 UIControllerFactory::UIControllerFactory(
51     const Reference< XMultiServiceFactory >& xServiceManager,
52     const rtl::OUString &rConfigurationNode )
53     : ThreadHelpBase()
54     , m_bConfigRead( sal_False )
55     , m_xServiceManager( xServiceManager )
56     , m_pConfigAccess()
57 {
58     rtl::OUStringBuffer aBuffer;
59     aBuffer.appendAscii(
60         RTL_CONSTASCII_STRINGPARAM(
61             "/org.openoffice.Office.UI.Controller/Registered/" ) );
62     aBuffer.append( rConfigurationNode );
63     m_pConfigAccess = new ConfigurationAccess_ControllerFactory(
64         m_xServiceManager, aBuffer.makeStringAndClear() );
65     m_pConfigAccess->acquire();
66 }
67 
~UIControllerFactory()68 UIControllerFactory::~UIControllerFactory()
69 {
70     ResetableGuard aLock( m_aLock );
71 
72     // reduce reference count
73     m_pConfigAccess->release();
74 }
75 
76 // XMultiComponentFactory
createInstanceWithContext(const::rtl::OUString & aServiceSpecifier,const Reference<XComponentContext> &)77 Reference< XInterface > SAL_CALL UIControllerFactory::createInstanceWithContext(
78     const ::rtl::OUString& aServiceSpecifier,
79     const Reference< XComponentContext >& )
80 throw (Exception, RuntimeException)
81 {
82     // SAFE
83     ResetableGuard aLock( m_aLock );
84 
85     if ( !m_bConfigRead )
86     {
87         m_bConfigRead = sal_True;
88         m_pConfigAccess->readConfigurationData();
89     }
90 
91     rtl::OUString aServiceName = m_pConfigAccess->getServiceFromCommandModule( aServiceSpecifier, rtl::OUString() );
92     if ( aServiceName.getLength() > 0 )
93         return m_xServiceManager->createInstance( aServiceName );
94     else
95         return Reference< XInterface >();
96     // SAFE
97 }
98 
createInstanceWithArgumentsAndContext(const::rtl::OUString & ServiceSpecifier,const Sequence<Any> & Arguments,const Reference<XComponentContext> &)99 Reference< XInterface > SAL_CALL UIControllerFactory::createInstanceWithArgumentsAndContext(
100     const ::rtl::OUString&                  ServiceSpecifier,
101     const Sequence< Any >&                  Arguments,
102     const Reference< XComponentContext >& )
103 throw (Exception, RuntimeException)
104 {
105     const rtl::OUString aPropModuleName( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
106     const rtl::OUString aPropValueName( RTL_CONSTASCII_USTRINGPARAM( "Value" ));
107 
108     rtl::OUString   aPropName;
109     PropertyValue   aPropValue;
110 
111     // Retrieve the optional module name form the Arguments sequence. It is used as a part of
112     // the hash map key to support different controller implementation for the same URL but different
113     // module!!
114     for ( int i = 0; i < Arguments.getLength(); i++ )
115     {
116         if (( Arguments[i] >>= aPropValue ) && ( aPropValue.Name.equals( aPropModuleName )))
117         {
118             aPropValue.Value >>= aPropName;
119             break;
120         }
121     }
122 
123     Sequence< Any > aNewArgs( Arguments );
124 
125     sal_Int32 nAppendIndex = aNewArgs.getLength();
126     bool bHasValue = m_pConfigAccess->hasValue();
127     aNewArgs.realloc( aNewArgs.getLength() + (bHasValue ? 2 : 1) );
128 
129     // Append the command URL to the Arguments sequence so that one controller can be
130     // used for more than one command URL.
131     aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
132     aPropValue.Value  <<= ServiceSpecifier;
133     aNewArgs[nAppendIndex] <<= aPropValue;
134 
135     if ( bHasValue )
136     {
137         // Append the optional value argument. It's an empty string if no additional info
138         // is provided to the controller.
139         rtl::OUString aValue = m_pConfigAccess->getValueFromCommandModule( ServiceSpecifier, aPropName );
140         aPropValue.Name = aPropValueName;
141         aPropValue.Value <<= aValue;
142         aNewArgs[nAppendIndex+1] <<= aPropValue;
143     }
144 
145     {
146         // SAFE
147         ResetableGuard aLock( m_aLock );
148 
149         if ( !m_bConfigRead )
150         {
151             m_bConfigRead = sal_True;
152             m_pConfigAccess->readConfigurationData();
153         }
154 
155         rtl::OUString aServiceName = m_pConfigAccess->getServiceFromCommandModule( ServiceSpecifier, aPropName );
156         Reference< XMultiServiceFactory > xServiceManager( m_xServiceManager );
157 
158         aLock.unlock();
159         // SAFE
160 
161         if ( aServiceName.getLength() > 0 )
162             return xServiceManager->createInstanceWithArguments( aServiceName, aNewArgs );
163         else
164             return Reference< XInterface >();
165     }
166 }
167 
getAvailableServiceNames()168 Sequence< ::rtl::OUString > SAL_CALL UIControllerFactory::getAvailableServiceNames()
169 throw (RuntimeException)
170 {
171     return Sequence< ::rtl::OUString >();
172 }
173 
174 // XUIControllerRegistration
hasController(const::rtl::OUString & aCommandURL,const rtl::OUString & aModuleName)175 sal_Bool SAL_CALL UIControllerFactory::hasController(
176     const ::rtl::OUString& aCommandURL,
177     const rtl::OUString& aModuleName )
178 throw (::com::sun::star::uno::RuntimeException)
179 {
180     ResetableGuard aLock( m_aLock );
181 
182     if ( !m_bConfigRead )
183     {
184         m_bConfigRead = sal_True;
185         m_pConfigAccess->readConfigurationData();
186     }
187 
188     return ( m_pConfigAccess->getServiceFromCommandModule( aCommandURL, aModuleName ).getLength() > 0 );
189 }
190 
registerController(const::rtl::OUString & aCommandURL,const::rtl::OUString & aModuleName,const::rtl::OUString & aControllerImplementationName)191 void SAL_CALL UIControllerFactory::registerController(
192     const ::rtl::OUString& aCommandURL,
193     const ::rtl::OUString& aModuleName,
194     const ::rtl::OUString& aControllerImplementationName )
195 throw (RuntimeException)
196 {
197     // SAFE
198     ResetableGuard aLock( m_aLock );
199 
200     if ( !m_bConfigRead )
201     {
202         m_bConfigRead = sal_True;
203         m_pConfigAccess->readConfigurationData();
204     }
205 
206     m_pConfigAccess->addServiceToCommandModule( aCommandURL, aModuleName, aControllerImplementationName );
207     // SAFE
208 }
209 
deregisterController(const::rtl::OUString & aCommandURL,const rtl::OUString & aModuleName)210 void SAL_CALL UIControllerFactory::deregisterController(
211     const ::rtl::OUString& aCommandURL,
212     const rtl::OUString& aModuleName )
213 throw (RuntimeException)
214 {
215     // SAFE
216     ResetableGuard aLock( m_aLock );
217 
218     if ( !m_bConfigRead )
219     {
220         m_bConfigRead = sal_True;
221         m_pConfigAccess->readConfigurationData();
222     }
223 
224     m_pConfigAccess->removeServiceFromCommandModule( aCommandURL, aModuleName );
225     // SAFE
226 }
227 
228 
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(PopupMenuControllerFactory,::cppu::OWeakObject,SERVICENAME_POPUPMENUCONTROLLERFACTORY,IMPLEMENTATIONNAME_POPUPMENUCONTROLLERFACTORY)229 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   PopupMenuControllerFactory                      ,
230                                             ::cppu::OWeakObject                             ,
231                                             SERVICENAME_POPUPMENUCONTROLLERFACTORY          ,
232                                             IMPLEMENTATIONNAME_POPUPMENUCONTROLLERFACTORY
233                                         )
234 
235 DEFINE_INIT_SERVICE                     (   PopupMenuControllerFactory, {} )
236 
237 PopupMenuControllerFactory::PopupMenuControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
238     UIControllerFactory(
239         xServiceManager,
240         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PopupMenu" )) )
241 {
242 }
243 
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(ToolbarControllerFactory,::cppu::OWeakObject,SERVICENAME_TOOLBARCONTROLLERFACTORY,IMPLEMENTATIONNAME_TOOLBARCONTROLLERFACTORY)244 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   ToolbarControllerFactory                     ,
245                                             ::cppu::OWeakObject                             ,
246                                             SERVICENAME_TOOLBARCONTROLLERFACTORY            ,
247                                             IMPLEMENTATIONNAME_TOOLBARCONTROLLERFACTORY
248                                         )
249 
250 DEFINE_INIT_SERVICE                     (   ToolbarControllerFactory, {} )
251 
252 ToolbarControllerFactory::ToolbarControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
253     UIControllerFactory(
254         xServiceManager,
255         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolBar" )))
256 {
257 }
258 
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(StatusbarControllerFactory,::cppu::OWeakObject,SERVICENAME_STATUSBARCONTROLLERFACTORY,IMPLEMENTATIONNAME_STATUSBARCONTROLLERFACTORY)259 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   StatusbarControllerFactory                      ,
260                                             ::cppu::OWeakObject                             ,
261                                             SERVICENAME_STATUSBARCONTROLLERFACTORY          ,
262                                             IMPLEMENTATIONNAME_STATUSBARCONTROLLERFACTORY
263                                         )
264 
265 DEFINE_INIT_SERVICE                     (   StatusbarControllerFactory, {} )
266 
267 StatusbarControllerFactory::StatusbarControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
268     UIControllerFactory(
269         xServiceManager,
270         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusBar" )) )
271 {
272 }
273 
274 } // namespace framework
275