Back to index

lightning-sunbird  0.9+nobinonly
nsTextImport.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org Code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Pierre Phaneuf <pp@ludusdesign.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 
00041 /*
00042 
00043   Text import addressbook interfaces
00044 
00045 */
00046 #ifdef MOZ_LOGGING
00047 // sorry, this has to be before the pre-compiled header
00048 #define FORCE_PR_LOG /* Allow logging in the release build */
00049 #endif
00050 
00051 #include "nscore.h"
00052 #include "nsCRT.h"
00053 #include "nsString.h"
00054 #include "nsReadableUtils.h"
00055 #include "nsIServiceManager.h"
00056 #include "nsIImportService.h"
00057 #include "nsIComponentManager.h"
00058 #include "nsTextImport.h"
00059 #include "nsIMemory.h"
00060 #include "nsIImportGeneric.h"
00061 #include "nsIImportAddressBooks.h"
00062 #include "nsIImportABDescriptor.h"
00063 #include "nsIImportFieldMap.h"
00064 #include "nsIOutputStream.h"
00065 #include "nsIAddrDatabase.h"
00066 #include "nsIAbLDIFService.h"
00067 #include "nsAbBaseCID.h"
00068 #include "nsTextFormatter.h"
00069 #include "nsTextStringBundle.h"
00070 #include "nsIStringBundle.h"
00071 #include "nsTextAddress.h"
00072 #include "nsIPrefService.h"
00073 #include "nsIPrefBranch.h"
00074 #include "nsXPIDLString.h"
00075 #include "nsProxiedService.h"
00076 #include "TextDebugLog.h"
00077 
00078 static NS_DEFINE_IID(kISupportsIID,                     NS_ISUPPORTS_IID);
00079 PRLogModuleInfo* TEXTIMPORTLOGMODULE;
00080 
00081 class ImportAddressImpl : public nsIImportAddressBooks
00082 {
00083 public:
00084     ImportAddressImpl();
00085     virtual ~ImportAddressImpl();
00086 
00087        static nsresult Create(nsIImportAddressBooks** aImport);
00088 
00089     // nsISupports interface
00090     NS_DECL_ISUPPORTS
00091 
00092     // nsIImportAddressBooks interface
00093     
00094        /* PRBool GetSupportsMultiple (); */
00095        NS_IMETHOD GetSupportsMultiple(PRBool *_retval) { *_retval = PR_FALSE; return( NS_OK);}
00096        
00097        /* PRBool GetAutoFind (out wstring description); */
00098        NS_IMETHOD GetAutoFind(PRUnichar **description, PRBool *_retval);
00099        
00100        /* PRBool GetNeedsFieldMap (nsIFileSpec *location); */
00101        NS_IMETHOD GetNeedsFieldMap(nsIFileSpec *location, PRBool *_retval);
00102        
00103        /* void GetDefaultLocation (out nsIFileSpec location, out boolean found, out boolean userVerify); */
00104        NS_IMETHOD GetDefaultLocation(nsIFileSpec **location, PRBool *found, PRBool *userVerify);
00105        
00106        /* nsISupportsArray FindAddressBooks (in nsIFileSpec location); */
00107        NS_IMETHOD FindAddressBooks(nsIFileSpec *location, nsISupportsArray **_retval);
00108        
00109        /* nsISupports InitFieldMap(nsIFileSpec location, nsIImportFieldMap fieldMap); */
00110        NS_IMETHOD InitFieldMap(nsIFileSpec *location, nsIImportFieldMap *fieldMap);
00111        
00112        /* void ImportAddressBook (in nsIImportABDescriptor source, in nsIAddrDatabase destination, in nsIImportFieldMap fieldMap, in boolean isAddrLocHome, out wstring errorLog, out wstring successLog, out boolean fatalError); */
00113        NS_IMETHOD ImportAddressBook(      nsIImportABDescriptor *source, 
00114                                                                nsIAddrDatabase *    destination, 
00115                                                                nsIImportFieldMap *  fieldMap, 
00116                                                                PRBool isAddrLocHome, 
00117                                                                PRUnichar **         errorLog,
00118                                                                PRUnichar **         successLog,
00119                                                                PRBool *                    fatalError);
00120        
00121        /* unsigned long GetImportProgress (); */
00122        NS_IMETHOD GetImportProgress(PRUint32 *_retval);
00123  
00124        NS_IMETHOD GetSampleData( PRInt32 index, PRBool *pFound, PRUnichar **pStr);
00125 
00126        NS_IMETHOD SetSampleLocation( nsIFileSpec *);
00127 
00128 private:
00129        void   ClearSampleFile( void);
00130        void   SaveFieldMap( nsIImportFieldMap *pMap);
00131 
00132        static void   ReportSuccess( nsString& name, nsString *pStream);
00133        static void SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess);
00134        static void ReportError( PRInt32 errorNum, nsString& name, nsString *pStream);
00135        static void   SanitizeSampleData( nsCString& val);
00136 
00137 private:
00138        nsTextAddress m_text;
00139        PRBool               m_haveDelim;
00140        nsIFileSpec * m_fileLoc;
00141        char                 m_delim;
00142        PRUint32             m_bytesImported;
00143 };
00144 
00145 
00148 
00149 
00150 nsTextImport::nsTextImport()
00151 {
00152   // Init logging module.
00153   if (!TEXTIMPORTLOGMODULE)
00154     TEXTIMPORTLOGMODULE = PR_NewLogModule("IMPORT");
00155        IMPORT_LOG0( "nsTextImport Module Created\n");
00156 
00157        nsTextStringBundle::GetStringBundle();
00158 }
00159 
00160 
00161 nsTextImport::~nsTextImport()
00162 {
00163 
00164        IMPORT_LOG0( "nsTextImport Module Deleted\n");
00165 
00166 }
00167 
00168 
00169 
00170 NS_IMPL_ISUPPORTS1(nsTextImport, nsIImportModule)
00171 
00172 
00173 NS_IMETHODIMP nsTextImport::GetName( PRUnichar **name)
00174 {
00175     NS_PRECONDITION(name != nsnull, "null ptr");
00176     if (! name)
00177         return NS_ERROR_NULL_POINTER;
00178 
00179        *name = nsTextStringBundle::GetStringByID( TEXTIMPORT_NAME);
00180               
00181     return NS_OK;
00182 }
00183 
00184 NS_IMETHODIMP nsTextImport::GetDescription( PRUnichar **name)
00185 {
00186     NS_PRECONDITION(name != nsnull, "null ptr");
00187     if (! name)
00188         return NS_ERROR_NULL_POINTER;
00189 
00190        *name = nsTextStringBundle::GetStringByID( TEXTIMPORT_DESCRIPTION);
00191               
00192     return NS_OK;
00193 }
00194 
00195 NS_IMETHODIMP nsTextImport::GetSupports( char **supports)
00196 {
00197     NS_PRECONDITION(supports != nsnull, "null ptr");
00198     if (! supports)
00199         return NS_ERROR_NULL_POINTER;
00200        
00201        *supports = nsCRT::strdup( kTextSupportsString);
00202        return( NS_OK);
00203 }
00204 
00205 NS_IMETHODIMP nsTextImport::GetSupportsUpgrade( PRBool *pUpgrade)
00206 {
00207     NS_PRECONDITION(pUpgrade != nsnull, "null ptr");
00208     if (! pUpgrade)
00209         return NS_ERROR_NULL_POINTER;
00210        
00211        *pUpgrade = PR_FALSE;
00212        return( NS_OK);
00213 }
00214 
00215 
00216 NS_IMETHODIMP nsTextImport::GetImportInterface( const char *pImportType, nsISupports **ppInterface)
00217 {
00218     NS_PRECONDITION(pImportType != nsnull, "null ptr");
00219     if (! pImportType)
00220         return NS_ERROR_NULL_POINTER;
00221     NS_PRECONDITION(ppInterface != nsnull, "null ptr");
00222     if (! ppInterface)
00223         return NS_ERROR_NULL_POINTER;
00224 
00225        *ppInterface = nsnull;
00226        nsresult      rv;
00227        
00228        if (!nsCRT::strcmp( pImportType, "addressbook")) {
00229               // create the nsIImportMail interface and return it!
00230               nsIImportAddressBooks *     pAddress = nsnull;
00231               nsIImportGeneric *          pGeneric = nsnull;
00232               rv = ImportAddressImpl::Create( &pAddress);
00233               if (NS_SUCCEEDED( rv)) {
00234                      nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
00235                      if (NS_SUCCEEDED( rv)) {
00236                             rv = impSvc->CreateNewGenericAddressBooks( &pGeneric);
00237                             if (NS_SUCCEEDED( rv)) {
00238                                    pGeneric->SetData( "addressInterface", pAddress);
00239                                    rv = pGeneric->QueryInterface( kISupportsIID, (void **)ppInterface);
00240                             }
00241                      }
00242               }
00243               NS_IF_RELEASE( pAddress);
00244               NS_IF_RELEASE( pGeneric);
00245               return( rv);
00246        }
00247                      
00248        return( NS_ERROR_NOT_AVAILABLE);
00249 }
00250 
00252 
00253 
00254 
00255 nsresult ImportAddressImpl::Create(nsIImportAddressBooks** aImport)
00256 {
00257     NS_PRECONDITION(aImport != nsnull, "null ptr");
00258     if (! aImport)
00259         return NS_ERROR_NULL_POINTER;
00260 
00261     *aImport = new ImportAddressImpl();
00262     if (! *aImport)
00263         return NS_ERROR_OUT_OF_MEMORY;
00264 
00265     NS_ADDREF(*aImport);
00266 
00267     return NS_OK;
00268 }
00269 
00270 ImportAddressImpl::ImportAddressImpl()
00271 {
00272        m_fileLoc = nsnull;
00273        m_haveDelim = PR_FALSE;
00274 }
00275 
00276 
00277 ImportAddressImpl::~ImportAddressImpl()
00278 {
00279        if (m_fileLoc) {
00280               PRBool open = PR_FALSE;
00281               m_fileLoc->IsStreamOpen( &open);
00282               if (open)
00283                      m_fileLoc->CloseStream();
00284               NS_RELEASE( m_fileLoc);
00285        }
00286 }
00287 
00288 
00289 
00290 NS_IMPL_THREADSAFE_ISUPPORTS1(ImportAddressImpl, nsIImportAddressBooks)
00291 
00292        
00293 NS_IMETHODIMP ImportAddressImpl::GetAutoFind(PRUnichar **addrDescription, PRBool *_retval)
00294 {
00295     NS_PRECONDITION(addrDescription != nsnull, "null ptr");
00296     NS_PRECONDITION(_retval != nsnull, "null ptr");
00297     if (! addrDescription || !_retval)
00298         return NS_ERROR_NULL_POINTER;
00299     
00300     nsString  str;
00301     *_retval = PR_FALSE;
00302     nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_NAME, str);
00303     *addrDescription = ToNewUnicode(str);
00304     
00305     return( NS_OK);
00306 }
00307 
00308 
00309 NS_IMETHODIMP ImportAddressImpl::GetDefaultLocation(nsIFileSpec **ppLoc, PRBool *found, PRBool *userVerify)
00310 {
00311     NS_PRECONDITION(found != nsnull, "null ptr");
00312     NS_PRECONDITION(ppLoc != nsnull, "null ptr");
00313     NS_PRECONDITION(userVerify != nsnull, "null ptr");
00314     if (! found || !userVerify || !ppLoc)
00315         return NS_ERROR_NULL_POINTER;
00316     
00317        *ppLoc = nsnull;
00318        *found = PR_FALSE;
00319        *userVerify = PR_TRUE;
00320        
00321        return( NS_OK);    
00322 }
00323 
00324 
00325        
00326 NS_IMETHODIMP ImportAddressImpl::FindAddressBooks(nsIFileSpec *pLoc, nsISupportsArray **ppArray)
00327 {
00328     NS_PRECONDITION(pLoc != nsnull, "null ptr");
00329     NS_PRECONDITION(ppArray != nsnull, "null ptr");
00330     if (!pLoc || !ppArray)
00331         return NS_ERROR_NULL_POINTER;
00332        
00333        ClearSampleFile();
00334 
00335        *ppArray = nsnull;
00336        PRBool exists = PR_FALSE;
00337        nsresult rv = pLoc->Exists( &exists);
00338        if (NS_FAILED( rv) || !exists)
00339               return( NS_ERROR_FAILURE);
00340        
00341        PRBool isFile = PR_FALSE;
00342        rv = pLoc->IsFile( &isFile);
00343        if (NS_FAILED( rv) || !isFile)
00344               return( NS_ERROR_FAILURE);
00345 
00346        rv = m_text.DetermineDelim( pLoc);
00347        
00348        if (NS_FAILED( rv)) {
00349               IMPORT_LOG0( "*** Error determining delimitter\n");
00350               return( rv);
00351        }
00352        m_haveDelim = PR_TRUE;
00353        m_delim = m_text.GetDelim();
00354        
00355        m_fileLoc = pLoc;
00356        NS_ADDREF( m_fileLoc);
00357 
00358        /* Build an address book descriptor based on the file passed in! */
00359        nsCOMPtr<nsISupportsArray>  array;
00360        rv = NS_NewISupportsArray( getter_AddRefs( array));
00361        if (NS_FAILED( rv)) {
00362               IMPORT_LOG0( "FAILED to allocate the nsISupportsArray\n");
00363               return( rv);
00364        }
00365               
00366        nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
00367        if (NS_FAILED( rv)) {
00368               IMPORT_LOG0( "*** Failed to obtain the import service\n");
00369               return( rv);
00370        }
00371        
00372        nsXPIDLCString pName;
00373        rv = pLoc->GetLeafName(getter_Copies(pName));
00374        if (NS_FAILED( rv)) {
00375               IMPORT_LOG0( "*** Failed getting leaf name of file\n");
00376               return( rv);
00377        }
00378 
00379        // for get unicode leafname.  If it uses nsILocalFile interface,
00380        // these codes do not need due to nsILocalFile->GetUnicodeLeafName()
00381        nsString      name;
00382        rv = impSvc->SystemStringToUnicode((const char*) pName, name);
00383        if (NS_FAILED(rv))
00384               name.AssignWithConversion((const char*) pName);
00385 
00386        PRInt32              idx = name.RFindChar( '.');
00387        if ((idx != -1) && (idx > 0) && ((name.Length() - idx - 1) < 5)) {
00388               nsString t;
00389               name.Left( t, idx);
00390               name = t;
00391        }
00392 
00393        nsCOMPtr<nsIImportABDescriptor>    desc;
00394        nsISupports *                             pInterface;
00395 
00396        rv = impSvc->CreateNewABDescriptor( getter_AddRefs( desc));
00397        if (NS_SUCCEEDED( rv)) {
00398               PRUint32 sz = 0;
00399               pLoc->GetFileSize( &sz);    
00400               desc->SetPreferredName( name.get());
00401               desc->SetSize( sz);
00402               nsIFileSpec *pSpec = nsnull;
00403               desc->GetFileSpec( &pSpec);
00404               if (pSpec) {
00405                      pSpec->FromFileSpec( pLoc);
00406                      NS_RELEASE( pSpec);
00407               }
00408               rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
00409               array->AppendElement( pInterface);
00410               pInterface->Release();
00411        }
00412        if (NS_FAILED( rv)) {
00413               IMPORT_LOG0( "*** Error creating address book descriptor for text import\n");
00414        }             
00415        else {
00416               rv = array->QueryInterface( NS_GET_IID(nsISupportsArray), (void **) ppArray);
00417        }
00418 
00419        return( rv);
00420 }
00421 
00422        
00423 
00424 void ImportAddressImpl::ReportSuccess( nsString& name, nsString *pStream)
00425 {
00426        if (!pStream)
00427               return;
00428        // load the success string
00429        nsIStringBundle *pBundle = nsTextStringBundle::GetStringBundleProxy();
00430        PRUnichar *pFmt = nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_SUCCESS, pBundle);
00431        PRUnichar *pText = nsTextFormatter::smprintf( pFmt, name.get());
00432        pStream->Append( pText);
00433        nsTextFormatter::smprintf_free( pText);
00434        nsTextStringBundle::FreeString( pFmt);
00435        pStream->Append( PRUnichar(nsCRT::LF));
00436        NS_IF_RELEASE( pBundle);
00437 }
00438 
00439 void ImportAddressImpl::ReportError( PRInt32 errorNum, nsString& name, nsString *pStream)
00440 {
00441        if (!pStream)
00442               return;
00443        // load the error string
00444        nsIStringBundle *pBundle = nsTextStringBundle::GetStringBundleProxy();
00445        PRUnichar *pFmt = nsTextStringBundle::GetStringByID( errorNum, pBundle);
00446        PRUnichar *pText = nsTextFormatter::smprintf( pFmt, name.get());
00447        pStream->Append( pText);
00448        nsTextFormatter::smprintf_free( pText);
00449        nsTextStringBundle::FreeString( pFmt);
00450        pStream->Append( PRUnichar(nsCRT::LF));
00451        NS_IF_RELEASE( pBundle);
00452 }
00453 
00454 void ImportAddressImpl::SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess)
00455 {
00456        if (pError)
00457               *pError = ToNewUnicode(error);
00458        if (pSuccess)
00459               *pSuccess = ToNewUnicode(success);
00460 }
00461 
00462 
00463 NS_IMETHODIMP ImportAddressImpl::ImportAddressBook(     nsIImportABDescriptor *pSource, 
00464                                                                                            nsIAddrDatabase *    pDestination, 
00465                                                                                            nsIImportFieldMap *  fieldMap, 
00466                                                                                            PRBool isAddrLocHome, 
00467                                                                                            PRUnichar **         pErrorLog,
00468                                                                                            PRUnichar **         pSuccessLog,
00469                                                                                            PRBool *                    fatalError)
00470 {
00471     NS_PRECONDITION(pSource != nsnull, "null ptr");
00472     NS_PRECONDITION(pDestination != nsnull, "null ptr");
00473     NS_PRECONDITION(fatalError != nsnull, "null ptr");
00474        
00475        nsCOMPtr<nsIStringBundle>   bundle( dont_AddRef( nsTextStringBundle::GetStringBundleProxy()));
00476        m_bytesImported = 0;
00477 
00478        nsString      success;
00479        nsString      error;
00480     if (!pSource || !pDestination || !fatalError) {
00481               IMPORT_LOG0( "*** Bad param passed to text address import\n");
00482               nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_BADPARAM, error, bundle);
00483               if (fatalError)
00484                      *fatalError = PR_TRUE;
00485               SetLogs( success, error, pErrorLog, pSuccessLog);
00486            return( NS_ERROR_NULL_POINTER);
00487        }
00488    
00489        ClearSampleFile();
00490 
00491     PRBool           addrAbort = PR_FALSE;
00492     nsString  name;
00493     PRUnichar *      pName;
00494     if (NS_SUCCEEDED( pSource->GetPreferredName( &pName))) {
00495        name = pName;
00496        nsCRT::free( pName);
00497     }
00498     
00499        PRUint32 addressSize = 0;
00500        pSource->GetSize( &addressSize);
00501        if (addressSize == 0) {
00502               IMPORT_LOG0( "Address book size is 0, skipping import.\n");
00503               ReportSuccess( name, &success);
00504               SetLogs( success, error, pErrorLog, pSuccessLog);
00505               return( NS_OK);
00506        }
00507 
00508     
00509        nsIFileSpec   *      inFile;
00510     if (NS_FAILED( pSource->GetFileSpec( &inFile))) {
00511               ReportError( TEXTIMPORT_ADDRESS_BADSOURCEFILE, name, &error);
00512               SetLogs( success, error, pErrorLog, pSuccessLog);              
00513        return( NS_ERROR_FAILURE);
00514     }
00515 
00516   nsXPIDLCString pPath; 
00517   inFile->GetNativePath(getter_Copies(pPath));
00518        IMPORT_LOG1( "Importing address book: %s\n", pPath.get());
00519        
00520     nsresult rv = NS_OK;
00521        PRBool isLDIF = PR_FALSE;
00522 
00523     nsCOMPtr<nsIAbLDIFService> ldifService = do_GetService(NS_ABLDIFSERVICE_CONTRACTID, &rv);
00524 
00525     if (NS_SUCCEEDED(rv)) {
00526       rv = ldifService->IsLDIFFile(inFile, &isLDIF);
00527       if (NS_FAILED(rv)) {
00528         IMPORT_LOG0( "*** Error reading address file\n");
00529       }
00530     }
00531 
00532        if (NS_FAILED( rv)) {
00533               inFile->Release();
00534               ReportError( TEXTIMPORT_ADDRESS_CONVERTERROR, name, &error);
00535               SetLogs( success, error, pErrorLog, pSuccessLog);
00536               return( rv);
00537        }
00538        
00539     if (isLDIF) {
00540         if (ldifService)
00541           rv = ldifService->ImportLDIFFile(pDestination, inFile, PR_FALSE, &m_bytesImported);
00542         else
00543           return NS_ERROR_FAILURE;
00544        }
00545        else { 
00546               rv = m_text.ImportAddresses( &addrAbort, name.get(), inFile, pDestination, fieldMap, error, &m_bytesImported);
00547               SaveFieldMap( fieldMap);
00548        }
00549 
00550     inFile->Release();
00551            
00552     
00553        if (NS_SUCCEEDED( rv) && error.IsEmpty()) {
00554               ReportSuccess( name, &success);
00555        }
00556        else {
00557               ReportError( TEXTIMPORT_ADDRESS_CONVERTERROR, name, &error);
00558        }
00559 
00560        SetLogs( success, error, pErrorLog, pSuccessLog);
00561 
00562        IMPORT_LOG0( "*** Text address import done\n");
00563   return rv;
00564 }
00565 
00566 
00567 NS_IMETHODIMP ImportAddressImpl::GetImportProgress(PRUint32 *_retval)
00568 {
00569   NS_ENSURE_ARG_POINTER(_retval);
00570        
00571        *_retval = m_bytesImported;
00572        return NS_OK;
00573 }
00574 
00575 
00576 NS_IMETHODIMP ImportAddressImpl::GetNeedsFieldMap(nsIFileSpec *location, PRBool *_retval)
00577 {
00578   NS_ENSURE_ARG_POINTER(_retval);
00579   NS_ENSURE_ARG_POINTER(location);
00580 
00581        *_retval = PR_TRUE;
00582        PRBool exists = PR_FALSE;
00583        PRBool isFile = PR_FALSE;
00584 
00585        nsresult rv = location->Exists( &exists);
00586        rv = location->IsFile( &isFile);
00587        
00588        if (!exists || !isFile)
00589               return( NS_ERROR_FAILURE);
00590 
00591        PRBool isLDIF = PR_FALSE;
00592     nsCOMPtr<nsIAbLDIFService> ldifService = do_GetService(NS_ABLDIFSERVICE_CONTRACTID, &rv);
00593 
00594     if (NS_SUCCEEDED(rv))
00595       rv = ldifService->IsLDIFFile(location, &isLDIF);
00596 
00597        if (NS_FAILED( rv)) {
00598               IMPORT_LOG0( "*** Error determining if file is of type LDIF\n");
00599               return( rv);
00600        }
00601        
00602        if (isLDIF)
00603               *_retval = PR_FALSE;
00604        
00605        return( NS_OK);
00606 }
00607 
00608 void ImportAddressImpl::SanitizeSampleData( nsCString& val)
00609 {
00610        // remove any line-feeds...
00611        val.ReplaceSubstring( "\x0D\x0A", ", ");
00612        val.ReplaceChar( 13, ',');
00613        val.ReplaceChar( 10, ',');
00614 }
00615 
00616 NS_IMETHODIMP ImportAddressImpl::GetSampleData( PRInt32 index, PRBool *pFound, PRUnichar **pStr)
00617 {
00618     NS_PRECONDITION(pFound != nsnull, "null ptr");
00619     NS_PRECONDITION(pStr != nsnull, "null ptr");
00620        if (!pFound || !pStr)
00621               return( NS_ERROR_NULL_POINTER);
00622        
00623        if (!m_fileLoc) {
00624               IMPORT_LOG0( "*** Error, called GetSampleData before SetSampleLocation\n");
00625               return( NS_ERROR_FAILURE);
00626        }
00627 
00628        nsresult      rv;
00629        *pStr = nsnull;
00630        PRBool        open = PR_FALSE;
00631        PRUnichar     term = 0;
00632 
00633        if (!m_haveDelim) {
00634               rv = m_fileLoc->IsStreamOpen( &open);
00635               if (open) {
00636                      m_fileLoc->CloseStream();
00637                      open = PR_FALSE;
00638               }
00639               rv = m_text.DetermineDelim( m_fileLoc);
00640               if (NS_FAILED( rv))
00641                      return( rv);
00642               m_haveDelim = PR_TRUE;
00643               m_delim = m_text.GetDelim();
00644        }
00645        else {
00646               rv = m_fileLoc->IsStreamOpen( &open);                   
00647        }
00648        
00649        if (!open) {
00650               rv = m_fileLoc->OpenStreamForReading();
00651               if (NS_FAILED( rv)) {
00652                      *pFound = PR_FALSE;
00653                      *pStr = nsCRT::strdup( &term);
00654                      return( NS_OK);
00655               }
00656        }
00657        
00658        PRInt32       lineLen;
00659        PRInt32       bufSz = 10240;
00660        char   *pLine = new char[bufSz];
00661        
00662        nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
00663 
00664        rv = nsTextAddress::ReadRecordNumber( m_fileLoc, pLine, bufSz, m_delim, &lineLen, index);
00665        if (NS_SUCCEEDED( rv)) {
00666               nsString      str;
00667               nsCString     field;
00668               nsString      uField;
00669               PRInt32              fNum = 0;
00670               while (nsTextAddress::GetField( pLine, lineLen, fNum, field, m_delim)) {
00671                      if (fNum)
00672                             str.AppendLiteral("\n");
00673                      SanitizeSampleData( field);
00674                      if (impSvc)
00675                             impSvc->SystemStringToUnicode( field.get(), uField);
00676                      else
00677                             uField.AssignWithConversion( field.get());
00678 
00679                      str.Append( uField);
00680                      fNum++;
00681                      field.Truncate();
00682               }
00683 
00684               *pStr = nsCRT::strdup( str.get());
00685               *pFound = PR_TRUE;
00686 
00687               /* IMPORT_LOG1( "Sample data: %S\n", str.get()); */
00688        }
00689        else {
00690               *pFound = PR_FALSE;
00691               *pStr = nsCRT::strdup( &term);
00692        }
00693 
00694        delete [] pLine;
00695 
00696        return( NS_OK);
00697 }
00698 
00699 NS_IMETHODIMP ImportAddressImpl::SetSampleLocation( nsIFileSpec *pLocation)
00700 {
00701        NS_IF_RELEASE( m_fileLoc);
00702        m_haveDelim = PR_FALSE;
00703        m_fileLoc = pLocation;
00704        NS_IF_ADDREF( m_fileLoc);
00705 
00706        return( NS_OK);
00707 }
00708 
00709 
00710 void ImportAddressImpl::ClearSampleFile( void)
00711 {
00712        if (m_fileLoc) {
00713               PRBool        open = PR_FALSE;
00714               m_fileLoc->IsStreamOpen( &open);
00715               if (open)
00716                      m_fileLoc->CloseStream();
00717               NS_RELEASE( m_fileLoc);
00718               m_fileLoc = nsnull;
00719               m_haveDelim = PR_FALSE;
00720        }
00721 }
00722 
00723 
00724 NS_IMETHODIMP ImportAddressImpl::InitFieldMap(nsIFileSpec *location, nsIImportFieldMap *fieldMap)
00725 {
00726        // Let's remember the last one the user used!
00727        // This should be normal for someone importing multiple times, it's usually
00728        // from the same file format.
00729        
00730        nsresult rv;
00731        nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
00732        if (NS_SUCCEEDED( rv)) {
00733               nsXPIDLCString       prefStr;
00734               rv = prefs->GetCharPref( "mailnews.import.text.fieldmap", getter_Copies(prefStr));
00735               if (NS_SUCCEEDED( rv)) {
00736                      const char *pStr = (const char *)prefStr;
00737                      if (pStr) {
00738                             fieldMap->SetFieldMapSize( 0);
00739                             long          fNum;
00740                             PRBool        active;
00741                             long          fIndex = 0;
00742                             while (*pStr) {
00743                                    while (*pStr && (*pStr != '+') && (*pStr != '-'))
00744                                           pStr++;
00745                                    if (*pStr == '+')
00746                                           active = PR_TRUE;
00747                                    else if (*pStr == '-')
00748                                           active = PR_FALSE;
00749                                    else
00750                                           break;
00751                                    fNum = 0;
00752                                    while (*pStr && ((*pStr < '0') || (*pStr > '9')))
00753                                           pStr++;
00754                                    if (!(*pStr))
00755                                           break;
00756                                    while (*pStr && (*pStr >= '0') && (*pStr <= '9')) {
00757                                           fNum *= 10;
00758                                           fNum += (*pStr - '0');
00759                                           pStr++;
00760                                    }
00761                                    while (*pStr && (*pStr != ','))
00762                                           pStr++;
00763                                    if (*pStr == ',')
00764                                           pStr++;
00765                                    fieldMap->SetFieldMap( -1, fNum);
00766                                    fieldMap->SetFieldActive( fIndex, active);
00767                                    fIndex++;
00768                             }
00769                             if (!fIndex) {
00770                                    int num;
00771                                    fieldMap->GetNumMozFields( &num);
00772                                    fieldMap->DefaultFieldMap( num);
00773                             }
00774                      }
00775               }
00776 
00777         // Now also get the last used skip first record value.
00778         PRBool skipFirstRecord = PR_FALSE;
00779         rv = prefs->GetBoolPref("mailnews.import.text.skipfirstrecord", &skipFirstRecord);
00780         if (NS_SUCCEEDED(rv))
00781         {
00782           fieldMap->SetSkipFirstRecord(skipFirstRecord);
00783         }
00784        }
00785 
00786        return( NS_OK);
00787 }
00788 
00789 
00790 void ImportAddressImpl::SaveFieldMap( nsIImportFieldMap *pMap)
00791 {
00792        if (!pMap)
00793               return;
00794 
00795        int                  size;
00796        int                  index;
00797        PRBool        active;
00798        nsCString     str;
00799 
00800        pMap->GetMapSize( &size);
00801        for (long i = 0; i < size; i++) {
00802               index = i;
00803               active = PR_FALSE;
00804               pMap->GetFieldMap( i, &index);
00805               pMap->GetFieldActive( i, &active);
00806               if (active)
00807                      str.Append( '+');
00808               else
00809                      str.Append( '-');
00810 
00811               str.AppendInt( index);
00812               str.Append( ',');
00813        }
00814 
00815        PRBool done = PR_FALSE;
00816        nsresult rv;
00817 
00818        nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
00819 
00820        if (NS_SUCCEEDED( rv)) {
00821               nsXPIDLCString       prefStr;
00822               rv = prefs->GetCharPref( "mailnews.import.text.fieldmap", getter_Copies(prefStr));
00823               if (NS_SUCCEEDED( rv)) {
00824                      if (str.Equals(prefStr))
00825                             done = PR_TRUE;
00826               }
00827               if (!done) {
00828                      rv = prefs->SetCharPref( "mailnews.import.text.fieldmap", str.get());
00829               }
00830        }
00831 
00832     // Now also save last used skip first record value.
00833     PRBool skipFirstRecord = PR_FALSE;
00834     rv = pMap->GetSkipFirstRecord(&skipFirstRecord);
00835     if (NS_SUCCEEDED(rv))
00836     {
00837       prefs->SetBoolPref("mailnews.import.text.skipfirstrecord", skipFirstRecord);
00838     }
00839 }