Added option for Gmail threading

This commit is contained in:
M66B 2020-05-01 21:47:59 +02:00
parent 974fe5c25b
commit fb46927766
21 changed files with 1561 additions and 5 deletions

View File

@ -0,0 +1,234 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.gimap.protocol.*;
/**
* A Gmail folder. Defines new FetchProfile items and
* uses GmailMessage to store additional Gmail message attributes.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailFolder extends IMAPFolder {
/**
* A fetch profile item for fetching headers.
* This inner class extends the <code>FetchProfile.Item</code>
* class to add new FetchProfile item types, specific to Gmail.
*
* @see FetchProfile
*/
public static class FetchProfileItem extends FetchProfile.Item {
protected FetchProfileItem(String name) {
super(name);
}
/**
* MSGID is a fetch profile item that can be included in a
* <code>FetchProfile</code> during a fetch request to a Folder.
* This item indicates that the Gmail unique message ID for messages
* in the specified range are desired to be prefetched. <p>
*
* An example of how a client uses this is below:
* <blockquote><pre>
*
* FetchProfile fp = new FetchProfile();
* fp.add(GmailFolder.FetchProfileItem.MSGID);
* folder.fetch(msgs, fp);
*
* </pre></blockquote>
*/
public static final FetchProfileItem MSGID =
new FetchProfileItem("X-GM-MSGID");
/**
* THRID is a fetch profile item that can be included in a
* <code>FetchProfile</code> during a fetch request to a Folder.
* This item indicates that the Gmail unique thread ID for messages
* in the specified range are desired to be prefetched. <p>
*
* An example of how a client uses this is below:
* <blockquote><pre>
*
* FetchProfile fp = new FetchProfile();
* fp.add(GmailFolder.FetchProfileItem.THRID);
* folder.fetch(msgs, fp);
*
* </pre></blockquote>
*/
public static final FetchProfileItem THRID =
new FetchProfileItem("X-GM-THRID");
/**
* LABELS is a fetch profile item that can be included in a
* <code>FetchProfile</code> during a fetch request to a Folder.
* This item indicates that the Gmail labels for messages
* in the specified range are desired to be prefetched. <p>
*
* An example of how a client uses this is below:
* <blockquote><pre>
*
* FetchProfile fp = new FetchProfile();
* fp.add(GmailFolder.FetchProfileItem.LABELS);
* folder.fetch(msgs, fp);
*
* </pre></blockquote>
*/
public static final FetchProfileItem LABELS =
new FetchProfileItem("X-GM-LABELS");
}
/**
* Set the specified labels for the given array of messages.
*
* @param msgs the messages
* @param labels the labels to add or remove
* @param set true to add, false to remove
* @exception MessagingException for failures
* @since JavaMail 1.5.5
*/
public synchronized void setLabels(Message[] msgs,
String[] labels, boolean set)
throws MessagingException {
checkOpened();
if (msgs.length == 0) // boundary condition
return;
synchronized(messageCacheLock) {
try {
IMAPProtocol ip = getProtocol();
assert ip instanceof GmailProtocol;
GmailProtocol p = (GmailProtocol)ip;
MessageSet[] ms = Utility.toMessageSetSorted(msgs, null);
if (ms == null)
throw new MessageRemovedException(
"Messages have been removed");
p.storeLabels(ms, labels, set);
} catch (ConnectionException cex) {
throw new FolderClosedException(this, cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
}
/**
* Set the specified labels for the given range of message numbers.
*
* @param start first message number
* @param end last message number
* @param labels the labels to add or remove
* @param set true to add, false to remove
* @exception MessagingException for failures
* @since JavaMail 1.5.5
*/
public synchronized void setLabels(int start, int end,
String[] labels, boolean set)
throws MessagingException {
checkOpened();
Message[] msgs = new Message[end - start + 1];
int i = 0;
for (int n = start; n <= end; n++)
msgs[i++] = getMessage(n);
setLabels(msgs, labels, set);
}
/**
* Set the specified labels for the given array of message numbers.
*
* @param msgnums the message numbers
* @param labels the labels to add or remove
* @param set true to add, false to remove
* @exception MessagingException for failures
* @since JavaMail 1.5.5
*/
public synchronized void setLabels(int[] msgnums,
String[] labels, boolean set)
throws MessagingException {
checkOpened();
Message[] msgs = new Message[msgnums.length];
for (int i = 0; i < msgnums.length; i++)
msgs[i] = getMessage(msgnums[i]);
setLabels(msgs, labels, set);
}
/**
* Constructor used to create a possibly non-existent folder.
*
* @param fullName fullname of this folder
* @param separator the default separator character for this
* folder's namespace
* @param store the Store
* @param isNamespace does this name represent a namespace?
*/
protected GmailFolder(String fullName, char separator, IMAPStore store,
Boolean isNamespace) {
super(fullName, separator, store, isNamespace);
}
/**
* Constructor used to create an existing folder.
*
* @param li the ListInfo for this folder
* @param store the store containing this folder
*/
protected GmailFolder(ListInfo li, IMAPStore store) {
super(li, store);
}
/**
* Create a new IMAPMessage object to represent the given message number.
*/
protected IMAPMessage newIMAPMessage(int msgnum) {
return new GmailMessage(this, msgnum);
}
}

View File

@ -0,0 +1,163 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.gimap.protocol.*;
/**
* A Gmail message. Adds methods to access Gmail-specific per-message data.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailMessage extends IMAPMessage {
/**
* Constructor.
*
* @param folder the containing folder
* @param msgnum the message sequence number
*/
protected GmailMessage(IMAPFolder folder, int msgnum) {
super(folder, msgnum);
}
/**
* Constructor, for use by IMAPNestedMessage.
*
* @param session the Session
*/
protected GmailMessage(Session session) {
super(session);
}
/**
* Return the Gmail unique message ID.
*
* @return the message ID
* @exception MessagingException for failures
*/
public long getMsgId() throws MessagingException {
Long msgid = (Long)getItem(GmailProtocol.MSGID_ITEM);
if (msgid != null)
return msgid.longValue();
else
return -1;
}
/**
* Return the Gmail unique thread ID.
*
* @return the thread ID
* @exception MessagingException for failures
*/
public long getThrId() throws MessagingException {
Long thrid = (Long)getItem(GmailProtocol.THRID_ITEM);
if (thrid != null)
return thrid.longValue();
else
return -1;
}
/**
* Return the Gmail labels associated with this message.
*
* @return array of labels, or empty array if none
* @exception MessagingException for failures
*/
public String[] getLabels() throws MessagingException {
String[] labels = (String[])getItem(GmailProtocol.LABELS_ITEM);
if (labels != null)
return (String[])(labels.clone());
else
return new String[0];
}
/**
* Set/Unset the given labels on this message.
*
* @param labels the labels to add or remove
* @param set true to add labels, false to remove
* @exception MessagingException for failures
* @since JavaMail 1.5.5
*/
public synchronized void setLabels(String[] labels, boolean set)
throws MessagingException {
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(getMessageCacheLock()) {
try {
IMAPProtocol ip = getProtocol();
assert ip instanceof GmailProtocol;
GmailProtocol p = (GmailProtocol)ip;
checkExpunged(); // Insure that this message is not expunged
p.storeLabels(getSequenceNumber(), labels, set);
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
}
/**
* Clear any cached labels for this message.
* The Gmail labels for a messge will be cached when first accessed
* using either the fetch method or the getLabels method. Gmail provides
* no notification when the labels have been changed by another application
* so applications may need to clear the cache if accessing the labels for
* a message more than once while the Folder is open.
*
* @since JavaMail 1.5.6
*/
public synchronized void clearCachedLabels() {
if (items != null)
items.remove(GmailProtocol.LABELS_ITEM.getName());
}
}

View File

@ -0,0 +1,98 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.Message;
import javax.mail.search.StringTerm;
/**
* This class implements searching for the Gmail message ID.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public final class GmailMsgIdTerm extends LongTerm {
private static final long serialVersionUID = -7090909401071626866L;
/**
* Constructor.
*
* @param msgId the message ID
*/
public GmailMsgIdTerm(long msgId) {
super(msgId);
}
/**
* The match method.
*
* @param msg the Message number is matched with this Message
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
long msgId;
try {
if (msg instanceof GmailMessage)
msgId = ((GmailMessage)msg).getMsgId();
else
return false;
} catch (Exception e) {
return false;
}
return super.match(msgId);
}
/**
* Equality comparison.
*
* @param obj the object to compare with
* @return true if equal
*/
public boolean equals(Object obj) {
if (!(obj instanceof GmailMsgIdTerm))
return false;
return super.equals(obj);
}
}

View File

@ -0,0 +1,53 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.Provider;
/**
* The Gmail IMAP protocol provider.
*/
public class GmailProvider extends Provider {
public GmailProvider() {
super(Provider.Type.STORE, "gimap", GmailStore.class.getName(),
"Oracle", null);
}
}

View File

@ -0,0 +1,86 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.Message;
import javax.mail.search.StringTerm;
/**
* This class implements searching using the Gmail X-GM-RAW extension.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public final class GmailRawSearchTerm extends StringTerm {
private static final long serialVersionUID = 6284730140424242662L;
/**
* Constructor.
*
* @param pattern the pattern to search for
*/
public GmailRawSearchTerm(String pattern) {
// Note: comparison is case-insensitive
super(pattern);
}
/**
* The match method.
*
* @param msg the pattern match is applied to this Message's
* subject header
* @exception RuntimeException this can't be supported locally
*/
public boolean match(Message msg) {
throw new RuntimeException("GmailRawSearchTerm not supported locally");
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof GmailRawSearchTerm))
return false;
return super.equals(obj);
}
}

View File

@ -0,0 +1,53 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.Provider;
/**
* The Gmail IMAP protocol provider.
*/
public class GmailSSLProvider extends Provider {
public GmailSSLProvider() {
super(Provider.Type.STORE, "gimaps", GmailSSLStore.class.getName(),
"Oracle", null);
}
}

View File

@ -0,0 +1,65 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.*;
/**
* Support "gimaps" protocol name.
* Unnecessary, since Gmail always uses SSL, but someone might
* expect this name to work.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailSSLStore extends GmailStore {
/**
* Constructor that takes a Session object and a URLName that
* represents a specific IMAP server.
*
* @param session the Session
* @param url the URLName of this store
*/
public GmailSSLStore(Session session, URLName url) {
super(session, url, "gimaps", true);
}
}

View File

@ -0,0 +1,118 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import java.io.IOException;
import javax.mail.*;
import com.sun.mail.iap.ProtocolException;
import com.sun.mail.imap.IMAPStore;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.protocol.IMAPProtocol;
import com.sun.mail.imap.protocol.ListInfo;
import com.sun.mail.gimap.protocol.GmailProtocol;
/**
* A Gmail Store. Defaults to imap.gmail.com with SSL.
* Uses a GmailProtocol and Gmail Folder to support Gmail extensions.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailStore extends IMAPStore {
/**
* Constructor that takes a Session object and a URLName that
* represents a specific IMAP server.
*
* @param session the Session
* @param url the URLName of this store
*/
public GmailStore(Session session, URLName url) {
this(session, url, "gimap", true);
}
/**
* Constructor used by GmailSSLStore subclass.
*
* @param session the Session
* @param url the URLName of this store
* @param name the protocol name
* @param isSSL use SSL to connect?
*/
protected GmailStore(Session session, URLName url,
String name, boolean isSSL) {
super(session, url, name, true); // Gmail requires SSL
}
protected boolean protocolConnect(String host, int pport,
String user, String password)
throws MessagingException {
if (host == null)
host = "imap.gmail.com"; // default to Gmail host
return super.protocolConnect(host, pport, user, password);
}
protected IMAPProtocol newIMAPProtocol(String host, int port)
throws IOException, ProtocolException {
return new GmailProtocol(name, host, port,
session.getProperties(),
isSSL,
logger
);
}
/**
* Create an IMAPFolder object.
*/
protected IMAPFolder newIMAPFolder(String fullName, char separator,
Boolean isNamespace) {
return new GmailFolder(fullName, separator, this, isNamespace);
}
/**
* Create an IMAPFolder object.
*/
protected IMAPFolder newIMAPFolder(ListInfo li) {
return new GmailFolder(li, this);
}
}

View File

@ -0,0 +1,98 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.Message;
import javax.mail.search.StringTerm;
/**
* This class implements searching for the Gmail thread ID.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public final class GmailThrIdTerm extends LongTerm {
private static final long serialVersionUID = -4549268502183739744L;
/**
* Constructor.
*
* @param thrId the thread ID
*/
public GmailThrIdTerm(long thrId) {
super(thrId);
}
/**
* The match method.
*
* @param msg the Message number is matched with this Message
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
long thrId;
try {
if (msg instanceof GmailMessage)
thrId = ((GmailMessage)msg).getThrId();
else
return false;
} catch (Exception e) {
return false;
}
return super.match(thrId);
}
/**
* Equality comparison.
*
* @param obj the object to compare with
* @return true if equal
*/
public boolean equals(Object obj) {
if (!(obj instanceof GmailThrIdTerm))
return false;
return super.equals(obj);
}
}

View File

@ -0,0 +1,95 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap;
import javax.mail.search.SearchTerm;
/**
* This class implements a long integer search term.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
abstract class LongTerm extends SearchTerm {
/**
* The number.
*
* @serial
*/
protected long number;
private static final long serialVersionUID = 5285147193246128043L;
protected LongTerm(long number) {
this.number = number;
}
/**
* Return the number to compare with.
*
* @return the number
*/
public long getNumber() {
return number;
}
protected boolean match(long i) {
return i == number;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof LongTerm))
return false;
LongTerm t = (LongTerm)obj;
return t.number == this.number && super.equals(obj);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return (int)number + super.hashCode();
}
}

View File

@ -0,0 +1,129 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://oss.oracle.com/licenses/CDDL+GPL-1.1
or LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
<TITLE>com.sun.mail.gimap package</TITLE>
</HEAD>
<BODY BGCOLOR="white">
<P>
An EXPERIMENTAL IMAP protocol provider that supports the
<A HREF="https://developers.google.com/google-apps/gmail/imap_extensions"
TARGET="_top">
Gmail-specific IMAP protocol extensions
</A>.
This provider supports all the features of the IMAP provider, plus
additional Gmail-specific features.
This provider can be used by including gimap.jar in your CLASSPATH
along with mail.jar, and by using the "gimap" protocol instead of
the "imap" protocol.
Remember that this means that all properties should be named "mail.gimap.*",
but that otherwise this provider supports all the same properties as the
IMAP protocol provider.
The Gmail IMAP provider defaults to using SSL to connect to "imap.gmail.com".
</P>
<P>
In general, applications should not need to use the classes in this
package directly. Instead, they should use the APIs defined by the
<code>javax.mail</code> package (and subpackages). Applications should
never construct instances of <code>GmailStore</code> or
<code>GmailFolder</code> directly. Instead, they should use the
<code>Session</code> method <code>getStore</code> to acquire an
appropriate <code>Store</code> object, and from that acquire
<code>Folder</code> objects.
</P>
<P>
Message objects returned by this provider may be cast to GmailMessage
to access Gmail-specific data, e.g., using the methods GmailMessage.getMsgId(),
GmailMessage.getThrId(), and GmailMessage.getLabels().
For example:
</P>
<PRE>
GmailMessage gmsg = (GmailMessage)msg;
System.out.println("Gmail message ID is " + gmsg.getMsgId());
String[] labels = gmsg.getLabels();
for (String s : labels)
System.out.println("Gmail message label: " + s);
</PRE>
<P>
Gmail-specific data may be prefetched using the GmailFolder.FetchProfileItems
MSGID, THRID, and LABELS.
For example:
</P>
<PRE>
FetchProfile fp = new FetchProfile();
fp.add(GmailFolder.FetchProfileItem.MSGID);
folder.fetch(fp);
</PRE>
<P>
You can search using Gmail-specific data using the GmailMsgIdTerm,
GmailThrIdTerm, and GmailRawSearchTerm search terms.
For example:
</P>
<PRE>
// find the message with this Gmail unique message ID
long msgid = ...;
Message[] msgs = folder.search(new GmailMsgIdTerm(msgid));
</PRE>
<P>
You can access the Gmail extended attributes (returned by XLIST) for a
folder using the IMAPFolder.getAttributes() method.
For example:
</P>
<PRE>
IMAPFolder ifolder = (IMAPFolder)folder;
String[] attrs = ifolder.getAttributes();
for (String s : attrs)
System.out.println("Folder attribute: " + s);
</PRE>
<P>
<strong>WARNING:</strong> The APIs unique to this package should be
considered <strong>EXPERIMENTAL</strong>. They may be changed in the
future in ways that are incompatible with applications using the
current APIs.
</P>
</BODY>
</HTML>

View File

@ -0,0 +1,214 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap.protocol;
import java.io.*;
import java.util.*;
import java.nio.charset.StandardCharsets;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.gimap.GmailFolder.FetchProfileItem;
import com.sun.mail.util.MailLogger;
/**
* Extend IMAP support to handle Gmail-specific protocol extensions.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailProtocol extends IMAPProtocol {
/*
* Define the Gmail-specific FETCH items.
*/
public static final FetchItem MSGID_ITEM =
new FetchItem("X-GM-MSGID", FetchProfileItem.MSGID) {
public Object parseItem(FetchResponse r) {
return Long.valueOf(r.readLong());
}
};
public static final FetchItem THRID_ITEM =
new FetchItem("X-GM-THRID", FetchProfileItem.THRID) {
public Object parseItem(FetchResponse r) {
return Long.valueOf(r.readLong());
}
};
public static final FetchItem LABELS_ITEM =
new FetchItem("X-GM-LABELS", FetchProfileItem.LABELS) {
public Object parseItem(FetchResponse r) {
return r.readAtomStringList();
}
};
private static final FetchItem[] myFetchItems = {
MSGID_ITEM,
THRID_ITEM,
LABELS_ITEM
};
private FetchItem[] fetchItems = null;
/**
* Connect to Gmail.
*
* @param name the protocol name
* @param host host to connect to
* @param port portnumber to connect to
* @param props Properties object used by this protocol
* @param isSSL use SSL?
* @param logger for log messages
* @exception IOException for I/O errors
* @exception ProtocolException for protocol failures
*/
public GmailProtocol(String name, String host, int port,
Properties props, boolean isSSL, MailLogger logger)
throws IOException, ProtocolException {
super(name, host, port, props, isSSL, logger);
// check to see if this is really Gmail
if (!hasCapability("X-GM-EXT-1")) {
logger.fine("WARNING! Not connected to Gmail!");
// XXX - could call "disconnect()" here and make this a fatal error
} else {
logger.fine("connected to Gmail");
}
}
/**
* Return the additional fetch items supported by the Gmail protocol.
* Combines our fetch items with those supported by the superclass.
*/
public FetchItem[] getFetchItems() {
if (fetchItems != null)
return fetchItems;
FetchItem[] sfi = super.getFetchItems();
if (sfi == null || sfi.length == 0)
fetchItems = myFetchItems;
else {
fetchItems = new FetchItem[sfi.length + myFetchItems.length];
System.arraycopy(sfi, 0, fetchItems, 0, sfi.length);
System.arraycopy(myFetchItems, 0, fetchItems, sfi.length,
myFetchItems.length);
}
return fetchItems;
}
/**
* Set the specified labels on this message.
*
* @param msgsets the message sets
* @param labels the labels
* @param set true to set, false to clear
* @exception ProtocolException for protocol failures
* @since JavaMail 1.5.5
*/
public void storeLabels(MessageSet[] msgsets, String[] labels, boolean set)
throws ProtocolException {
storeLabels(MessageSet.toString(msgsets), labels, set);
}
/**
* Set the specified labels on this message.
*
* @param start the first message number
* @param end the last message number
* @param labels the labels
* @param set true to set, false to clear
* @exception ProtocolException for protocol failures
* @since JavaMail 1.5.5
*/
public void storeLabels(int start, int end, String[] labels, boolean set)
throws ProtocolException {
storeLabels(String.valueOf(start) + ":" + String.valueOf(end),
labels, set);
}
/**
* Set the specified labels on this message.
*
* @param msg the message number
* @param labels the labels
* @param set true to set, false to clear
* @exception ProtocolException for protocol failures
* @since JavaMail 1.5.5
*/
public void storeLabels(int msg, String[] labels, boolean set)
throws ProtocolException {
storeLabels(String.valueOf(msg), labels, set);
}
private void storeLabels(String msgset, String[] labels, boolean set)
throws ProtocolException {
Response[] r;
if (set)
r = command("STORE " + msgset + " +X-GM-LABELS",
createLabelList(labels));
else
r = command("STORE " + msgset + " -X-GM-LABELS",
createLabelList(labels));
// Dispatch untagged responses
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
}
// XXX - assume Gmail always supports UTF-8
private Argument createLabelList(String[] labels) {
Argument args = new Argument();
Argument itemArgs = new Argument();
for (int i = 0, len = labels.length; i < len; i++)
itemArgs.writeString(labels[i], StandardCharsets.UTF_8);
args.writeArgument(itemArgs);
return args;
}
/**
* Return a GmailSearchSequence.
*/
protected SearchSequence getSearchSequence() {
if (searchSequence == null)
searchSequence = new GmailSearchSequence(this);
return searchSequence;
}
}

View File

@ -0,0 +1,100 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.gimap.protocol;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.gimap.*;
/**
* Support Gmail-specific search extensions.
*
* @since JavaMail 1.4.6
* @author Bill Shannon
*/
public class GmailSearchSequence extends SearchSequence {
public GmailSearchSequence(IMAPProtocol p) {
super(p);
}
public Argument generateSequence(SearchTerm term, String charset)
throws SearchException, IOException {
if (term instanceof GmailMsgIdTerm)
return gmailMsgidSearch((GmailMsgIdTerm)term);
else if (term instanceof GmailThrIdTerm)
return gmailThridSearch((GmailThrIdTerm)term);
else if (term instanceof GmailRawSearchTerm)
return gmailRawSearch((GmailRawSearchTerm)term, charset);
else
return super.generateSequence(term, charset);
}
protected Argument gmailMsgidSearch(GmailMsgIdTerm term)
throws IOException {
Argument result = new Argument();
result.writeAtom("X-GM-MSGID");
result.writeNumber(term.getNumber());
return result;
}
protected Argument gmailThridSearch(GmailThrIdTerm term)
throws IOException {
Argument result = new Argument();
result.writeAtom("X-GM-THRID");
result.writeNumber(term.getNumber());
return result;
}
protected Argument gmailRawSearch(GmailRawSearchTerm term, String charset)
throws IOException {
Argument result = new Argument();
result.writeAtom("X-GM-RAW");
result.writeString(term.getPattern(), charset);
return result;
}
}

View File

@ -29,6 +29,7 @@ import androidx.annotation.Nullable;
import androidx.paging.PagedList;
import androidx.preference.PreferenceManager;
import com.sun.mail.gimap.GmailFolder;
import com.sun.mail.iap.Argument;
import com.sun.mail.iap.ProtocolException;
import com.sun.mail.iap.Response;
@ -504,6 +505,8 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
//fp.add(IMAPFolder.FetchProfileItem.MESSAGE);
fp.add(FetchProfile.Item.SIZE);
fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE);
if (account.isGmail())
fp.add(GmailFolder.FetchProfileItem.THRID);
state.ifolder.fetch(add.toArray(new Message[0]), fp);
}

View File

@ -42,6 +42,7 @@ import androidx.core.app.RemoteInput;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager;
import com.sun.mail.gimap.GmailFolder;
import com.sun.mail.iap.BadCommandException;
import com.sun.mail.iap.CommandFailedException;
import com.sun.mail.iap.ConnectionException;
@ -982,6 +983,8 @@ class Core {
//fp.add(IMAPFolder.FetchProfileItem.MESSAGE);
fp.add(FetchProfile.Item.SIZE);
fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE);
if (account.isGmail())
fp.add(GmailFolder.FetchProfileItem.THRID);
ifolder.fetch(new Message[]{imessage}, fp);
EntityMessage message = synchronizeMessage(context, account, folder, istore, ifolder, imessage, false, download, rules, state);
@ -1945,6 +1948,8 @@ class Core {
//fp.add(IMAPFolder.FetchProfileItem.MESSAGE);
fp.add(FetchProfile.Item.SIZE);
fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE);
if (account.isGmail())
fp.add(GmailFolder.FetchProfileItem.THRID);
// Add/update local messages
Long[] ids = new Long[imessages.length];
@ -2748,6 +2753,8 @@ class Core {
//fp.add(IMAPFolder.FetchProfileItem.MESSAGE);
//fp.add(FetchProfile.Item.SIZE);
//fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE);
//if (account.isGmail())
// fp.add(GmailFolder.FetchProfileItem.THRID);
//ifolder.fetch(new Message[]{imessage}, fp);
MessageHelper helper = new MessageHelper(imessage);

View File

@ -11,6 +11,7 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import com.sun.mail.gimap.GmailSSLProvider;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import com.sun.mail.smtp.SMTPTransport;
@ -185,7 +186,7 @@ public class EmailService implements AutoCloseable {
properties.put("mail.pop3.starttls.enable", "true");
properties.put("mail.pop3.starttls.required", Boolean.toString(!insecure));
} else if ("imap".equals(protocol) || "imaps".equals(protocol)) {
} else if ("imap".equals(protocol) || "imaps".equals(protocol) || "gimaps".equals(protocol)) {
// https://javaee.github.io/javamail/docs/api/com/sun/mail/imap/package-summary.html#properties
properties.put("mail.imaps.starttls.enable", "false");
@ -465,13 +466,14 @@ public class EmailService implements AutoCloseable {
isession = Session.getInstance(properties, null);
isession.setDebug(debug);
//System.setProperty("mail.socket.debug", Boolean.toString(debug));
isession.addProvider(new GmailSSLProvider());
if ("pop3".equals(protocol) || "pop3s".equals(protocol)) {
isession.setDebug(true);
iservice = isession.getStore(protocol);
iservice.connect(address.getHostAddress(), port, user, password);
} else if ("imap".equals(protocol) || "imaps".equals(protocol)) {
} else if ("imap".equals(protocol) || "imaps".equals(protocol) || "gimaps".equals(protocol)) {
iservice = isession.getStore(protocol);
if (listener != null)
((IMAPStore) iservice).addStoreListener(listener);

View File

@ -147,7 +147,10 @@ public class EntityAccount extends EntityOrder implements Serializable {
String getProtocol() {
switch (protocol) {
case TYPE_IMAP:
return "imap" + (starttls ? "" : "s");
if (isGmail())
return "gimaps";
else
return "imap" + (starttls ? "" : "s");
case TYPE_POP:
return "pop3" + (starttls ? "" : "s");
default:

View File

@ -73,6 +73,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
private SwitchCompat swFlagged;
private SwitchCompat swDeleteUnseen;
private SwitchCompat swSyncKept;
private SwitchCompat swGmailThread;
private SwitchCompat swSyncFolders;
private SwitchCompat swSubscriptions;
private TextView tvSubscriptionPro;
@ -84,7 +85,8 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
private final static String[] RESET_OPTIONS = new String[]{
"enabled", "poll_interval", "schedule", "schedule_start", "schedule_end",
"sync_nodate", "sync_unseen", "sync_flagged", "delete_unseen", "sync_kept", "sync_folders", "subscriptions",
"sync_nodate", "sync_unseen", "sync_flagged", "delete_unseen", "sync_kept", "gmail_thread_id",
"sync_folders", "subscriptions",
"check_mx", "check_reply"
};
@ -119,6 +121,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
swFlagged = view.findViewById(R.id.swFlagged);
swDeleteUnseen = view.findViewById(R.id.swDeleteUnseen);
swSyncKept = view.findViewById(R.id.swSyncKept);
swGmailThread = view.findViewById(R.id.swGmailThread);
swSyncFolders = view.findViewById(R.id.swSyncFolders);
swSubscriptions = view.findViewById(R.id.swSubscriptions);
tvSubscriptionPro = view.findViewById(R.id.tvSubscriptionPro);
@ -256,6 +259,13 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
}
});
swGmailThread.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("gmail_thread_id", checked).apply();
}
});
swSyncFolders.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@ -368,6 +378,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
swFlagged.setChecked(prefs.getBoolean("sync_flagged", false));
swDeleteUnseen.setChecked(prefs.getBoolean("delete_unseen", false));
swSyncKept.setChecked(prefs.getBoolean("sync_kept", true));
swGmailThread.setChecked(prefs.getBoolean("gmail_thread_id", false));
swSyncFolders.setChecked(prefs.getBoolean("sync_folders", true));
swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false) && pro);
swSubscriptions.setEnabled(pro);

View File

@ -28,6 +28,7 @@ import android.text.TextUtils;
import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceManager;
import com.sun.mail.gimap.GmailMessage;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.BASE64DecoderStream;
import com.sun.mail.util.FolderClosedIOException;
@ -863,6 +864,17 @@ public class MessageHelper {
}
String getThreadId(Context context, long account, long uid) throws MessagingException {
if (imessage instanceof GmailMessage) {
// https://developers.google.com/gmail/imap/imap-extensions#access_to_the_gmail_thread_id_x-gm-thrid
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean gmail_thread_id = prefs.getBoolean("gmail_thread_id", false);
if (gmail_thread_id) {
long thrid = ((GmailMessage) imessage).getThrId();
if (thrid > 0)
return "gmail:" + thrid;
}
}
String thread = null;
String msgid = getMessageID();

View File

@ -374,6 +374,17 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swSyncKept" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swGmailThread"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_gmail_thread"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSyncKeptHint"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSyncFolders"
android:layout_width="0dp"
@ -383,7 +394,7 @@
android:text="@string/title_advanced_sync_folders"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSyncKeptHint"
app:layout_constraintTop_toBottomOf="@id/swGmailThread"
app:switchPadding="12dp" />
<eu.faircode.email.FixedTextView

View File

@ -268,6 +268,7 @@
<string name="title_advanced_flagged">All starred messages</string>
<string name="title_advanced_delete_unseen">Delete old unread messages</string>
<string name="title_advanced_kept_removed">Check if old messages were removed from the server</string>
<string name="title_advanced_gmail_thread">Gmail message grouping style for Gmail accounts</string>
<string name="title_advanced_sync_folders">Synchronize folder list</string>
<string name="title_advanced_subscriptions">Manage folder subscriptions</string>