📄 imapfolder.java
字号:
else // Folder was closed "implicitly" throw new FolderClosedException(this, "Lost folder connection to server" ); } } /* * Check that the given message number is within the range * of messages present in this folder. If the message * number is out of range, we ping the server to obtain any * pending new message notifications from the server. */ private void checkRange(int msgno) throws MessagingException { if (msgno < 1) // message-numbers start at 1 throw new IndexOutOfBoundsException(); if (msgno <= total) return; // Out of range, let's ping the server and see if // the server has more messages for us. synchronized(messageCacheLock) { // Acquire lock try { keepConnectionAlive(false); } catch (ConnectionException cex) { // Oops, lost connection throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } // Release lock if (msgno > total) // Still out of range ? Throw up ... throw new IndexOutOfBoundsException(); } /* * Check whether the given flags are supported by this server, * and also verify that the folder allows setting flags. */ private void checkFlags(Flags flags) throws MessagingException { assert Thread.holdsLock(this); if (mode != READ_WRITE) throw new IllegalStateException( "Cannot change flags on READ_ONLY folder: " + fullName ); /* if (!availableFlags.contains(flags)) throw new MessagingException( "These flags are not supported by this implementation" ); */ } /** * Get the name of this folder. */ public synchronized String getName() { /* Return the last component of this Folder's full name. * Folder components are delimited by the separator character. */ if (name == null) { try { name = fullName.substring( fullName.lastIndexOf(getSeparator()) + 1 ); } catch (MessagingException mex) { } } return name; } /** * Get the fullname of this folder. */ public synchronized String getFullName() { return fullName; } /** * Get this folder's parent. */ public synchronized Folder getParent() throws MessagingException { char c = getSeparator(); int index; if ((index = fullName.lastIndexOf(c)) != -1) return new IMAPFolder(fullName.substring(0, index), c, (IMAPStore)store); else return new DefaultFolder((IMAPStore)store); } /** * Check whether this folder really exists on the server. */ public synchronized boolean exists() throws MessagingException { // Check whether this folder exists .. ListInfo[] li = null; final String lname; if (isNamespace && separator != '\0') lname = fullName + separator; else lname = fullName; li = (ListInfo[])doCommand(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { return p.list("", lname); } }); if (li != null) { int i = findName(li, lname); fullName = li[i].name; separator = li[i].separator; int len = fullName.length(); if (separator != '\0' && len > 0 && fullName.charAt(len - 1) == separator) { fullName = fullName.substring(0, len - 1); } type = 0; if (li[i].hasInferiors) type |= HOLDS_FOLDERS; if (li[i].canOpen) type |= HOLDS_MESSAGES; exists = true; attributes = li[i].attrs; } else { exists = opened; attributes = null; } return exists; } /** * Which entry in <code>li</code> matches <code>lname</code>? * If the name contains wildcards, more than one entry may be * returned. */ private int findName(ListInfo[] li, String lname) { int i; // if the name contains a wildcard, there might be more than one for (i = 0; i < li.length; i++) { if (li[i].name.equals(lname)) break; } if (i >= li.length) { // nothing matched exactly // XXX - possibly should fail? But what if server // is case insensitive and returns the preferred // case of the name here? i = 0; // use first one } return i; } /** * List all subfolders matching the specified pattern. */ public Folder[] list(String pattern) throws MessagingException { return doList(pattern, false); } /** * List all subscribed subfolders matching the specified pattern. */ public Folder[] listSubscribed(String pattern) throws MessagingException { return doList(pattern, true); } private synchronized Folder[] doList(final String pattern, final boolean subscribed) throws MessagingException { checkExists(); // insure that this folder does exist. if (!isDirectory()) // Why waste a roundtrip to the server ? return new Folder[0]; final char c = getSeparator(); ListInfo[] li = (ListInfo[])doCommandIgnoreFailure( new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { if (subscribed) return p.lsub("", fullName + c + pattern); else return p.list("", fullName + c + pattern); } }); if (li == null) return new Folder[0]; /* * The UW based IMAP4 servers (e.g. SIMS2.0) include * current folder (terminated with the separator), when * the LIST pattern is '%' or '*'. i.e, <LIST "" mail/%> * returns "mail/" as the first LIST response. * * Doesn't make sense to include the current folder in this * case, so we filter it out. Note that I'm assuming that * the offending response is the *first* one, my experiments * with the UW & SIMS2.0 servers indicate that .. */ int start = 0; // Check the first LIST response. if (li.length > 0 && li[0].name.equals(fullName + c)) start = 1; // start from index = 1 IMAPFolder[] folders = new IMAPFolder[li.length - start]; for (int i = start; i < li.length; i++) folders[i-start] = new IMAPFolder(li[i], (IMAPStore)store); return folders; } /** * Get the separator character. */ public synchronized char getSeparator() throws MessagingException { if (separator == UNKNOWN_SEPARATOR) { ListInfo[] li = null; li = (ListInfo[])doCommand(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { // REV1 allows the following LIST format to obtain // the hierarchy delimiter of non-existent folders if (p.isREV1()) // IMAP4rev1 return p.list(fullName, ""); else // IMAP4, note that this folder must exist for this // to work :( return p.list("", fullName); } }); if (li != null) separator = li[0].separator; else separator = '/'; // punt ! } return separator; } /** * Get the type of this folder. */ public synchronized int getType() throws MessagingException { if (opened) { // never throw FolderNotFoundException if folder is open if (attributes == null) exists(); // try to fetch attributes } else { checkExists(); } return type; } /** * Check whether this folder is subscribed. <p> */ public synchronized boolean isSubscribed() { ListInfo[] li = null; final String lname; if (isNamespace && separator != '\0') lname = fullName + separator; else lname = fullName; try { li = (ListInfo[])doProtocolCommand(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { return p.lsub("", lname); } }); } catch (ProtocolException pex) { } if (li != null) { int i = findName(li, lname); return li[i].canOpen; } else return false; } /** * Subscribe/Unsubscribe this folder. */ public synchronized void setSubscribed(final boolean subscribe) throws MessagingException { doCommandIgnoreFailure(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { if (subscribe) p.subscribe(fullName); else p.unsubscribe(fullName); return null; } }); } /** * Create this folder, with the specified type. */ public synchronized boolean create(final int type) throws MessagingException { char c = 0; if ((type & HOLDS_MESSAGES) == 0) // only holds folders c = getSeparator(); final char sep = c; Object ret = doCommandIgnoreFailure(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { if ((type & HOLDS_MESSAGES) == 0) // only holds folders p.create(fullName + sep); else { p.create(fullName); // Certain IMAP servers do not allow creation of folders // that can contain messages *and* subfolders. So, if we // were asked to create such a folder, we should verify // that we could indeed do so. if ((type & HOLDS_FOLDERS) != 0) { // we want to hold subfolders and messages. Check // whether we could create such a folder. ListInfo[] li = p.list("", fullName); if (li != null && !li[0].hasInferiors) { // Hmm ..the new folder // doesn't support Inferiors ? Fail p.delete(fullName); throw new ProtocolException("Unsupported type"); } } } return Boolean.TRUE; } }); if (ret == null) return false; // CREATE failure, maybe this // folder already exists ? // exists = true; // this.type = type; boolean retb = exists(); // set exists, type, and attributes if (retb) // Notify listeners on self and our Store notifyFolderListeners(FolderEvent.CREATED); return retb; } /** * Check whether this folder has new messages. */ public synchronized boolean hasNewMessages() throws MessagingException { if (opened) { // If we are open, we already have this information // Folder is open, make sure information is up to date synchronized(messageCacheLock) { // tickle the folder and store connections. try { keepConnectionAlive(true); } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } return recent > 0 ? true : false; } } // First, the cheap way - use LIST and look for the \Marked // or \Unmarked tag ListInfo[] li = null; final String lname; if (isNamespace && separator != '\0') lname = fullName + separator; else lname = fullName; li = (ListInfo[])doCommandIgnoreFailure(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { return p.list("", lname); } }); // if folder doesn't exist, throw exception if (li == null) throw new FolderNotFoundException(this, fullName + " not found"); int i = findName(li, lname); if (li[i].changeState == ListInfo.CHANGED) return true; else if (li[i].changeState == ListInfo.UNCHANGED) return false; // LIST didn't work. Try the hard way, using STATUS try { Status status = getStatus(); if (status.recent > 0) return true; else return false; } catch (BadCommandException bex) { // Probably doesn't support STATUS, tough luck. return false; } catch (ConnectionException cex) { throw new StoreClosedException(store, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -