User:Jcranmer/Writing an Importer: Difference between revisions
No edit summary |
No edit summary |
||
| Line 3: | Line 3: | ||
The first step to writing an importer is to implement the basic interface: <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportModule.idl nsIImportModule]</tt>. The <tt>name</tt> and <tt>description</tt> properties are the strings that the user sees (the name being what appears in the list box, the description the blurb beneath the box). The <tt>supports</tt> property is a comma-delineated list of import types that the module supports--for example, the address book or mail filters. The <tt>supportsUpgrade</tt> property is, as far as I can tell, completely pointless and always has been. | The first step to writing an importer is to implement the basic interface: <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportModule.idl nsIImportModule]</tt>. The <tt>name</tt> and <tt>description</tt> properties are the strings that the user sees (the name being what appears in the list box, the description the blurb beneath the box). The <tt>supports</tt> property is a comma-delineated list of import types that the module supports--for example, the address book or mail filters. The <tt>supportsUpgrade</tt> property is, as far as I can tell, completely pointless and always has been. | ||
The final piece of <tt>nsIImportModule</tt> is the <tt>GetImportInterface</tt> function, which will return the object that actually does the import. The caller passes in the type. For mail and address book imports, the caller returns an <tt>nsIImportGeneric</tt> wrapping the actual import implementation; for other imports, the regular import implementation is what is returned. | The final piece of <tt>nsIImportModule</tt> is the <tt>GetImportInterface</tt> function, which will return the object that actually does the import. The caller passes in the type. For mail and address book imports, the caller returns an <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportGeneric.idl nsIImportGeneric]</tt> wrapping the actual import implementation; for other imports, the regular import implementation is what is returned. | ||
To inform the import service of your module, you need to register it with the category manager. The category is "<tt>mailnewsimport</tt>" and the value should be the same as your supports string. If you're writing C++ code, you can see example code from the import module: [http://mxr.mozilla.org/comm-central/mailnews/import/build/nsImportModule.cpp]. | To inform the import service of your module, you need to register it with the category manager. The category is "<tt>mailnewsimport</tt>" and the value should be the same as your supports string. If you're writing C++ code, you can see example code from the import module: [http://mxr.mozilla.org/comm-central/mailnews/import/build/nsImportModule.cpp]. | ||
| Line 11: | Line 11: | ||
== Importing an address book == | == Importing an address book == | ||
The address book supports string is <tt>NS_IMPORT_ADDRESS_STR</tt>, <tt>"addressbook"</tt>. The importer needs to implement the <tt>nsIImportAddressBooks</tt> interface, although the <tt>GetImportInterface</tt> must return it wrapped in an <tt>nsIImportGeneric</tt>. | The address book supports string is <tt>NS_IMPORT_ADDRESS_STR</tt>, <tt>"addressbook"</tt>. The importer needs to implement the <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportAddressBooks.idl nsIImportAddressBooks]</tt> interface, although the <tt>GetImportInterface</tt> must return it wrapped in an <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportGeneric.idl nsIImportGeneric]</tt>. | ||
The first step in importing the address book is to get the file to import. If <tt>GetAutoFind</tt> returns false, the user will be presented a dialog with a file to import. If it's true, the user is sent straight to the import step. The description isn't terribly important in either case--it doesn't seem to be used anymore. | The first step in importing the address book is to get the file to import. If <tt>GetAutoFind</tt> returns false, the user will be presented a dialog with a file to import. If it's true, the user is sent straight to the import step. The description isn't terribly important in either case--it doesn't seem to be used anymore. | ||
| Line 21: | Line 21: | ||
''Information on the the field map is still under construction'' | ''Information on the the field map is still under construction'' | ||
After building the field map, the import can begin. <tt>FindAddressBooks</tt> is called with the location parameter as selected (it is null if <tt>GetAutoFind</tt> returned true). The return value here is an <tt>nsISupportsArray</tt> of <tt> | After building the field map, the import can begin. <tt>FindAddressBooks</tt> is called with the location parameter as selected (it is null if <tt>GetAutoFind</tt> returned true). The return value here is an <tt>[http://mxr.mozilla.org/comm-central/source/mozilla/xpcom/ds/nsISupportsArray.idl nsISupportsArray]</tt> of <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportABDescriptor.idl nsIImportABDescriptor]</tt>s, an array of information to coalesce into address books. Implementations can choose to use the default implementation by calling <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/import/public/nsIImportService.idl nsIImportService::CreateNewABDescriptor]</tt> or provide their own. The important parameters are <tt>import</tt> (whether or not the representative address book is imported), <tt>size</tt> (representative of the total amount to process), and <tt>preferredName</tt> (the name of the new address book). | ||
At this point, <tt>ImportAddressBook</tt> is called. The parameters here are your descriptor (unmolested), the database to import to (which is already a proxy object), the field map, a copy of the (proxied) <tt>nsIAbLDIFService</tt>, and a parameter as to whether or not an address location is the home (for NS 4.x import; it's false for everyone else). The output are strings for the error and success logs, as well as whether or not the fatal errors. The log strings will be shown to the users. Fatal errors will stop import immediately. | At this point, <tt>ImportAddressBook</tt> is called. The parameters here are your descriptor (unmolested), the database to import to (which is already a proxy object), the field map, a copy of the (proxied) <tt>[http://mxr.mozilla.org/comm-central/source/mailnews/addrbook/public/nsIAbLDIFService.idl nsIAbLDIFService]</tt>, and a parameter as to whether or not an address location is the home (for NS 4.x import; it's false for everyone else). The output are strings for the error and success logs, as well as whether or not the fatal errors. The log strings will be shown to the users. Fatal errors will stop import immediately. | ||
== Importing mail == | == Importing mail == | ||
This section is not yet finished. | This section is not yet finished. | ||
Revision as of 03:30, 15 May 2009
When it comes to import, there are two basic pieces: the import service and the import modules or importers. The basic flow of the system is like this: when the user opens the import dialog, he is presented with a choice of things to import (such as an address book). Once this is selected, the import service queries all importers to see which can import the given object. Once an importer is chosen, the file to import is selected (if need be), and then an import is run off of the main thread.
The first step to writing an importer is to implement the basic interface: nsIImportModule. The name and description properties are the strings that the user sees (the name being what appears in the list box, the description the blurb beneath the box). The supports property is a comma-delineated list of import types that the module supports--for example, the address book or mail filters. The supportsUpgrade property is, as far as I can tell, completely pointless and always has been.
The final piece of nsIImportModule is the GetImportInterface function, which will return the object that actually does the import. The caller passes in the type. For mail and address book imports, the caller returns an nsIImportGeneric wrapping the actual import implementation; for other imports, the regular import implementation is what is returned.
To inform the import service of your module, you need to register it with the category manager. The category is "mailnewsimport" and the value should be the same as your supports string. If you're writing C++ code, you can see example code from the import module: [1].
A key thing to note about the importer is that the actual import operates on a separate thread; the pre-import steps are performed on the UI thread. For this reason, the importer implementation needs to have thread-safe addref and care should be taken to make sure that the code properly synchronizes across threads. It is recommended that you implement importers in C++ and not JS for this reason. Running on a debug build while building an importer would be very helpful.
Importing an address book
The address book supports string is NS_IMPORT_ADDRESS_STR, "addressbook". The importer needs to implement the nsIImportAddressBooks interface, although the GetImportInterface must return it wrapped in an nsIImportGeneric.
The first step in importing the address book is to get the file to import. If GetAutoFind returns false, the user will be presented a dialog with a file to import. If it's true, the user is sent straight to the import step. The description isn't terribly important in either case--it doesn't seem to be used anymore.
If GetAutoFind returned false, the next step is to select the file. GetDefaultLocation is then queried, to get the default file, if it's been found, and if the user can set the location. If the default file is not null, that is treated as the selected file; if it is null, a file picker is opened. If the address book supports multiple, a directory is selectable; if it does not, a file itself is selectable. If the user cannot set the location, this is treated as an error. The found status is completely and utterly pointless.
The next step is to build the field map, if necessary. This is determined via GetNeedsFieldMap; the location parameter is the address book (file or directory) that we will be importing, determined from the past step. If GetAutoFind returned true, this function will not be called.
Information on the the field map is still under construction
After building the field map, the import can begin. FindAddressBooks is called with the location parameter as selected (it is null if GetAutoFind returned true). The return value here is an nsISupportsArray of nsIImportABDescriptors, an array of information to coalesce into address books. Implementations can choose to use the default implementation by calling nsIImportService::CreateNewABDescriptor or provide their own. The important parameters are import (whether or not the representative address book is imported), size (representative of the total amount to process), and preferredName (the name of the new address book).
At this point, ImportAddressBook is called. The parameters here are your descriptor (unmolested), the database to import to (which is already a proxy object), the field map, a copy of the (proxied) nsIAbLDIFService, and a parameter as to whether or not an address location is the home (for NS 4.x import; it's false for everyone else). The output are strings for the error and success logs, as well as whether or not the fatal errors. The log strings will be shown to the users. Fatal errors will stop import immediately.
Importing mail
This section is not yet finished.
Importing filters
This section is not yet finished.
Importing settings
This section is not yet finished.