KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > imapserver > commands > StoreCommand


1 /***********************************************************************
2  * Copyright (c) 2000-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17
18 package org.apache.james.imapserver.commands;
19
20 import org.apache.james.imapserver.ImapRequestLineReader;
21 import org.apache.james.imapserver.ImapResponse;
22 import org.apache.james.imapserver.ImapSession;
23 import org.apache.james.imapserver.ProtocolException;
24 import org.apache.james.imapserver.store.MessageFlags;
25 import org.apache.james.imapserver.store.ImapMailbox;
26 import org.apache.james.imapserver.store.SimpleImapMessage;
27 import org.apache.james.imapserver.store.MailboxException;
28
29 /**
30  * Handles processeing for the STORE imap command.
31  *
32  *
33  * @version $Revision: 1.1.2.3 $
34  */

35 class StoreCommand extends SelectedStateCommand implements UidEnabledCommand
36 {
37     public static final String JavaDoc NAME = "STORE";
38     public static final String JavaDoc ARGS = "<Message-set> ['+'|'-']FLAG[.SILENT] <flag-list>";
39
40     private final StoreCommandParser parser = new StoreCommandParser();
41
42     /** @see CommandTemplate#doProcess */
43     protected void doProcess( ImapRequestLineReader request,
44                               ImapResponse response,
45                               ImapSession session )
46             throws ProtocolException, MailboxException
47     {
48         doProcess( request, response, session , false );
49     }
50
51     public void doProcess( ImapRequestLineReader request,
52                               ImapResponse response,
53                               ImapSession session,
54                               boolean useUids )
55             throws ProtocolException, MailboxException
56     {
57         IdSet idSet = parser.set( request );
58         StoreDirective directive = parser.storeDirective( request );
59         MessageFlags flags = parser.flagList( request );
60         parser.endLine( request );
61
62         ImapMailbox mailbox = session.getSelected();
63         long[] uids = mailbox.getMessageUids();
64         for ( int i = 0; i < uids.length; i++ ) {
65             long uid = uids[i];
66             int msn = mailbox.getMsn( uid );
67
68             if ( ( useUids && idSet.includes( uid ) ) ||
69                  ( !useUids && idSet.includes( msn ) ) )
70             {
71                 SimpleImapMessage imapMessage = mailbox.getMessage( uid );
72                 storeFlags( imapMessage, directive, flags );
73                 mailbox.updateMessage( imapMessage );
74
75                 if ( ! directive.isSilent() ) {
76                     StringBuffer JavaDoc out = new StringBuffer JavaDoc( "FLAGS " );
77                     out.append( imapMessage.getFlags().format() );
78                     response.fetchResponse( msn, out.toString() );
79                 }
80             }
81         }
82
83         session.unsolicitedResponses( response );
84         response.commandComplete( this );
85     }
86
87     private void storeFlags( SimpleImapMessage imapMessage, StoreDirective directive, MessageFlags newFlags )
88     {
89         MessageFlags messageFlags = imapMessage.getFlags();
90         if ( directive.getSign() == 0 ) {
91             messageFlags.setAll( newFlags );
92         }
93         else if ( directive.getSign() < 0 ) {
94             messageFlags.removeAll( newFlags );
95         }
96         else if ( directive.getSign() > 0 ) {
97             messageFlags.addAll( newFlags );
98         }
99     }
100
101     /** @see ImapCommand#getName */
102     public String JavaDoc getName()
103     {
104         return NAME;
105     }
106
107     /** @see CommandTemplate#getArgSyntax */
108     public String JavaDoc getArgSyntax()
109     {
110         return ARGS;
111     }
112
113     private class StoreCommandParser extends CommandParser
114     {
115         StoreDirective storeDirective( ImapRequestLineReader request ) throws ProtocolException
116         {
117             int sign = 0;
118             boolean silent = false;
119
120             char next = request.nextWordChar();
121             if ( next == '+' ) {
122                 sign = 1;
123                 request.consume();
124             }
125             else if ( next == '-' ) {
126                 sign = -1;
127                 request.consume();
128             }
129             else {
130                 sign = 0;
131             }
132
133             String JavaDoc directive = consumeWord( request, new NoopCharValidator() );
134             if ( "FLAGS".equalsIgnoreCase( directive ) ) {
135                 silent = false;
136             }
137             else if ( "FLAGS.SILENT".equalsIgnoreCase( directive ) ) {
138                 silent = true;
139             }
140             else {
141                 throw new ProtocolException( "Invalid Store Directive: '" + directive + "'" );
142             }
143             return new StoreDirective( sign, silent );
144         }
145     }
146
147     private class StoreDirective
148     {
149         private int sign;
150         private boolean silent;
151
152         public StoreDirective( int sign, boolean silent )
153         {
154             this.sign = sign;
155             this.silent = silent;
156         }
157
158         public int getSign()
159         {
160             return sign;
161         }
162
163         public boolean isSilent()
164         {
165             return silent;
166         }
167     }
168 }
169 /*
170 6.4.6. STORE Command
171
172    Arguments: message set
173                message data item name
174                value for message data item
175
176    Responses: untagged responses: FETCH
177
178    Result: OK - store completed
179                NO - store error: can't store that data
180                BAD - command unknown or arguments invalid
181
182       The STORE command alters data associated with a message in the
183       mailbox. Normally, STORE will return the updated value of the
184       data with an untagged FETCH response. A suffix of ".SILENT" in
185       the data item name prevents the untagged FETCH, and the server
186       SHOULD assume that the client has determined the updated value
187       itself or does not care about the updated value.
188
189          Note: regardless of whether or not the ".SILENT" suffix was
190          used, the server SHOULD send an untagged FETCH response if a
191          change to a message's flags from an external source is
192          observed. The intent is that the status of the flags is
193          determinate without a race condition.
194
195       The currently defined data items that can be stored are:
196
197       FLAGS <flag list>
198                      Replace the flags for the message with the
199                      argument. The new value of the flags are returned
200                      as if a FETCH of those flags was done.
201
202       FLAGS.SILENT <flag list>
203                      Equivalent to FLAGS, but without returning a new
204                      value.
205
206       +FLAGS <flag list>
207                      Add the argument to the flags for the message. The
208                      new value of the flags are returned as if a FETCH
209                      of those flags was done.
210
211       +FLAGS.SILENT <flag list>
212                      Equivalent to +FLAGS, but without returning a new
213                      value.
214
215       -FLAGS <flag list>
216                      Remove the argument from the flags for the message.
217                      The new value of the flags are returned as if a
218                      FETCH of those flags was done.
219
220       -FLAGS.SILENT <flag list>
221                      Equivalent to -FLAGS, but without returning a new
222                      value.
223
224    Example: C: A003 STORE 2:4 +FLAGS (\Deleted)
225                S: * 2 FETCH FLAGS (\Deleted \Seen)
226                S: * 3 FETCH FLAGS (\Deleted)
227                S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
228                S: A003 OK STORE completed
229
230 */

231
Popular Tags