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 #include <accelerators/documentacceleratorconfiguration.hxx>
27 
28 #ifndef __FRAMEWORK_XML_ACCELERATORCONFIGURATIONREADER_HXX_
29 #include <xml/acceleratorconfigurationreader.hxx>
30 #endif
31 
32 #ifndef __FRAMEWORK_XML_ACCELERATORCONFIGURATIONWRITER_HXX_
33 #include <xml/acceleratorconfigurationwriter.hxx>
34 #endif
35 
36 #ifndef __FRAMEWORK_XML_SAXNAMESPACEFILTER_HXX_
37 #include <xml/saxnamespacefilter.hxx>
38 #endif
39 
40 //_______________________________________________
41 // own includes
42 #include <threadhelp/readguard.hxx>
43 #include <threadhelp/writeguard.hxx>
44 
45 #ifndef __FRAMEWORK_ACCELERATORCONST_H_
46 #include <acceleratorconst.h>
47 #endif
48 #include <services.h>
49 
50 //_______________________________________________
51 // interface includes
52 
53 #ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
54 #include <com/sun/star/io/XActiveDataSource.hpp>
55 #endif
56 
57 #ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
58 #include <com/sun/star/io/XSeekable.hpp>
59 #endif
60 
61 #ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_
62 #include <com/sun/star/io/XTruncate.hpp>
63 #endif
64 
65 #ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
66 #include <com/sun/star/embed/ElementModes.hpp>
67 #endif
68 
69 #ifndef _COM_SUN_STAR_XML_SAX_INPUTSOURCE_HPP_
70 #include <com/sun/star/xml/sax/InputSource.hpp>
71 #endif
72 
73 #ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP_
74 #include <com/sun/star/xml/sax/XParser.hpp>
75 #endif
76 
77 //_______________________________________________
78 // other includes
79 
80 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX
81 #include <comphelper/sequenceashashmap.hxx>
82 #endif
83 
84 //_______________________________________________
85 // const
86 
87 namespace framework
88 {
89 
90 //-----------------------------------------------
91 // XInterface, XTypeProvider, XServiceInfo
DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration,XMLBasedAcceleratorConfiguration,DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::lang::XInitialization))92 DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration                   ,
93                     XMLBasedAcceleratorConfiguration                           ,
94                     DIRECT_INTERFACE(css::lang::XServiceInfo)          ,
95                     DIRECT_INTERFACE(css::lang::XInitialization))
96 //                    DIRECT_INTERFACE(css::ui::XUIConfigurationStorage))
97 
98 DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(DocumentAcceleratorConfiguration ,
99                                       XMLBasedAcceleratorConfiguration         ,
100                                       css::lang::XServiceInfo          ,
101                                       css::lang::XInitialization)
102 //                                      css::ui::XUIConfigurationStorage)
103 
104 DEFINE_XSERVICEINFO_MULTISERVICE(DocumentAcceleratorConfiguration                   ,
105                                  ::cppu::OWeakObject                                ,
106                                  SERVICENAME_DOCUMENTACCELERATORCONFIGURATION       ,
107                                  IMPLEMENTATIONNAME_DOCUMENTACCELERATORCONFIGURATION)
108 
109 DEFINE_INIT_SERVICE(DocumentAcceleratorConfiguration,
110                     {
111                         /*Attention
112                         I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
113                         to create a new instance of this class by our own supported service factory.
114                         see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
115                         */
116                     }
117                    )
118 
119 //-----------------------------------------------
120 DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
121     : XMLBasedAcceleratorConfiguration(xSMGR)
122 {
123 }
124 
125 //-----------------------------------------------
~DocumentAcceleratorConfiguration()126 DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
127 {
128     m_aPresetHandler.removeStorageListener(this);
129 }
130 
131 //-----------------------------------------------
initialize(const css::uno::Sequence<css::uno::Any> & lArguments)132 void SAL_CALL DocumentAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
133     throw(css::uno::Exception       ,
134           css::uno::RuntimeException)
135 {
136     // SAFE -> ----------------------------------
137     WriteGuard aWriteLock(m_aLock);
138 
139     ::comphelper::SequenceAsHashMap lArgs(lArguments);
140     m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
141                         ::rtl::OUString::createFromAscii("DocumentRoot"),
142                         css::uno::Reference< css::embed::XStorage >());
143 
144     aWriteLock.unlock();
145     // <- SAFE ----------------------------------
146 
147     impl_ts_fillCache();
148 }
149 
150 //-----------------------------------------------
setStorage(const css::uno::Reference<css::embed::XStorage> & xStorage)151 void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
152 	throw(css::uno::RuntimeException)
153 {
154 	// Attention! xStorage must be accepted too, if it's NULL !
155 
156 	// SAFE -> ----------------------------------
157 	WriteGuard aWriteLock(m_aLock);
158 	sal_Bool bForgetOldStorages = m_xDocumentRoot.is();
159 	m_xDocumentRoot = xStorage;
160 	aWriteLock.unlock();
161 	// <- SAFE ----------------------------------
162 
163 	if (bForgetOldStorages)
164 		impl_ts_clearCache();
165 
166 	if (xStorage.is())
167 		impl_ts_fillCache();
168 }
169 
170 //-----------------------------------------------
hasStorage()171 sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
172 	throw(css::uno::RuntimeException)
173 {
174 	// SAFE -> ----------------------------------
175 	ReadGuard aReadLock(m_aLock);
176 	return m_xDocumentRoot.is();
177 	// <- SAFE ----------------------------------
178 }
179 
180 //-----------------------------------------------
impl_ts_fillCache()181 void DocumentAcceleratorConfiguration::impl_ts_fillCache()
182 {
183 	// SAFE -> ----------------------------------
184 	ReadGuard aReadLock(m_aLock);
185 	css::uno::Reference< css::embed::XStorage > xDocumentRoot = m_xDocumentRoot;
186 	aReadLock.unlock();
187 	// <- SAFE ----------------------------------
188 
189 	// Sometimes we must live without a document root.
190 	// E.g. if the document is readonly ...
191 	if (!xDocumentRoot.is())
192 		return;
193 
194 	// get current office locale ... but dont cache it.
195 	// Otherwise we must be listener on the configuration layer
196 	// which seems to superflous for this small implementation .-)
197 	::comphelper::Locale aLocale = impl_ts_getLocale();
198 
199 	// May be the current document does not contain any
200 	// accelerator config? Handle it gracefully :-)
201 	try
202 	{
203 		// Note: The used preset class is threadsafe by itself ... and live if we live!
204 		// We do not need any mutex here.
205 
206 		// open the folder, where the configuration exists
207 		m_aPresetHandler.connectToResource(
208 			PresetHandler::E_DOCUMENT,
209 			PresetHandler::RESOURCETYPE_ACCELERATOR(),
210 			::rtl::OUString(),
211 			xDocumentRoot,
212 			aLocale);
213 
214 		DocumentAcceleratorConfiguration::reload();
215 		m_aPresetHandler.addStorageListener(this);
216 	}
217 	/*
218 
219 	Sometimes the configuration seems to be corrupted...
220 	So it would be nice if we don't crash the office then .-)
221 	#121559#
222 
223 	catch(const css::uno::RuntimeException& exRun)
224 	{ throw exRun; }
225 	*/
226 	catch(const css::uno::Exception&)
227 	{}
228 }
229 
230 //-----------------------------------------------
impl_ts_clearCache()231 void DocumentAcceleratorConfiguration::impl_ts_clearCache()
232 {
233     m_aPresetHandler.forgetCachedStorages();
234 }
235 
236 } // namespace framework
237