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_desktop.hxx" 26 #include "wordbookmigration.hxx" 27 #include <tools/urlobj.hxx> 28 #include <unotools/bootstrap.hxx> 29 #include <unotools/ucbstreamhelper.hxx> 30 31 using namespace ::com::sun::star; 32 using namespace ::com::sun::star::uno; 33 34 35 //......................................................................... 36 namespace migration 37 { 38 //......................................................................... 39 40 41 static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) ); 42 static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) ); 43 static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/wordbook" ) ); 44 static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dic" ) ); 45 46 47 // ============================================================================= 48 // component operations 49 // ============================================================================= 50 51 ::rtl::OUString WordbookMigration_getImplementationName() 52 { 53 static ::rtl::OUString* pImplName = 0; 54 if ( !pImplName ) 55 { 56 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 57 if ( !pImplName ) 58 { 59 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Wordbooks" ) ); 60 pImplName = &aImplName; 61 } 62 } 63 return *pImplName; 64 } 65 66 // ----------------------------------------------------------------------------- 67 68 Sequence< ::rtl::OUString > WordbookMigration_getSupportedServiceNames() 69 { 70 static Sequence< ::rtl::OUString >* pNames = 0; 71 if ( !pNames ) 72 { 73 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 74 if ( !pNames ) 75 { 76 static Sequence< ::rtl::OUString > aNames(1); 77 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Wordbooks" ) ); 78 pNames = &aNames; 79 } 80 } 81 return *pNames; 82 } 83 84 // ============================================================================= 85 // WordbookMigration 86 // ============================================================================= 87 88 WordbookMigration::WordbookMigration() 89 { 90 } 91 92 // ----------------------------------------------------------------------------- 93 94 WordbookMigration::~WordbookMigration() 95 { 96 } 97 98 // ----------------------------------------------------------------------------- 99 100 TStringVectorPtr WordbookMigration::getFiles( const ::rtl::OUString& rBaseURL ) const 101 { 102 TStringVectorPtr aResult( new TStringVector ); 103 ::osl::Directory aDir( rBaseURL); 104 105 if ( aDir.open() == ::osl::FileBase::E_None ) 106 { 107 // iterate over directory content 108 TStringVector aSubDirs; 109 ::osl::DirectoryItem aItem; 110 while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None ) 111 { 112 ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL ); 113 if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None ) 114 { 115 if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory ) 116 aSubDirs.push_back( aFileStatus.getFileURL() ); 117 else 118 aResult->push_back( aFileStatus.getFileURL() ); 119 } 120 } 121 122 // iterate recursive over subfolders 123 TStringVector::const_iterator aI = aSubDirs.begin(); 124 while ( aI != aSubDirs.end() ) 125 { 126 TStringVectorPtr aSubResult = getFiles( *aI ); 127 aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() ); 128 ++aI; 129 } 130 } 131 132 return aResult; 133 } 134 135 // ----------------------------------------------------------------------------- 136 137 ::osl::FileBase::RC WordbookMigration::checkAndCreateDirectory( INetURLObject& rDirURL ) 138 { 139 ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); 140 if ( aResult == ::osl::FileBase::E_NOENT ) 141 { 142 INetURLObject aBaseURL( rDirURL ); 143 aBaseURL.removeSegment(); 144 checkAndCreateDirectory( aBaseURL ); 145 return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); 146 } 147 else 148 { 149 return aResult; 150 } 151 } 152 153 #define MAX_HEADER_LENGTH 16 154 bool IsUserWordbook( const ::rtl::OUString& rFile ) 155 { 156 static const sal_Char* pVerStr2 = "WBSWG2"; 157 static const sal_Char* pVerStr5 = "WBSWG5"; 158 static const sal_Char* pVerStr6 = "WBSWG6"; 159 static const sal_Char* pVerOOo7 = "OOoUserDict1"; 160 161 bool bRet = false; 162 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( String(rFile), STREAM_STD_READ ); 163 if ( pStream && !pStream->GetError() ) 164 { 165 sal_Size nSniffPos = pStream->Tell(); 166 static sal_Size nVerOOo7Len = sal::static_int_cast< sal_Size >(strlen( pVerOOo7 )); 167 sal_Char pMagicHeader[MAX_HEADER_LENGTH]; 168 pMagicHeader[ nVerOOo7Len ] = '\0'; 169 if ((pStream->Read((void *) pMagicHeader, nVerOOo7Len) == nVerOOo7Len)) 170 { 171 if ( !strcmp(pMagicHeader, pVerOOo7) ) 172 bRet = true; 173 else 174 { 175 sal_uInt16 nLen; 176 pStream->Seek (nSniffPos); 177 *pStream >> nLen; 178 if ( nLen < MAX_HEADER_LENGTH ) 179 { 180 pStream->Read(pMagicHeader, nLen); 181 pMagicHeader[nLen] = '\0'; 182 if ( !strcmp(pMagicHeader, pVerStr2) 183 || !strcmp(pMagicHeader, pVerStr5) 184 || !strcmp(pMagicHeader, pVerStr6) ) 185 bRet = true; 186 } 187 } 188 } 189 } 190 191 delete pStream; 192 return bRet; 193 } 194 195 196 // ----------------------------------------------------------------------------- 197 198 void WordbookMigration::copyFiles() 199 { 200 ::rtl::OUString sTargetDir; 201 ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir ); 202 if ( aStatus == ::utl::Bootstrap::PATH_EXISTS ) 203 { 204 sTargetDir += sTargetSubDir; 205 TStringVectorPtr aFileList = getFiles( m_sSourceDir ); 206 TStringVector::const_iterator aI = aFileList->begin(); 207 while ( aI != aFileList->end() ) 208 { 209 if (IsUserWordbook(*aI) ) 210 { 211 ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() ); 212 ::rtl::OUString sTargetName = sTargetDir + sSourceLocalName; 213 INetURLObject aURL( sTargetName ); 214 aURL.removeSegment(); 215 checkAndCreateDirectory( aURL ); 216 ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName ); 217 if ( aResult != ::osl::FileBase::E_None ) 218 { 219 ::rtl::OString aMsg( "WordbookMigration::copyFiles: cannot copy " ); 220 aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to " 221 + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 ); 222 OSL_ENSURE( sal_False, aMsg.getStr() ); 223 } 224 } 225 ++aI; 226 } 227 } 228 else 229 { 230 OSL_ENSURE( sal_False, "WordbookMigration::copyFiles: no user installation!" ); 231 } 232 } 233 234 // ----------------------------------------------------------------------------- 235 // XServiceInfo 236 // ----------------------------------------------------------------------------- 237 238 ::rtl::OUString WordbookMigration::getImplementationName() throw (RuntimeException) 239 { 240 return WordbookMigration_getImplementationName(); 241 } 242 243 // ----------------------------------------------------------------------------- 244 245 sal_Bool WordbookMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) 246 { 247 Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); 248 const ::rtl::OUString* pNames = aNames.getConstArray(); 249 const ::rtl::OUString* pEnd = pNames + aNames.getLength(); 250 for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) 251 ; 252 253 return pNames != pEnd; 254 } 255 256 // ----------------------------------------------------------------------------- 257 258 Sequence< ::rtl::OUString > WordbookMigration::getSupportedServiceNames() throw (RuntimeException) 259 { 260 return WordbookMigration_getSupportedServiceNames(); 261 } 262 263 // ----------------------------------------------------------------------------- 264 // XInitialization 265 // ----------------------------------------------------------------------------- 266 267 void WordbookMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) 268 { 269 ::osl::MutexGuard aGuard( m_aMutex ); 270 271 const Any* pIter = aArguments.getConstArray(); 272 const Any* pEnd = pIter + aArguments.getLength(); 273 for ( ; pIter != pEnd ; ++pIter ) 274 { 275 beans::NamedValue aValue; 276 *pIter >>= aValue; 277 if ( aValue.Name.equalsAscii( "UserData" ) ) 278 { 279 if ( !(aValue.Value >>= m_sSourceDir) ) 280 { 281 OSL_ENSURE( false, "WordbookMigration::initialize: argument UserData has wrong type!" ); 282 } 283 m_sSourceDir += sSourceSubDir; 284 break; 285 } 286 } 287 } 288 289 // ----------------------------------------------------------------------------- 290 // XJob 291 // ----------------------------------------------------------------------------- 292 293 Any WordbookMigration::execute( const Sequence< beans::NamedValue >& ) 294 throw (lang::IllegalArgumentException, Exception, RuntimeException) 295 { 296 ::osl::MutexGuard aGuard( m_aMutex ); 297 298 copyFiles(); 299 300 return Any(); 301 } 302 303 // ============================================================================= 304 // component operations 305 // ============================================================================= 306 307 Reference< XInterface > SAL_CALL WordbookMigration_create( 308 Reference< XComponentContext > const & ) 309 SAL_THROW( () ) 310 { 311 return static_cast< lang::XTypeProvider * >( new WordbookMigration() ); 312 } 313 314 // ----------------------------------------------------------------------------- 315 316 //......................................................................... 317 } // namespace migration 318 //......................................................................... 319