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 
WordbookMigration_getImplementationName()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 
WordbookMigration_getSupportedServiceNames()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 
WordbookMigration()88     WordbookMigration::WordbookMigration()
89     {
90     }
91 
92     // -----------------------------------------------------------------------------
93 
~WordbookMigration()94     WordbookMigration::~WordbookMigration()
95     {
96     }
97 
98     // -----------------------------------------------------------------------------
99 
getFiles(const::rtl::OUString & rBaseURL) const100     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 
checkAndCreateDirectory(INetURLObject & rDirURL)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
IsUserWordbook(const::rtl::OUString & rFile)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 
copyFiles()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 
getImplementationName()238     ::rtl::OUString WordbookMigration::getImplementationName() throw (RuntimeException)
239     {
240         return WordbookMigration_getImplementationName();
241     }
242 
243     // -----------------------------------------------------------------------------
244 
supportsService(const::rtl::OUString & rServiceName)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 
getSupportedServiceNames()258     Sequence< ::rtl::OUString > WordbookMigration::getSupportedServiceNames() throw (RuntimeException)
259     {
260         return WordbookMigration_getSupportedServiceNames();
261     }
262 
263     // -----------------------------------------------------------------------------
264     // XInitialization
265     // -----------------------------------------------------------------------------
266 
initialize(const Sequence<Any> & aArguments)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 
execute(const Sequence<beans::NamedValue> &)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 
WordbookMigration_create(Reference<XComponentContext> const &)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