1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_desktop.hxx"
30 #include "autocorrmigration.hxx"
31 #include <i18npool/mslangid.hxx>
32 #include <tools/urlobj.hxx>
33 #include <unotools/bootstrap.hxx>
34 
35 
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
38 
39 
40 //.........................................................................
41 namespace migration
42 {
43 //.........................................................................
44 
45 
46     static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
47     static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
48     static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/acor" ) );
49     static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dat" ) );
50 
51 
52     // =============================================================================
53     // component operations
54     // =============================================================================
55 
56     ::rtl::OUString AutocorrectionMigration_getImplementationName()
57     {
58         static ::rtl::OUString* pImplName = 0;
59 	    if ( !pImplName )
60 	    {
61             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
62             if ( !pImplName )
63 		    {
64                 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Autocorrection" ) );
65 			    pImplName = &aImplName;
66 		    }
67 	    }
68 	    return *pImplName;
69     }
70 
71     // -----------------------------------------------------------------------------
72 
73     Sequence< ::rtl::OUString > AutocorrectionMigration_getSupportedServiceNames()
74     {
75         static Sequence< ::rtl::OUString >* pNames = 0;
76 	    if ( !pNames )
77 	    {
78             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
79 		    if ( !pNames )
80 		    {
81                 static Sequence< ::rtl::OUString > aNames(1);
82                 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Autocorrection" ) );
83                 pNames = &aNames;
84 		    }
85 	    }
86 	    return *pNames;
87     }
88 
89     // =============================================================================
90     // AutocorrectionMigration
91     // =============================================================================
92 
93     AutocorrectionMigration::AutocorrectionMigration()
94     {
95     }
96 
97     // -----------------------------------------------------------------------------
98 
99     AutocorrectionMigration::~AutocorrectionMigration()
100     {
101     }
102 
103     // -----------------------------------------------------------------------------
104 
105     TStringVectorPtr AutocorrectionMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
106     {
107         TStringVectorPtr aResult( new TStringVector );
108         ::osl::Directory aDir( rBaseURL);
109 
110         if ( aDir.open() == ::osl::FileBase::E_None )
111         {
112             // iterate over directory content
113             TStringVector aSubDirs;
114             ::osl::DirectoryItem aItem;
115             while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
116             {
117                 ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
118                 if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
119                 {
120                     if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
121                         aSubDirs.push_back( aFileStatus.getFileURL() );
122                     else
123                         aResult->push_back( aFileStatus.getFileURL() );
124                 }
125             }
126 
127             // iterate recursive over subfolders
128             TStringVector::const_iterator aI = aSubDirs.begin();
129             while ( aI != aSubDirs.end() )
130             {
131                 TStringVectorPtr aSubResult = getFiles( *aI );
132                 aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
133                 ++aI;
134             }
135         }
136 
137         return aResult;
138     }
139 
140     // -----------------------------------------------------------------------------
141 
142     ::osl::FileBase::RC AutocorrectionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
143     {
144         ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
145         if ( aResult == ::osl::FileBase::E_NOENT )
146         {
147             INetURLObject aBaseURL( rDirURL );
148             aBaseURL.removeSegment();
149             checkAndCreateDirectory( aBaseURL );
150             return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
151         }
152         else
153         {
154             return aResult;
155         }
156     }
157 
158     // -----------------------------------------------------------------------------
159 
160     void AutocorrectionMigration::copyFiles()
161     {
162         ::rtl::OUString sTargetDir;
163         ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
164         if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
165         {
166             sTargetDir += sTargetSubDir;
167             TStringVectorPtr aFileList = getFiles( m_sSourceDir );
168             TStringVector::const_iterator aI = aFileList->begin();
169             while ( aI != aFileList->end() )
170             {
171                 ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() );
172                 sal_Int32 nStart = sBaseName.getLength();
173                 sal_Int32 nEnd = sSourceLocalName.lastIndexOf ( sSuffix );
174                 ::rtl::OUString sLanguageType = sSourceLocalName.copy( nStart, nEnd - nStart );
175                 ::rtl::OUString sIsoName = MsLangId::convertLanguageToIsoString( (LanguageType) sLanguageType.toInt32() );
176                 ::rtl::OUString sTargetLocalName = sBaseName;
177                 sTargetLocalName += ::rtl::OUString::createFromAscii( "_" );
178                 sTargetLocalName += sIsoName;
179                 sTargetLocalName += sSuffix;
180                 ::rtl::OUString sTargetName = sTargetDir + sTargetLocalName;
181                 INetURLObject aURL( sTargetName );
182                 aURL.removeSegment();
183                 checkAndCreateDirectory( aURL );
184                 ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
185                 if ( aResult != ::osl::FileBase::E_None )
186                 {
187                     ::rtl::OString aMsg( "AutocorrectionMigration::copyFiles: cannot copy " );
188                     aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
189                          +  ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
190                     OSL_ENSURE( sal_False, aMsg.getStr() );
191                 }
192                 ++aI;
193             }
194         }
195         else
196         {
197             OSL_ENSURE( sal_False, "AutocorrectionMigration::copyFiles: no user installation!" );
198         }
199     }
200 
201     // -----------------------------------------------------------------------------
202     // XServiceInfo
203     // -----------------------------------------------------------------------------
204 
205     ::rtl::OUString AutocorrectionMigration::getImplementationName() throw (RuntimeException)
206     {
207         return AutocorrectionMigration_getImplementationName();
208     }
209 
210     // -----------------------------------------------------------------------------
211 
212     sal_Bool AutocorrectionMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
213     {
214 	    Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
215 	    const ::rtl::OUString* pNames = aNames.getConstArray();
216 	    const ::rtl::OUString* pEnd = pNames + aNames.getLength();
217 	    for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
218 		    ;
219 
220 	    return pNames != pEnd;
221     }
222 
223     // -----------------------------------------------------------------------------
224 
225     Sequence< ::rtl::OUString > AutocorrectionMigration::getSupportedServiceNames() throw (RuntimeException)
226     {
227         return AutocorrectionMigration_getSupportedServiceNames();
228     }
229 
230     // -----------------------------------------------------------------------------
231     // XInitialization
232     // -----------------------------------------------------------------------------
233 
234     void AutocorrectionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
235     {
236         ::osl::MutexGuard aGuard( m_aMutex );
237 
238         const Any* pIter = aArguments.getConstArray();
239         const Any* pEnd = pIter + aArguments.getLength();
240         for ( ; pIter != pEnd ; ++pIter )
241         {
242             beans::NamedValue aValue;
243             *pIter >>= aValue;
244             if ( aValue.Name.equalsAscii( "UserData" ) )
245             {
246                 if ( !(aValue.Value >>= m_sSourceDir) )
247                 {
248                     OSL_ENSURE( false, "AutocorrectionMigration::initialize: argument UserData has wrong type!" );
249                 }
250                 m_sSourceDir += sSourceSubDir;
251                 break;
252             }
253         }
254     }
255 
256     // -----------------------------------------------------------------------------
257     // XJob
258     // -----------------------------------------------------------------------------
259 
260     Any AutocorrectionMigration::execute( const Sequence< beans::NamedValue >& )
261         throw (lang::IllegalArgumentException, Exception, RuntimeException)
262     {
263         ::osl::MutexGuard aGuard( m_aMutex );
264 
265         copyFiles();
266 
267         return Any();
268     }
269 
270     // =============================================================================
271     // component operations
272     // =============================================================================
273 
274     Reference< XInterface > SAL_CALL AutocorrectionMigration_create(
275         Reference< XComponentContext > const & )
276         SAL_THROW( () )
277     {
278         return static_cast< lang::XTypeProvider * >( new AutocorrectionMigration() );
279     }
280 
281     // -----------------------------------------------------------------------------
282 
283 //.........................................................................
284 }	// namespace migration
285 //.........................................................................
286