1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inetoptions.cxx,v $
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>
37 #include <tools/wldcrd.hxx>
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 //============================================================================
70 //============================================================================
74 template< typename T
> inline T
takeAny(star::uno::Any
const & rAny
)
83 //============================================================================
85 // SvtInetOptions::Impl
87 //============================================================================
89 class SvtInetOptions::Impl
: public salhelper::ReferenceObject
,
90 public utl::ConfigItem
99 INDEX_HTTP_PROXY_NAME
,
100 INDEX_HTTP_PROXY_PORT
105 star::uno::Any
getProperty(Index nIndex
);
108 setProperty(Index nIndex
, star::uno::Any
const & rValue
, bool bFlush
);
110 inline void flush() { Commit(); }
113 addPropertiesChangeListener(
114 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
115 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
119 removePropertiesChangeListener(
120 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
121 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
125 enum { ENTRY_COUNT
= INDEX_HTTP_PROXY_PORT
+ 1 };
129 enum State
{ UNKNOWN
, KNOWN
, MODIFIED
};
131 inline Entry(): m_eState(UNKNOWN
) {}
133 rtl::OUString m_aName
;
134 star::uno::Any m_aValue
;
138 // MSVC has problems with the below Map type when
139 // star::uno::Reference< star::beans::XPropertiesChangeListener > is not
140 // wrapped in class Listener:
142 public star::uno::Reference
< star::beans::XPropertiesChangeListener
>
145 Listener(star::uno::Reference
<
146 star::beans::XPropertiesChangeListener
> const &
148 star::uno::Reference
< star::beans::XPropertiesChangeListener
>(
153 typedef std::map
< Listener
, std::set
< rtl::OUString
> > Map
;
156 Entry m_aEntries
[ENTRY_COUNT
];
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 //============================================================================
171 SvtInetOptions::Impl::Notify(star::uno::Sequence
< rtl::OUString
> const &
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
;
184 notifyListeners(rKeys
);
187 //============================================================================
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
;
202 m_aEntries
[i
].m_eState
= Entry::KNOWN
;
207 aKeys
.realloc(nCount
);
208 aValues
.realloc(nCount
);
209 PutProperties(aKeys
, aValues
);
213 //============================================================================
215 SvtInetOptions::Impl::notifyListeners(
216 star::uno::Sequence
< rtl::OUString
> const & rKeys
)
219 std::vector
< std::pair
< star::uno::Reference
<
220 star::beans::XPropertiesChangeListener
>,
222 star::beans::PropertyChangeEvent
> > >
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
;
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
)
240 aTheKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
243 if (rSet
.find(aTheKey
) != aSetEnd
)
245 aEvents
[nCount
].PropertyName
= aTheKey
;
246 aEvents
[nCount
].PropertyHandle
= -1;
252 aEvents
.realloc(nCount
);
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
))
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
;
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
;
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
,
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
;
361 star::uno::Sequence
< star::uno::Any
> aValues(1);
363 PutProperties(aKeys
, aValues
);
366 notifyListeners(aKeys
);
369 //============================================================================
371 SvtInetOptions::Impl::addPropertiesChangeListener(
372 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
373 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
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 //============================================================================
384 SvtInetOptions::Impl::removePropertiesChangeListener(
385 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
386 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
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 //============================================================================
404 //============================================================================
408 class LocalSingleton
: public rtl::Static
< osl::Mutex
, LocalSingleton
>
414 SvtInetOptions::Impl
* SvtInetOptions::m_pImpl
= 0;
416 //============================================================================
417 SvtInetOptions::SvtInetOptions()
419 osl::MutexGuard
aGuard(LocalSingleton::get());
422 RTL_LOGFILE_CONTEXT(aLog
, "svtools ( ??? ) ::SvtInetOptions_Impl::ctor()");
425 ItemHolder1::holdConfigItem(E_INETOPTIONS
);
430 //============================================================================
431 SvtInetOptions::~SvtInetOptions()
433 osl::MutexGuard
aGuard(LocalSingleton::get());
434 if (m_pImpl
->release() == 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
->
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
->
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
,
486 m_pImpl
->setProperty(Impl::INDEX_NO_PROXY
,
487 star::uno::makeAny(rValue
),
491 //============================================================================
492 void SvtInetOptions::SetProxyType(ProxyType eValue
, bool bFlush
)
494 m_pImpl
->setProperty(Impl::INDEX_PROXY_TYPE
,
495 star::uno::makeAny(sal_Int32(eValue
)),
499 //============================================================================
500 void SvtInetOptions::SetProxyFtpName(rtl::OUString
const & rValue
,
503 m_pImpl
->setProperty(Impl::INDEX_FTP_PROXY_NAME
,
504 star::uno::makeAny(rValue
),
508 //============================================================================
509 void SvtInetOptions::SetProxyFtpPort(sal_Int32 nValue
, bool bFlush
)
511 m_pImpl
->setProperty(Impl::INDEX_FTP_PROXY_PORT
,
512 star::uno::makeAny(nValue
),
516 //============================================================================
517 void SvtInetOptions::SetProxyHttpName(rtl::OUString
const & rValue
,
520 m_pImpl
->setProperty(Impl::INDEX_HTTP_PROXY_NAME
,
521 star::uno::makeAny(rValue
),
525 //============================================================================
526 void SvtInetOptions::SetProxyHttpPort(sal_Int32 nValue
, bool bFlush
)
528 m_pImpl
->setProperty(Impl::INDEX_HTTP_PROXY_PORT
,
529 star::uno::makeAny(nValue
),
533 //============================================================================
534 void SvtInetOptions::flush()
539 //============================================================================
541 SvtInetOptions::addPropertiesChangeListener(
542 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
543 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
546 m_pImpl
->addPropertiesChangeListener(rPropertyNames
, rListener
);
549 //============================================================================
551 SvtInetOptions::removePropertiesChangeListener(
552 star::uno::Sequence
< rtl::OUString
> const & rPropertyNames
,
553 star::uno::Reference
< star::beans::XPropertiesChangeListener
> const &
556 m_pImpl
->removePropertiesChangeListener(rPropertyNames
, rListener
);