You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jl...@apache.org on 2020/10/07 15:58:41 UTC
svn commit: r1882306 [11/17] - in
/geronimo/javamail/trunk/geronimo-javamail_1.6: ./
geronimo-javamail_1.6_mail/ geronimo-javamail_1.6_mail/src/
geronimo-javamail_1.6_mail/src/site/ geronimo-javamail_1.6_provider/
geronimo-javamail_1.6_provider/src/ ge...
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrc;
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcFile;
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+import org.apache.geronimo.mail.util.SessionUtil;
+
+/**
+ * NNTP implementation of javax.mail.Store POP protocol spec is implemented in
+ * org.apache.geronimo.javamail.store.pop3.NNTPConnection
+ *
+ * @version $Rev$ $Date$
+ */
+public class NNTPStore extends Store {
+ protected static final String NNTP_NEWSRC = "newsrc";
+
+ protected static final String protocol = "nntp";
+
+ protected static final int DEFAULT_NNTP_PORT = 119;
+ protected static final int DEFAULT_NNTP_SSL_PORT = 563;
+
+ // our accessor for protocol properties and the holder of
+ // protocol-specific information
+ protected ProtocolProperties props;
+ // our active connection object (shared code with the NNTPStore).
+ protected NNTPConnection connection;
+
+ // the root folder
+ protected NNTPRootFolder root;
+ // the newsrc file where we store subscriptions and seen message markers.
+ protected NNTPNewsrc newsrc;
+
+ /**
+ * Construct an NNTPStore item. This will load the .newsrc file associated
+ * with the server.
+ *
+ * @param session
+ * The owning javamail Session.
+ * @param name
+ * The Store urlName, which can contain server target
+ * information.
+ */
+ public NNTPStore(Session session, URLName name) {
+ this(session, name, "nntp", DEFAULT_NNTP_PORT, false);
+ }
+
+ /**
+ * Common constructor used by the POP3Store and POP3SSLStore classes
+ * to do common initialization of defaults.
+ *
+ * @param session
+ * The host session instance.
+ * @param name
+ * The URLName of the target.
+ * @param protocol
+ * The protocol type ("nntp" or "nntps"). This helps us in
+ * retrieving protocol-specific session properties.
+ * @param defaultPort
+ * The default port used by this protocol. For pop3, this will
+ * be 110. The default for pop3 with ssl is 995.
+ * @param sslConnection
+ * Indicates whether an SSL connection should be used to initial
+ * contact the server. This is different from the STARTTLS
+ * support, which switches the connection to SSL after the
+ * initial startup.
+ */
+ protected NNTPStore(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+ super(session, name);
+
+ // create the protocol property holder. This gives an abstraction over the different
+ // flavors of the protocol.
+ props = new ProtocolProperties(session, protocol, sslConnection, defaultPort);
+
+ // the connection manages connection for the transport
+ connection = new NNTPConnection(props);
+ }
+
+ /**
+ * @see Store#getDefaultFolder()
+ *
+ * This returns a root folder object for all of the news groups.
+ */
+ public Folder getDefaultFolder() throws MessagingException {
+ checkConnectionStatus();
+ if (root == null) {
+ return new NNTPRootFolder(this, connection.getHost(), connection.getWelcomeString());
+ }
+ return root;
+ }
+
+ /**
+ * @see Store#getFolder(String)
+ */
+ public Folder getFolder(String name) throws MessagingException {
+ return getDefaultFolder().getFolder(name);
+ }
+
+ /**
+ *
+ * @see Store#getFolder(URLName)
+ */
+ public Folder getFolder(URLName url) throws MessagingException {
+ return getDefaultFolder().getFolder(url.getFile());
+ }
+
+
+ /**
+ * Do the protocol connection for an NNTP transport. This handles server
+ * authentication, if possible. Returns false if unable to connect to the
+ * server.
+ *
+ * @param host
+ * The target host name.
+ * @param port
+ * The server port number.
+ * @param user
+ * The authentication user (if any).
+ * @param password
+ * The server password. Might not be sent directly if more
+ * sophisticated authentication is used.
+ *
+ * @return true if we were able to connect to the server properly, false for
+ * any failures.
+ * @exception MessagingException
+ */
+ protected boolean protocolConnect(String host, int port, String username, String password)
+ throws MessagingException {
+ // the connection pool handles all of the details here. But don't proceed
+ // without a connection
+ if (!connection.protocolConnect(host, port, username, password)) {
+ return false;
+ }
+
+ // see if we have a newsrc file location specified
+ String newsrcFile = props.getProperty(NNTP_NEWSRC);
+
+ File source = null;
+
+ // not given as a property? Then look for a file in user.home
+ if (newsrcFile != null) {
+ source = new File(newsrcFile);
+ } else {
+ // ok, look for a file in the user.home directory. If possible,
+ // we'll try for a file
+ // with the hostname appended.
+ String home = SessionUtil.getProperty("user.home");
+
+ // try for a host-specific file first. If not found, use (and
+ // potentially create) a generic
+ // .newsrc file.
+ newsrcFile = ".newsrc-" + host;
+ source = new File(home, newsrcFile);
+ if (!source.exists()) {
+ source = new File(home, ".newsrc");
+ }
+ }
+
+ // now create a newsrc read and load the file.
+ newsrc = new NNTPNewsrcFile(source);
+ newsrc.load();
+
+ // we're going to return success here, but in truth, the server may end
+ // up asking for our bonafides at any time, and we'll be expected to authenticate then.
+ return true;
+ }
+
+
+ /**
+ * @see javax.mail.Service#close()
+ */
+ public void close() throws MessagingException {
+ // This is done to ensure proper event notification.
+ super.close();
+ // persist the newsrc file, if possible
+ if (newsrc != null) {
+ newsrc.close();
+ newsrc = null;
+ }
+ connection.close();
+ connection = null;
+ }
+
+ private void checkConnectionStatus() throws MessagingException {
+ if (!this.isConnected()) {
+ throw new MessagingException("Not connected ");
+ }
+ }
+
+ /**
+ * Retrieve the server connection created by this store.
+ *
+ * @return The active connection object.
+ */
+ NNTPConnection getConnection() {
+ return connection;
+ }
+
+ /**
+ * Retrieve the Session object this Store is operating under.
+ *
+ * @return The attached Session instance.
+ */
+ Session getSession() {
+ return session;
+ }
+
+ /**
+ * Retrieve all of the groups we nave persistent store information about.
+ *
+ * @return The set of groups contained in the newsrc file.
+ */
+ Iterator getNewsrcGroups() {
+ return newsrc.getGroups();
+ }
+
+ /**
+ * Retrieve the newsrc group information for a named group. If the file does
+ * not currently include this group, an unsubscribed group will be added to
+ * the file.
+ *
+ * @param name
+ * The name of the target group.
+ *
+ * @return The NNTPNewsrcGroup item corresponding to this name.
+ */
+ NNTPNewsrcGroup getNewsrcGroup(String name) {
+ return newsrc.getGroup(name);
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Base class implementation of a standard news reader news rc file. This is
+ * used to track newsgroup subscriptions and SEEN flags for articles. This is an
+ * abstract class designed for subclasses to bridge to the physical store type
+ * used for the newsgroup information.
+ */
+public abstract class NNTPNewsrc {
+
+ // the group information we've read from the news rc file.
+ Map groups = new HashMap();
+
+ // flag to let us know of we need to persist the newsrc file on close.
+ boolean dirty = false;
+
+ /**
+ * Base class constructor for NNTPNewsrc items. Subclasses provide their own
+ * domain-specific intialization.
+ */
+ protected NNTPNewsrc() {
+ }
+
+ /**
+ * Load the data from the newsrc file and parse into an instore group
+ * database.
+ */
+ public void load() {
+ BufferedReader in = null;
+
+ try {
+ in = getInputReader();
+
+ String line = in.readLine();
+
+ while (line != null) {
+ // parse the line...this returns null if it's something
+ // unrecognized.
+ NNTPNewsrcGroup group = NNTPNewsrcGroup.parse(this, line);
+ // if it parsed ok, add it to the group list, and potentially to
+ // the subscribed list.
+ if (group != null) {
+ groups.put(group.getName(), group);
+ }
+
+ line = in.readLine();
+ }
+
+ in.close();
+ } catch (IOException e) {
+ // an IOException may mean that the file just doesn't exist, which
+ // is fine. We'll ignore and
+ // proceed with the information we have.
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Save the newsrc file data back to the original source file.
+ *
+ * @exception IOException
+ */
+ public void save() throws IOException {
+ Writer out = getOutputWriter();
+
+ Iterator i = groups.values().iterator();
+
+ while (i.hasNext()) {
+ NNTPNewsrcGroup group = (NNTPNewsrcGroup) i.next();
+ group.save(out);
+ }
+
+ out.close();
+ }
+
+ /**
+ * Abstract open method intended for sub class initialization. The subclass
+ * is responsible for creating the BufferedReaded used to read the .newsrc
+ * file.
+ *
+ * @return A BufferedReader for reading the .newsrc file.
+ * @exception IOException
+ */
+ abstract public BufferedReader getInputReader() throws IOException;
+
+ /**
+ * Abstract open for output method intended for subclass implementation. The
+ * subclasses are reponsible for opening the output stream and creating an
+ * appropriate Writer for saving the .newsrc file.
+ *
+ * @return A Writer target at the .newsrc file save location.
+ * @exception IOException
+ */
+ abstract public Writer getOutputWriter() throws IOException;
+
+ /**
+ * Retrieve the newsrc group information for a named group. If the file does
+ * not currently include this group, an unsubscribed group will be added to
+ * the file.
+ *
+ * @param name
+ * The name of the target group.
+ *
+ * @return The NNTPNewsrcGroup item corresponding to this name.
+ */
+ public NNTPNewsrcGroup getGroup(String name) {
+ NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.get(name);
+ // if we don't know about this, create a new one and add to the list.
+ // This
+ // will be an unsubscribed one.
+ if (group == null) {
+ group = new NNTPNewsrcGroup(this, name, null, false);
+ groups.put(name, group);
+ // we've added a group, so we need to resave
+ dirty = true;
+ }
+ return group;
+ }
+
+ /**
+ * Mark this newsrc database as dirty.
+ */
+ public void setDirty() {
+ dirty = true;
+ }
+
+ /**
+ * Close the newsrc file, persisting it back to disk if the file has
+ * changed.
+ */
+ public void close() {
+ if (dirty) {
+ try {
+ save();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Retrieve the current set of loaded groups.
+ *
+ * @return An iterator for traversing the group set.
+ */
+ public Iterator getGroups() {
+ return groups.values().iterator();
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class NNTPNewsrcFile extends NNTPNewsrc {
+ // source for the file data
+ File source;
+
+ /**
+ * Construct a NNTPNewsrc object that is targetted at a file-based backing
+ * store.
+ *
+ * @param source
+ * The source File for the .newsrc data.
+ */
+ public NNTPNewsrcFile(File source) {
+ this.source = source;
+ }
+
+ /**
+ * Retrieve an input reader for loading the newsrc file.
+ *
+ * @return A BufferedReader object for reading from the newsrc file.
+ * @exception IOException
+ */
+ public BufferedReader getInputReader() throws IOException {
+ return new BufferedReader(new InputStreamReader(new FileInputStream(source), "ISO8859-1"));
+ }
+
+ /**
+ * Obtain a writer for saving a newsrc file.
+ *
+ * @return The output writer targetted to the newsrc file.
+ * @exception IOException
+ */
+ public Writer getOutputWriter() throws IOException {
+ // open this for overwriting
+ return new OutputStreamWriter(new FileOutputStream(source, false), "ISO8859-1");
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class NNTPNewsrcGroup {
+ // the newsrc database we're part of
+ NNTPNewsrc newsrc;
+
+ // the name of the group
+ protected String name;
+
+ // the subscription flage
+ protected boolean subscribed;
+
+ // the range of already seen articles.
+ protected RangeList ranges;
+
+ /**
+ * Construct a NNTPNewsrcGroup item associated with a given .newsrc
+ * database.
+ *
+ * @param newsrc
+ * The owning .newsrc database.
+ * @param line
+ * The .newsrc range entries in .newsrc format. These ranges are
+ * parsed to create a set of seen flags.
+ *
+ * @return A created NNTPNewsrcGroup item.
+ */
+ public static NNTPNewsrcGroup parse(NNTPNewsrc newsrc, String line) {
+ String groupName = null;
+ String ranges = null;
+
+ // subscribed lines have a ':' marker acting as a delimiter
+ int marker = line.indexOf(':');
+
+ if (marker != -1) {
+ groupName = line.substring(0, marker);
+ ranges = line.substring(marker + 1);
+ return new NNTPNewsrcGroup(newsrc, groupName, ranges, true);
+ }
+
+ // now check for an unsubscribed group
+ marker = line.indexOf('!');
+
+ if (marker != -1) {
+ groupName = line.substring(0, marker);
+ ranges = line.substring(marker + 1);
+ return new NNTPNewsrcGroup(newsrc, groupName, ranges, false);
+ }
+
+ // must be a comment line
+ return null;
+ }
+
+ /**
+ * Construct a .newsrc group item.
+ *
+ * @param newsrc
+ * The owning newsrc database.
+ * @param name
+ * The group name.
+ * @param newsrcRanges
+ * The initial set of seen ranges for the group (may be null).
+ * @param subscribed
+ * The initial group subscription state.
+ */
+ public NNTPNewsrcGroup(NNTPNewsrc newsrc, String name, String newsrcRanges, boolean subscribed) {
+ this.newsrc = newsrc;
+ this.name = name;
+ this.subscribed = subscribed;
+ this.ranges = new RangeList(newsrcRanges);
+ }
+
+ /**
+ * Get the group name.
+ *
+ * @return The String name of the group.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the newsrc subscribed status for an article.
+ *
+ * @return The current subscription flag.
+ */
+ public boolean isSubscribed() {
+ return subscribed;
+ }
+
+ /**
+ * Set the subscription status for an article.
+ *
+ * @param flag
+ * The new subscription value.
+ */
+ public void setSubscribed(boolean flag) {
+ // we don't blindly set this to the new value since we only want to
+ // resave the newsrc file if
+ // something changes.
+ if (flag && !subscribed) {
+ subscribed = true;
+ newsrc.setDirty();
+ } else if (!flag && subscribed) {
+ subscribed = false;
+ newsrc.setDirty();
+ }
+ }
+
+ /**
+ * Test if an article has been seen yet.
+ *
+ * @param article
+ * The target article.
+ *
+ * @return The seen mark for the article.
+ */
+ public boolean isArticleSeen(int article) {
+ return ranges.isMarked(article);
+ }
+
+ /**
+ * Mark an article as seen.
+ *
+ * @param article
+ * The target article number.
+ */
+ public void markArticleSeen(int article) {
+ ranges.setMarked(article);
+ if (ranges.isDirty()) {
+ newsrc.setDirty();
+ }
+ }
+
+ /**
+ * Mark an article as unseen.
+ *
+ * @param article
+ * The target article number.
+ */
+ public void markArticleUnseen(int article) {
+ ranges.setUnmarked(article);
+ if (ranges.isDirty()) {
+ newsrc.setDirty();
+ }
+ }
+
+ /**
+ * Save this group definition to a .newsrc file.
+ *
+ * @param out
+ * The output writer to send the information to.
+ *
+ * @exception IOException
+ */
+ public void save(Writer out) throws IOException {
+ out.write(name);
+ out.write(subscribed ? ": " : "! ");
+ ranges.save(out);
+ // put a terminating line end
+ out.write("\r\n");
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Represent a single Range in a newsrc file. A Range can be either a single
+ * number (start == end) or a span of article numbers.
+ */
+public class Range {
+ // the low end of the range
+ int start;
+
+ // the high end of the range (start and end are inclusive);
+ int end;
+
+ /**
+ * Construct a Range item for a single digit range.
+ *
+ * @param spot
+ * The location of the singleton.
+ */
+ public Range(int spot) {
+ this(spot, spot);
+ }
+
+ /**
+ * Construct a Range item.
+ *
+ * @param start
+ * The starting point of the Range.
+ * @param end
+ * The Range end point (which may be equal to the starting
+ * point).
+ */
+ public Range(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * Parse a section of a .newsrc range string into a single Range item. The
+ * range is either a single number, or a pair of numbers separated by a
+ * hyphen.
+ *
+ * @param range
+ * The range string.
+ *
+ * @return A constructed Range item, or null if there is a parsing error.
+ */
+ static public Range parse(String range) {
+ // a range from a newsrc file is either a single number or in the format
+ // 'nnnn-mmmm'. We need
+ // to figure out which type this is.
+ int marker = range.indexOf('-');
+
+ try {
+ if (marker != -1) {
+ String rangeStart = range.substring(0, marker).trim();
+ String rangeEnd = range.substring(marker + 1).trim();
+
+ int start = Integer.parseInt(rangeStart);
+ int end = Integer.parseInt(rangeEnd);
+
+ if (start >= 0 && end >= 0) {
+ return new Range(start, end);
+ }
+ } else {
+ // use the entire token
+ int start = Integer.parseInt(range);
+ // and start and the end are the same
+ return new Range(start, start);
+
+ }
+ } catch (NumberFormatException e) {
+ }
+ // return null for any bad values
+ return null;
+ }
+
+ /**
+ * Get the starting point for the Range.
+ *
+ * @return The beginning of the mark range.
+ */
+ public int getStart() {
+ return start;
+ }
+
+ /**
+ * Set the starting point for a Range.
+ *
+ * @param start
+ * The new start value.
+ */
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ /**
+ * Get the ending point for the Range.
+ *
+ * @return The end of the mark range.
+ */
+ public int getEnd() {
+ return end;
+ }
+
+ /**
+ * Set the ending point for a Range.
+ *
+ * @param end
+ * The new end value.
+ */
+ public void setEnd(int end) {
+ this.end = end;
+ }
+
+ /**
+ * Test if a range contains a point value.
+ *
+ * @param target
+ * The article location to test.
+ *
+ * @return True if the target is between the start and end values,
+ * inclusive.
+ */
+ public boolean contains(int target) {
+ return target >= start && target <= end;
+ }
+
+ /**
+ * Test if one range is completely contained within another Range.
+ *
+ * @param other
+ * The other test range.
+ *
+ * @return true if the other start and end points are contained within this
+ * range.
+ */
+ public boolean contains(Range other) {
+ return contains(other.getStart()) && contains(other.getEnd());
+ }
+
+ /**
+ * Tests if two ranges overlap
+ *
+ * @param other
+ * The other test range.
+ *
+ * @return true if the start or end points of either range are contained
+ * within the range of the other.
+ */
+ public boolean overlaps(Range other) {
+ return other.contains(start) || other.contains(end) || contains(other.getStart()) || contains(other.getEnd());
+ }
+
+ /**
+ * Test if two ranges exactly abutt each other.
+ *
+ * @param other
+ * The other Range to test.
+ *
+ * @return true if the end of one range abutts the start of the other range.
+ */
+ public boolean abutts(Range other) {
+ return other.getStart() == end + 1 || other.getEnd() == start - 1;
+ }
+
+ /**
+ * Tests if a single point abutts either the start or end of this Range.
+ *
+ * @param article
+ * The point to test.
+ *
+ * @return true if test point is equal to start - 1 or end + 1.
+ */
+ public boolean abutts(int article) {
+ return article == start - 1 || article == end + 1;
+ }
+
+ /**
+ * Test if a point is below the test Range.
+ *
+ * @param article
+ * The point to test.
+ *
+ * @return true if the entire range is less than the test point.
+ */
+ public boolean lessThan(int article) {
+ return end < article;
+ }
+
+ /**
+ * Test if another Range is less than this Range.
+ *
+ * @param other
+ * The other Range to test.
+ *
+ * @return true if the other Range lies completely below this Range.
+ */
+ public boolean lessThan(Range other) {
+ return end < other.start;
+ }
+
+ /**
+ * Test if a point is above the test Range.
+ *
+ * @param article
+ * The point to test.
+ *
+ * @return true if the entire range is greater than the test point.
+ */
+ public boolean greaterThan(int article) {
+ return start > article;
+ }
+
+ /**
+ * Test if another Range is greater than this Range.
+ *
+ * @param other
+ * The other Range to test.
+ *
+ * @return true if the other Range lies completely below this Range.
+ */
+ public boolean greaterThan(Range other) {
+ return start > other.end;
+ }
+
+ /**
+ * Merge another Range into this one. Merging will increase the bounds of
+ * this Range to encompass the entire span of the two. If the Ranges do not
+ * overlap, the newly created range will include the gap between the two.
+ *
+ * @param other
+ * The Range to merge.
+ */
+ public void merge(Range other) {
+ if (other.start < start) {
+ start = other.start;
+ }
+
+ if (other.end > end) {
+ end = other.end;
+ }
+ }
+
+ /**
+ * Split a range at a given split point. Splitting will truncate at the
+ * split location - 1 and return a new range beginning at location + 1; This
+ * code assumes that the split location is at neither end poing.
+ *
+ * @param location
+ * The split location. Location must be in the range start <
+ * location < end.
+ *
+ * @return A new Range object for the split portion of the range.
+ */
+ public Range split(int location) {
+ int newEnd = end;
+
+ end = location - 1;
+
+ return new Range(location + 1, newEnd);
+ }
+
+ /**
+ * Save an individual range element to a newsrc file. The range is expressed
+ * either as a single number, or a hypenated pair of numbers.
+ *
+ * @param out
+ * The output writer used to save the data.
+ *
+ * @exception IOException
+ */
+ public void save(Writer out) throws IOException {
+ // do we have a single data point range?
+ if (start == end) {
+ out.write(Integer.toString(start));
+ } else {
+ out.write(Integer.toString(start));
+ out.write("-");
+ out.write(Integer.toString(end));
+ }
+ }
+
+ /**
+ * Convert a Range into String form. Used mostly for debugging.
+ *
+ * @return The String representation of the Range.
+ */
+ public String toString() {
+ if (start == end) {
+ return Integer.toString(start);
+ } else {
+ return Integer.toString(start) + "-" + Integer.toString(end);
+ }
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+/**
+ * Manage a list of ranges values from a newsrc file.
+ */
+public class RangeList {
+ boolean dirty = false;
+
+ ArrayList ranges = new ArrayList();
+
+ /**
+ * Create a RangeList instance from a newsrc range line. Values are saved as
+ * a comma separated set of range values. A range value is either a single
+ * number or a hypenated pair of numbers.
+ *
+ * @param line
+ * The newsrc range line.
+ */
+ public RangeList(String line) {
+
+ // we might be creating an first time list, so nothing to parse.
+ if (line != null) {
+ // ranges are comma delimited tokens
+ StringTokenizer tokenizer = new StringTokenizer(line, ",");
+
+ while (tokenizer.hasMoreTokens()) {
+ String rangeString = (String) tokenizer.nextToken();
+ rangeString = rangeString.trim();
+ if (rangeString.length() != 0) {
+ Range range = Range.parse(rangeString);
+ if (range != null) {
+ insert(range);
+ }
+ }
+ }
+ }
+ // make sure we start out in a clean state. Any changes from this point
+ // will flip on the dirty flat.
+ dirty = false;
+ }
+
+ /**
+ * Insert a range item into our list. If possible, the inserted range will
+ * be merged with existing ranges.
+ *
+ * @param newRange
+ * The new range item.
+ */
+ public void insert(Range newRange) {
+ // first find the insertion point
+ for (int i = 0; i < ranges.size(); i++) {
+ Range range = (Range) ranges.get(i);
+ // does an existing range fully contain the new range, we don't need
+ // to insert anything.
+ if (range.contains(newRange)) {
+ return;
+ }
+
+ // does the current one abutt or overlap with the inserted range?
+ if (range.abutts(newRange) || range.overlaps(newRange)) {
+ // rats, we have an overlap...and it is possible that we could
+ // overlap with
+ // the next range after this one too. Therefore, we merge these
+ // two ranges together,
+ // remove the place where we're at, and then recursively insert
+ // the larger range into
+ // the list.
+ dirty = true;
+ newRange.merge(range);
+ ranges.remove(i);
+ insert(newRange);
+ return;
+ }
+
+ // ok, we don't touch the current one at all. If it is completely
+ // above
+ // range we're adding, we can just poke this into the list here.
+ if (newRange.lessThan(range)) {
+ dirty = true;
+ ranges.add(i, newRange);
+ return;
+ }
+ }
+ dirty = true;
+ // this is easy (and fairly common)...we just tack this on to the end.
+ ranges.add(newRange);
+ }
+
+ /**
+ * Test if a given article point falls within one of the contained Ranges.
+ *
+ * @param article
+ * The test point.
+ *
+ * @return true if this falls within one of our current mark Ranges, false
+ * otherwise.
+ */
+ public boolean isMarked(int article) {
+ for (int i = 0; i < ranges.size(); i++) {
+ Range range = (Range) ranges.get(i);
+ if (range.contains(article)) {
+ return true;
+ }
+ // we've passed the point where a match is possible.
+ if (range.greaterThan(article)) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Mark a target article as having been seen.
+ *
+ * @param article
+ * The target article number.
+ */
+ public void setMarked(int article) {
+ // go through the insertion logic.
+ insert(new Range(article, article));
+ }
+
+ /**
+ * Clear the seen mark for a target article.
+ *
+ * @param article
+ * The target article number.
+ */
+ public void setUnmarked(int article) {
+ for (int i = 0; i < ranges.size(); i++) {
+ Range range = (Range) ranges.get(i);
+ // does this fall within an existing range? We don't need to do
+ // anything here.
+ if (range.contains(article)) {
+ // ok, we've found where to insert, now to figure out how to
+ // insert
+ // article is at the beginning of the range. We can just
+ // increment the lower
+ // bound, or if this is a single element range, we can remove it
+ // entirely.
+ if (range.getStart() == article) {
+ if (range.getEnd() == article) {
+ // piece of cake!
+ ranges.remove(i);
+ } else {
+ // still pretty easy.
+ range.setStart(article + 1);
+ }
+ } else if (range.getEnd() == article) {
+ // pretty easy also
+ range.setEnd(article - 1);
+ } else {
+ // split this into two ranges and insert the trailing piece
+ // after this.
+ Range section = range.split(article);
+ ranges.add(i + 1, section);
+ }
+ dirty = true;
+ return;
+ }
+ // did we find a point where any articles are greater?
+ if (range.greaterThan(article)) {
+ // nothing to do
+ return;
+ }
+ }
+ // didn't find it at all. That was easy!
+ }
+
+ /**
+ * Save this List of Ranges out to a .newsrc file. This creates a
+ * comma-separated list of range values from each of the Ranges.
+ *
+ * @param out
+ * The target output stream.
+ *
+ * @exception IOException
+ */
+ public void save(Writer out) throws IOException {
+ // we have an empty list
+ if (ranges.size() == 0) {
+ return;
+ }
+
+ Range range = (Range) ranges.get(0);
+ range.save(out);
+
+ for (int i = 1; i < ranges.size(); i++) {
+ out.write(",");
+ range = (Range) ranges.get(i);
+ range.save(out);
+ }
+ }
+
+ /**
+ * Return the state of the dirty flag.
+ *
+ * @return True if the range list information has changed, false otherwise.
+ */
+ public boolean isDirty() {
+ return dirty;
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.pop3;
+
+/**
+ * Defines a few constants that are used throught the implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+
+public interface POP3Constants {
+ public final static String SPACE = " ";
+
+ public final static String CRLF = "\r\n";
+
+ public final static int DOT = '.';
+
+ public final static int OK = 0;
+
+ public final static int ERR = 1;
+
+ public final static int CHALLENGE = 2;
+}
\ No newline at end of file
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.pop3;
+
+import java.util.List;
+
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.FolderClosedException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+import javax.mail.event.ConnectionEvent;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection;
+import org.apache.geronimo.javamail.store.pop3.connection.POP3StatusResponse;
+
+/**
+ * The POP3 implementation of the javax.mail.Folder Note that only INBOX is
+ * supported in POP3
+ * <p>
+ * <url>http://www.faqs.org/rfcs/rfc1939.html</url>
+ * </p>
+ *
+ * @see Folder
+ *
+ * @version $Rev$ $Date$
+ */
+public class POP3Folder extends Folder {
+
+ protected boolean isFolderOpen = false;
+
+ protected int mode;
+
+ protected int msgCount;
+
+ private POP3Message[] messageCache;
+ // The fully qualified name of the folder. For a POP3 folder, this is either "" for the root or
+ // "INPUT" for the in-basket. It is possible to create other folders, but they will report that
+ // they don't exist.
+ protected String fullName;
+ // indicates whether this folder exists or not
+ protected boolean exists = false;
+ // indicates the type of folder this is.
+ protected int folderType;
+
+ /**
+ * Create a new folder associate with a POP3 store instance.
+ *
+ * @param store The owning Store.
+ * @param name The name of the folder. Note that POP3 stores only
+ * have 2 real folders, the root ("") and the in-basket
+ * ("INBOX"). It is possible to create other instances
+ * of Folder associated with the Store, but they will
+ * be non-functional.
+ */
+ public POP3Folder(POP3Store store, String name) {
+ super(store);
+ this.fullName = name;
+ // if this is the input folder, this exists
+ if (name.equalsIgnoreCase("INBOX")) {
+ exists = true;
+ }
+ // by default, we're holding messages.
+ folderType = Folder.HOLDS_MESSAGES;
+ }
+
+
+ /**
+ * Retrieve the folder name. This is the simple folder
+ * name at the its hiearchy level. This can be invoked when the folder is closed.
+ *
+ * @return The folder's name.
+ */
+ public String getName() {
+ // the name and the full name are always the same
+ return fullName;
+ }
+
+ /**
+ * Retrieve the folder's full name (including hierarchy information).
+ * This can be invoked when the folder is closed.
+ *
+ * @return The full name value.
+ */
+ public String getFullName() {
+ return fullName;
+ }
+
+
+ /**
+ * Never return "this" as the parent folder. Somebody not familliar with
+ * POP3 may do something like while(getParent() != null) or something
+ * simmilar which will result in an infinte loop
+ */
+ public Folder getParent() throws MessagingException {
+ // the default folder returns null. We return the default
+ // folder
+ return store.getDefaultFolder();
+ }
+
+ /**
+ * Indicate whether a folder exists. Only the root
+ * folder and "INBOX" will ever return true.
+ *
+ * @return true for real POP3 folders, false for any other
+ * instances that have been created.
+ * @exception MessagingException
+ */
+ public boolean exists() throws MessagingException {
+ // only one folder truely exists...this might be it.
+ return exists;
+ }
+
+ public Folder[] list(String pattern) throws MessagingException {
+ throw new MethodNotSupportedException("Only INBOX is supported in POP3, no sub folders");
+ }
+
+ /**
+ * No sub folders, hence there is no notion of a seperator. This is always a null character.
+ */
+ public char getSeparator() throws MessagingException {
+ return '\0';
+ }
+
+ /**
+ * There's no hierarchy in POP3, so the only type
+ * is HOLDS_MESSAGES (and only one of those exists).
+ *
+ * @return Always returns HOLDS_MESSAGES.
+ * @exception MessagingException
+ */
+ public int getType() throws MessagingException {
+ return folderType;
+ }
+
+ /**
+ * Always returns false as any creation operation must
+ * fail.
+ *
+ * @param type The type of folder to create. This is ignored.
+ *
+ * @return Always returns false.
+ * @exception MessagingException
+ */
+ public boolean create(int type) throws MessagingException {
+ return false;
+ }
+
+ /**
+ * No way to detect new messages, so always return false.
+ *
+ * @return Always returns false.
+ * @exception MessagingException
+ */
+ public boolean hasNewMessages() throws MessagingException {
+ return false;
+ }
+
+ public Folder getFolder(String name) throws MessagingException {
+ throw new MethodNotSupportedException("Only INBOX is supported in POP3, no sub folders");
+ }
+
+ public boolean delete(boolean recurse) throws MessagingException {
+ throw new MethodNotSupportedException("Only INBOX is supported in POP3 and INBOX cannot be deleted");
+ }
+
+ public boolean renameTo(Folder f) throws MessagingException {
+ throw new MethodNotSupportedException("Only INBOX is supported in POP3 and INBOX cannot be renamed");
+ }
+
+ /**
+ * @see Folder#open(int)
+ */
+ public void open(int mode) throws MessagingException {
+ // Can only be performed on a closed folder
+ checkClosed();
+
+ // get a connection object
+ POP3Connection connection = getConnection();
+
+ try {
+ POP3StatusResponse res = connection.retrieveMailboxStatus();
+ this.mode = mode;
+ this.isFolderOpen = true;
+ this.msgCount = res.getNumMessages();
+ // JavaMail API has no method in Folder to expose the total
+ // size (no of bytes) of the mail drop;
+
+ // NB: We use the actual message number to access the messages from
+ // the cache, which is origin 1. Vectors are origin 0, so we have to subtract each time
+ // we access a messagge.
+ messageCache = new POP3Message[msgCount];
+ } catch (Exception e) {
+ throw new MessagingException("Unable to execute STAT command", e);
+ }
+ finally {
+ // return the connection when finished
+ releaseConnection(connection);
+ }
+
+ notifyConnectionListeners(ConnectionEvent.OPENED);
+ }
+
+ /**
+ * Close a POP3 folder.
+ *
+ * @param expunge The expunge flag (ignored for POP3).
+ *
+ * @exception MessagingException
+ */
+ public void close(boolean expunge) throws MessagingException {
+ // Can only be performed on an open folder
+ checkOpen();
+
+ // get a connection object
+ POP3Connection connection = getConnection();
+ try {
+ // we might need to reset the connection before we
+ // process deleted messages and send the QUIT. The
+ // connection knows if we need to do this.
+ connection.reset();
+ // clean up any messages marked for deletion
+ expungeDeletedMessages(connection);
+ } finally {
+ // return the connection when finished
+ releaseConnection(connection);
+ // cleanup the the state even if exceptions occur when deleting the
+ // messages.
+ cleanupFolder(false);
+ }
+ }
+
+ /**
+ * Mark any messages we've flagged as deleted from the
+ * POP3 server before closing.
+ *
+ * @exception MessagingException
+ */
+ protected void expungeDeletedMessages(POP3Connection connection) throws MessagingException {
+ if (mode == READ_WRITE) {
+ for (int i = 0; i < messageCache.length; i++) {
+ POP3Message msg = messageCache[i];
+ if (msg != null) {
+ // if the deleted flag is set, go delete this
+ // message. NB: We adjust the index back to an
+ // origin 1 value
+ if (msg.isSet(Flags.Flag.DELETED)) {
+ try {
+ connection.deleteMessage(i + 1);
+ } catch (MessagingException e) {
+ throw new MessagingException("Exception deleting message number " + (i + 1), e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Do folder cleanup. This is used both for normal
+ * close operations, and adnormal closes where the
+ * server has sent us a BYE message.
+ *
+ * @param expunge Indicates whether open messages should be expunged.
+ * @param disconnected
+ * The disconnected flag. If true, the server has cut
+ * us off, which means our connection can not be returned
+ * to the connection pool.
+ *
+ * @exception MessagingException
+ */
+ protected void cleanupFolder(boolean disconnected) throws MessagingException {
+ messageCache = null;
+ isFolderOpen = false;
+ notifyConnectionListeners(ConnectionEvent.CLOSED);
+ }
+
+
+ /**
+ * Obtain a connection object for a Message attached to this Folder. This
+ * will be the Folder's connection, which is only available if the Folder
+ * is currently open.
+ *
+ * @return The connection object for the Message instance to use.
+ * @exception MessagingException
+ */
+ synchronized POP3Connection getMessageConnection() throws MessagingException {
+ // we always get one from the store. If we're fully single threaded, then
+ // we can get away with just a single one.
+ return getConnection();
+ }
+
+
+ /**
+ * Release the connection object back to the Folder instance.
+ *
+ * @param connection The connection being released.
+ *
+ * @exception MessagingException
+ */
+ void releaseMessageConnection(POP3Connection connection) throws MessagingException {
+ // give this back to the store
+ releaseConnection(connection);
+ }
+
+ public boolean isOpen() {
+ // if we're not open, we're not open
+ if (!isFolderOpen) {
+ return false;
+ }
+
+ try {
+ // we might be open, but the Store has been closed. In which case, we're not any more
+ // closing also changes the isFolderOpen flag.
+ if (!((POP3Store)store).isConnected()) {
+ close(false);
+ }
+ } catch (MessagingException e) {
+ }
+ return isFolderOpen;
+ }
+
+ public Flags getPermanentFlags() {
+ // unfortunately doesn't have a throws clause for this method
+ // throw new MethodNotSupportedException("POP3 doesn't support permanent
+ // flags");
+
+ // Better than returning null, save the extra condition from a user to
+ // check for null
+ // and avoids a NullPointerException for the careless.
+ return new Flags();
+ }
+
+ /**
+ * Get the folder message count.
+ *
+ * @return The number of messages in the folder.
+ * @exception MessagingException
+ */
+ public int getMessageCount() throws MessagingException {
+ // NB: returns -1 if the folder isn't open.
+ return msgCount;
+ }
+
+ /**
+ * Checks wether the message is in cache, if not will create a new message
+ * object and return it.
+ *
+ * @see Folder#getMessage(int)
+ */
+ public Message getMessage(int msgNum) throws MessagingException {
+ // Can only be performed on an Open folder
+ checkOpen();
+ if (msgNum < 1 || msgNum > getMessageCount()) {
+ throw new MessagingException("Invalid Message number");
+ }
+
+ Message msg = messageCache[msgNum - 1];
+ if (msg == null) {
+ msg = new POP3Message(this, msgNum);
+ messageCache[msgNum - 1] = (POP3Message)msg;
+ }
+
+ return msg;
+ }
+
+ public void appendMessages(Message[] msgs) throws MessagingException {
+ throw new MethodNotSupportedException("Message appending is not supported in POP3");
+
+ }
+
+ public Message[] expunge() throws MessagingException {
+ throw new MethodNotSupportedException("Expunge is not supported in POP3");
+ }
+
+ public int getMode() throws IllegalStateException {
+ // Can only be performed on an Open folder
+ checkOpen();
+ return mode;
+ }
+
+ /**
+ * @see Folder#fetch(Message[],
+ * FetchProfile)
+ *
+ * The JavaMail API recommends that this method be overrident to provide a
+ * meaningfull implementation.
+ */
+ public synchronized void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {
+ // Can only be performed on an Open folder
+ checkOpen();
+ for (int i = 0; i < msgs.length; i++) {
+ Message msg = msgs[i];
+
+ if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+ // fetching the size and the subject will force all of the
+ // envelope information to load
+ msg.getHeader("Subject");
+ msg.getSize();
+ }
+ if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+ // force the content to load...this also fetches the header information.
+ // C'est la vie.
+ ((POP3Message)msg).loadContent();
+ msg.getSize();
+ }
+ // force flag loading for this message
+ if (fp.contains(FetchProfile.Item.FLAGS)) {
+ msg.getFlags();
+ }
+
+ if (fp.getHeaderNames().length > 0) {
+ // loading any header loads all headers, so just grab the header set.
+ msg.getHeader("Subject");
+ }
+ }
+ }
+
+ /**
+ * Retrieve the UID for a given message.
+ *
+ * @param msg The message of interest.
+ *
+ * @return The String UID value for this message.
+ * @exception MessagingException
+ */
+ public synchronized String getUID(Message msg) throws MessagingException {
+ checkOpen();
+ // the Message knows how to do this
+ return ((POP3Message)msg).getUID();
+ }
+
+
+ /**
+ * Below is a list of covinience methods that avoid repeated checking for a
+ * value and throwing an exception
+ */
+
+ /** Ensure the folder is open */
+ private void checkOpen() throws IllegalStateException {
+ if (!isFolderOpen) {
+ throw new IllegalStateException("Folder is not Open");
+ }
+ }
+
+ /** Ensure the folder is not open */
+ private void checkClosed() throws IllegalStateException {
+ if (isFolderOpen) {
+ throw new IllegalStateException("Folder is Open");
+ }
+ }
+
+ /**
+ * @see Folder#notifyMessageChangedListeners(int,
+ * Message)
+ *
+ * this method is protected and cannot be used outside of Folder, therefore
+ * had to explicitly expose it via a method in POP3Folder, so that
+ * POP3Message has access to it
+ *
+ * Bad design on the part of the Java Mail API.
+ */
+ public void notifyMessageChangedListeners(int type, Message m) {
+ super.notifyMessageChangedListeners(type, m);
+ }
+
+
+ /**
+ * Retrieve the connection attached to this folder. Throws an
+ * exception if we don't have an active connection.
+ *
+ * @return The current connection object.
+ * @exception MessagingException
+ */
+ protected synchronized POP3Connection getConnection() throws MessagingException {
+ // request a connection from the central store.
+ return ((POP3Store)store).getFolderConnection(this);
+ }
+
+
+ /**
+ * Release our connection back to the Store.
+ *
+ * @param connection The connection to release.
+ *
+ * @exception MessagingException
+ */
+ protected void releaseConnection(POP3Connection connection) throws MessagingException {
+ // we need to release the connection to the Store once we're finished with it
+ ((POP3Store)store).releaseFolderConnection(this, connection);
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,378 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.javamail.store.pop3;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.IllegalWriteException;
+import javax.mail.MessagingException;
+import javax.mail.event.MessageChangedEvent;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection;
+
+/**
+ * POP3 implementation of javax.mail.internet.MimeMessage
+ *
+ * Only the most basic information is given and Message objects created here is
+ * a light-weight reference to the actual Message As per the JavaMail spec items
+ * from the actual message will get filled up on demand
+ *
+ * If some other items are obtained from the server as a result of one call,
+ * then the other details are also processed and filled in. For ex if RETR is
+ * called then header information will also be processed in addition to the
+ * content
+ *
+ * @version $Rev$ $Date$
+ */
+public class POP3Message extends MimeMessage {
+ // the size of the message, in bytes
+ protected int msgSize = -1;
+ // the size of the headers. We keep this around, as it's needed to
+ // properly calculate the size of the message
+ protected int headerSize = -1;
+ // the UID value retrieved from the server
+ protected String uid;
+ // the raw message data from loading the message
+ protected byte[] messageData;
+
+ /**
+ * Create a new POP3 message associated with a folder.
+ *
+ * @param folder The owning folder.
+ * @param msgnum The message sequence number in the folder.
+ */
+ protected POP3Message(Folder folder, int msgnum) {
+ super(folder, msgnum);
+ this.session = session;
+ // force the headers to empty so we'll load them the first time they're referenced.
+ this.headers = null;
+ }
+
+ /**
+ * Get an InputStream for reading the message content.
+ *
+ * @return An InputStream instance initialized to read the message
+ * content.
+ * @exception MessagingException
+ */
+ protected InputStream getContentStream() throws MessagingException {
+ // make sure the content is loaded first
+ loadContent();
+ // allow the super class to handle creating it from the loaded content.
+ return super.getContentStream();
+ }
+
+
+ /**
+ * Write out the byte data to the provided output stream.
+ *
+ * @param out The target stream.
+ *
+ * @exception IOException
+ * @exception MessagingException
+ */
+ public void writeTo(OutputStream out) throws IOException, MessagingException {
+ // make sure we have everything loaded
+ loadContent();
+ // just write out the raw message data
+ out.write(messageData);
+ }
+
+
+ /**
+ * Set a flag value for this Message. The flags are
+ * only set locally, not the server. When the folder
+ * is closed, any messages with the Deleted flag set
+ * will be removed from the server.
+ *
+ * @param newFlags The new flag values.
+ * @param set Indicates whether this is a set or an unset operation.
+ *
+ * @exception MessagingException
+ */
+ public void setFlags(Flags newFlags, boolean set) throws MessagingException {
+ Flags oldFlags = (Flags) flags.clone();
+ super.setFlags(newFlags, set);
+
+ if (!flags.equals(oldFlags)) {
+ ((POP3Folder) folder).notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, this);
+ }
+ }
+
+ /**
+ * Unconditionally load the headers from an inputstream.
+ * When retrieving content, we get back the entire message,
+ * including the headers. This allows us to skip over
+ * them to reach the content, even if we already have
+ * headers loaded.
+ *
+ * @param in The InputStream with the header data.
+ *
+ * @exception MessagingException
+ */
+ protected void loadHeaders(InputStream in) throws MessagingException {
+ try {
+ headerSize = in.available();
+ // just load and replace the haders
+ headers = new InternetHeaders(in);
+ headerSize -= in.available();
+ } catch (IOException e) {
+ // reading from a ByteArrayInputStream...this should never happen.
+ }
+ }
+
+ /**
+ * Lazy loading of the message content.
+ *
+ * @exception MessagingException
+ */
+ protected void loadContent() throws MessagingException {
+ if (content == null) {
+ POP3Connection connection = getConnection();
+ try {
+ // retrieve (and save the raw message data
+ messageData = connection.retrieveMessageData(msgnum);
+ } finally {
+ // done with the connection
+ releaseConnection(connection);
+ }
+ // now create a input stream for splitting this into headers and
+ // content
+ ByteArrayInputStream in = new ByteArrayInputStream(messageData);
+
+ // the Sun implementation has an option that forces headers loaded using TOP
+ // should be forgotten when retrieving the message content. This is because
+ // some POP3 servers return different results for TOP and RETR. Since we need to
+ // retrieve the headers anyway, and this set should be the most complete, we'll
+ // just replace the headers unconditionally.
+ loadHeaders(in);
+ // load headers stops loading at the header terminator. Everything
+ // after that is content.
+ loadContent(in);
+ }
+ }
+
+ /**
+ * Load the message content from the server.
+ *
+ * @param stream A ByteArrayInputStream containing the message content.
+ * We explicitly use ByteArrayInputStream because
+ * there are some optimizations that can take advantage
+ * of the fact it is such a stream.
+ *
+ * @exception MessagingException
+ */
+ protected void loadContent(ByteArrayInputStream stream) throws MessagingException {
+ // since this is a byte array input stream, available() returns reliable value.
+ content = new byte[stream.available()];
+ try {
+ // just read everything in to the array
+ stream.read(content);
+ } catch (IOException e) {
+ // should never happen
+ throw new MessagingException("Error loading content info", e);
+ }
+ }
+
+ /**
+ * Get the size of the message.
+ *
+ * @return The calculated message size, in bytes.
+ * @exception MessagingException
+ */
+ public int getSize() throws MessagingException {
+ if (msgSize < 0) {
+ // we need to get the headers loaded, since we need that information to calculate the total
+ // content size without retrieving the content.
+ loadHeaders();
+
+ POP3Connection connection = getConnection();
+ try {
+
+ // get the total message size, and adjust by size of the headers to get the content size.
+ msgSize = connection.retrieveMessageSize(msgnum) - headerSize;
+ } finally {
+ // done with the connection
+ releaseConnection(connection);
+ }
+ }
+ return msgSize;
+ }
+
+ /**
+ * notice that we pass zero as the no of lines from the message,as it
+ * doesn't serv any purpose to get only a certain number of lines.
+ *
+ * However this maybe important if a mail client only shows 3 or 4 lines of
+ * the message in the list and then when the user clicks they would load the
+ * message on demand.
+ *
+ */
+ protected void loadHeaders() throws MessagingException {
+ if (headers == null) {
+ POP3Connection connection = getConnection();
+ try {
+ loadHeaders(connection.retrieveMessageHeaders(msgnum));
+ } finally {
+ // done with the connection
+ releaseConnection(connection);
+ }
+ }
+ }
+
+ /**
+ * Retrieve the message UID from the server.
+ *
+ * @return The string UID value.
+ * @exception MessagingException
+ */
+ protected String getUID() throws MessagingException {
+ if (uid == null) {
+ POP3Connection connection = getConnection();
+ try {
+ uid = connection.retrieveMessageUid(msgnum);
+ } finally {
+ // done with the connection
+ releaseConnection(connection);
+ }
+ }
+ return uid;
+ }
+
+ // The following are methods that deal with all header accesses. Most of the
+ // methods that retrieve information from the headers funnel through these, so we
+ // can lazy-retrieve the header information.
+
+ public String[] getHeader(String name) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getHeader(name);
+ }
+
+ public String getHeader(String name, String delimiter) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getHeader(name, delimiter);
+ }
+
+ public Enumeration getAllHeaders() throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getAllHeaders();
+ }
+
+ public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getMatchingHeaders(names);
+ }
+
+ public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getNonMatchingHeaders(names);
+ }
+
+ public Enumeration getAllHeaderLines() throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getAllHeaderLines();
+ }
+
+ public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getMatchingHeaderLines(names);
+ }
+
+ public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+ // make sure the headers are loaded
+ loadHeaders();
+ // allow the super class to handle everything from here
+ return super.getNonMatchingHeaderLines(names);
+ }
+
+ // the following are overrides for header modification methods. These
+ // messages are read only,
+ // so the headers cannot be modified.
+ public void addHeader(String name, String value) throws MessagingException {
+ throw new IllegalWriteException("POP3 messages are read-only");
+ }
+
+ public void setHeader(String name, String value) throws MessagingException {
+ throw new IllegalWriteException("POP3 messages are read-only");
+ }
+
+ public void removeHeader(String name) throws MessagingException {
+ throw new IllegalWriteException("POP3 messages are read-only");
+ }
+
+ public void addHeaderLine(String line) throws MessagingException {
+ throw new IllegalWriteException("POP3 messages are read-only");
+ }
+
+ /**
+ * We cannot modify these messages
+ */
+ public void saveChanges() throws MessagingException {
+ throw new IllegalWriteException("POP3 messages are read-only");
+ }
+
+
+ /**
+ * get the current connection pool attached to the folder. We need
+ * to do this dynamically, to A) ensure we're only accessing an
+ * currently open folder, and B) to make sure we're using the
+ * correct connection attached to the folder.
+ *
+ * @return A connection attached to the hosting folder.
+ */
+ protected POP3Connection getConnection() throws MessagingException {
+ // the folder owns everything.
+ return ((POP3Folder)folder).getMessageConnection();
+ }
+
+ /**
+ * Release the connection back to the Folder after performing an operation
+ * that requires a connection.
+ *
+ * @param connection The previously acquired connection.
+ */
+ protected void releaseConnection(POP3Connection connection) throws MessagingException {
+ // the folder owns everything.
+ ((POP3Folder)folder).releaseMessageConnection(connection);
+ }
+}
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,142 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.geronimo.javamail.store.pop3;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Store;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection;
+
+/**
+ * An POP3 folder instance for the root of POP3 folder tree. This has
+ * some of the folder operations disabled.
+ */
+public class POP3RootFolder extends POP3Folder {
+ // the inbox folder is the only one that exists
+ protected Folder inbox;
+
+ /**
+ * Create a default POP3RootFolder attached to a specific Store instance.
+ *
+ * @param store The Store instance this is the root for.
+ */
+ public POP3RootFolder(POP3Store store) {
+ // create a folder with a null string name and the default separator.
+ super(store, "");
+ // this only holds folders
+ folderType = HOLDS_FOLDERS;
+ // this folder does exist
+ exists = true;
+ // no messages in this folder
+ msgCount = 0;
+ }
+
+
+ /**
+ * Get the parent. This is the root folder, which
+ * never has a parent.
+ *
+ * @return Always returns null.
+ */
+ public Folder getParent() {
+ // we never have a parent folder
+ return null;
+ }
+
+ /**
+ * We have a separator because the root folder is "special".
+ */
+ public char getSeparator() throws MessagingException {
+ return '/';
+ }
+
+ /**
+ * Retrieve a list of folders that match a pattern.
+ *
+ * @param pattern The match pattern.
+ *
+ * @return An array of matching folders.
+ * @exception MessagingException
+ */
+ public Folder[] list(String pattern) throws MessagingException {
+ // I'm not sure this is correct, but the Sun implementation appears to
+ // return a array containing the inbox regardless of what pattern was specified.
+ return new Folder[] { getInbox() };
+ }
+
+ /**
+ * Get a folder of a given name from the root folder.
+ * The Sun implementation seems somewhat inconsistent
+ * here. The docs for Store claim that only INBOX is
+ * supported, but it will return a Folder instance for any
+ * name. On the other hand, the root folder raises
+ * an exception for anything but the INBOX.
+ *
+ * @param name The folder name (which must be "INBOX".
+ *
+ * @return The inbox folder instance.
+ * @exception MessagingException
+ */
+ public Folder getFolder(String name) throws MessagingException {
+ if (!name.equalsIgnoreCase("INBOX")) {
+ throw new MessagingException("Only the INBOX folder is supported");
+ }
+ // return the inbox folder
+ return getInbox();
+ }
+
+ /**
+ * Override for the isOpen method. The root folder can
+ * never be opened.
+ *
+ * @return always returns false.
+ */
+ public boolean isOpen() {
+ return false;
+ }
+
+ public void open(int mode) throws MessagingException {
+ throw new MessagingException("POP3 root folder cannot be opened");
+ }
+
+ public void open(boolean expunge) throws MessagingException {
+ throw new MessagingException("POP3 root folder cannot be close");
+ }
+
+
+ /**
+ * Retrieve the INBOX folder from the root.
+ *
+ * @return The Folder instance for the inbox.
+ * @exception MessagingException
+ */
+ protected Folder getInbox() throws MessagingException {
+ // we're the only place that creates folders, and
+ // we only create the single instance.
+ if (inbox == null) {
+ inbox = new POP3Folder((POP3Store)store, "INBOX");
+ }
+ return inbox;
+ }
+}
+
+
Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java Wed Oct 7 15:58:39 2020
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.geronimo.javamail.store.pop3;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+/**
+ * POP3 implementation of javax.mail.Store over an SSL connection.
+ *
+ * @version $Rev$ $Date$
+ */
+public class POP3SSLStore extends POP3Store {
+ /**
+ * Construct an POP3SSLStore item.
+ *
+ * @param session The owning javamail Session.
+ * @param urlName The Store urlName, which can contain server target information.
+ */
+ public POP3SSLStore(Session session, URLName urlName) {
+ // we're the imaps protocol, our default connection port is 993, and we must use
+ // an SSL connection for the initial hookup
+ super(session, urlName, "pop3s", DEFAULT_POP3_SSL_PORT, true);
+ }
+}
+
+