1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 #include <accelerators/documentacceleratorconfiguration.hxx>
31 
32 #ifndef __FRAMEWORK_XML_ACCELERATORCONFIGURATIONREADER_HXX_
33 #include <xml/acceleratorconfigurationreader.hxx>
34 #endif
35 
36 #ifndef __FRAMEWORK_XML_ACCELERATORCONFIGURATIONWRITER_HXX_
37 #include <xml/acceleratorconfigurationwriter.hxx>
38 #endif
39 
40 #ifndef __FRAMEWORK_XML_SAXNAMESPACEFILTER_HXX_
41 #include <xml/saxnamespacefilter.hxx>
42 #endif
43 
44 //_______________________________________________
45 // own includes
46 #include <threadhelp/readguard.hxx>
47 #include <threadhelp/writeguard.hxx>
48 
49 #ifndef __FRAMEWORK_ACCELERATORCONST_H_
50 #include <acceleratorconst.h>
51 #endif
52 #include <services.h>
53 
54 //_______________________________________________
55 // interface includes
56 
57 #ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
58 #include <com/sun/star/io/XActiveDataSource.hpp>
59 #endif
60 
61 #ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
62 #include <com/sun/star/io/XSeekable.hpp>
63 #endif
64 
65 #ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_
66 #include <com/sun/star/io/XTruncate.hpp>
67 #endif
68 
69 #ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
70 #include <com/sun/star/embed/ElementModes.hpp>
71 #endif
72 
73 #ifndef _COM_SUN_STAR_XML_SAX_INPUTSOURCE_HPP_
74 #include <com/sun/star/xml/sax/InputSource.hpp>
75 #endif
76 
77 #ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP_
78 #include <com/sun/star/xml/sax/XParser.hpp>
79 #endif
80 
81 //_______________________________________________
82 // other includes
83 
84 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX
85 #include <comphelper/sequenceashashmap.hxx>
86 #endif
87 
88 //_______________________________________________
89 // const
90 
91 namespace framework
92 {
93 
94 //-----------------------------------------------
95 // XInterface, XTypeProvider, XServiceInfo
96 DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration                   ,
97                     XMLBasedAcceleratorConfiguration                           ,
98                     DIRECT_INTERFACE(css::lang::XServiceInfo)          ,
99                     DIRECT_INTERFACE(css::lang::XInitialization))
100 //                    DIRECT_INTERFACE(css::ui::XUIConfigurationStorage))
101 
102 DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(DocumentAcceleratorConfiguration ,
103                                       XMLBasedAcceleratorConfiguration         ,
104                                       css::lang::XServiceInfo          ,
105                                       css::lang::XInitialization)
106 //                                      css::ui::XUIConfigurationStorage)
107 
108 DEFINE_XSERVICEINFO_MULTISERVICE(DocumentAcceleratorConfiguration                   ,
109                                  ::cppu::OWeakObject                                ,
110                                  SERVICENAME_DOCUMENTACCELERATORCONFIGURATION       ,
111                                  IMPLEMENTATIONNAME_DOCUMENTACCELERATORCONFIGURATION)
112 
113 DEFINE_INIT_SERVICE(DocumentAcceleratorConfiguration,
114                     {
115                         /*Attention
116                         I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
117                         to create a new instance of this class by our own supported service factory.
118                         see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
119                         */
120                     }
121                    )
122 
123 //-----------------------------------------------
124 DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
125     : XMLBasedAcceleratorConfiguration(xSMGR)
126 {
127 }
128 
129 //-----------------------------------------------
130 DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
131 {
132     m_aPresetHandler.removeStorageListener(this);
133 }
134 
135 //-----------------------------------------------
136 void SAL_CALL DocumentAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
137     throw(css::uno::Exception       ,
138           css::uno::RuntimeException)
139 {
140     // SAFE -> ----------------------------------
141     WriteGuard aWriteLock(m_aLock);
142 
143     ::comphelper::SequenceAsHashMap lArgs(lArguments);
144     m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
145                         ::rtl::OUString::createFromAscii("DocumentRoot"),
146                         css::uno::Reference< css::embed::XStorage >());
147 
148     aWriteLock.unlock();
149     // <- SAFE ----------------------------------
150 
151     impl_ts_fillCache();
152 }
153 
154 //-----------------------------------------------
155 void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
156 	throw(css::uno::RuntimeException)
157 {
158 	// Attention! xStorage must be accepted too, if it's NULL !
159 
160 	// SAFE -> ----------------------------------
161 	WriteGuard aWriteLock(m_aLock);
162 	sal_Bool bForgetOldStorages = m_xDocumentRoot.is();
163 	m_xDocumentRoot = xStorage;
164 	aWriteLock.unlock();
165 	// <- SAFE ----------------------------------
166 
167 	if (bForgetOldStorages)
168 		impl_ts_clearCache();
169 
170 	if (xStorage.is())
171 		impl_ts_fillCache();
172 }
173 
174 //-----------------------------------------------
175 sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
176 	throw(css::uno::RuntimeException)
177 {
178 	// SAFE -> ----------------------------------
179 	ReadGuard aReadLock(m_aLock);
180 	return m_xDocumentRoot.is();
181 	// <- SAFE ----------------------------------
182 }
183 
184 //-----------------------------------------------
185 void DocumentAcceleratorConfiguration::impl_ts_fillCache()
186 {
187 	// SAFE -> ----------------------------------
188 	ReadGuard aReadLock(m_aLock);
189 	css::uno::Reference< css::embed::XStorage > xDocumentRoot = m_xDocumentRoot;
190 	aReadLock.unlock();
191 	// <- SAFE ----------------------------------
192 
193 	// Sometimes we must live without a document root.
194 	// E.g. if the document is readonly ...
195 	if (!xDocumentRoot.is())
196 		return;
197 
198 	// get current office locale ... but dont cache it.
199 	// Otherwise we must be listener on the configuration layer
200 	// which seems to superflous for this small implementation .-)
201 	::comphelper::Locale aLocale = impl_ts_getLocale();
202 
203 	// May be the current document does not contain any
204 	// accelerator config? Handle it gracefully :-)
205 	try
206 	{
207 		// Note: The used preset class is threadsafe by itself ... and live if we live!
208 		// We do not need any mutex here.
209 
210 		// open the folder, where the configuration exists
211 		m_aPresetHandler.connectToResource(
212 			PresetHandler::E_DOCUMENT,
213 			PresetHandler::RESOURCETYPE_ACCELERATOR(),
214 			::rtl::OUString(),
215 			xDocumentRoot,
216 			aLocale);
217 
218 		DocumentAcceleratorConfiguration::reload();
219 		m_aPresetHandler.addStorageListener(this);
220 	}
221 	/*
222 
223 	Sometimes the configuration seams to be corrupted ..
224 	So it would be nice if we dont crash the office then .-)
225 	#121559#
226 
227 	catch(const css::uno::RuntimeException& exRun)
228 	{ throw exRun; }
229 	*/
230 	catch(const css::uno::Exception&)
231 	{}
232 }
233 
234 //-----------------------------------------------
235 void DocumentAcceleratorConfiguration::impl_ts_clearCache()
236 {
237     m_aPresetHandler.forgetCachedStorages();
238 }
239 
240 } // namespace framework
241