3. Bundle Dependencies
3.2. Defining an API
To support multiple kinds of message sources, we need to build an abstraction over messages and mailboxes, so a good place to start is to think about what those abstractions should look like. In Java we would represent them as in- terfaces. Listing3.1contains a reasonable attempt to define a message in the most general way.
3.2 Defining an API 47
Listing 3.1 The Message Interface 1 p a c k a g e o r g.o s g i.b o o k.r e a d e r.a p i; 3 i m p o r t j a v a.i o.I n p u t S t r e a m; 5 p u b l i c i n t e r f a c e M e s s a g e {
7 /∗∗
8 ∗ @return The unique ( w i t h i n t h i s message ’ s mailbox ) message ID .
9 ∗/
10 l o n g g e t I d( ) ;
12 /∗∗
13 ∗ @return A human−r e a d a b l e t e x t summary o f the message . In some 14 ∗ messaging systems t h i s would map to the " s u b j e c t " f i e l d .
15 ∗/
16 S t r i n g g e t S u m m a r y( ) ;
18 /∗∗
19 ∗ @return The I n t e r n e t MIME type o f the message content .
20 ∗/
21 S t r i n g g e t M I M E T y p e( ) ;
23 /∗∗
24 ∗ Access the content o f the message .
25 ∗
26 ∗ @throws MessageReaderException
27 ∗/
28 I n p u t S t r e a m g e t C o n t e n t( ) t h r o w s M e s s a g e R e a d e r E x c e p t i o n; 30 }
Objects implementing this interface are really just message headers. The body of the message could be of any type: text, image, video, etc. We need the header object to tell us what type the body data is, and how to access it. Listing 3.2The Mailbox Interface
1 p a c k a g e o r g.o s g i.b o o k.r e a d e r.a p i; 3 p u b l i c i n t e r f a c e M a i l b o x {
5 p u b l i c s t a t i c f i n a l S t r i n g N A M E _ P R O P E R T Y = " m a i l b o x N a m e ";
7 /∗∗
8 ∗ R etr i e v e a l l messages a v a i l a b l e in the mailbox .
9 ∗
10 ∗ @return An array o f message IDs .
11 ∗ @throws MailboxException
12 ∗/
13 l o n g[ ] g e t A l l M e s s a g e s( ) t h r o w s M a i l b o x E x c e p t i o n;
15 /∗∗
16 ∗ R e tr i e v e a l l messages r e c e i v e d a f t e r the s p e c i f i e d message .
17 ∗
18 ∗ @param i d The message ID . 19 ∗ @return An array o f message IDs .
20 ∗ @throws MailboxException
21 ∗/
22 l o n g[ ] g e t M e s s a g e s S i n c e(l o n g i d) t h r o w s M a i l b o x E x c e p t i o n;
24 /∗∗
25 ∗ Mark the s p e c i f i e d messages as read /unread on the back−end 26 ∗ message source , where supported , e . g . IMAP supports t h i s 27 ∗ f e a t u r e .
28 ∗
29 ∗ @param read Whether the s p e c i f i e d messages have been read . 30 ∗ @param i d s An array o f message IDs .
31 ∗ @throws MailboxException
32 ∗/
33 v o i d m a r k R e a d(b o o l e a n r e a d, l o n g[ ] i d s) t h r o w s M a i l b o x E x c e p t i o n;
35 /∗∗
36 ∗ Retrie ve the s p e c i f i e d messages .
37 ∗
38 ∗ @param i d s The IDs o f the messages to be r e t r i e v e d . 39 ∗ @return An array o f Messages .
40 ∗ @throws MailboxException
41 ∗/
42 M e s s a g e[ ] g e t M e s s a g e s(l o n g[ ] i d s) t h r o w s M a i l b o x E x c e p t i o n; 44 }
Next we need a way to retrieve messages. The interface for a mailbox could look like Listing 3.2. We need a unique identifier to refer to each message, so we assume that an ID of typelong can be generated or assigned by the mailbox implementation. We also assume that the mailbox maintains some temporal ordering of messages, and is capable of telling us about all the new messages available given the ID of the most recent message known about by the reader tool. In this way the tool can notify us only of new messages, rather than ones that we have already read.