📄 imapprotocol.java
字号:
handleResult(response); return null; } } /** * Partial FETCH of given BODY section, without setting SEEN flag. */ public BODY peekBody(int msgno, String section, int start, int size) throws ProtocolException { return fetchBody(msgno, section, start, size, true, null); } /** * Partial FETCH of given BODY section. */ public BODY fetchBody(int msgno, String section, int start, int size) throws ProtocolException { return fetchBody(msgno, section, start, size, false, null); } /** * Partial FETCH of given BODY section, without setting SEEN flag. */ public BODY peekBody(int msgno, String section, int start, int size, ByteArray ba) throws ProtocolException { return fetchBody(msgno, section, start, size, true, ba); } /** * Partial FETCH of given BODY section. */ public BODY fetchBody(int msgno, String section, int start, int size, ByteArray ba) throws ProtocolException { return fetchBody(msgno, section, start, size, false, ba); } protected BODY fetchBody(int msgno, String section, int start, int size, boolean peek, ByteArray ba) throws ProtocolException { this.ba = ba; // save for later use by getResponseBuffer Response[] r = fetch( msgno, (peek ? "BODY.PEEK[" : "BODY[" ) + (section == null ? "]<" : (section +"]<")) + String.valueOf(start) + "." + String.valueOf(size) + ">" ); notifyResponseHandlers(r); Response response = r[r.length-1]; if (response.isOK()) return (BODY)FetchResponse.getItem(r, msgno, BODY.class); else if (response.isNO()) return null; else { handleResult(response); return null; } } /** * Return a buffer to read a response into. * The buffer is provided by fetchBody and is * used only once. */ protected ByteArray getResponseBuffer() { ByteArray ret = ba; ba = null; return ret; } /** * Fetch the specified RFC822 Data item. 'what' names * the item to be fetched. 'what' can be <code>null</code> * to fetch the whole message. */ public RFC822DATA fetchRFC822(int msgno, String what) throws ProtocolException { Response[] r = fetch(msgno, what == null ? "RFC822" : "RFC822." + what ); // dispatch untagged responses notifyResponseHandlers(r); Response response = r[r.length-1]; if (response.isOK()) return (RFC822DATA)FetchResponse.getItem(r, msgno, RFC822DATA.class); else if (response.isNO()) return null; else { handleResult(response); return null; } } /** * Fetch the FLAGS for the given message. */ public Flags fetchFlags(int msgno) throws ProtocolException { Flags flags = null; Response[] r = fetch(msgno, "FLAGS"); // Search for our FLAGS response for (int i = 0, len = r.length; i < len; i++) { if (r[i] == null || !(r[i] instanceof FetchResponse) || ((FetchResponse)r[i]).getNumber() != msgno) continue; FetchResponse fr = (FetchResponse)r[i]; if ((flags = (Flags)fr.getItem(Flags.class)) != null) { r[i] = null; // remove this response break; } } // dispatch untagged responses notifyResponseHandlers(r); handleResult(r[r.length-1]); return flags; } /** * Fetch the IMAP UID for the given message. */ public UID fetchUID(int msgno) throws ProtocolException { Response[] r = fetch(msgno, "UID"); // dispatch untagged responses notifyResponseHandlers(r); Response response = r[r.length-1]; if (response.isOK()) return (UID)FetchResponse.getItem(r, msgno, UID.class); else if (response.isNO()) // XXX: Issue NOOP ? return null; else { handleResult(response); return null; // NOTREACHED } } /** * Get the sequence number for the given UID. A UID object * containing the sequence number is returned. If the given UID * is invalid, <code>null</code> is returned. */ public UID fetchSequenceNumber(long uid) throws ProtocolException { UID u = null; Response[] r = fetch(String.valueOf(uid), "UID", true); for (int i = 0, len = r.length; i < len; i++) { if (r[i] == null || !(r[i] instanceof FetchResponse)) continue; FetchResponse fr = (FetchResponse)r[i]; if ((u = (UID)fr.getItem(UID.class)) != null) { if (u.uid == uid) // this is the one we want break; else u = null; } } notifyResponseHandlers(r); handleResult(r[r.length-1]); return u; } /** * Get the sequence numbers for UIDs ranging from start till end. * UID objects that contain the sequence numbers are returned. * If no UIDs in the given range are found, an empty array is returned. */ public UID[] fetchSequenceNumbers(long start, long end) throws ProtocolException { Response[] r = fetch(String.valueOf(start) + ":" + (end == UIDFolder.LASTUID ? "*" : String.valueOf(end)), "UID", true); UID u; Vector v = new Vector(); for (int i = 0, len = r.length; i < len; i++) { if (r[i] == null || !(r[i] instanceof FetchResponse)) continue; FetchResponse fr = (FetchResponse)r[i]; if ((u = (UID)fr.getItem(UID.class)) != null) v.addElement(u); } notifyResponseHandlers(r); handleResult(r[r.length-1]); UID[] ua = new UID[v.size()]; v.copyInto(ua); return ua; } /** * Get the sequence numbers for UIDs ranging from start till end. * UID objects that contain the sequence numbers are returned. * If no UIDs in the given range are found, an empty array is returned. */ public UID[] fetchSequenceNumbers(long[] uids) throws ProtocolException { StringBuffer sb = new StringBuffer(); for (int i = 0; i < uids.length; i++) { if (i > 0) sb.append(","); sb.append(String.valueOf(uids[i])); } Response[] r = fetch(sb.toString(), "UID", true); UID u; Vector v = new Vector(); for (int i = 0, len = r.length; i < len; i++) { if (r[i] == null || !(r[i] instanceof FetchResponse)) continue; FetchResponse fr = (FetchResponse)r[i]; if ((u = (UID)fr.getItem(UID.class)) != null) v.addElement(u); } notifyResponseHandlers(r); handleResult(r[r.length-1]); UID[] ua = new UID[v.size()]; v.copyInto(ua); return ua; } public Response[] fetch(MessageSet[] msgsets, String what) throws ProtocolException { return fetch(MessageSet.toString(msgsets), what, false); } public Response[] fetch(int start, int end, String what) throws ProtocolException { return fetch(String.valueOf(start) + ":" + String.valueOf(end), what, false); } public Response[] fetch(int msg, String what) throws ProtocolException { return fetch(String.valueOf(msg), what, false); } private Response[] fetch(String msgSequence, String what, boolean uid) throws ProtocolException { if (uid) return command("UID FETCH " + msgSequence +" (" + what + ")",null); else return command("FETCH " + msgSequence + " (" + what + ")", null); } /** * COPY command. */ public void copy(MessageSet[] msgsets, String mbox) throws ProtocolException { copy(MessageSet.toString(msgsets), mbox); } public void copy(int start, int end, String mbox) throws ProtocolException { copy(String.valueOf(start) + ":" + String.valueOf(end), mbox); } private void copy(String msgSequence, String mbox) throws ProtocolException { // encode the mbox as per RFC2060 mbox = BASE64MailboxEncoder.encode(mbox); Argument args = new Argument(); args.writeAtom(msgSequence); args.writeString(mbox); simpleCommand("COPY", args); } public void storeFlags(MessageSet[] msgsets, Flags flags, boolean set) throws ProtocolException { storeFlags(MessageSet.toString(msgsets), flags, set); } public void storeFlags(int start, int end, Flags flags, boolean set) throws ProtocolException { storeFlags(String.valueOf(start) + ":" + String.valueOf(end), flags, set); } /** * Set the specified flags on this message. <p> */ public void storeFlags(int msg, Flags flags, boolean set) throws ProtocolException { storeFlags(String.valueOf(msg), flags, set); } private void storeFlags(String msgset, Flags flags, boolean set) throws ProtocolException { Response[] r; if (set) r = command("STORE " + msgset + " +FLAGS " + createFlagList(flags), null); else r = command("STORE " + msgset + " -FLAGS " + createFlagList(flags), null); // Dispatch untagged responses notifyResponseHandlers(r); handleResult(r[r.length-1]); } /** * Creates an IMAP flag_list from the given Flags object. */ private String createFlagList(Flags flags) { StringBuffer sb = new StringBuffer(); sb.append("("); // start of flag_list Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags boolean first = true; for (int i = 0; i < sf.length; i++) { String s; Flags.Flag f = sf[i]; if (f == Flags.Flag.ANSWERED) s = "\\Answered"; else if (f == Flags.Flag.DELETED) s = "\\Deleted"; else if (f == Flags.Flag.DRAFT) s = "\\Draft"; else if (f == Flags.Flag.FLAGGED) s = "\\Flagged"; else if (f == Flags.Flag.RECENT) s = "\\Recent"; else if (f == Flags.Flag.SEEN) s = "\\Seen"; else continue; // skip it if (first) first = false; else sb.append(' '); sb.append(s); } String[] uf = flags.getUserFlags(); // get the user flag strings for (int i = 0; i < uf.length; i++) { if (first) first = false; else sb.append(' '); sb.append(uf[i]); } sb.append(")"); // terminate flag_list return sb.toString(); } /** * Issue the given search criterion on the specified message sets. * Returns array of matching sequence numbers. An empty array * is returned if no matches are found. * * @param msgsets array of MessageSets * @param term SearchTerm * @return array of matching sequence numbers. */ public int[] search(MessageSet[] msgsets, SearchTerm term) throws ProtocolException, SearchException { return search(MessageSet.toString(msgsets), term); } /** * Issue the given search criterion on all messages in this folder. * Returns array of matching sequence numbers. An empty array * is returned if no matches are found. * * @param term SearchTerm * @return array of matching sequence numbers. */ public int[] search(SearchTerm term) throws ProtocolException, SearchException { return search("ALL", term); } /* Apply the given SearchTerm on the specified sequence. * Returns array of matching sequence numbers. Note that an empty * array is returned for no matches. */ private int[] search(String msgSequence, SearchTerm term) throws ProtocolException, SearchException { // Check if the search "text" terms contain only ASCII chars if (SearchSequence.isAscii(term)) { try { return issueSearch(msgSequence, term, null); } catch (IOException ioex) { /* will not happen */ } } /* The search "text" terms do contain non-ASCII chars. We need to * use SEARCH CHARSET <charset> ... * The charsets we try to use are UTF-8 and the locale's * default charset. If the server supports UTF-8, great, * always use it. Else we try to use the default charset. */ // Cycle thru the list of charsets for (int i = 0; i < searchCharsets.length; i++) { if (searchCharsets[i] == null) continue; try { return issueSearch(msgSequence, term, searchCharsets[i]); } catch (CommandFailedException cfx) { /* Server returned NO. For now, I'll just assume that * this indicates that this charset is unsupported. * We can check the BADCHARSET response code once * that's spec'd into the IMAP RFC .. */ searchCharsets[i] = null; continue; } catch (IOException ioex) { /* Charset conversion failed. Try the next one */ continue; } catch (ProtocolException pex) { throw pex; } catch (SearchException sex) { throw sex; } } // No luck. throw new SearchException("Search failed"); } /* Apply the given SearchTerm on the specified sequence, using the * given charset. <p> * Returns array of matching sequence numbers. Note that an empty * array is returned for no matches. */ private int[] issueSearch(String msgSequence, SearchTerm term, String charset) throws ProtocolException, SearchException, IOException { // Generate a search-sequence with the given charset Argument args = SearchSequence.generateSequence(term, charset == null ? null : MimeUtility.javaCharset(charset) ); args.writeAtom(msgSequence); Response[] r; if (charset == null) // text is all US-ASCII r = command("SEARCH", args); else r = command("SEARCH CHARSET " + charset, args); Response response = r[r.length-1]; int[] matches = null; // Grab all SEARCH responses if (response.isOK()) { // command succesful Vector v = new Vector(); int num; for (int i = 0, len = r.length; i < len; i++) { if (!(r[i] instanceof IMAPResponse)) continue; IMAPResponse ir = (IMAPResponse)r[i]; // There *will* be one SEARCH response. if (ir.keyEquals("SEARCH")) { while ((num = ir.readNumber()) != -1) v.addElement(new Integer(num)); r[i] = null; } } // Copy the vector into 'matches' int vsize = v.size(); matches = new int[vsize]; for (int i = 0; i < vsize; i++) matches[i] = ((Integer)v.elementAt(i)).intValue(); } // dispatch remaining untagged responses notifyResponseHandlers(r); handleResult(response); return matches; } /** * NAMESPACE Command. * * @see "RFC2342" */ public Namespaces namespace() throws ProtocolException { if (!hasCapability("NAMESPACE")) throw new BadCommandException("NAMESPACE not supported"); Response[] r = command("NAMESPACE", null); Namespaces namespace = null; Response response = r[r.length-1]; // Grab NAMESPACE response if (response.isOK()) { // command succesful for (int i = 0, len = r.length; i < len; i++) { if (!(r[i] instanceof IMAPResponse)) continue; IMAPResponse ir = (IMAPResponse)r[i]; if (ir.keyEquals("NAMESPACE")) { if (namespace == null) namespace = new Namespaces(ir); r[i] = null; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -