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_extensions.hxx"
26
27
28 #include "updatecheckconfig.hxx"
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/beans/XPropertyState.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
33
34 #include <osl/security.hxx>
35 #include <osl/time.h>
36 #include <osl/file.hxx>
37
38 #ifdef WNT
39 #ifdef _MSC_VER
40 #pragma warning(push,1) // disable warnings within system headers
41 #pragma warning(disable: 4917)
42 #endif
43 #include <shlobj.h>
44 #ifdef _MSC_VER
45 #pragma warning(pop)
46 #endif
47 #endif
48
49 namespace container = com::sun::star::container ;
50 namespace beans = com::sun::star::beans ;
51 namespace lang = com::sun::star::lang ;
52 namespace util = com::sun::star::util ;
53 namespace uno = com::sun::star::uno ;
54
55 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
56
57 #define LAST_CHECK "LastCheck"
58 #define VERSION_FOUND "UpdateVersionFound"
59 #define UPDATE_VERSION "UpdateVersion"
60 #define UPDATE_BUILDID "UpdateBuildId"
61 #define UPDATE_DESCRIPTION "UpdateDescription"
62 #define DOWNLOAD_URL "DownloadURL"
63 #define IS_DIRECT_DOWNLOAD "IsDirectDownload"
64 #define OLD_VERSION "UpdateFoundFor"
65 #define AUTOCHECK_ENABLED "AutoCheckEnabled"
66 #define AUTODOWNLOAD_ENABLED "AutoDownloadEnabled"
67 #define CHECK_INTERVAL "CheckInterval"
68 #define LOCAL_FILE "LocalFile"
69 #define DOWNLOAD_SIZE "DownloadSize"
70 #define DOWNLOAD_PAUSED "DownloadPaused"
71 #define DOWNLOAD_DESTINATION "DownloadDestination"
72 #define RELEASE_NOTE "ReleaseNote"
73 #define EXTENSION_PREFIX "Extension_"
74
75 #define PROPERTY_VERSION UNISTRING("Version")
76
77 static const sal_Char * const aUpdateEntryProperties[] = {
78 UPDATE_VERSION,
79 UPDATE_BUILDID,
80 UPDATE_DESCRIPTION,
81 DOWNLOAD_URL,
82 IS_DIRECT_DOWNLOAD,
83 RELEASE_NOTE"1",
84 RELEASE_NOTE"2",
85 RELEASE_NOTE"3",
86 RELEASE_NOTE"4",
87 RELEASE_NOTE"5",
88 OLD_VERSION
89 };
90
91 static const sal_uInt32 nUpdateEntryProperties = sizeof(aUpdateEntryProperties) / sizeof(sal_Char *);
92
93 //------------------------------------------------------------------------------
94
~NamedValueByNameAccess()95 NamedValueByNameAccess::~NamedValueByNameAccess()
96 {
97 }
98
99 //------------------------------------------------------------------------------
100
101 ::com::sun::star::uno::Any
getValue(const sal_Char * pName)102 NamedValueByNameAccess::getValue(const sal_Char * pName)
103 {
104 const sal_Int32 nLen = m_rValues.getLength();
105 for( sal_Int32 n=0; n < nLen; ++n )
106 {
107 if( m_rValues[n].Name.equalsAscii( pName ) )
108 return m_rValues[n].Value;
109 }
110 return ::com::sun::star::uno::Any();
111 }
112
113
114 //------------------------------------------------------------------------------
115
116 bool
isAutoCheckEnabled() const117 UpdateCheckROModel::isAutoCheckEnabled() const
118 {
119 return sal_True == m_aNameAccess.getValue(AUTOCHECK_ENABLED).get< sal_Bool >();
120 }
121
122 //------------------------------------------------------------------------------
123
124 bool
isDownloadPaused() const125 UpdateCheckROModel::isDownloadPaused() const
126 {
127 return sal_True == m_aNameAccess.getValue(DOWNLOAD_PAUSED).get< sal_Bool >();
128 }
129
130 //------------------------------------------------------------------------------
131
132 rtl::OUString
getStringValue(const sal_Char * pStr) const133 UpdateCheckROModel::getStringValue(const sal_Char * pStr) const
134 {
135 uno::Any aAny( m_aNameAccess.getValue(pStr) );
136 rtl::OUString aRet;
137
138 aAny >>= aRet;
139
140 return aRet;
141 }
142
143 //------------------------------------------------------------------------------
144
getLocalFileName() const145 rtl::OUString UpdateCheckROModel::getLocalFileName() const
146 {
147 return getStringValue(LOCAL_FILE);
148 };
149
150 //------------------------------------------------------------------------------
151
getDownloadSize() const152 sal_Int64 UpdateCheckROModel::getDownloadSize() const
153 {
154 uno::Any aAny( m_aNameAccess.getValue(DOWNLOAD_SIZE) );
155 sal_Int64 nRet = -1;
156
157 aAny >>= nRet;
158 return nRet;
159 };
160
161 //------------------------------------------------------------------------------
162
163 rtl::OUString
getUpdateEntryVersion() const164 UpdateCheckROModel::getUpdateEntryVersion() const
165 {
166 return getStringValue(OLD_VERSION);
167 }
168
169 //------------------------------------------------------------------------------
170
171 void
getUpdateEntry(UpdateInfo & rInfo) const172 UpdateCheckROModel::getUpdateEntry(UpdateInfo& rInfo) const
173 {
174 rInfo.BuildId = getStringValue(UPDATE_BUILDID);
175 rInfo.Version = getStringValue(UPDATE_VERSION);
176 rInfo.Description = getStringValue(UPDATE_DESCRIPTION);
177
178 sal_Bool isDirectDownload = sal_False;
179 m_aNameAccess.getValue(IS_DIRECT_DOWNLOAD) >>= isDirectDownload;
180
181 rInfo.Sources.push_back( DownloadSource( isDirectDownload, getStringValue(DOWNLOAD_URL) ) );
182
183 rtl::OString aStr(RELEASE_NOTE);
184 for(sal_Int32 n=1; n < 6; ++n )
185 {
186 rtl::OUString aUStr = getStringValue( (aStr + rtl::OString::valueOf(n)).getStr());
187 if( aUStr.getLength() > 0 )
188 rInfo.ReleaseNotes.push_back(ReleaseNote((sal_Int8) n, aUStr));
189 }
190 }
191
192
193 //------------------------------------------------------------------------------
194
getDesktopDirectory()195 rtl::OUString UpdateCheckConfig::getDesktopDirectory()
196 {
197 rtl::OUString aRet;
198
199 #ifdef WNT
200 WCHAR szPath[MAX_PATH];
201
202 if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_DESKTOPDIRECTORY, true ) ) )
203 {
204 aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) );
205 osl::FileBase::getFileURLFromSystemPath( aRet, aRet );
206 }
207 #else
208 // This should become a desktop specific setting in some system backend...
209 rtl::OUString aHomeDir;
210 osl::Security().getHomeDir( aHomeDir );
211 aRet = aHomeDir + rtl::OUString::createFromAscii("/Desktop");
212
213 // Set path to home directory when there is no /Desktop directory
214 osl::Directory aDocumentsDir( aRet );
215 if( osl::FileBase::E_None != aDocumentsDir.open() )
216 aRet = aHomeDir;
217 #endif
218
219 return aRet;
220 }
221
222 //------------------------------------------------------------------------------
223
getAllUsersDirectory()224 rtl::OUString UpdateCheckConfig::getAllUsersDirectory()
225 {
226 rtl::OUString aRet;
227
228 #ifdef WNT
229 WCHAR szPath[MAX_PATH];
230
231 if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_COMMON_DOCUMENTS, true ) ) )
232 {
233 aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) );
234 osl::FileBase::RC rc;
235 rc = osl::FileBase::getFileURLFromSystemPath( aRet, aRet );
236 }
237 #else
238 osl::FileBase::getTempDirURL(aRet);
239 #endif
240
241 return aRet;
242 }
243
244 //------------------------------------------------------------------------------
UpdateCheckConfig(const uno::Reference<container::XNameContainer> & xContainer,const uno::Reference<container::XNameContainer> & xAvailableUpdates,const uno::Reference<container::XNameContainer> & xIgnoredUpdates,const::rtl::Reference<UpdateCheckConfigListener> & rListener)245 UpdateCheckConfig::UpdateCheckConfig( const uno::Reference<container::XNameContainer>& xContainer,
246 const uno::Reference<container::XNameContainer>& xAvailableUpdates,
247 const uno::Reference<container::XNameContainer>& xIgnoredUpdates,
248 const ::rtl::Reference< UpdateCheckConfigListener >& rListener ) :
249 m_xContainer( xContainer ),
250 m_xAvailableUpdates( xAvailableUpdates ),
251 m_xIgnoredUpdates( xIgnoredUpdates ),
252 m_rListener( rListener )
253 {}
254
255 //------------------------------------------------------------------------------
~UpdateCheckConfig()256 UpdateCheckConfig::~UpdateCheckConfig()
257 {}
258
259 //------------------------------------------------------------------------------
260
261 ::rtl::Reference< UpdateCheckConfig >
get(const uno::Reference<uno::XComponentContext> & xContext,const::rtl::Reference<UpdateCheckConfigListener> & rListener)262 UpdateCheckConfig::get(
263 const uno::Reference<uno::XComponentContext>& xContext,
264 const ::rtl::Reference< UpdateCheckConfigListener >& rListener)
265 {
266 if( !xContext.is() )
267 throw uno::RuntimeException(
268 UNISTRING( "UpdateCheckConfig: empty component context" ),
269 uno::Reference< uno::XInterface >() );
270
271 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
272
273 if( !xServiceManager.is() )
274 throw uno::RuntimeException(
275 UNISTRING( "UpdateCheckConfig: unable to obtain service manager from component context" ),
276 uno::Reference< uno::XInterface >() );
277
278 uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
279 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), xContext ),
280 uno::UNO_QUERY_THROW);
281
282 beans::PropertyValue aProperty;
283 aProperty.Name = UNISTRING( "nodepath" );
284 aProperty.Value = uno::makeAny( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") );
285
286 uno::Sequence< uno::Any > aArgumentList( 1 );
287 aArgumentList[0] = uno::makeAny( aProperty );
288
289 uno::Reference< container::XNameContainer > xContainer(
290 xConfigProvider->createInstanceWithArguments(
291 UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ),
292 uno::UNO_QUERY_THROW );
293
294 aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates") );
295 aArgumentList[0] = uno::makeAny( aProperty );
296 uno::Reference< container::XNameContainer > xIgnoredExt( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW );
297
298 aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/AvailableUpdates") );
299 aArgumentList[0] = uno::makeAny( aProperty );
300 uno::Reference< container::XNameContainer > xUpdateAvail( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW );
301
302 return new UpdateCheckConfig( xContainer, xUpdateAvail, xIgnoredExt, rListener );
303 }
304
305 //------------------------------------------------------------------------------
306
307 bool
isAutoCheckEnabled() const308 UpdateCheckConfig::isAutoCheckEnabled() const
309 {
310 sal_Bool nValue = sal_False;
311 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTOCHECK_ENABLED ) ) >>= nValue;
312 return nValue;
313 }
314
315 //------------------------------------------------------------------------------
316
317 bool
isAutoDownloadEnabled() const318 UpdateCheckConfig::isAutoDownloadEnabled() const
319 {
320 sal_Bool nValue = sal_False;
321 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTODOWNLOAD_ENABLED ) ) >>= nValue;
322 return nValue;
323 }
324
325 //------------------------------------------------------------------------------
326
327 rtl::OUString
getUpdateEntryVersion() const328 UpdateCheckConfig::getUpdateEntryVersion() const
329 {
330 rtl::OUString aValue;
331
332 // getByName is defined as non const in XNameAccess
333 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( OLD_VERSION ) ) >>= aValue;
334
335 return aValue;
336 }
337
338 //------------------------------------------------------------------------------
339
340 sal_Int64
getLastChecked() const341 UpdateCheckConfig::getLastChecked() const
342 {
343 sal_Int64 nValue = 0;
344
345 // getByName is defined as non const in XNameAccess
346 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( LAST_CHECK ) ) >>= nValue;
347
348 return nValue;
349 }
350
351 //------------------------------------------------------------------------------
352
353 sal_Int64
getCheckInterval() const354 UpdateCheckConfig::getCheckInterval() const
355 {
356 sal_Int64 nValue = 0;
357
358 // getByName is defined as non const in XNameAccess
359 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( CHECK_INTERVAL ) ) >>= nValue;
360
361 return nValue;
362 }
363
364 //------------------------------------------------------------------------------
365
366 rtl::OUString
getLocalFileName() const367 UpdateCheckConfig::getLocalFileName() const
368 {
369 rtl::OUString aName = UNISTRING(LOCAL_FILE);
370 rtl::OUString aRet;
371
372 if( m_xContainer->hasByName(aName) )
373 m_xContainer->getByName(aName) >>= aRet;
374
375 return aRet;
376 }
377
378 //------------------------------------------------------------------------------
379
380 rtl::OUString
getDownloadDestination() const381 UpdateCheckConfig::getDownloadDestination() const
382 {
383 rtl::OUString aName = UNISTRING(DOWNLOAD_DESTINATION);
384 rtl::OUString aRet;
385
386 const_cast <UpdateCheckConfig *> (this)->getByName(aName) >>= aRet;
387
388 return aRet;
389 }
390
391 //------------------------------------------------------------------------------
392
393 void
storeLocalFileName(const rtl::OUString & rLocalFileName,sal_Int64 nFileSize)394 UpdateCheckConfig::storeLocalFileName(const rtl::OUString& rLocalFileName, sal_Int64 nFileSize)
395 {
396 const sal_uInt8 nItems = 2;
397 const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) };
398 const uno::Any aValueList[nItems] = { uno::makeAny(rLocalFileName), uno::makeAny(nFileSize) };
399
400 for( sal_uInt8 i=0; i < nItems; ++i )
401 {
402 if( m_xContainer->hasByName(aNameList[i]) )
403 m_xContainer->replaceByName(aNameList[i], aValueList[i]);
404 else
405 m_xContainer->insertByName(aNameList[i], aValueList[i]);
406 }
407
408 commitChanges();
409 }
410
411 //------------------------------------------------------------------------------
412
413 void
clearLocalFileName()414 UpdateCheckConfig::clearLocalFileName()
415 {
416 const sal_uInt8 nItems = 2;
417 const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) };
418
419 for( sal_uInt8 i=0; i < nItems; ++i )
420 {
421 if( m_xContainer->hasByName(aNameList[i]) )
422 m_xContainer->removeByName(aNameList[i]);
423 }
424
425 commitChanges();
426 }
427
428 //------------------------------------------------------------------------------
429
430 void
storeDownloadPaused(bool paused)431 UpdateCheckConfig::storeDownloadPaused(bool paused)
432 {
433 replaceByName(UNISTRING(DOWNLOAD_PAUSED) , uno::makeAny(paused));
434 commitChanges();
435 }
436
437 //------------------------------------------------------------------------------
438
439 void
updateLastChecked()440 UpdateCheckConfig::updateLastChecked()
441 {
442 TimeValue systime;
443 osl_getSystemTime(&systime);
444
445 sal_Int64 lastCheck = systime.Seconds;
446
447 replaceByName(UNISTRING(LAST_CHECK), uno::makeAny(lastCheck));
448 }
449
450 //------------------------------------------------------------------------------
451
452 void
storeUpdateFound(const UpdateInfo & rInfo,const rtl::OUString & aCurrentBuild)453 UpdateCheckConfig::storeUpdateFound( const UpdateInfo& rInfo, const rtl::OUString& aCurrentBuild)
454
455 {
456 bool autoDownloadEnabled = isAutoDownloadEnabled();
457
458 uno::Any aValues[nUpdateEntryProperties] =
459 {
460 uno::makeAny(rInfo.Version),
461 uno::makeAny(rInfo.BuildId),
462 uno::makeAny(rInfo.Description),
463 uno::makeAny(rInfo.Sources[0].URL),
464 uno::makeAny(rInfo.Sources[0].IsDirect ? sal_True : sal_False),
465 uno::makeAny(getReleaseNote(rInfo, 1, autoDownloadEnabled) ),
466 uno::makeAny(getReleaseNote(rInfo, 2, autoDownloadEnabled) ),
467 uno::makeAny(getReleaseNote(rInfo, 3, autoDownloadEnabled) ),
468 uno::makeAny(getReleaseNote(rInfo, 4, autoDownloadEnabled) ),
469 uno::makeAny(getReleaseNote(rInfo, 5, autoDownloadEnabled) ),
470 uno::makeAny(aCurrentBuild)
471 };
472
473 rtl::OUString aName;
474 for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n )
475 {
476 aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]);
477
478 if( m_xContainer->hasByName(aName) )
479 m_xContainer->replaceByName(aName, aValues[n]);
480 else
481 m_xContainer->insertByName(aName,aValues[n]);
482 }
483
484 commitChanges();
485 }
486
487 //------------------------------------------------------------------------------
488
489 void
clearUpdateFound()490 UpdateCheckConfig::clearUpdateFound()
491 {
492 rtl::OUString aName;
493
494 for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n )
495 {
496 aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]);
497
498 try {
499 if( m_xContainer->hasByName(aName) )
500 m_xContainer->removeByName(aName);
501 } catch(const lang::WrappedTargetException& ) {
502 // Can not remove value, probably in share layer
503 OSL_ASSERT(false);
504 m_xContainer->replaceByName(aName, uno::makeAny(rtl::OUString()));
505 }
506 }
507
508 /* As we have removed UpdateVersionFound from the shared configuration
509 * existing entries in the user layer do not have a oor operation and
510 * thus are completely ignored (which also means they can not be removed).
511 */
512
513 commitChanges();
514 }
515
516 //------------------------------------------------------------------------------
517
518 uno::Sequence< rtl::OUString >
getServiceNames()519 UpdateCheckConfig::getServiceNames()
520 {
521 uno::Sequence< rtl::OUString > aServiceList(1);
522 aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheckConfig");
523 return aServiceList;
524 }
525
526 //------------------------------------------------------------------------------
527
528 rtl::OUString
getImplName()529 UpdateCheckConfig::getImplName()
530 {
531 return UNISTRING( "vnd.sun.UpdateCheckConfig");
532 }
533
534 //------------------------------------------------------------------------------
535
536 uno::Type SAL_CALL
getElementType()537 UpdateCheckConfig::getElementType() throw (uno::RuntimeException)
538 {
539 return m_xContainer->getElementType();
540 }
541
542 //------------------------------------------------------------------------------
543
544 sal_Bool SAL_CALL
hasElements()545 UpdateCheckConfig::hasElements() throw (uno::RuntimeException)
546 {
547 return m_xContainer->hasElements();
548 }
549
550 //------------------------------------------------------------------------------
551
552 uno::Any SAL_CALL
getByName(const::rtl::OUString & aName)553 UpdateCheckConfig::getByName( const ::rtl::OUString& aName )
554 throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
555 {
556 uno::Any aValue = m_xContainer->getByName( aName );
557
558 // Provide dynamic default value
559 if( aName.equalsAscii(DOWNLOAD_DESTINATION) )
560 {
561 rtl::OUString aStr;
562 aValue >>= aStr;
563
564 if( aStr.getLength() == 0 )
565 aValue = uno::makeAny(getDesktopDirectory());
566 }
567
568 return aValue;
569 }
570
571 //------------------------------------------------------------------------------
572
573 uno::Sequence< ::rtl::OUString > SAL_CALL
getElementNames()574 UpdateCheckConfig::getElementNames( ) throw (uno::RuntimeException)
575 {
576 return m_xContainer->getElementNames();
577 }
578
579 //------------------------------------------------------------------------------
580
581 sal_Bool SAL_CALL
hasByName(const::rtl::OUString & aName)582 UpdateCheckConfig::hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
583 {
584 return m_xContainer->hasByName( aName );
585 }
586
587 //------------------------------------------------------------------------------
588
589 void SAL_CALL
replaceByName(const::rtl::OUString & aName,const uno::Any & aElement)590 UpdateCheckConfig::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement )
591 throw (lang::IllegalArgumentException, container::NoSuchElementException,
592 lang::WrappedTargetException, uno::RuntimeException)
593 {
594 return m_xContainer->replaceByName( aName, aElement );
595 }
596
597 //------------------------------------------------------------------------------
598 // XChangesBatch
599
600 void SAL_CALL
commitChanges()601 UpdateCheckConfig::commitChanges()
602 throw (lang::WrappedTargetException, uno::RuntimeException)
603 {
604 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
605 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
606 {
607 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
608 xChangesBatch->commitChanges();
609
610 if( m_rListener.is() )
611 {
612 const sal_Int32 nChanges = aChangesSet.getLength();
613 rtl::OUString aString;
614
615 for( sal_Int32 i=0; i<nChanges; ++i )
616 {
617 aChangesSet[i].Accessor >>= aString;
618
619 // FIXME: use non IgnoreAsciiCase version as soon as it becomes available
620 if( aString.endsWithIgnoreAsciiCaseAsciiL(AUTOCHECK_ENABLED "']", sizeof(AUTOCHECK_ENABLED)+1) )
621 {
622 sal_Bool bEnabled = sal_False;
623 aChangesSet[i].Element >>= bEnabled;
624 m_rListener->autoCheckStatusChanged(sal_True == bEnabled);
625 }
626 // FIXME: use non IgnoreAsciiCase version as soon as it becomes available
627 else if( aString.endsWithIgnoreAsciiCaseAsciiL(CHECK_INTERVAL "']", sizeof(CHECK_INTERVAL)+1) )
628 {
629 m_rListener->autoCheckIntervalChanged();
630 }
631 }
632 }
633 }
634
635 xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xAvailableUpdates, uno::UNO_QUERY );
636 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
637 {
638 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
639 xChangesBatch->commitChanges();
640 }
641 xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xIgnoredUpdates, uno::UNO_QUERY );
642 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
643 {
644 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
645 xChangesBatch->commitChanges();
646 }
647 }
648
649 //------------------------------------------------------------------------------
650
651 sal_Bool SAL_CALL
hasPendingChanges()652 UpdateCheckConfig::hasPendingChanges( ) throw (uno::RuntimeException)
653 {
654 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
655 if( xChangesBatch.is() )
656 return xChangesBatch->hasPendingChanges();
657
658 return sal_False;
659 }
660
661 //------------------------------------------------------------------------------
662
663 uno::Sequence< util::ElementChange > SAL_CALL
getPendingChanges()664 UpdateCheckConfig::getPendingChanges( ) throw (uno::RuntimeException)
665 {
666 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
667 if( xChangesBatch.is() )
668 return xChangesBatch->getPendingChanges();
669
670 return uno::Sequence< util::ElementChange >();
671 }
672
673 //------------------------------------------------------------------------------
storeExtensionVersion(const rtl::OUString & rExtensionName,const rtl::OUString & rVersion)674 bool UpdateCheckConfig::storeExtensionVersion( const rtl::OUString& rExtensionName,
675 const rtl::OUString& rVersion )
676 {
677 bool bNotify = true;
678
679 if ( m_xAvailableUpdates->hasByName( rExtensionName ) )
680 uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) );
681 else
682 {
683 uno::Reference< beans::XPropertySet > elem( uno::Reference< lang::XSingleServiceFactory >( m_xAvailableUpdates, uno::UNO_QUERY_THROW )->createInstance(), uno::UNO_QUERY_THROW );
684 elem->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) );
685 m_xAvailableUpdates->insertByName( rExtensionName, uno::Any( elem ) );
686 }
687
688 if ( m_xIgnoredUpdates->hasByName( rExtensionName ) )
689 {
690 ::rtl::OUString aIgnoredVersion;
691 uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
692 aValue >>= aIgnoredVersion;
693 if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates
694 bNotify = false;
695 else if ( aIgnoredVersion == rVersion ) // the user wanted to ignore this update
696 bNotify = false;
697 }
698
699 commitChanges();
700
701 return bNotify;
702 }
703
704 //------------------------------------------------------------------------------
checkExtensionVersion(const rtl::OUString & rExtensionName,const rtl::OUString & rVersion)705 bool UpdateCheckConfig::checkExtensionVersion( const rtl::OUString& rExtensionName,
706 const rtl::OUString& rVersion )
707 {
708 if ( m_xAvailableUpdates->hasByName( rExtensionName ) )
709 {
710 ::rtl::OUString aStoredVersion;
711 uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
712 aValue >>= aStoredVersion;
713
714 if ( m_xIgnoredUpdates->hasByName( rExtensionName ) )
715 {
716 ::rtl::OUString aIgnoredVersion;
717 uno::Any aValue2( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
718 aValue2 >>= aIgnoredVersion;
719 if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates
720 return false;
721 else if ( aIgnoredVersion == aStoredVersion ) // the user wanted to ignore this update
722 return false;
723 // TODO: else delete ignored entry?
724 }
725 if ( isVersionGreater( rVersion, aStoredVersion ) )
726 return true;
727 else
728 {
729 m_xAvailableUpdates->removeByName( rExtensionName );
730 commitChanges();
731 }
732 }
733
734 return false;
735 }
736
737 //------------------------------------------------------------------------------
getSubVersion(const rtl::OUString & rVersion,sal_Int32 * nIndex)738 rtl::OUString UpdateCheckConfig::getSubVersion( const rtl::OUString& rVersion,
739 sal_Int32 *nIndex )
740 {
741 while ( *nIndex < rVersion.getLength() && rVersion[*nIndex] == '0')
742 {
743 ++*nIndex;
744 }
745
746 return rVersion.getToken( 0, '.', *nIndex );
747 }
748
749 //------------------------------------------------------------------------------
750 // checks if the second version string is greater than the first one
751
isVersionGreater(const rtl::OUString & rVersion1,const rtl::OUString & rVersion2)752 bool UpdateCheckConfig::isVersionGreater( const rtl::OUString& rVersion1,
753 const rtl::OUString& rVersion2 )
754 {
755 for ( sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0; )
756 {
757 ::rtl::OUString sSub1( getSubVersion( rVersion1, &i1 ) );
758 ::rtl::OUString sSub2( getSubVersion( rVersion2, &i2 ) );
759
760 if ( sSub1.getLength() < sSub2.getLength() ) {
761 return true;
762 } else if ( sSub1.getLength() > sSub2.getLength() ) {
763 return false;
764 } else if ( sSub1 < sSub2 ) {
765 return true;
766 } else if ( sSub1 > sSub2 ) {
767 return false;
768 }
769 }
770 return false;
771 }
772
773 //------------------------------------------------------------------------------
774 //------------------------------------------------------------------------------
775 //------------------------------------------------------------------------------
776
777 rtl::OUString SAL_CALL
getImplementationName()778 UpdateCheckConfig::getImplementationName() throw (uno::RuntimeException)
779 {
780 return getImplName();
781 }
782
783 //------------------------------------------------------------------------------
784
785 sal_Bool SAL_CALL
supportsService(rtl::OUString const & serviceName)786 UpdateCheckConfig::supportsService(rtl::OUString const & serviceName)
787 throw (uno::RuntimeException)
788 {
789 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
790
791 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
792 if( aServiceNameList[n].equals(serviceName) )
793 return sal_True;
794
795 return sal_False;
796 }
797
798 //------------------------------------------------------------------------------
799
800 uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()801 UpdateCheckConfig::getSupportedServiceNames() throw (uno::RuntimeException)
802 {
803 return getServiceNames();
804 }
805
806