geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r1743397 [10/17] - in /geronimo/javamail/trunk/geronimo-javamail_1.5: ./ geronimo-javamail_1.5_mail/ geronimo-javamail_1.5_mail/src/ geronimo-javamail_1.5_mail/src/site/ geronimo-javamail_1.5_mail/src/site/apt/ geronimo-javamail_1.5_provide...
Date Wed, 11 May 2016 16:49:39 GMT
Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java Wed May 11 16:49:36 2016
@@ -0,0 +1,69 @@
+/**
+ * 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.imap.connection;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Formats ths date in the form used by the javamail IMAP SEARCH command, 
+ * <p/>
+ * The format used is <code>d MMM yyyy</code> and  locale is always US-ASCII.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPSearchDateFormat extends SimpleDateFormat {
+    public IMAPSearchDateFormat() {
+        super("dd-MMM-yyyy", Locale.US);
+    }
+    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
+        StringBuffer result = super.format(date, buffer, position);
+        // The RFC 2060 requires that the day in the date be formatted with either 2 digits
+        // or one digit.  Our format specifies 2 digits, which pads with leading
+        // zeros.  We need to check for this and whack it if it's there
+        if (result.charAt(0) == '0') {
+            result.deleteCharAt(0); 
+        }
+        return result;
+    }
+
+    /**
+     * The calendar cannot be set
+     * @param calendar
+     * @throws UnsupportedOperationException
+     */
+    public void setCalendar(Calendar calendar) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The format cannot be set
+     * @param format
+     * @throws UnsupportedOperationException
+     */
+    public void setNumberFormat(NumberFormat format) {
+        throw new UnsupportedOperationException();
+    }
+}
+
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,53 @@
+/**
+ * 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.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPSearchResponse extends IMAPUntaggedResponse {
+    public int[] messageNumbers; 
+    
+    public IMAPSearchResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("SEARCH",  data); 
+        
+        Token token = source.next(); 
+        List tokens = new ArrayList();
+        
+        // just accumulate the list of tokens first 
+        while (token.getType() != Token.EOF) {
+            tokens.add(token); 
+            token = source.next(); 
+        }
+        
+        messageNumbers = new int[tokens.size()]; 
+        
+        // now parse these into numbers 
+        for (int i = 0; i < messageNumbers.length; i++) {
+            token = (Token)tokens.get(i); 
+            messageNumbers[i] = token.getInteger(); 
+        }
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,50 @@
+/**
+ * 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.imap.connection;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPServerStatusResponse extends IMAPUntaggedResponse {
+    // any message following the response 
+    protected String message; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPServerStatusResponse(String keyword, String message, byte [] response) {
+        super(keyword, response); 
+        this.message = message; 
+    }
+    
+    /**
+     * Get any trailing message associated with this 
+     * status response. 
+     * 
+     * @return 
+     */
+    public String getMessage() {
+        return message; 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,50 @@
+/**
+ * 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.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a server size response.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPSizeResponse extends IMAPUntaggedResponse {
+    // the associated size 
+    protected int size; 
+
+    /**
+     * Create a size response item.
+     * 
+     * @param keyword  The KEYWORD item associated with the size.
+     * @param size     The size value.
+     * @param response The raw response data.
+     */
+    public IMAPSizeResponse(String keyword, int size, byte [] response) {
+        super(keyword, response); 
+        this.size = size; 
+    }
+    
+    public int getSize() {
+        return size; 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,82 @@
+/**
+ * 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.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPStatusResponse extends IMAPUntaggedResponse {
+    // the mail box name 
+    public String mailbox; 
+    // number of messages in the box
+    public int messages = -1;
+    // number of recent messages 
+    public int recentMessages = -1; 
+    // the number of unseen messages
+    public int unseenMessages = -1;
+    // the next UID for this mailbox
+    public long uidNext = -1L;
+    // the UID validity item
+    public long uidValidity = -1L;
+
+    public IMAPStatusResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("STATUS",  data); 
+        
+        // the mail box name is supposed to be encoded, so decode it now.
+        mailbox = source.readEncodedString();
+
+        // parse the list of flag values
+        List flags = source.readStringList();
+        if (flags == null) {
+            return;
+        }
+
+        for (int i = 0; i < flags.size(); i += 2) {
+            String field = ((String)flags.get(i)).toUpperCase();
+            String stringValue = ((String)flags.get(i + 1)); 
+            long value; 
+            try {
+                value = Long.parseLong(stringValue); 
+            } catch (NumberFormatException e) {
+                throw new MessagingException("Invalid IMAP Status response", e); 
+            }
+                
+
+            if (field.equals("MESSAGES")) {
+                messages = (int)value; 
+            }
+            else if (field.equals("RECENT")) {
+                recentMessages = (int)value;
+            }
+            else if (field.equals("UIDNEXT")) {
+                uidNext = value;
+            }
+            else if (field.equals("UIDVALIDITY")) {
+                uidValidity = value; 
+            }
+            else if (field.equals("UNSEEN")) {
+                unseenMessages = (int)value; 
+            }
+        }
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,161 @@
+/**
+ * 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.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.mail.util.Base64;
+
+/**
+ * Util class to represent a response from a IMAP server
+ *
+ * @version $Rev: 1633281 $ $Date: 2014-10-21 02:29:50 -0400 (Tue, 21 Oct 2014) $
+ */
+public class IMAPTaggedResponse extends IMAPResponse {
+
+    // the reply state
+    protected String status;
+    // the tag associated with a reply.
+    protected String tag;
+    // the message associated with the completion response 
+    protected String message;
+
+    /**
+     * Create a command completion response for a 
+     * submitted command.  The tag prefix identifies 
+     * the command this response is for. 
+     * 
+     * @param tag      The command tag value.
+     * @param status   The Status response (OK, BAD, or NO).
+     * @param message  The remainder of the response, as a string.
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(String tag, String status, String message, byte [] response) {
+        super(response); 
+        this.tag = tag; 
+        this.status = status;
+        this.message = message; 
+    }
+
+
+    /**
+     * Create a continuation response for a 
+     * submitted command.  
+     * 
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(byte [] response) {
+        super(response); 
+        this.tag = "";  
+        this.status = "CONTINUATION";
+        this.message = message; 
+    }
+
+    /**
+     * Test if the response code was "OK".
+     *
+     * @return True if the response status was OK, false for any other status.
+     */
+    public boolean isOK() {
+        return status.equals("OK");
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was BAD.
+     */
+    public boolean isBAD() {
+        return status.equals("BAD"); 
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was NO.
+     */
+    public boolean isNO() {
+        return status.equals("NO"); 
+    }
+    
+    /**
+     * Get the message included on the tagged response. 
+     * 
+     * @return The String message data. 
+     */
+    public String getMessage() {
+        return message; 
+    }
+    
+    /**
+     * Decode the message portion of a continuation challenge response.
+     * 
+     * @return The byte array containing the decoded data. 
+     */
+    public byte[] decodeChallengeResponse() 
+    {
+        // we're passed back a challenge value, Base64 encoded.  Decode that portion of the 
+        // response data. 
+    	
+    	//handle plain authentication gracefully, see GERONIMO-6526
+    	if(response.length <= 2){
+    		return null;
+    	}
+    	
+        return Base64.decode(response, 2, response.length - 2);
+    }
+    
+    
+    /**
+     * Test if this is a continuation response. 
+     * 
+     * @return True if this a continuation.  false for a normal tagged response. 
+     */
+    public boolean isContinuation() {
+        return status.equals("CONTINUATION"); 
+    }
+    
+    
+    /**
+     * Test if the untagged response includes a given 
+     * status indicator.  Mostly used for checking 
+     * READ-ONLY or READ-WRITE status after selecting a 
+     * mail box.
+     * 
+     * @param name   The status name to check.
+     * 
+     * @return true if this is found in the "[" "]" delimited
+     *         section of the response message.
+     */
+    public boolean hasStatus(String name) {
+        // see if we have the status bits at all 
+        int statusStart = message.indexOf('['); 
+        if (statusStart == -1) {
+            return false; 
+        }
+        
+        int statusEnd = message.indexOf(']'); 
+        String statusString = message.substring(statusStart, statusEnd).toUpperCase(); 
+        // just search for the status token. 
+        return statusString.indexOf(name) != -1; 
+    }
+}
+
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java Wed May 11 16:49:36 2016
@@ -0,0 +1,36 @@
+/**
+ * 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.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPUid extends IMAPFetchDataItem {
+    // the returned uid
+    public long uid;
+    // the returned sequence number for the message 
+    public int messageNumber; 
+
+    public IMAPUid(int messageNumber, IMAPResponseTokenizer source) throws MessagingException {
+        super(UID);
+        // just read the number pairs 
+        this.messageNumber = messageNumber;
+        uid = source.readLong();
+    }
+}
+
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java Wed May 11 16:49:36 2016
@@ -0,0 +1,67 @@
+/**
+ * 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.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPUntaggedResponse extends IMAPResponse {
+    // the response key word 
+    protected String keyword; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPUntaggedResponse(String keyword, byte [] response) {
+        super(response); 
+        this.keyword = keyword; 
+    }
+
+    /**
+     * Return the KEYWORD that identifies the type 
+     * of this untagged response.
+     * 
+     * @return The identifying keyword.
+     */
+    public String getKeyword() {
+        return keyword; 
+    }
+    
+    
+    /**
+     * Test if an untagged response is of a given 
+     * keyword type.
+     * 
+     * @param keyword The test keyword.
+     * 
+     * @return True if this is a type match, false for mismatches.
+     */
+    public boolean isKeyword(String keyword) {
+        return this.keyword.equals(keyword); 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java Wed May 11 16:49:36 2016
@@ -0,0 +1,34 @@
+/**
+ * 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.imap.connection;
+
+public interface IMAPUntaggedResponseHandler {
+    /**
+     * Handle an unsolicited untagged response receive back from a command.  This 
+     * will be any responses left over after the command has cherry picked the 
+     * bits that are relevent to the command just issued.  It is important 
+     * that the unsolicited response be reacted to in order to keep the message 
+     * caches in sync. 
+     * 
+     * @param response The response to handle.
+     * 
+     * @return true if the handle took care of the response and it should not be sent 
+     *         to additional handlers.  false if broadcasting of the response should continue.
+     */
+    public boolean handleResponse(IMAPUntaggedResponse response);
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java Wed May 11 16:49:36 2016
@@ -0,0 +1,449 @@
+/*
+ * 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 javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.IllegalWriteException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Session;
+import javax.mail.event.ConnectionEvent;
+
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+
+/**
+ * The base NNTP implementation of the javax.mail.Folder This is a base class
+ * for both the Root NNTP server and each NNTP group folder.
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 437941 $
+ */
+public class NNTPFolder extends Folder {
+
+    // our active connection.
+    protected NNTPConnection connection;
+
+    // our attached session
+    protected Session session;
+
+    // the name of this folder (either the name of the server for the root or
+    // the news group name).
+    protected String name;
+
+    // the "full" name of the folder. For the root folder, this is the name
+    // returned by the connection
+    // welcome string. Otherwise, this is the same as the name.
+    protected String fullName;
+
+    // the parent folder. For the root folder, this is null. For a group folder,
+    // this is the root.
+    protected Folder parent;
+
+    // the folder open state
+    protected boolean folderOpen = false;
+
+    // the folder message count. For the root folder, this is always 0.
+    protected int messageCount = 0;
+
+    // the persistent flags we save in the store (basically just the SEEN flag).
+    protected Flags permanentFlags;
+
+    /**
+     * Super class constructor the base NNTPFolder class.
+     * 
+     * @param store
+     *            The javamail store this folder is attached to.
+     */
+    protected NNTPFolder(NNTPStore store) {
+        super(store);
+        // get the active connection from the store...all commands are sent
+        // there
+        this.connection = store.getConnection();
+        this.session = store.getSession();
+
+        // set up our permanent flags bit.
+        permanentFlags = new Flags();
+        permanentFlags.add(Flags.Flag.SEEN);
+    }
+
+    /**
+     * Retrieve the folder name.
+     * 
+     * @return The folder's name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Retrieve the folder's full name (including hierarchy information). NNTP
+     * folders are flat, so the full name is generally the same as the name.
+     * 
+     * @return The full name value.
+     */
+    public String getFullName() {
+        return fullName;
+    }
+
+    /**
+     * Returns the parent folder for this folder. Returns null if this is the
+     * root folder.
+     */
+    public Folder getParent() throws MessagingException {
+        return parent;
+    }
+
+    /**
+     * Indicated whether the folder "exists" or not. Existance in this context
+     * indicates that the group still exists on the server.
+     * 
+     * @return
+     * @exception MessagingException
+     */
+    public boolean exists() throws MessagingException {
+        // by default, return true. This is really only the case for the root.
+        // The group folder will
+        // need to override this.
+        return true;
+    }
+
+    /**
+     * List the subfolders. For group folders, this is a meaningless so we throw
+     * a MethodNotSupportedException.
+     * 
+     * @param pattern
+     *            The folder pattern string.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public Folder[] list(String pattern) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
+    }
+
+    /**
+     * Retrieve the list of subscribed folders that match the given pattern
+     * string.
+     * 
+     * @param pattern
+     *            The pattern string used for the matching
+     * 
+     * @return An array of matching folders from the subscribed list.
+     */
+    public Folder[] listSubscribed(String pattern) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
+    }
+
+    /**
+     * No sub folders, hence there is no notion of a seperator. We return a null
+     * character (consistent with what Sun returns for POP3 folders).
+     */
+    public char getSeparator() throws MessagingException {
+        return '\0';
+    }
+
+    /**
+     * Return whether this folder can hold just messages or also subfolders.
+     * Only the root folder can hold other folders, so it will need to override.
+     * 
+     * @return Either Folder.HOLDS_MESSAGES or Folder.HOLDS_FOLDERS.
+     * @exception MessagingException
+     */
+    public int getType() throws MessagingException {
+        return HOLDS_MESSAGES;
+    }
+
+    /**
+     * Create a new folder. NNTP folders are read only, so this is a nop.
+     * 
+     * @param type
+     *            The type of folder.
+     * 
+     * @return Not support, throws an exception.
+     * @exception MessagingException
+     */
+    public boolean create(int type) throws MessagingException {
+        throw new MethodNotSupportedException("Sub folders cannot be created in NNTP");
+    }
+
+    /**
+     * Check for new messages. We always return false for the root folder. The
+     * group folders will need to override.
+     * 
+     * @return Always returns false.
+     * @exception MessagingException
+     */
+    public boolean hasNewMessages() throws MessagingException {
+        return false;
+    }
+
+    /**
+     * Get a named subfolder from this folder. This only has meaning from the
+     * root NNTP folder.
+     * 
+     * @param name
+     *            The requested name.
+     * 
+     * @return If the folder exists, returns a Folder object representing the
+     *         named folder.
+     * @exception MessagingException
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP Group folders do not support sub folders");
+    }
+
+    /**
+     * Delete a folder. This is not supported for NNTP.
+     * 
+     * @param recurse
+     *            The recusion flag.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public boolean delete(boolean recurse) throws MessagingException {
+        throw new MethodNotSupportedException("Deleting of NNTP folders is not supported");
+    }
+
+    /**
+     * Rename a folder. Not supported for NNTP folders.
+     * 
+     * @param f
+     *            The new folder specifying the rename location.
+     * 
+     * @return
+     * @exception MessagingException
+     */
+    public boolean renameTo(Folder f) throws MessagingException {
+        throw new MethodNotSupportedException("Renaming of NNTP folders is not supported.");
+    }
+
+    /**
+     * @see javax.mail.Folder#open(int)
+     */
+    public void open(int mode) throws MessagingException {
+
+        // we don't support READ_WRITE mode, so don't allow opening in that
+        // mode.
+        if (mode == READ_WRITE) {
+            throw new IllegalWriteException("Newsgroup folders cannot be opened read/write");
+        }
+
+        // an only be performed on a closed folder
+        checkClosed();
+
+        this.mode = mode;
+
+        // perform folder type-specific open actions.
+        openFolder();
+
+        folderOpen = true;
+
+        notifyConnectionListeners(ConnectionEvent.OPENED);
+    }
+
+    /**
+     * Perform folder type-specific open actions. The default action is to do
+     * nothing.
+     * 
+     * @exception MessagingException
+     */
+    protected void openFolder() throws MessagingException {
+    }
+
+    /**
+     * Peform folder type-specific close actions. The default action is to do
+     * nothing.
+     * 
+     * @exception MessagingException
+     */
+    protected void closeFolder() throws MessagingException {
+    }
+
+    /**
+     * Close the folder. Cleans up resources, potentially expunges messages
+     * marked for deletion, and sends an event notification.
+     * 
+     * @param expunge
+     *            The expunge flag, which is ignored for NNTP folders.
+     * 
+     * @exception MessagingException
+     */
+    public void close(boolean expunge) throws MessagingException {
+        // Can only be performed on an open folder
+        checkOpen();
+
+        // give the subclasses an opportunity to do some cleanup
+        closeFolder();
+
+        folderOpen = false;
+        notifyConnectionListeners(ConnectionEvent.CLOSED);
+    }
+
+    /**
+     * Tests the open status of the folder.
+     * 
+     * @return true if the folder is open, false otherwise.
+     */
+    public boolean isOpen() {
+        return folderOpen;
+    }
+
+    /**
+     * Get the permanentFlags
+     * 
+     * @return The set of permanent flags we support (only SEEN).
+     */
+    public Flags getPermanentFlags() {
+        // we need a copy of our master set.
+        return new Flags(permanentFlags);
+    }
+
+    /**
+     * Get the count of messages in this folder.
+     * 
+     * @return The message count.
+     * @exception MessagingException
+     */
+    public int getMessageCount() throws MessagingException {
+        return messageCount;
+    }
+
+    /**
+     * Checks wether the message is in cache, if not will create a new message
+     * object and return it.
+     * 
+     * @see javax.mail.Folder#getMessage(int)
+     */
+    public Message getMessage(int msgNum) throws MessagingException {
+        // for the base, we just throw an exception.
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+    }
+
+    /**
+     * Append messages to a folder. NNTP folders are read only, so this is not
+     * supported.
+     * 
+     * @param msgs
+     *            The list of messages to append.
+     * 
+     * @exception MessagingException
+     */
+    public void appendMessages(Message[] msgs) throws MessagingException {
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+
+    }
+
+    /**
+     * Expunge messages marked for deletion and return a list of the Messages.
+     * Not supported for NNTP.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public Message[] expunge() throws MessagingException {
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+    }
+
+    /**
+     * Below is a list of convenience methods that avoid repeated checking for a
+     * value and throwing an exception
+     */
+
+    /** Ensure the folder is open */
+    protected void checkOpen() throws IllegalStateException {
+        if (!folderOpen) {
+            throw new IllegalStateException("Folder is not Open");
+        }
+    }
+
+    /** Ensure the folder is not open */
+    protected void checkClosed() throws IllegalStateException {
+        if (folderOpen) {
+            throw new IllegalStateException("Folder is Open");
+        }
+    }
+
+    /**
+     * @see javax.mail.Folder#notifyMessageChangedListeners(int,
+     *      javax.mail.Message)
+     * 
+     * this method is protected and cannot be used outside of Folder, therefore
+     * had to explicitly expose it via a method in NNTPFolder, so that
+     * NNTPMessage 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 subscribed status for a folder. This default implementation
+     * just returns false (which is true for the root folder).
+     * 
+     * @return Always returns true.
+     */
+    public boolean isSubscribed() {
+        return false;
+    }
+
+    /**
+     * Set the subscribed status for a folder.
+     * 
+     * @param flag
+     *            The new subscribed status.
+     * 
+     * @exception MessagingException
+     */
+    public void setSubscribed(boolean flag) throws MessagingException {
+        throw new MessagingException("Root NNTP folder cannot be subscribed to");
+    }
+
+    /**
+     * Test if a given article number is marked as SEEN.
+     * 
+     * @param article
+     *            The target article number.
+     * 
+     * @return The articles current seen status.
+     */
+    public boolean isSeen(int article) {
+        return false;
+    }
+
+    /**
+     * Set the SEEN status for an article.
+     * 
+     * @param article
+     *            The target article.
+     * @param flag
+     *            The new seen setting.
+     * 
+     * @exception MessagingException
+     */
+    public void setSeen(int article, boolean flag) throws MessagingException {
+        throw new MessagingException("Root NNTP folder does not contain articles");
+    }
+
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java Wed May 11 16:49:36 2016
@@ -0,0 +1,391 @@
+/*
+ * 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.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.FetchProfile;
+import javax.mail.FolderNotFoundException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+
+/**
+ * The NNTP implementation of the javax.mail.Folder Note that only INBOX is
+ * supported in NNTP
+ * <p>
+ * <url>http://www.faqs.org/rfcs/rfc1939.html</url>
+ * </p>
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 686231 $ $Date: 2008-08-15 10:24:20 -0400 (Fri, 15 Aug 2008) $
+ */
+public class NNTPGroupFolder extends NNTPFolder {
+
+    // holders for status information returned by the GROUP command.
+    protected int firstArticle = -1;
+
+    protected int lastArticle = -1;
+
+    // retrieved articles, mapped by article number.
+    Map articles;
+
+    // information stored in the newsrc group.
+    NNTPNewsrcGroup groupInfo;
+
+    /**
+     * Construct a "real" folder representing an NNTP news group.
+     * 
+     * @param parent
+     *            The parent root folder.
+     * @param store
+     *            The Store this folder is attached to.
+     * @param name
+     *            The folder name.
+     * @param groupInfo
+     *            The newsrc group information attached to the newsrc database.
+     *            This contains subscription and article "SEEN" information.
+     */
+    protected NNTPGroupFolder(NNTPRootFolder parent, NNTPStore store, String name, NNTPNewsrcGroup groupInfo) {
+        super(store);
+        // the name and the full name are the same.
+        this.name = name;
+        this.fullName = name;
+        // set the parent appropriately.
+        this.parent = parent = parent;
+        this.groupInfo = groupInfo;
+    }
+
+    /**
+     * Ping the server and update the group count, first, and last information.
+     * 
+     * @exception MessagingException
+     */
+    private void updateGroupStats() throws MessagingException {
+        // ask the server for information about the group. This is a one-line
+        // reponse with status on
+        // the group, if it exists.
+        NNTPReply reply = connection.sendCommand("GROUP " + name);
+
+        // explicitly not there?
+        if (reply.getCode() == NNTPReply.NO_SUCH_NEWSGROUP) {
+            throw new FolderNotFoundException(this, "Folder does not exist on server: " + reply);
+        } else if (reply.getCode() != NNTPReply.GROUP_SELECTED) {
+            throw new MessagingException("Error requesting group information: " + reply);
+        }
+
+        // we've gotten back a good response, now parse out the group specifics
+        // from the
+        // status response.
+
+        StringTokenizer tokenizer = new StringTokenizer(reply.getMessage());
+
+        // we should have a least 3 tokens here, in the order "count first
+        // last".
+
+        // article count
+        if (tokenizer.hasMoreTokens()) {
+            String count = tokenizer.nextToken();
+            try {
+                messageCount = Integer.parseInt(count);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        // first article number
+        if (tokenizer.hasMoreTokens()) {
+            String first = tokenizer.nextToken();
+            try {
+                firstArticle = Integer.parseInt(first);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        // last article number.
+        if (tokenizer.hasMoreTokens()) {
+            String last = tokenizer.nextToken();
+            try {
+                lastArticle = Integer.parseInt(last);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Test to see if this folder actually exists. This pings the server for
+     * information about the GROUP and updates the article count and index
+     * information.
+     * 
+     * @return true if the newsgroup exists on the server, false otherwise.
+     * @exception MessagingException
+     */
+    public boolean exists() throws MessagingException {
+
+        try {
+            // update the group statistics. If the folder doesn't exist, we'll
+            // get an exception that we
+            // can turn into a false reply.
+            updateGroupStats();
+            // updated ok, so it must be there.
+            return true;
+        } catch (FolderNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Ping the NNTP server to check if a newsgroup has any new messages.
+     * 
+     * @return True if the server has new articles from the last time we
+     *         checked. Also returns true if this is the first time we've
+     *         checked.
+     * @exception MessagingException
+     */
+    public boolean hasNewMessages() throws MessagingException {
+        int oldLast = lastArticle;
+        updateGroupStats();
+
+        return lastArticle > oldLast;
+    }
+
+    /**
+     * Open the folder for use. This retrieves article count information from
+     * the server.
+     * 
+     * @exception MessagingException
+     */
+    protected void openFolder() throws MessagingException {
+        // update the group specifics, especially the message count.
+        updateGroupStats();
+
+        // get a cache for retrieved articles
+        articles = new HashMap();
+    }
+
+    /**
+     * Close the folder, which also clears out the article caches.
+     * 
+     * @exception MessagingException
+     */
+    public void closeFolder() throws MessagingException {
+        // get ride of any retrieve articles, and flip over the open for
+        // business sign.
+        articles = null;
+    }
+
+    /**
+     * Checks wether the message is in cache, if not will create a new message
+     * object and return it.
+     * 
+     * @see javax.mail.Folder#getMessage(int)
+     */
+    public Message getMessage(int msgNum) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+
+        // get an object form to look up in the retrieve messages list (oh how I
+        // wish there was
+        // something like Map that could use integer keys directly!).
+        Integer key = new Integer(msgNum);
+        NNTPMessage message = (NNTPMessage) articles.get(key);
+        if (message != null) {
+            // piece of cake!
+            return message;
+        }
+
+        // we need to suck a message down from the server.
+        // but first, make sure the group is still valid.
+        updateGroupStats();
+
+        // just send a STAT command to this message. Right now, all we want is
+        // existance proof. We'll
+        // retrieve the other bits when requested.
+        NNTPReply reply = connection.sendCommand("STAT " + Integer.toString(msgNum));
+        if (reply.getCode() != NNTPReply.REQUEST_TEXT_SEPARATELY) {
+            throw new MessagingException("Error retrieving article from NNTP server: " + reply);
+        }
+
+        // we need to parse out the message id.
+        String response = reply.getMessage();
+
+        int idStart = response.indexOf('<');
+        int idEnd = response.indexOf('>');
+
+        // NB:  The "<" and ">" delimiters are required elements of the message id, not just 
+        // delimiters for the sake of the command.  We need to keep these around 
+        message = new NNTPMessage(this, (NNTPStore) store, msgNum, response.substring(idStart, idEnd + 1));
+
+        // add this to the article cache.
+        articles.put(key, message);
+
+        return message;
+    }
+
+    /**
+     * Retrieve all articles in the group.
+     * 
+     * @return An array of all messages in the group.
+     */
+    public Message[] getMessages() throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        
+        // we're going to try first with XHDR, which will allow us to retrieve
+        // everything in one shot. If that
+        // fails, we'll fall back on issing STAT commands for the entire article
+        // range.
+        NNTPReply reply = connection.sendCommand("XHDR Message-ID " + Integer.toString(firstArticle) + "-"
+                + Integer.toString(lastArticle), NNTPReply.HEAD_FOLLOWS);
+
+        List messages = new ArrayList();
+
+        if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
+            List lines = reply.getData();
+
+            for (int i = 0; i < lines.size(); i++) {
+                String line = (String) lines.get(i);
+
+                try {
+                    int pos = line.indexOf(' ');
+                    int articleID = Integer.parseInt(line.substring(0, pos));
+                    String messageID = line.substring(pos + 1);
+                    Integer key = new Integer(articleID);
+                    // see if we have this message cached, If not, create it.
+                    Message message = (Message)articles.get(key);
+                    if (message == null) {
+                        message = new NNTPMessage(this, (NNTPStore) store, key.intValue(), messageID);
+                        articles.put(key, message);
+                    }
+
+                    messages.add(message);
+
+                } catch (NumberFormatException e) {
+                    // should never happen, but just skip this entry if it does.
+                }
+            }
+        } else {
+            // grumble, we need to stat each article id to see if it
+            // exists....lots of round trips.
+            for (int i = firstArticle; i <= lastArticle; i++) {
+                try {
+                    messages.add(getMessage(i));
+                } catch (MessagingException e) {
+                    // just assume if there is an error, it's because the
+                    // message id doesn't exist.
+                }
+            }
+        }
+
+        return (Message[]) messages.toArray(new Message[0]);
+    }
+
+    /**
+     * @see javax.mail.Folder#fetch(javax.mail.Message[],
+     *      javax.mail.FetchProfile)
+     * 
+     * The JavaMail API recommends that this method be overrident to provide a
+     * meaningfull implementation.
+     */
+    public 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];
+            // we can only perform this operation for NNTPMessages.
+            if (msg == null || !(msg instanceof NNTPMessage)) {
+                // we can't fetch if it's the wrong message type
+                continue;
+            }
+
+            // fetching both the headers and body?
+            if (fp.contains(FetchProfile.Item.ENVELOPE) && fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+
+                // retrive everything
+                ((NNTPMessage) msg).loadArticle();
+            }
+            // headers only?
+            else if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+                ((NNTPMessage) msg).loadHeaders();
+            } else if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+                ((NNTPMessage) msg).loadContent();
+            }
+        }
+    }
+
+    /**
+     * Return the subscription status of this folder.
+     * 
+     * @return true if the folder is marked as subscribed, false for
+     *         unsubscribed.
+     */
+    public boolean isSubscribed() {
+        return groupInfo.isSubscribed();
+    }
+
+    /**
+     * Set or clear the subscription status of a file.
+     * 
+     * @param flag
+     *            The new subscription state.
+     */
+    public void setSubscribed(boolean flag) {
+        groupInfo.setSubscribed(flag);
+    }
+
+    /**
+     * Return the "seen" state for an article in a folder.
+     * 
+     * @param article
+     *            The article number.
+     * 
+     * @return true if the article is marked as seen in the newsrc file, false
+     *         for unseen files.
+     */
+    public boolean isSeen(int article) {
+        return groupInfo.isArticleSeen(article);
+    }
+
+    /**
+     * Set the seen state for an article in a folder.
+     * 
+     * @param article
+     *            The article number.
+     * @param flag
+     *            The new seen state.
+     */
+    public void setSeen(int article, boolean flag) {
+        if (flag) {
+            groupInfo.markArticleSeen(article);
+        } else {
+            groupInfo.markArticleUnseen(article);
+        }
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java Wed May 11 16:49:36 2016
@@ -0,0 +1,377 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import javax.mail.Flags;
+import javax.mail.IllegalWriteException;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+import org.apache.geronimo.javamail.transport.nntp.StringListInputStream;
+
+/**
+ * NNTP 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: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
+ */
+public class NNTPMessage extends MimeMessage {
+    // the server message identifer
+    String messageID = null;
+
+    // our attached session
+    protected Session session;
+
+    // the Store we're stored in (which manages the connection and other stuff).
+    protected NNTPStore store;
+
+    // our active connection.
+    protected NNTPConnection connection;
+
+    // used to force loading of headers
+    protected boolean headersLoaded = false;
+
+    // use to force content loading
+    protected boolean contentLoaded = false;
+
+    /**
+     * Contruct an NNTPMessage instance.
+     * 
+     * @param folder
+     *            The hosting folder for the message.
+     * @param store
+     *            The Store owning the article (and folder).
+     * @param msgnum
+     *            The article message number.
+     * @param messageID
+     *            The article messageID (as assigned by the server).
+     * 
+     * @exception MessagingException
+     */
+    NNTPMessage(NNTPFolder folder, NNTPStore store, int msgnum, String messageID) throws MessagingException {
+        super(folder, msgnum);
+        this.messageID = messageID;
+        this.store = store;
+        this.session = ((NNTPStore) store).getSession();
+        // get the active connection from the store...all commands are sent
+        // there
+        this.connection = ((NNTPStore) store).getConnection();
+
+        // get our flag set from the folder.
+        flags = folder.getPermanentFlags();
+        // now check our initial SEEN state and set the flags appropriately
+        if (folder.isSeen(msgnum)) {
+            flags.add(Flags.Flag.SEEN);
+        } else {
+            flags.remove(Flags.Flag.SEEN);
+        }
+    }
+
+    /**
+     * Retrieve the size of the message content. The content will be retrieved
+     * from the server, if necessary.
+     * 
+     * @return The size of the content.
+     * @exception MessagingException
+     */
+    public int getSize() throws MessagingException {
+        // make sure we've retrieved the message content and continue with the
+        // superclass version.
+        loadContent();
+        return super.getSize();
+    }
+
+    /**
+     * Get a line count for the NNTP message. This is potentially stored in the
+     * Lines article header. If not there, we return a default of -1.
+     * 
+     * @return The header line count estimate, or -1 if not retrieveable.
+     * @exception MessagingException
+     */
+    public int getLineCount() throws MessagingException {
+        String[] headers = getHeader("Lines");
+
+        // hopefully, there's only a single one of these. No sensible way of
+        // interpreting
+        // multiples.
+        if (headers.length == 1) {
+            try {
+                return Integer.parseInt(headers[0].trim());
+
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+        // dunno...and let them know I don't know.
+        return -1;
+    }
+
+    /**
+     * @see javax.mail.internet.MimeMessage#getContentStream()
+     */
+    protected InputStream getContentStream() throws MessagingException {
+        // get the article information.
+        loadArticle();
+        return super.getContentStream();
+    }
+
+    /***************************************************************************
+     * Following is a set of methods that deal with headers These methods are
+     * just overrides on the superclass methods to allow lazy loading of the
+     * header information.
+     **************************************************************************/
+
+    public String[] getHeader(String name) throws MessagingException {
+        loadHeaders();
+        return headers.getHeader(name);
+    }
+
+    public String getHeader(String name, String delimiter) throws MessagingException {
+        loadHeaders();
+        return headers.getHeader(name, delimiter);
+    }
+
+    public Enumeration getAllHeaders() throws MessagingException {
+        loadHeaders();
+        return headers.getAllHeaders();
+    }
+
+    public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getMatchingHeaders(names);
+    }
+
+    public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getNonMatchingHeaders(names);
+    }
+
+    public Enumeration getAllHeaderLines() throws MessagingException {
+        loadHeaders();
+        return headers.getAllHeaderLines();
+    }
+
+    public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getMatchingHeaderLines(names);
+    }
+
+    public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.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("NNTP messages are read-only");
+    }
+
+    public void setHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    public void removeHeader(String name) throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    public void addHeaderLine(String line) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    /**
+     * We cannot modify these messages
+     */
+    public void saveChanges() throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    /**
+     * Retrieve the message headers from the NNTP server.
+     * 
+     * @exception MessagingException
+     */
+    public void loadHeaders() throws MessagingException {
+        // don't retrieve if already loaded.
+        if (headersLoaded) {
+            return;
+        }
+
+        NNTPReply reply = connection.sendCommand("HEAD " + messageID, NNTPReply.HEAD_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
+            try {
+                // wrap a stream around the reply data and read as headers.
+                updateHeaders(new StringListInputStream(reply.getData()));
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article headers from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article headers from server: " + reply);
+        }
+    }
+
+    /**
+     * Update the message headers from an input stream.
+     * 
+     * @param in
+     *            The InputStream source for the header information.
+     * 
+     * @exception MessagingException
+     */
+    public void updateHeaders(InputStream in) throws MessagingException {
+        // wrap a stream around the reply data and read as headers.
+        headers = new InternetHeaders(in);
+        headersLoaded = true;
+    }
+
+    /**
+     * Load just the message content from the NNTP server.
+     * 
+     * @exception MessagingException
+     */
+    public void loadContent() throws MessagingException {
+        if (contentLoaded) {
+            return;
+        }
+
+        NNTPReply reply = connection.sendCommand("BODY " + messageID, NNTPReply.BODY_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.BODY_FOLLOWS) {
+            try {
+                InputStream in = new StringListInputStream(reply.getData());
+                updateContent(in);
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article body from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article body from server: " + reply);
+        }
+    }
+
+    /**
+     * Load the entire article from the NNTP server. This updates both the
+     * headers and the content.
+     * 
+     * @exception MessagingException
+     */
+    public void loadArticle() throws MessagingException {
+        // if the headers are already loaded, retrieve the content portion.
+        if (headersLoaded) {
+            loadContent();
+            return;
+        }
+
+        // we need to retrieve everything.
+        NNTPReply reply = connection.sendCommand("ARTICLE " + messageID, NNTPReply.ARTICLE_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.ARTICLE_FOLLOWS) {
+            try {
+                InputStream in = new StringListInputStream(reply.getData());
+                // update both the headers and the content.
+                updateHeaders(in);
+                updateContent(in);
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article from server: " + reply);
+        }
+    }
+
+    /**
+     * Update the article content from an input stream.
+     * 
+     * @param in
+     *            The content data source.
+     * 
+     * @exception MessagingException
+     */
+    public void updateContent(InputStream in) throws MessagingException {
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            byte[] buffer = new byte[4096];
+
+            // copy the content data from the stream into a byte buffer for the
+            // content.
+            while (true) {
+                int read = in.read(buffer);
+                if (read == -1) {
+                    break;
+                }
+                out.write(buffer, 0, read);
+            }
+
+            content = out.toByteArray();
+            contentLoaded = true;
+        } catch (IOException e) {
+            throw new MessagingException("Error retrieving message body from server", e);
+        }
+    }
+
+    /**
+     * Get the server assigned messageid for the article.
+     * 
+     * @return The server assigned message id.
+     */
+    public String getMessageId() {
+        return messageID;
+    }
+
+    /**
+     * Override of setFlags(). We need to ensure that if the SEEN flag is set or
+     * cleared, that the newsrc file correctly reflects the current state.
+     * 
+     * @param flag
+     *            The flag being set.
+     * @param newvalue
+     *            The new flag value.
+     * 
+     * @exception MessagingException
+     */
+    public void setFlags(Flags flag, boolean newvalue) throws MessagingException {
+        // if this is the SEEN flag, make sure we shadow this in the newsrc
+        // file.
+        if (flag.contains(Flags.Flag.SEEN)) {
+            ((NNTPFolder) folder).setSeen(msgnum, newvalue);
+        }
+        // have the superclass do the real flag setting.
+        super.setFlags(flag, newvalue);
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java Wed May 11 16:49:36 2016
@@ -0,0 +1,399 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+import org.apache.geronimo.mail.util.SessionUtil;
+
+/**
+ * The base NNTP implementation of the javax.mail.Folder This is a base class
+ * for both the Root NNTP server and each NNTP group folder.
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 437941 $
+ */
+public class NNTPRootFolder extends NNTPFolder {
+    protected static final String NNTP_LISTALL = "mail.nntp.listall";
+
+    /**
+     * Construct the NNTPRootFolder.
+     * 
+     * @param store
+     *            The owning Store.
+     * @param name
+     *            The folder name (by default, this is the server host name).
+     * @param fullName
+     *            The fullName to use for this server (derived from welcome
+     *            string).
+     */
+    protected NNTPRootFolder(NNTPStore store, String name, String fullName) {
+        super(store);
+
+        this.name = name;
+        this.fullName = fullName;
+    }
+
+    /**
+     * List the subfolders. For group folders, this is a meaningless so we throw
+     * a MethodNotSupportedException.
+     * 
+     * @param pattern
+     *            The folder pattern string.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public synchronized Folder[] list(String pattern) throws MessagingException {
+        // the pattern specfied for javamail uses two wild card characters, "%"
+        // and "*". The "%" matches
+        // and character except hierarchy separators. Since we have a flag
+        // hierarchy, "%" and "*" are
+        // essentially the same. If we convert the "%" into "*", we can just
+        // treat this as a wildmat
+        // formatted pattern and pass this on to the server rather than having
+        // to read everything and
+        // process the strings on the client side.
+
+        pattern = pattern.replace('%', '*');
+
+        // if we're not supposed to list everything, then just filter the list
+        // of subscribed groups.
+        if (SessionUtil.getBooleanProperty(NNTP_LISTALL, false)) {
+            return filterActiveGroups(pattern);
+        } else {
+            return filterSubscribedGroups(pattern);
+        }
+    }
+
+    /**
+     * Retrieve the list of subscribed folders that match the given pattern
+     * string.
+     * 
+     * @param pattern
+     *            The pattern string used for the matching
+     * 
+     * @return An array of matching folders from the subscribed list.
+     */
+    public Folder[] listSubscribed(String pattern) throws MessagingException {
+        // the pattern specfied for javamail uses two wild card characters, "%"
+        // and "*". The "%" matches
+        // and character except hierarchy separators. Since we have a flag
+        // hierarchy, "%" and "*" are
+        // essentially the same. If we convert the "%" into "*", we can just
+        // treat this as a wildmat
+        // formatted pattern and pass this on to the server rather than having
+        // to read everything and
+        // process the strings on the client side.
+
+        pattern = pattern.replace('%', '*');
+
+        return filterSubscribedGroups(pattern);
+    }
+
+    /**
+     * Retrieve the list of matching groups from the NNTP server using the LIST
+     * ACTIVE command. The server does the wildcard matching for us.
+     * 
+     * @param pattern
+     *            The pattern string (in wildmat format) used to match.
+     * 
+     * @return An array of folders for the matching groups.
+     */
+    protected Folder[] filterActiveGroups(String pattern) throws MessagingException {
+        NNTPReply reply = connection.sendCommand("LIST ACTIVE " + pattern, NNTPReply.LIST_FOLLOWS);
+
+        // if the LIST ACTIVE command isn't supported,
+        if (reply.getCode() == NNTPReply.COMMAND_NOT_RECOGNIZED) {
+            // only way to list all is to retrieve all and filter.
+            return filterAllGroups(pattern);
+        } else if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
+            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
+        }
+
+        // get the response back from the server and process each returned group
+        // name.
+        List groups = reply.getData();
+
+        Folder[] folders = new Folder[groups.size()];
+        for (int i = 0; i < groups.size(); i++) {
+            folders[i] = getFolder(getGroupName((String) groups.get(i)));
+        }
+        return folders;
+    }
+
+    /**
+     * Retrieve a list of all groups from the server and filter on the names.
+     * Not recommended for the usenet servers, as there are over 30000 groups to
+     * process.
+     * 
+     * @param pattern
+     *            The pattern string used for the selection.
+     * 
+     * @return The Folders for the matching groups.
+     */
+    protected Folder[] filterAllGroups(String pattern) throws MessagingException {
+        NNTPReply reply = connection.sendCommand("LIST", NNTPReply.LIST_FOLLOWS);
+
+        if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
+            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
+        }
+
+        // get the response back from the server and process each returned group
+        // name.
+        List groups = reply.getData();
+
+        WildmatMatcher matcher = new WildmatMatcher(pattern);
+
+        List folders = new ArrayList();
+        for (int i = 0; i < groups.size(); i++) {
+            String name = getGroupName((String) groups.get(i));
+            // does this match our pattern? Add to the list
+            if (matcher.matches(name)) {
+                folders.add(getFolder(name));
+            }
+        }
+        return (Folder[]) folders.toArray(new Folder[0]);
+    }
+
+    /**
+     * Return the set of groups from the newsrc subscribed groups list that
+     * match a given filter.
+     * 
+     * @param pattern
+     *            The selection pattern.
+     * 
+     * @return The Folders for the matching groups.
+     */
+    protected Folder[] filterSubscribedGroups(String pattern) throws MessagingException {
+        Iterator groups = ((NNTPStore) store).getNewsrcGroups();
+
+        WildmatMatcher matcher = new WildmatMatcher(pattern);
+
+        List folders = new ArrayList();
+        while (groups.hasNext()) {
+            NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.next();
+            if (group.isSubscribed()) {
+                // does this match our pattern? Add to the list
+                if (matcher.matches(group.getName())) {
+                    folders.add(getFolder(group.getName()));
+                }
+            }
+        }
+        return (Folder[]) folders.toArray(new Folder[0]);
+    }
+
+    /**
+     * Utility method for extracting a name from a group list response.
+     * 
+     * @param response
+     *            The response string.
+     * 
+     * @return The group name.
+     */
+    protected String getGroupName(String response) {
+        int blank = response.indexOf(' ');
+        return response.substring(0, blank).trim();
+    }
+
+    /**
+     * Return whether this folder can hold just messages or also subfolders.
+     * Only the root folder can hold other folders, so it will need to override.
+     * 
+     * @return Always returns Folder.HOLDS_FOLDERS.
+     * @exception MessagingException
+     */
+    public int getType() throws MessagingException {
+        return HOLDS_FOLDERS;
+    }
+
+    /**
+     * Get a new folder from the root folder. This creates a new folder, which
+     * might not actually exist on the server. If the folder doesn't exist, an
+     * error will occur on folder open.
+     * 
+     * @param name
+     *            The name of the requested folder.
+     * 
+     * @return A new folder object for this folder.
+     * @exception MessagingException
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        // create a new group folder and return
+        return new NNTPGroupFolder(this, (NNTPStore) store, name, ((NNTPStore) store).getNewsrcGroup(name));
+    }
+
+    /**
+     * Utility class to do Wildmat pattern matching on folder names.
+     */
+    class WildmatMatcher {
+        // middle match sections...because these are separated by wildcards, if
+        // they appear in
+        // sequence in the string, it is a match.
+        List matchSections = new ArrayList();
+
+        // just a "*" match, so everything is true
+        boolean matchAny = false;
+
+        // no wildcards, so this must be an exact match.
+        String exactMatch = null;
+
+        // a leading section which must be at the beginning
+        String firstSection = null;
+
+        // a trailing section which must be at the end of the string.
+        String lastSection = null;
+
+        /**
+         * Create a wildmat pattern matcher.
+         * 
+         * @param pattern
+         *            The wildmat pattern to apply to string matches.
+         */
+        public WildmatMatcher(String pattern) {
+            int section = 0;
+
+            // handle the easy cases first
+
+            // single wild card?
+            if (pattern.equals("*")) {
+                matchAny = true;
+                return;
+            }
+
+            // find the first wild card
+            int wildcard = pattern.indexOf('*');
+
+            // no wild card at all?
+            if (wildcard == -1) {
+                exactMatch = pattern;
+                return;
+            }
+
+            // pattern not begin with a wildcard? We need to pull off the
+            // leading section
+            if (!pattern.startsWith("*")) {
+                firstSection = pattern.substring(0, wildcard);
+                section = wildcard + 1;
+                // this could be "yada*", so we could be done.
+                if (section >= pattern.length()) {
+                    return;
+                }
+            }
+
+            // now parse off the middle sections, making sure to handle the end
+            // condition correctly.
+            while (section < pattern.length()) {
+                // find the next wildcard position
+                wildcard = pattern.indexOf('*', section);
+                if (wildcard == -1) {
+                    // not found, we're at the end of the pattern. We need to
+                    // match on the end.
+                    lastSection = pattern.substring(section);
+                    return;
+                }
+                // we could have a null section, which we'll just ignore.
+                else if (wildcard == section) {
+                    // step over the wild card
+                    section++;
+                } else {
+                    // pluck off the next section
+                    matchSections.add(pattern.substring(section, wildcard));
+                    // step over the wild card character and check if we've
+                    // reached the end.
+                    section = wildcard + 1;
+                }
+            }
+        }
+
+        /**
+         * Test if a name string matches to parsed wildmat pattern.
+         * 
+         * @param name
+         *            The name to test.
+         * 
+         * @return true if the string matches the pattern, false otherwise.
+         */
+        public boolean matches(String name) {
+
+            // handle the easy cases first
+
+            // full wildcard? Always matches
+            if (matchAny) {
+                return true;
+            }
+
+            // required exact matches are easy.
+            if (exactMatch != null) {
+                return exactMatch.equals(name);
+            }
+
+            int span = 0;
+
+            // must match the beginning?
+            if (firstSection != null) {
+                // if it doesn't start with that, it can't be true.
+                if (!name.startsWith(firstSection)) {
+                    return false;
+                }
+
+                // we do all additional matching activity from here.
+                span = firstSection.length();
+            }
+
+            // scan for each of the sections along the string
+            for (int i = 1; i < matchSections.size(); i++) {
+                // if a section is not found, this is false
+
+                String nextMatch = (String) matchSections.get(i);
+                int nextLocation = name.indexOf(nextMatch, span);
+                if (nextLocation == -1) {
+                    return false;
+                }
+                // step over that one
+                span = nextMatch.length() + nextLocation;
+            }
+
+            // we've matched everything up to this point, now check to see if
+            // need an end match
+            if (lastSection != null) {
+                // we need to have at least the number of characters of the end
+                // string left, else this fails.
+                if (name.length() - span < lastSection.length()) {
+                    return false;
+                }
+
+                // ok, make sure we end with this string
+                return name.endsWith(lastSection);
+            }
+
+            // no falsies, this must be the truth.
+            return true;
+        }
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java?rev=1743397&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java Wed May 11 16:49:36 2016
@@ -0,0 +1,44 @@
+/**
+ * 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 javax.mail.Session;
+import javax.mail.URLName;
+
+/**
+ * NNTP implementation of javax.mail.Store over an SSL connection.
+ *
+ * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
+ */
+public class NNTPSSLStore extends NNTPStore {
+    /**
+     * Construct an NNTPSSLStore item.
+     *
+     * @param session The owning javamail Session.
+     * @param urlName The Store urlName, which can contain server target information.
+     */
+	public NNTPSSLStore(Session session, URLName urlName) {
+        // we're the imaps protocol, our default connection port is 563, and we must use
+        // an SSL connection for the initial hookup 
+		super(session, urlName, "nntps", DEFAULT_NNTP_SSL_PORT, true);
+	}
+}
+
+
+




Mime
View raw message