Update ooo320-m1
[ooovba.git] / svtools / source / config / inetoptions.cxx
blobb46de8763234a15fdb49b80f4f1c63a06e501866
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inetoptions.cxx,v $
10 * $Revision: 1.33 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/inetoptions.hxx>
34 #include "rtl/instance.hxx"
35 #include <tools/urlobj.hxx>
36 #ifndef _WILDCARD_HXX
37 #include <tools/wldcrd.hxx>
38 #endif
40 #include <algorithm>
41 #include <map>
42 #include <set>
43 #include <vector>
44 #include <utility>
45 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
46 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/system/XProxySettings.hpp>
49 #include <com/sun/star/uno/Any.hxx>
50 #include <com/sun/star/uno/Exception.hpp>
51 #include <com/sun/star/uno/Reference.hxx>
52 #include <com/sun/star/uno/RuntimeException.hpp>
53 #include <osl/mutex.hxx>
54 #include <rtl/ustring.h>
55 #include <rtl/ustring.hxx>
56 #include <sal/types.h>
57 #include <unotools/configitem.hxx>
58 #include <unotools/processfactory.hxx>
59 #include <osl/diagnose.h>
60 #include <salhelper/refobj.hxx>
61 #include <rtl/logfile.hxx>
62 #include "itemholder1.hxx"
64 using namespace com::sun;
66 //============================================================================
68 // takeAny
70 //============================================================================
72 namespace {
74 template< typename T > inline T takeAny(star::uno::Any const & rAny)
76 T aValue = T();
77 rAny >>= aValue;
78 return aValue;
83 //============================================================================
85 // SvtInetOptions::Impl
87 //============================================================================
89 class SvtInetOptions::Impl: public salhelper::ReferenceObject,
90 public utl::ConfigItem
92 public:
93 enum Index
95 INDEX_NO_PROXY,
96 INDEX_PROXY_TYPE,
97 INDEX_FTP_PROXY_NAME,
98 INDEX_FTP_PROXY_PORT,
99 INDEX_HTTP_PROXY_NAME,
100 INDEX_HTTP_PROXY_PORT
103 Impl();
105 star::uno::Any getProperty(Index nIndex);
107 void
108 setProperty(Index nIndex, star::uno::Any const & rValue, bool bFlush);
110 inline void flush() { Commit(); }
112 void
113 addPropertiesChangeListener(
114 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
115 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
116 rListener);
118 void
119 removePropertiesChangeListener(
120 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
121 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
122 rListener);
124 private:
125 enum { ENTRY_COUNT = INDEX_HTTP_PROXY_PORT + 1 };
127 struct Entry
129 enum State { UNKNOWN, KNOWN, MODIFIED };
131 inline Entry(): m_eState(UNKNOWN) {}
133 rtl::OUString m_aName;
134 star::uno::Any m_aValue;
135 State m_eState;
138 // MSVC has problems with the below Map type when
139 // star::uno::Reference< star::beans::XPropertiesChangeListener > is not
140 // wrapped in class Listener:
141 class Listener:
142 public star::uno::Reference< star::beans::XPropertiesChangeListener >
144 public:
145 Listener(star::uno::Reference<
146 star::beans::XPropertiesChangeListener > const &
147 rListener):
148 star::uno::Reference< star::beans::XPropertiesChangeListener >(
149 rListener)
153 typedef std::map< Listener, std::set< rtl::OUString > > Map;
155 osl::Mutex m_aMutex;
156 Entry m_aEntries[ENTRY_COUNT];
157 Map m_aListeners;
159 virtual inline ~Impl() { Commit(); }
161 virtual void Notify(star::uno::Sequence< rtl::OUString > const & rKeys);
163 virtual void Commit();
165 void notifyListeners(star::uno::Sequence< rtl::OUString > const & rKeys);
168 //============================================================================
169 // virtual
170 void
171 SvtInetOptions::Impl::Notify(star::uno::Sequence< rtl::OUString > const &
172 rKeys)
175 osl::MutexGuard aGuard(m_aMutex);
176 for (sal_Int32 i = 0; i < rKeys.getLength(); ++i)
177 for (sal_Int32 j = 0; j < ENTRY_COUNT; ++j)
178 if (rKeys[i] == m_aEntries[j].m_aName)
180 m_aEntries[j].m_eState = Entry::UNKNOWN;
181 break;
184 notifyListeners(rKeys);
187 //============================================================================
188 // virtual
189 void SvtInetOptions::Impl::Commit()
191 star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT);
192 star::uno::Sequence< star::uno::Any > aValues(ENTRY_COUNT);
193 sal_Int32 nCount = 0;
195 osl::MutexGuard aGuard(m_aMutex);
196 for (sal_Int32 i = 0; i < ENTRY_COUNT; ++i)
197 if (m_aEntries[i].m_eState == Entry::MODIFIED)
199 aKeys[nCount] = m_aEntries[i].m_aName;
200 aValues[nCount] = m_aEntries[i].m_aValue;
201 ++nCount;
202 m_aEntries[i].m_eState = Entry::KNOWN;
205 if (nCount > 0)
207 aKeys.realloc(nCount);
208 aValues.realloc(nCount);
209 PutProperties(aKeys, aValues);
213 //============================================================================
214 void
215 SvtInetOptions::Impl::notifyListeners(
216 star::uno::Sequence< rtl::OUString > const & rKeys)
218 typedef
219 std::vector< std::pair< star::uno::Reference<
220 star::beans::XPropertiesChangeListener >,
221 star::uno::Sequence<
222 star::beans::PropertyChangeEvent > > >
223 List;
224 List aNotifications;
226 osl::MutexGuard aGuard(m_aMutex);
227 aNotifications.reserve(m_aListeners.size());
228 Map::const_iterator aMapEnd(m_aListeners.end());
229 for (Map::const_iterator aIt(m_aListeners.begin()); aIt != aMapEnd;
230 ++aIt)
232 const Map::mapped_type &rSet = aIt->second;
233 Map::mapped_type::const_iterator aSetEnd(rSet.end());
234 star::uno::Sequence< star::beans::PropertyChangeEvent >
235 aEvents(rKeys.getLength());
236 sal_Int32 nCount = 0;
237 for (sal_Int32 i = 0; i < rKeys.getLength(); ++i)
239 rtl::OUString
240 aTheKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
241 "Inet/")));
242 aTheKey += rKeys[i];
243 if (rSet.find(aTheKey) != aSetEnd)
245 aEvents[nCount].PropertyName = aTheKey;
246 aEvents[nCount].PropertyHandle = -1;
247 ++nCount;
250 if (nCount > 0)
252 aEvents.realloc(nCount);
253 aNotifications.
254 push_back(std::make_pair< List::value_type::first_type,
255 List::value_type::second_type >(
256 aIt->first, aEvents));
260 for (List::size_type i = 0; i < aNotifications.size(); ++i)
261 if (aNotifications[i].first.is())
262 aNotifications[i].first->
263 propertiesChange(aNotifications[i].second);
266 //============================================================================
267 SvtInetOptions::Impl::Impl():
268 ConfigItem(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Inet/Settings")))
270 m_aEntries[INDEX_NO_PROXY].m_aName
271 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetNoProxy"));
272 m_aEntries[INDEX_PROXY_TYPE].m_aName
273 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetProxyType"));
274 m_aEntries[INDEX_FTP_PROXY_NAME].m_aName
275 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetFTPProxyName"));
276 m_aEntries[INDEX_FTP_PROXY_PORT].m_aName
277 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetFTPProxyPort"));
278 m_aEntries[INDEX_HTTP_PROXY_NAME].m_aName
279 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetHTTPProxyName"));
280 m_aEntries[INDEX_HTTP_PROXY_PORT].m_aName
281 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooInetHTTPProxyPort"));
283 star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT);
284 for (sal_Int32 i = 0; i < ENTRY_COUNT; ++i)
285 aKeys[i] = m_aEntries[i].m_aName;
286 if (!EnableNotification(aKeys))
287 OSL_ENSURE(false,
288 "SvtInetOptions::Impl::Impl(): Bad EnableNotifications()");
291 //============================================================================
292 star::uno::Any SvtInetOptions::Impl::getProperty(Index nPropIndex)
294 for (int nTryCount = 0; nTryCount < 10; ++nTryCount)
297 osl::MutexGuard aGuard(m_aMutex);
298 if (m_aEntries[nPropIndex].m_eState != Entry::UNKNOWN)
299 return m_aEntries[nPropIndex].m_aValue;
301 star::uno::Sequence< rtl::OUString > aKeys(ENTRY_COUNT);
302 int nIndices[ENTRY_COUNT];
303 sal_Int32 nCount = 0;
305 osl::MutexGuard aGuard(m_aMutex);
306 for (int i = 0; i < ENTRY_COUNT; ++i)
307 if (m_aEntries[i].m_eState == Entry::UNKNOWN)
309 aKeys[nCount] = m_aEntries[i].m_aName;
310 nIndices[nCount] = i;
311 ++nCount;
314 if (nCount > 0)
316 aKeys.realloc(nCount);
317 star::uno::Sequence< star::uno::Any >
318 aValues(GetProperties(aKeys));
319 OSL_ENSURE(aValues.getLength() == nCount,
320 "SvtInetOptions::Impl::getProperty():"
321 " Bad GetProperties() result");
322 nCount = std::min(nCount, aValues.getLength());
324 osl::MutexGuard aGuard(m_aMutex);
325 for (sal_Int32 i = 0; i < nCount; ++i)
327 int nIndex = nIndices[i];
328 if (m_aEntries[nIndex].m_eState == Entry::UNKNOWN)
330 m_aEntries[nIndices[i]].m_aValue = aValues[i];
331 m_aEntries[nIndices[i]].m_eState = Entry::KNOWN;
337 OSL_ENSURE(false,
338 "SvtInetOptions::Impl::getProperty(): Possible life lock");
340 osl::MutexGuard aGuard(m_aMutex);
341 return m_aEntries[nPropIndex].m_aValue;
345 //============================================================================
346 void SvtInetOptions::Impl::setProperty(Index nIndex,
347 star::uno::Any const & rValue,
348 bool bFlush)
350 SetModified();
352 osl::MutexGuard aGuard(m_aMutex);
353 m_aEntries[nIndex].m_aValue = rValue;
354 m_aEntries[nIndex].m_eState = bFlush ? Entry::KNOWN : Entry::MODIFIED;
357 star::uno::Sequence< rtl::OUString > aKeys(1);
358 aKeys[0] = m_aEntries[nIndex].m_aName;
359 if (bFlush)
361 star::uno::Sequence< star::uno::Any > aValues(1);
362 aValues[0] = rValue;
363 PutProperties(aKeys, aValues);
365 else
366 notifyListeners(aKeys);
369 //============================================================================
370 void
371 SvtInetOptions::Impl::addPropertiesChangeListener(
372 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
373 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
374 rListener)
376 osl::MutexGuard aGuard(m_aMutex);
377 Map::mapped_type & rEntry = m_aListeners[rListener];
378 for (sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i)
379 rEntry.insert(rPropertyNames[i]);
382 //============================================================================
383 void
384 SvtInetOptions::Impl::removePropertiesChangeListener(
385 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
386 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
387 rListener)
389 osl::MutexGuard aGuard(m_aMutex);
390 Map::iterator aIt(m_aListeners.find(rListener));
391 if (aIt != m_aListeners.end())
393 for (sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i)
394 aIt->second.erase(rPropertyNames[i]);
395 if (aIt->second.empty())
396 m_aListeners.erase(aIt);
400 //============================================================================
402 // SvtInetOptions
404 //============================================================================
406 namespace
408 class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton >
413 // static
414 SvtInetOptions::Impl * SvtInetOptions::m_pImpl = 0;
416 //============================================================================
417 SvtInetOptions::SvtInetOptions()
419 osl::MutexGuard aGuard(LocalSingleton::get());
420 if (!m_pImpl)
422 RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtInetOptions_Impl::ctor()");
423 m_pImpl = new Impl;
425 ItemHolder1::holdConfigItem(E_INETOPTIONS);
427 m_pImpl->acquire();
430 //============================================================================
431 SvtInetOptions::~SvtInetOptions()
433 osl::MutexGuard aGuard(LocalSingleton::get());
434 if (m_pImpl->release() == 0)
435 m_pImpl = 0;
438 //============================================================================
439 rtl::OUString SvtInetOptions::GetProxyNoProxy() const
441 return takeAny< rtl::OUString >(m_pImpl->
442 getProperty(Impl::INDEX_NO_PROXY));
445 //============================================================================
446 sal_Int32 SvtInetOptions::GetProxyType() const
448 return takeAny< sal_Int32 >(m_pImpl->
449 getProperty(Impl::INDEX_PROXY_TYPE));
452 //============================================================================
453 rtl::OUString SvtInetOptions::GetProxyFtpName() const
455 return takeAny< rtl::OUString >(m_pImpl->
456 getProperty(
457 Impl::INDEX_FTP_PROXY_NAME));
460 //============================================================================
461 sal_Int32 SvtInetOptions::GetProxyFtpPort() const
463 return takeAny< sal_Int32 >(m_pImpl->
464 getProperty(Impl::INDEX_FTP_PROXY_PORT));
467 //============================================================================
468 rtl::OUString SvtInetOptions::GetProxyHttpName() const
470 return takeAny< rtl::OUString >(m_pImpl->
471 getProperty(
472 Impl::INDEX_HTTP_PROXY_NAME));
475 //============================================================================
476 sal_Int32 SvtInetOptions::GetProxyHttpPort() const
478 return takeAny< sal_Int32 >(m_pImpl->
479 getProperty(Impl::INDEX_HTTP_PROXY_PORT));
482 //============================================================================
483 void SvtInetOptions::SetProxyNoProxy(rtl::OUString const & rValue,
484 bool bFlush)
486 m_pImpl->setProperty(Impl::INDEX_NO_PROXY,
487 star::uno::makeAny(rValue),
488 bFlush);
491 //============================================================================
492 void SvtInetOptions::SetProxyType(ProxyType eValue, bool bFlush)
494 m_pImpl->setProperty(Impl::INDEX_PROXY_TYPE,
495 star::uno::makeAny(sal_Int32(eValue)),
496 bFlush);
499 //============================================================================
500 void SvtInetOptions::SetProxyFtpName(rtl::OUString const & rValue,
501 bool bFlush)
503 m_pImpl->setProperty(Impl::INDEX_FTP_PROXY_NAME,
504 star::uno::makeAny(rValue),
505 bFlush);
508 //============================================================================
509 void SvtInetOptions::SetProxyFtpPort(sal_Int32 nValue, bool bFlush)
511 m_pImpl->setProperty(Impl::INDEX_FTP_PROXY_PORT,
512 star::uno::makeAny(nValue),
513 bFlush);
516 //============================================================================
517 void SvtInetOptions::SetProxyHttpName(rtl::OUString const & rValue,
518 bool bFlush)
520 m_pImpl->setProperty(Impl::INDEX_HTTP_PROXY_NAME,
521 star::uno::makeAny(rValue),
522 bFlush);
525 //============================================================================
526 void SvtInetOptions::SetProxyHttpPort(sal_Int32 nValue, bool bFlush)
528 m_pImpl->setProperty(Impl::INDEX_HTTP_PROXY_PORT,
529 star::uno::makeAny(nValue),
530 bFlush);
533 //============================================================================
534 void SvtInetOptions::flush()
536 m_pImpl->flush();
539 //============================================================================
540 void
541 SvtInetOptions::addPropertiesChangeListener(
542 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
543 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
544 rListener)
546 m_pImpl->addPropertiesChangeListener(rPropertyNames, rListener);
549 //============================================================================
550 void
551 SvtInetOptions::removePropertiesChangeListener(
552 star::uno::Sequence< rtl::OUString > const & rPropertyNames,
553 star::uno::Reference< star::beans::XPropertiesChangeListener > const &
554 rListener)
556 m_pImpl->removePropertiesChangeListener(rPropertyNames, rListener);