| components.conf |
|
3333 |
- |
| EwsClient.h |
|
536 |
- |
| EwsCopyMoveTransaction.cpp |
|
4200 |
- |
| EwsCopyMoveTransaction.h |
A transaction representing an intra-server EWS copy or move operation.
|
3223 |
- |
| EwsFetchMsgsToOffline.cpp |
Helper class for EwsFetchMsgsToOffline().
It calls IEwsClient.GetMessage() to download each message in turn, passing
itself as a listener.
As the message data arrives, it is written to the local message store.
When each message completes (see OnFetchStop()), it will update the message
database to set `.storeToken`, `.offlineMessageSize` and the `Offline`
message flag.
If there are remaining messages to download, the next one will then be
started.
If there are no more messages or if an error occurs, the onDone function
will be called and the async operation will finish.
|
7535 |
- |
| EwsFetchMsgsToOffline.h |
Asynchronously download the given messages, write them to the local
messageStore, update db to set storeToken/offlineMessageSize etc...
When all messages are successfully downloaded:
- onDone() will be invoked with NS_OK.
If an error occurs while downloading a message:
- onDone() will be invoked with the failure code.
- no more messages will be downloaded.
If the call to EwsFetchMsgsToOffline() returns an error code,
no async operation will be started and onDone() will _not_
be invoked.
If the call to EwsFetchMsgsToOffline() succeeds, it will return
NS_OK and the async operation will be started.
If the async operation is started, onDone() will _always_ be
invoked when it completes, with the resultant status.
NOTE: writes to mbox stores can be preempted - this is where something
starts writing a message when a write is already ongoing.
When this happens, the old write will be failed (and rolled back) and
the new write will be allowed.
If that happens while this function is running, it'll manifest itself
as a failure code passed out to onDone(), most likely
NS_BASE_STREAM_CLOSED.
|
1874 |
- |
| EwsFolder.cpp |
|
68004 |
- |
| EwsFolder.h |
Create a new local folder with the given EWS ID and name under the given
parent.
|
8257 |
- |
| EwsFolderCopyHandler.cpp |
|
6538 |
- |
| EwsFolderCopyHandler.h |
A handler for a single folder copy/move operation.
An instance of `FolderCopyHandler` is created for each copy/move operation. A
single operation always targets a single folder, but includes its subfolders,
meaning we might end up copying or moving multiple folders.
The current process of copying or moving a folder is the following (assuming
no failure):
1. A consumer requests a folder to be copied to an EWS folder
(`EwsFolder::CopyFolder()`).
2. The EWS folder class instantiates a copy handler, and instructs it to
start the operation (`FolderCopyHandler::CopyNextFolder()`).
3. The copy handler instructs its EWS client to begin creating a folder
with the current source folder's name on the server, underneath its
logical parent in the destination folder's hierarchy
(`IEwsClient::CreateFolder()`). It is called with an instance of
`FolderCreateCopyCallbacks`.
4. Once the folder has been created on the EWS server, the EWS client
instructs its callbacks instance to create the new folder locally
(`FolderCreateCopyCallbacks::OnSuccess()`).
5. The callbacks instance notifies the copy handler of the operation's
success (`FolderCopyHandler::OnFolderCreateFinished()`).
6. The copy handler iterates over all the subfolders in the source
folders, and adds them to the end of the list of folders to copy.
7. The copy handler builds a list of all the messages in the source folder
(non-recursively). If there are messages in this list, it instructs the
newly-created folder to start copying them from the source folder
(`EwsFolder::CopyMessages()`). It is called with an instance of
`MessageCopyListener`. If there are no messages to copy, it skips
straight to step 9.
8. The new folder notifies the listener when all the messages have been
copied (`MessageCopyListener::OnStopCopy()`).
9. `FolderCopyHandler::CopyNextFolder()` is called. If there are more
folders to copy, the copy handler moves to the next folder in the list
and starts the process again from step 3. Otherwise the operation stops
there.
|
5682 |
- |
| EwsIncomingServer.cpp |
Creates a new folder with the specified parent, name, and flags.
If a folder with the specified EWS ID already exists, then succeed without
creating the folder, assuming the folder has already been created locally and
we are processing the corresponding EWS message. If a folder with the same
name, but a different EWS ID exists, then return an error.
|
33083 |
- |
| EwsIncomingServer.h |
Locally creates a folder with the given properties. Intended to be called
by a friend class such as `FolderSyncListener`.
|
3820 |
- |
| EwsLanguageInteropFactory.cpp |
|
734 |
- |
| EwsLanguageInteropFactory.h |
Factory implementation for creating instances of EWS interfaces to span
language boundaries.
|
821 |
- |
| EwsListeners.cpp |
|
5429 |
- |
| EwsListeners.h |
A listener for "simple" EWS operations, i.e. operations that only need to
report a success to the consumer.
When the operation succeeds, the lambda function passed to this class's
constructor is called, with an array containing changed/new EWS
identifier(s), as well as a boolean indicating whether a resync of the
relevant entity (folder list, message list, etc) is required.
|
11941 |
- |
| EwsMessageChannel.cpp |
nsIChannel/nsIRequest impl for EwsOfflineMessageChannel
|
12159 |
- |
| EwsMessageChannel.h |
A channel for streaming an EWS message out of the relevant message store.
The message URI is expected to use the form:
x-moz-ews://{user}@{server}/{Path/To/Folder}/{MessageKey}
Note that no specific encoding is applied to the folder path (besides the
standard URL path encoding).
Translating this URI into a message header (which we can use to stream the
message's content from the message store) is done through calling
`EwsService::MessageURIToMsgHdr`.
Design considerations on the form of "x-moz-ews" URIs: it includes the
message key in the path to follow RESTful semantics. The message is the
resource the URI is pointing to, "located" to the path preceding its key
(i.e. the path to the folder). Some alternatives that were considered are:
* Setting the key as a query parameter, however we seem to use query
parameters to control how the message is fetched and/or rendered/streamed,
not which message the operation is about, so it would be inconsistent with
the rest of the code.
* Following the lead of `[protocol]-message` URIs, with the message key
located in the "ref" part of the URI. However, this does not work well for
displaying messages, as the DocShell does not take this part of the URI
into account to decide whether it matches with a document that's already
currently rendered (so it doesn't need to render it again); this would
lead to every message in a folder being considered the same document.
|
4265 |
- |
| EwsMessageCopyHandler.cpp |
|
13650 |
- |
| EwsMessageCopyHandler.h |
A handler for a single message copy/move operation, the source for which can
be either a file or a folder.
An instance of `MessageCopyHandler` is created for each copy/move operation,
but a single copy/move operation can target multiple messages.
It iterates over each message in the queue sequentially and
1. streams it from the relevant message service
2. creates a new item on the server for the message
3. creates a local copy of the message
4. triggers step 1 for the next message (if there is one)
The current process of copying or moving a message from a folder is the
following (assuming no failures, and excepting signaling start/stop/progress
updates to the source folder and the copy listener):
1. A consumer requests an array of messages to be copied to an EWS folder
(`EwsFolder::CopyMessages()`).
2. The EWS folder class instantiates a copy handler, and instructs it to
start the operation (`MessageCopyHandler::StartCopyingNextMessage()`).
3. The copy handler instructs the message service relevant to the first
message in line to stream said message's content to the handler
(`nsIMsgMessageService::CopyMessage()`).
4. Once the full message content has been streamed, the message service
then signals to the copy handler that it has finished streaming the
message's content (`MessageCopyHandler::EndCopy()`).
5. The copy handler instructs its EWS client to begin creating an item for
the message on the EWS server (`IEwsClient::CreateMessage()`). It is
called with an instance of `MessageCreateCallbacks`, which performs
database operations and notifies the copy handler about the operation's
progress.
6. Once the item has been created on the EWS server, the EWS client
instructs its callbacks instance to save the message's content to the
relevant local database and message store
(`MessageCreateCallbacks::OnRemoteCreateSuccessful()`).
7. The EWS client then notifies the copy handler (through its callbacks)
that the new message has been successfully created, both on the EWS
server and locally (`MessageCopyHandler::OnCreateFinished()`).
8. If the operation is a move, the copy handler deletes the source message
on the source folder.
9. The copy handler repeats this process from steps 3 onwards until every
message in the original array has been copied or moved.
10. Once the operation has completed, or if there has been a failure
during the operation, the copy handler notifies the source folder and
the global copy service about the end and final status of the
operation (`MessageCopyHandler::OnCopyCompleted()`).
When copying from a file, the same process is followed, apart from a few
changes:
* Step 3 is skipped, as the copy handler already holds a copy of the
message's content (in the file).
* Step 8 is skipped, as we're always dealing with a copy operation when
the source is a file.
* Step 9 is skipped, as we're always dealing with a single message when
the source is a file.
|
8880 |
- |
| EwsMessageSync.cpp |
Helper class for orchestrating a message sync operation for an EwsFolder.
You can think of it as an object which represents the sync operation as it
progresses.
It works by asking EwsClient to start a message sync operation.
As the operation progresses, EwsClient communicates updates via
IEwsMessageSyncListener callbacks. This class implements those callbacks
and responds by applying whatever changes need to be made to the local
folder, database, whatever.
It exists for the duration of the sync operation.
This removes most protocol-specific message sync code out of EwsFolder.
Architectural aside (potential future directions):
While other protocols might employ quite different approaches to
synchronising server and local state, the changes such operations need
to apply to the folder (and database et al) are actually very generic.
So, while the operation implementation is tightly coupled to the protocol,
it can be loosely coupled to the folder via protocol-agnostic interfaces.
We can use this pattern to strip such operations out of the various
folder implementations (nsImapMailFolder et al) leaving a small, shared
folder core.
The historical folder implementations tend to add all their operation
state tracking as member variables of the their folder class. Some
folder classes are huge. This vastly complicates the
folder code itself and the code flow followed during such operations.
Even without going to the logical extreme of sharing a single folder
class across all protocols, this pattern could help move complex protocol
operations out of folder code and into understandable units, making the
code vastly easier to reason with.
NOTE: we're using C++ derivation here to implement the
IEwsMessageSyncListener callbacks, as opposed to the lambda-based approach
used for other EWS operations.
Using derivation to implement listener callbacks is often a bad
idea:
- it exposes implementation details which shouldn't be part of the
public class interface.
- it often leads to an obfuscated flow of execution (crossing multiple
class and source file boundaries).
- it gets complicated where multiple operations use the same listener
interface, so derived callback implementations have to "demultiplex" and
figure out which in context they are being called.
The rationale for using derivation here:
- All the callback code is in the same source file as the function call
which initiates the operation so flow of execution is easier to track.
- The class itself is never exposed, being hidden away in this .cpp file.
- We need a ref-counted object to hold the ongoing state of the operation
(e.g. a list of messages added so far), and the derivation gives us that.
- It sidesteps some of the awkwardness and scoping foot-guns around
sharing state across multiple Lambda closures.
As this code evolves over time, this rationale should be re-evaluated.
This message sync code could be radically rewritten and nothing
outside this file needs to know.
|
12615 |
- |
| EwsMessageSync.h |
Starts an EWS message sync operation running upon the given folder.
`onStart` is called when the operation successfully starts.
`onStop` is called when the operation finishes or fails.
It is passed the final result status and a list of messages which have
been added to the folder. Even if the operation fails, some messages still
may have been added.
If this function returns a failure code, the operation has failed to start
and neither `onStart` or `onStop` will be called.
|
1127 |
- |
| EwsOAuth2CustomDetails.cpp |
|
5992 |
- |
| EwsOAuth2CustomDetails.h |
Configured OAuth2 connection parameters for EWS/Microsoft Office365.
Microsoft exchange exposes a single Tenant connection parameter
that is then used in conjunction with the endpoint host (issuer)
and a standard URL scheme to construct the authorization and token
endpoints. This class enables configuration of the user-facing
values and maps those values to the `IOAuth2CustomDetails` interface
to provide the standard OAuth2 connection parameter set.
All other configured values are passed through the interface verbatim to
their corresponding connection parameters.
|
3001 |
- |
| EwsProtocolHandler.cpp |
|
3103 |
- |
| EwsProtocolHandler.h |
|
617 |
- |
| EwsProtocolInfo.cpp |
|
4382 |
- |
| EwsProtocolInfo.h |
|
599 |
- |
| EwsService.cpp |
|
12545 |
- |
| EwsService.h |
Retrieves the message at the given URI, downloading it first if requested,
then optionally converting it to the desired output format.
When fetching a part of a message (e.g. to save an attachment), the URI's
query is expected to describe which part to isolate and what the output
format should be. This query is processed by the stream converter, and thus
will be ignored unless `aConvert` is true.
|
3332 |
- |
| GraphClient.h |
|
557 |
- |
| IEwsClient.idl |
A client for communicating with a Microsoft Exchange server via Exchange Web
Services.
This interface is intended to provide an abstraction of EWS operations to
bridge the foreign function interface between the components of a Thunderbird
mail protocol implementation and a single implementation of those EWS ops.
With the exception of initialization, all client operations are intended to
be asynchronous, with implementations of the callback interfaces used to
handle the results of the operations or handle errors.
|
23144 |
- |
| IEwsFolder.idl |
Specialized interface to folders on an EWS server.
|
3080 |
- |
| IEwsIncomingServer.idl |
IEwsIncomingServer is intended as a workaround for limitations in the folder
lookup service.
EWS folders require an EWS client object in order to fetch new messages. The
folder itself, however, does not have access to all of the details needed to
create such a client. This information is part of the incoming server.
Due to depending on the folder lookup service to create new folders, it is
not possible to give the folder a direct handle to its associated server, so
we are forced to go through XPCOM.
|
3260 |
- |
| IEwsLanguageInteropFactory.idl |
Interface for constructing XPCOM object parameterized on a value.
|
609 |
- |
| moz.build |
|
1157 |
- |
| nsEwsOutgoingServer.h |
|
692 |
- |