Should have svn copied instead of add to maintain provenance
git-svn-id: https://svn.apache.org/repos/asf/geronimo/javamail/trunk@1743398 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/geronimo-javamail_1.5/.travis.yml b/geronimo-javamail_1.5/.travis.yml
deleted file mode 100644
index ca8fc8c..0000000
--- a/geronimo-javamail_1.5/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: java
-
-jdk:
- - openjdk6
- - openjdk7
- - oraclejdk7
- - oraclejdk8
-
diff --git a/geronimo-javamail_1.5/LICENSE b/geronimo-javamail_1.5/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/geronimo-javamail_1.5/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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.
diff --git a/geronimo-javamail_1.5/NOTICE b/geronimo-javamail_1.5/NOTICE
deleted file mode 100644
index e288221..0000000
--- a/geronimo-javamail_1.5/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-
-Geronimo JavaMail 1.5
-Copyright 2003-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-
diff --git a/geronimo-javamail_1.5/README.txt b/geronimo-javamail_1.5/README.txt
deleted file mode 100644
index cad0219..0000000
--- a/geronimo-javamail_1.5/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-Building
-========
-
-To build you will need:
-
- * J2SE SDK 1.5+ (http://java.sun.com/j2se/1.5/)
- * Maven 2.0.7+ (http://maven.apache.org)
-
-To build all changes incrementally:
-
- mvn install
-
-To perform clean builds, which are sometimes needed after some changes to the
-source tree:
-
- mvn clean install
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml
deleted file mode 100644
index 2aed314..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<!-- $Rev: 1704994 $ $Date: 2015-09-24 01:38:16 -0400 (Thu, 24 Sep 2015) $ -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5</artifactId>
- <version>1.9.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>geronimo-javamail_1.5_mail</artifactId>
- <packaging>bundle</packaging>
- <name>Geronimo JavaMail 1.5 :: Mail</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5_provider</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-javamail_1.5_spec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-activation_1.1_spec</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-osgi-locator</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <!-- NOTE: The shade build step is an important step in getting the bundle
- built correctly. This step copies all of the OSGI-INF/services and META-INF/*
- resources into the local build target, and then the bundle plugin merges those
- resources with the class files pulled from the dependency jars to create the
- final result. Without this extra step, only the class files make it into the
- final bundle.-->
-
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <artifactSet>
- <includes>
- <include>org.apache.geronimo.specs:geronimo-javamail_1.5_spec</include>
- <include>org.apache.geronimo.javamail:geronimo-javamail_1.5_provider</include>
- <include>${project.groupId}:${project.artifactId}</include>
- </includes>
- </artifactSet>
- <filters>
- <filter>
- <artifact>org.apache.geronimo.specs:geronimo-javamail_1.5_spec</artifact>
- <!-- All of the class files need to be excluded to avoid bnd errors about split packages -->
- <excludes>
- <exclude>javax/**</exclude>
- <exclude>org/apache/geronimo/mail/*.class</exclude>
- <exclude>org/apache/geronimo/osgi/**</exclude>
- </excludes>
- </filter>
- <filter>
- <artifact>org.apache.geronimo.javamail:geronimo-javamail_1.5_provider</artifact>
- <excludes>
- <exclude>org/apache/geronimo/javamail/**</exclude>
- <exclude>org/apache/geronimo/osgi/**</exclude>
- </excludes>
- </filter>
- </filters>
- <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
- <createDependencyReducedPom>true</createDependencyReducedPom>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>${project.groupId}.${project.artifactId};singleton=true</Bundle-SymbolicName>
- <Specification-Title>JSR-919 Javamail API 1.5 merged bundle</Specification-Title>
- <Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
- <Specification-Version>1.5</Specification-Version>
- <Private-Package>
- org.apache.geronimo.osgi.locator,
- org.apache.geronimo.mail,
- org.apache.geronimo.mail.util,
- org.apache.geronimo.javamail.util,
- org.apache.geronimo.javamail.authentication
- </Private-Package>
- <Export-Package>
- javax.mail*;version=1.5,
- org.apache.geronimo.javamail.handlers*;version=1.5,
- org.apache.geronimo.javamail.store*;version=1.5,
- org.apache.geronimo.javamail.transport*;version=1.5,
- org.apache.geronimo.mail.handlers*;version=1.5,
- </Export-Package>
- <Import-Package>
- javax.activation,
- javax.net,
- javax.mail*,
- javax.imageio*;resolution:="optional",
- javax.net.ssl*;resolution:="optional",
- javax.security.sasl*;resolution:="optional",
- javax.security.auth.callback*;resolution:="optional",
- org.apache.geronimo.osgi.registry.api;resolution:="optional",
- *
- </Import-Package>
- <Bundle-Activator>org.apache.geronimo.mail.Activator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml
deleted file mode 100644
index 251ed2b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<!-- $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $ -->
-
-<project name="${project.name}">
-
- <body>
-
- ${parentProject}
-
- ${modules}
-
- ${reports}
-
- </body>
-
-</project>
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml
deleted file mode 100644
index c9cccf5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml
+++ /dev/null
@@ -1,345 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-
-<!-- $Rev: 1704994 $ $Date: 2014-07-20 09:36:35 +0200 (So, 20. Jul 2014)
- $ -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>geronimo-javamail_1.5_provider</artifactId>
- <packaging>bundle</packaging>
- <name>Geronimo JavaMail 1.5 :: Provider</name>
-
- <properties>
- <james.version>3.0-beta4</james.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-activation_1.1_spec</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-javamail_1.5_spec</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>apache-mime4j-core</artifactId>
- <groupId>org.apache.james</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-james-imap-processor</artifactId>
- <version>0.3</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-protocols-pop3</artifactId>
- <version>${james.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-protocols-imap4</artifactId>
- <version>${james.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-protocols-smtp</artifactId>
- <version>${james.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <version>0.5</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <version>0.5</version>
- <type>test-jar</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-protocols-library</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- <version>${james.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-protocols-library</artifactId>
- <scope>test</scope>
- <version>${james.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-filesystem-api</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- <version>${james.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-data-library</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- <version>${james.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-data-library</artifactId>
- <scope>test</scope>
- <version>${james.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-data-file</artifactId>
- <version>${james.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-queue-file</artifactId>
- <version>${james.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-data-file</artifactId>
- <version>${james.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-queue-file</artifactId>
- <version>${james.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-queue-api</artifactId>
- <version>${james.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-data-api</artifactId>
- <version>${james.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <artifactId>mail</artifactId>
- <groupId>javax.mail</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.2</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>1.7.2</version>
- <scope>test</scope>
- </dependency>
-
- <!-- <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId>
- <version>1.3.1</version> <scope>test</scope> </dependency> -->
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>${project.groupId}.${project.artifactId};singleton=true</Bundle-SymbolicName>
- <Specification-Title>JSR-919 Javamail API 1.5
- provider bundle</Specification-Title>
- <Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
- <Specification-Version>1.5</Specification-Version>
- <Private-Package>
- org.apache.geronimo.javamail.util,
- org.apache.geronimo.javamail.authentication
- </Private-Package>
- <Export-Package>
- org.apache.geronimo.javamail.store*;version=1.5,
- org.apache.geronimo.javamail.transport*;version=1.5,
- org.apache.geronimo.javamail.handlers*;version=1.5
- </Export-Package>
- <Import-Package>
- javax.activation,
- javax.net,
- javax.mail*,
- org.apache.geronimo.mail.util,
- javax.imageio*;resolution:="optional",
- javax.net.ssl*;resolution:="optional",
- javax.security.sasl*;resolution:="optional",
- javax.security.auth.callback*;resolution:="optional",
- org.apache.geronimo.mail.james.mime4j.codec
- </Import-Package>
- </instructions>
- <unpackBundle>true</unpackBundle>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java
deleted file mode 100644
index c4341c7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * 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.authentication;
-
-import java.lang.reflect.Constructor;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-public class AuthenticatorFactory {
- // the list of authentication mechanisms we have direct support for. Others come from
- // SASL, if it's available.
-
- public static final String AUTHENTICATION_PLAIN = "PLAIN";
- public static final String AUTHENTICATION_LOGIN = "LOGIN";
- public static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
- public static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
-
- static public ClientAuthenticator getAuthenticator(ProtocolProperties props, List mechanisms, String host, String username, String password, String authId, String realm)
- {
- // if the authorization id isn't given, then this is the same as the logged in user name.
- if (authId == null) {
- authId = username;
- }
-
- // if SASL is enabled, try getting a SASL authenticator first
- if (props.getBooleanProperty("sasl.enable", false)) {
- // we need to convert the mechanisms map into an array of strings for SASL.
- String [] mechs = (String [])mechanisms.toArray(new String[mechanisms.size()]);
-
- try {
- // need to try to load this using reflection since it has references to
- // the SASL API. That's only available with 1.5 or later.
- Class authenticatorClass = Class.forName("org.apache.geronimo.javamail.authentication.SASLAuthenticator");
- Constructor c = authenticatorClass.getConstructor(new Class[] {
- (new String[0]).getClass(),
- Properties.class,
- String.class,
- String.class,
- String.class,
- String.class,
- String.class,
- String.class
- });
-
- Object[] args = { mechs, props.getProperties(), props.getProtocol(), host, realm, authId, username, password };
-
- return (ClientAuthenticator)c.newInstance(args);
- } catch (Throwable e) {
- // Any exception is likely because we're running on 1.4 and can't use the Sasl API.
- // just ignore and use our fallback implementations.
- }
- }
-
- // now go through the progression of mechanisms we support, from the
- // most secure to the least secure.
-
- if (mechanisms.contains(AUTHENTICATION_DIGESTMD5)) {
- return new DigestMD5Authenticator(host, username, password, realm);
- } else if (mechanisms.contains(AUTHENTICATION_CRAMMD5)) {
- return new CramMD5Authenticator(username, password);
- } else if (mechanisms.contains(AUTHENTICATION_LOGIN)) {
- return new LoginAuthenticator(username, password);
- } else if (mechanisms.contains(AUTHENTICATION_PLAIN)) {
- return new PlainAuthenticator(authId, username, password);
- } else {
- // can't find a mechanism we support in common
- return null;
- }
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java
deleted file mode 100644
index 0404d36..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.authentication;
-
-import javax.mail.MessagingException;
-
-/**
- * Simplified version of the Java 5 SaslClient interface. This is used to
- * implement a javamail authentication framework that mimics the Sasl framework
- * on a 1.4.2 JVM. Only the methods required by the Javamail code are
- * implemented here, but it should be a simple migration to the fuller SASL
- * interface.
- */
-public interface ClientAuthenticator {
- /**
- * Evaluate a challenge and return a response that can be sent back to the
- * server. Bot the challenge information and the response information are
- * "raw data", minus any special encodings used by the transport. For
- * example, SMTP DIGEST-MD5 authentication protocol passes information as
- * Base64 encoded strings. That encoding must be removed before calling
- * evaluateChallenge() and the resulting respose must be Base64 encoced
- * before transmission to the server.
- *
- * It is the authenticator's responsibility to keep track of the state of
- * the evaluations. That is, if the authentication process requires multiple
- * challenge/response cycles, then the authenticator needs to keep track of
- * context of the challenges.
- *
- * @param challenge
- * The challenge data.
- *
- * @return An appropriate response for the challenge data.
- */
-
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException;
-
- /**
- * Indicates that the authenticator has data that should be sent when the
- * authentication process is initiated. For example, the SMTP PLAIN
- * authentication sends userid/password without waiting for a challenge
- * response.
- *
- * If this method returns true, then the initial response is retrieved using
- * evaluateChallenge() passing null for the challenge information.
- *
- * @return True if the challenge/response process starts with an initial
- * response on the client side.
- */
- public boolean hasInitialResponse();
-
- /**
- * Indicates whether the client believes the challenge/response sequence is
- * now complete.
- *
- * @return true if the client has evaluated what it believes to be the last
- * challenge, false if there are additional stages to evaluate.
- */
-
- public boolean isComplete();
-
- /**
- * Return the mechanism name implemented by this authenticator.
- *
- * @return The string name of the authentication mechanism. This name should
- * match the names commonly used by the mail servers (e.g., "PLAIN",
- * "LOGIN", "DIGEST-MD5", etc.).
- */
- public String getMechanismName();
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
deleted file mode 100644
index 91a6425..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.authentication;
-
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.mail.util.Hex;
-
-public class CramMD5Authenticator implements ClientAuthenticator {
-
- // the user we're authenticating
- protected String username;
-
- // the user's password (the "shared secret")
- protected String password;
-
- // indicates whether we've gone through the entire challenge process.
- protected boolean complete = false;
-
- /**
- * Main constructor.
- *
- * @param username
- * The login user name.
- * @param password
- * The login password.
- */
- public CramMD5Authenticator(String username, String password) {
- this.username = username;
- this.password = password;
- }
-
- /**
- * Respond to the hasInitialResponse query. This mechanism does not have an
- * initial response.
- *
- * @return Always returns false.
- */
- public boolean hasInitialResponse() {
- return false;
- }
-
- /**
- * Indicate whether the challenge/response process is complete.
- *
- * @return True if the last challenge has been processed, false otherwise.
- */
- public boolean isComplete() {
- return complete;
- }
-
- /**
- * Retrieve the authenticator mechanism name.
- *
- * @return Always returns the string "CRAM-MD5"
- */
- public String getMechanismName() {
- return "CRAM-MD5";
- }
-
- /**
- * Evaluate a CRAM-MD5 login challenge, returning the a result string that
- * should satisfy the clallenge.
- *
- * @param challenge
- * The decoded challenge data, as a byte array.
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
- // we create the challenge from the userid and password information (the
- // "shared secret").
- byte[] passBytes;
-
- try {
- // get the password in an UTF-8 encoding to create the token
- passBytes = password.getBytes("UTF-8");
- // compute the password digest using the key
- byte[] digest = computeCramDigest(passBytes, challenge);
-
- // create a unified string using the user name and the hex encoded
- // digest
- String responseString = username + " " + new String(Hex.encode(digest), "ISO8859-1");
- complete = true;
- return responseString.getBytes("ISO8859-1");
- } catch (UnsupportedEncodingException e) {
- // got an error, fail this
- throw new MessagingException("Invalid character encodings");
- }
-
- }
-
- /**
- * Compute a CRAM digest using the hmac_md5 algorithm. See the description
- * of RFC 2104 for algorithm details.
- *
- * @param key
- * The key (K) for the calculation.
- * @param input
- * The encrypted text value.
- *
- * @return The computed digest, as a byte array value.
- * @exception NoSuchAlgorithmException
- */
- protected byte[] computeCramDigest(byte[] key, byte[] input) throws MessagingException {
- // CRAM digests are computed using the MD5 algorithm.
- MessageDigest digest;
- try {
- digest = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new MessagingException("Unable to access MD5 message digest", e);
- }
-
- // if the key is longer than 64 bytes, then we get a digest of the key
- // and use that instead.
- // this is required by RFC 2104.
- if (key.length > 64) {
- digest.update(key);
- key = digest.digest();
- }
-
- // now we create two 64 bit padding keys, initialized with the key
- // information.
- byte[] ipad = new byte[64];
- byte[] opad = new byte[64];
-
- System.arraycopy(key, 0, ipad, 0, key.length);
- System.arraycopy(key, 0, opad, 0, key.length);
-
- // and these versions are munged by XORing with "magic" values.
-
- for (int i = 0; i < 64; i++) {
- ipad[i] ^= 0x36;
- opad[i] ^= 0x5c;
- }
-
- // now there are a pair of MD5 operations performed, and inner and an
- // outer. The spec defines this as
- // H(K XOR opad, H(K XOR ipad, text)), where H is the MD5 operation.
-
- // inner operation
- digest.reset();
- digest.update(ipad);
- digest.update(input); // this appends the text to the pad
- byte[] md5digest = digest.digest();
-
- // outer operation
- digest.reset();
- digest.update(opad);
- digest.update(md5digest);
- return digest.digest(); // final result
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
deleted file mode 100644
index 0272b24..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * 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.authentication;
-
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-
-import javax.mail.AuthenticationFailedException;
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.geronimo.mail.util.Hex;
-
-/**
- * Process a DIGEST-MD5 authentication, using the challenge/response mechanisms.
- */
-public class DigestMD5Authenticator implements ClientAuthenticator {
-
- protected static final int AUTHENTICATE_CLIENT = 0;
-
- protected static final int AUTHENTICATE_SERVER = 1;
-
- protected static final int AUTHENTICATION_COMPLETE = 2;
-
- // the host server name
- protected String host;
-
- // the user we're authenticating
- protected String username;
-
- // the user's password (the "shared secret")
- protected String password;
-
- // the target login realm
- protected String realm;
-
- // our message digest for processing the challenges.
- MessageDigest digest;
-
- // the string we send to the server on the first challenge.
- protected String clientResponse;
-
- // the response back from an authentication challenge.
- protected String authenticationResponse = null;
-
- // our list of realms received from the server (normally just one).
- protected ArrayList realms;
-
- // the nonce value sent from the server
- protected String nonce;
-
- // indicates whether we've gone through the entire challenge process.
- protected int stage = AUTHENTICATE_CLIENT;
-
- /**
- * Main constructor.
- *
- * @param host
- * The server host name.
- * @param username
- * The login user name.
- * @param password
- * The login password.
- * @param realm
- * The target login realm (can be null).
- */
- public DigestMD5Authenticator(String host, String username, String password, String realm) {
- this.host = host;
- this.username = username;
- this.password = password;
- this.realm = realm;
- }
-
- /**
- * Respond to the hasInitialResponse query. This mechanism does not have an
- * initial response.
- *
- * @return Always returns false.
- */
- public boolean hasInitialResponse() {
- return false;
- }
-
- /**
- * Indicate whether the challenge/response process is complete.
- *
- * @return True if the last challenge has been processed, false otherwise.
- */
- public boolean isComplete() {
- return stage == AUTHENTICATION_COMPLETE;
- }
-
- /**
- * Retrieve the authenticator mechanism name.
- *
- * @return Always returns the string "DIGEST-MD5"
- */
- public String getMechanismName() {
- return "DIGEST-MD5";
- }
-
- /**
- * Evaluate a DIGEST-MD5 login challenge, returning the a result string that
- * should satisfy the clallenge.
- *
- * @param challenge
- * The decoded challenge data, as a string.
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
-
- // DIGEST-MD5 authentication goes in two stages. First state involves us
- // validating with the
- // server, the second stage is the server validating with us, using the
- // shared secret.
- switch (stage) {
- // stage one of the process.
- case AUTHENTICATE_CLIENT: {
- // get the response and advance the processing stage.
- byte[] response = authenticateClient(challenge);
- stage = AUTHENTICATE_SERVER;
- return response;
- }
-
- // stage two of the process.
- case AUTHENTICATE_SERVER: {
- // get the response and advance the processing stage to completed.
- byte[] response = authenticateServer(challenge);
- stage = AUTHENTICATION_COMPLETE;
- return response;
- }
-
- // should never happen.
- default:
- throw new MessagingException("Invalid LOGIN challenge");
- }
- }
-
- /**
- * Evaluate a DIGEST-MD5 login server authentication challenge, returning
- * the a result string that should satisfy the clallenge.
- *
- * @param challenge
- * The decoded challenge data, as a string.
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] authenticateServer(byte[] challenge) throws MessagingException {
- // parse the challenge string and validate.
- if (!parseChallenge(challenge)) {
- return null;
- }
-
- try {
- // like all of the client validation steps, the following is order
- // critical.
- // first add in the URI information.
- digest.update((":smtp/" + host).getBytes("US-ASCII"));
- // now mix in the response we sent originally
- String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
- digest.update(responseString.getBytes("US-ASCII"));
-
- // now convert that into a hex encoded string.
- String validationText = new String(Hex.encode(digest.digest()), "US-ASCII");
-
- // if everything went well, this calculated value should match what
- // we got back from the server.
- // our response back is just a null string....
- if (validationText.equals(authenticationResponse)) {
- return new byte[0];
- }
- throw new AuthenticationFailedException("Invalid DIGEST-MD5 response from server");
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Invalid character encodings");
- }
-
- }
-
- /**
- * Evaluate a DIGEST-MD5 login client authentication challenge, returning
- * the a result string that should satisfy the clallenge.
- *
- * @param challenge
- * The decoded challenge data, as a string.
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] authenticateClient(byte[] challenge) throws MessagingException {
- // parse the challenge string and validate.
- if (!parseChallenge(challenge)) {
- return null;
- }
-
- SecureRandom randomGenerator;
- // before doing anything, make sure we can get the required crypto
- // support.
- try {
- randomGenerator = new SecureRandom();
- digest = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new MessagingException("Unable to access cryptography libraries");
- }
-
- // if not configured for a realm, take the first realm from the list, if
- // any
- if (realm == null) {
- // if not handed any realms, just use the host name.
- if (realms.isEmpty()) {
- realm = host;
- } else {
- // pretty arbitrary at this point, so just use the first one.
- realm = (String) realms.get(0);
- }
- }
-
- // use secure random to generate a collection of bytes. that is our
- // cnonce value.
- byte[] cnonceBytes = new byte[32];
-
- randomGenerator.nextBytes(cnonceBytes);
-
- try {
- // and get this as a base64 encoded string.
- String cnonce = new String(Base64.encode(cnonceBytes), "US-ASCII");
-
- // Now the digest computation part. This gets a bit tricky, and must be
- // done in strict order.
- // this identifies where we're logging into.
- String idString = username + ":" + realm + ":" + password;
- // we get a digest for this string, then use the digest for the
- // first stage
- // of the next digest operation.
- digest.update(digest.digest(idString.getBytes("US-ASCII")));
-
- // now we add the nonce strings to the digest.
- String nonceString = ":" + nonce + ":" + cnonce;
- digest.update(nonceString.getBytes("US-ASCII"));
-
- // hex encode this digest, and add on the string values
- // NB, we only support "auth" for the quality of protection value
- // (qop). We save this in an
- // instance variable because we'll need this to validate the
- // response back from the server.
- clientResponse = new String(Hex.encode(digest.digest()), "US-ASCII") + ":" + nonce + ":00000001:" + cnonce + ":auth:";
-
- // now we add in identification values to the hash.
- String authString = "AUTHENTICATE:smtp/" + host;
- digest.update(authString.getBytes("US-ASCII"));
-
- // this gets added on to the client response
- String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
- // and this gets fed back into the digest
- digest.update(responseString.getBytes("US-ASCII"));
-
- // and FINALLY, the challege digest is hex encoded for sending back
- // to the server (whew).
- String challengeResponse = new String(Hex.encode(digest.digest()), "US-ASCII");
-
- // now finally build the keyword/value part of the challenge
- // response. These can be
- // in any order.
- StringBuffer response = new StringBuffer();
-
- response.append("username=\"");
- response.append(username);
- response.append("\"");
-
- response.append(",realm=\"");
- response.append(realm);
- response.append("\"");
-
- // we only support auth qop values, and the nonce-count (nc) is
- // always 1.
- response.append(",qop=auth");
- response.append(",nc=00000001");
-
- response.append(",nonce=\"");
- response.append(nonce);
- response.append("\"");
-
- response.append(",cnonce=\"");
- response.append(cnonce);
- response.append("\"");
-
- response.append(",digest-uri=\"smtp/");
- response.append(host);
- response.append("\"");
-
- response.append(",response=");
- response.append(challengeResponse);
-
- return response.toString().getBytes("US-ASCII");
-
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Invalid character encodings");
- }
- }
-
- /**
- * Parse the challege string, pulling out information required for our
- * challenge response.
- *
- * @param challenge
- * The challenge data.
- *
- * @return true if there were no errors parsing the string, false otherwise.
- * @exception MessagingException
- */
- protected boolean parseChallenge(byte[] challenge) throws MessagingException {
- realms = new ArrayList();
-
- DigestParser parser = null;
- try {
- parser = new DigestParser(new String(challenge, "US-ASCII"));
- } catch (UnsupportedEncodingException ex) {
- }
-
- // parse the entire string...but we ignore everything but the options we
- // support.
- while (parser.hasMore()) {
- NameValuePair pair = parser.parseNameValuePair();
-
- String name = pair.name;
-
- // realm to add to our list?
- if (name.equalsIgnoreCase("realm")) {
- realms.add(pair.value);
- }
- // we need the nonce to evaluate the client challenge.
- else if (name.equalsIgnoreCase("nonce")) {
- nonce = pair.value;
- }
- // rspauth is the challenge replay back, which allows us to validate
- // that server is also legit.
- else if (name.equalsIgnoreCase("rspauth")) {
- authenticationResponse = pair.value;
- }
- }
-
- return true;
- }
-
- /**
- * Inner class for parsing a DIGEST-MD5 challenge string, which is composed
- * of "name=value" pairs, separated by "," characters.
- */
- class DigestParser {
- // the challenge we're parsing
- String challenge;
-
- // length of the challenge
- int length;
-
- // current parsing position
- int position;
-
- /**
- * Normal constructor.
- *
- * @param challenge
- * The challenge string to be parsed.
- */
- public DigestParser(String challenge) {
- this.challenge = challenge;
- this.length = challenge.length();
- position = 0;
- }
-
- /**
- * Test if there are more values to parse.
- *
- * @return true if we've not reached the end of the challenge string,
- * false if the challenge has been completely consumed.
- */
- private boolean hasMore() {
- return position < length;
- }
-
- /**
- * Return the character at the current parsing position.
- *
- * @return The string character for the current parse position.
- */
- private char currentChar() {
- return challenge.charAt(position);
- }
-
- /**
- * step forward to the next character position.
- */
- private void nextChar() {
- position++;
- }
-
- /**
- * Skip over any white space characters in the challenge string.
- */
- private void skipSpaces() {
- while (position < length && Character.isWhitespace(currentChar())) {
- position++;
- }
- }
-
- /**
- * Parse a quoted string used with a name/value pair, accounting for
- * escape characters embedded within the string.
- *
- * @return The string value of the character string.
- */
- private String parseQuotedValue() {
- // we're here because we found the starting double quote. Step over
- // it and parse to the closing
- // one.
- nextChar();
-
- StringBuffer value = new StringBuffer();
-
- while (hasMore()) {
- char ch = currentChar();
-
- // is this an escape char?
- if (ch == '\\') {
- // step past this, and grab the following character
- nextChar();
- // we have an invalid quoted string....
- if (!hasMore()) {
- return null;
- }
- value.append(currentChar());
- }
- // end of the string?
- else if (ch == '"') {
- // step over this so the caller doesn't process it.
- nextChar();
- // return the constructed string.
- return value.toString();
- } else {
- // step over the character and contine with the next
- // characteer1
- value.append(ch);
- }
- nextChar();
- }
- /* fell off the end without finding a closing quote! */
- return null;
- }
-
- /**
- * Parse a token value used with a name/value pair.
- *
- * @return The string value of the token. Returns null if nothing is
- * found up to the separater.
- */
- private String parseTokenValue() {
-
- StringBuffer value = new StringBuffer();
-
- while (hasMore()) {
- char ch = currentChar();
- switch (ch) {
- // process the token separators.
- case ' ':
- case '\t':
- case '(':
- case ')':
- case '<':
- case '>':
- case '@':
- case ',':
- case ';':
- case ':':
- case '\\':
- case '"':
- case '/':
- case '[':
- case ']':
- case '?':
- case '=':
- case '{':
- case '}':
- // no token characters found? this is bad.
- if (value.length() == 0) {
- return null;
- }
- // return the accumulated characters.
- return value.toString();
-
- default:
- // is this a control character? That's a delimiter (likely
- // invalid for the next step,
- // but it is a token terminator.
- if (ch < 32 || ch > 127) {
- // no token characters found? this is bad.
- if (value.length() == 0) {
- return null;
- }
- // return the accumulated characters.
- return value.toString();
- }
- value.append(ch);
- break;
- }
- // step to the next character.
- nextChar();
- }
- // no token characters found? this is bad.
- if (value.length() == 0) {
- return null;
- }
- // return the accumulated characters.
- return value.toString();
- }
-
- /**
- * Parse out a name token of a name/value pair.
- *
- * @return The string value of the name.
- */
- private String parseName() {
- // skip to the value start
- skipSpaces();
-
- // the name is a token.
- return parseTokenValue();
- }
-
- /**
- * Parse out a a value of a name/value pair.
- *
- * @return The string value associated with the name.
- */
- private String parseValue() {
- // skip to the value start
- skipSpaces();
-
- // start of a quoted string?
- if (currentChar() == '"') {
- // parse it out as a string.
- return parseQuotedValue();
- }
- // the value must be a token.
- return parseTokenValue();
- }
-
- /**
- * Parse a name/value pair in an DIGEST-MD5 string.
- *
- * @return A NameValuePair object containing the two parts of the value.
- * @exception MessagingException
- */
- public NameValuePair parseNameValuePair() throws MessagingException {
- // get the name token
- String name = parseName();
- if (name == null) {
- throw new MessagingException("Name syntax error");
- }
-
- // the name should be followed by an "=" sign
- if (!hasMore() || currentChar() != '=') {
- throw new MessagingException("Name/value pair syntax error");
- }
-
- // step over the equals
- nextChar();
-
- // now get the value part
- String value = parseValue();
- if (value == null) {
- throw new MessagingException("Name/value pair syntax error");
- }
-
- // skip forward to the terminator, which should either be the end of
- // the line or a ","
- skipSpaces();
- // all that work, only to have a syntax error at the end (sigh)
- if (hasMore()) {
- if (currentChar() != ',') {
- throw new MessagingException("Name/value pair syntax error");
- }
- // step over, and make sure we position ourselves at either the
- // end or the first
- // real character for parsing the next name/value pair.
- nextChar();
- skipSpaces();
- }
- return new NameValuePair(name, value);
- }
- }
-
- /**
- * Simple inner class to represent a name/value pair.
- */
- public class NameValuePair {
- public String name;
-
- public String value;
-
- NameValuePair(String name, String value) {
- this.name = name;
- this.value = value;
- }
-
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java
deleted file mode 100644
index 9c52f62..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.authentication;
-
-import java.io.UnsupportedEncodingException;
-
-import javax.mail.MessagingException;
-
-public class LoginAuthenticator implements ClientAuthenticator {
-
- // constants for the authentication stages
- protected static final int USERNAME = 0;
-
- protected static final int PASSWORD = 1;
-
- protected static final int COMPLETE = 2;
-
- // the user we're authenticating
- protected String username;
-
- // the user's password (the "shared secret")
- protected String password;
-
- // indicates whether we've gone through the entire challenge process.
- protected int stage = USERNAME;
-
- /**
- * Main constructor.
- *
- * @param username
- * The login user name.
- * @param password
- * The login password.
- */
- public LoginAuthenticator(String username, String password) {
- this.username = username;
- this.password = password;
- }
-
- /**
- * Respond to the hasInitialResponse query. This mechanism does not have an
- * initial response.
- *
- * @return Always returns false;
- */
- public boolean hasInitialResponse() {
- return false;
- }
-
- /**
- * Indicate whether the challenge/response process is complete.
- *
- * @return True if the last challenge has been processed, false otherwise.
- */
- public boolean isComplete() {
- return stage == COMPLETE;
- }
-
- /**
- * Retrieve the authenticator mechanism name.
- *
- * @return Always returns the string "LOGIN"
- */
- public String getMechanismName() {
- return "LOGIN";
- }
-
- /**
- * Evaluate a PLAIN login challenge, returning the a result string that
- * should satisfy the clallenge.
- *
- * @param challenge
- * The decoded challenge data, as a byte array
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
-
- // process the correct stage for the challenge
- switch (stage) {
- // should never happen
- case COMPLETE:
- throw new MessagingException("Invalid LOGIN challenge");
-
- case USERNAME: {
- byte[] userBytes;
-
- try {
- // get the username and password in an UTF-8 encoding to create
- // the token
- userBytes = username.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- // got an error, fail this (this should never happen).
- throw new MessagingException("Invalid encoding");
- }
-
- // next time through we're looking for a password.
- stage = PASSWORD;
- // the user bytes are the entire challenge respose.
- return userBytes;
- }
-
- case PASSWORD: {
- byte[] passBytes;
-
- try {
- // get the username and password in an UTF-8 encoding to create
- // the token
- passBytes = password.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- // got an error, fail this (this should never happen).
- throw new MessagingException("Invalid encoding");
- }
- // we're finished
- stage = COMPLETE;
- return passBytes;
- }
- }
- // should never get here.
- throw new MessagingException("Invalid LOGIN challenge");
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java
deleted file mode 100644
index dd1e704..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.authentication;
-
-import java.io.UnsupportedEncodingException;
-
-import javax.mail.MessagingException;
-
-//Implements RFC 4616 PLAIN SASL mechanism
-//See also RFC 3501, section 6.2.2"
-//an RFC 2595, section 6"
-public class PlainAuthenticator implements ClientAuthenticator {
-
- // the sasl authzid we're authenticating
- protected String authzid;
-
- // the user we're authenticating
- protected String username;
-
- // the user's password (the "shared secret")
- protected String password;
-
- // indicates whether we've gone through the entire challenge process.
- protected boolean complete = false;
-
- /**
- * Main constructor.
- *
- * @param authzid
- * SASL authenticationid (optional)
- * @param username
- * The login user name.
- * @param password
- * The login password.
- */
- public PlainAuthenticator(String authzid, String username, String password) {
- this.authzid = authzid;
- this.username = username;
- this.password = password;
- }
-
- /**
- * Constructor without authzid
- *
- * @param username
- * The login user name.
- * @param password
- * The login password.
- */
- public PlainAuthenticator(String username, String password) {
- this(null, username, password);
- }
-
- /**
- * Respond to the hasInitialResponse query. This mechanism does have an
- * initial response, which is the entire challenge sequence.
- *
- * @return Always returns true.
- */
- public boolean hasInitialResponse() {
- return true;
- }
-
- /**
- * Indicate whether the challenge/response process is complete.
- *
- * @return True if the last challenge has been processed, false otherwise.
- */
- public boolean isComplete() {
- return complete;
- }
-
- /**
- * Retrieve the authenticator mechanism name.
- *
- * @return Always returns the string "PLAIN"
- */
- public String getMechanismName() {
- return "PLAIN";
- }
-
- /**
- * Evaluate a PLAIN login challenge, returning the a result string that
- * should satisfy the challenge.
- *
- * @param challenge
- * For PLAIN Authentication there is no challenge (so this is unused)
- *
- * @return A formatted challenge response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
- try {
-
- String result = "\0"+username+"\0"+password;
-
- if(authzid != null && authzid.length() > 0) {
- result = authzid+result;
- }
-
- complete = true;
- return result.getBytes("UTF-8");
-
- } catch (UnsupportedEncodingException e) {
- // got an error, fail this
- throw new MessagingException("Invalid encoding");
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java
deleted file mode 100644
index 9b22442..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.authentication;
-
-import java.io.UnsupportedEncodingException ;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.mail.MessagingException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.RealmChoiceCallback;
-
-public class SASLAuthenticator implements ClientAuthenticator, CallbackHandler {
- // The realm we're authenticating within
- protected String realm;
- // the user we're authenticating
- protected String username;
- // the user's password (the "shared secret")
- protected String password;
- // the authenticator we're proxying
- protected SaslClient authenticator;
-
- protected boolean complete = false;
-
- /**
- * Main constructor.
- *
- * @param username
- * The login user name.
- * @param password
- * The login password.
- */
- public SASLAuthenticator(String[] mechanisms, Properties properties, String protocol, String host, String realm,
- String authorizationID, String username, String password) throws MessagingException {
- this.realm = realm;
- this.username = username;
- this.password = password;
- try {
- authenticator = Sasl.createSaslClient(mechanisms, authorizationID, protocol, host, (Map)properties,
- this);
- } catch (SaslException e) {
- }
- }
-
-
- /**
- * Respond to the hasInitialResponse query. We defer this to the Sasl client.
- *
- * @return The SaslClient response to the same query.
- */
- public boolean hasInitialResponse() {
- return authenticator.hasInitialResponse();
- }
-
- /**
- * Indicate whether the challenge/response process is complete.
- *
- * @return True if the last challenge has been processed, false otherwise.
- */
- public boolean isComplete() {
- return authenticator.hasInitialResponse();
- }
-
- /**
- * Retrieve the authenticator mechanism name.
- *
- * @return Always returns the string "PLAIN"
- */
- public String getMechanismName() {
- // the authenticator selects this for us.
- return authenticator.getMechanismName();
- }
-
- /**
- * Evaluate a login challenge, returning the a result string that
- * should satisfy the clallenge. This is forwarded to the
- * SaslClient, which will use the CallBackHandler to retrieve the
- * information it needs for the given protocol.
- *
- * @param challenge
- * The decoded challenge data, as byte array.
- *
- * @return A formatted challege response, as an array of bytes.
- * @exception MessagingException
- */
- public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
- // for an initial response challenge, there's no challenge date. The SASL
- // client still expects a byte array argument.
- if (challenge == null) {
- challenge = new byte[0];
- }
-
- try {
- return authenticator.evaluateChallenge(challenge);
- } catch (SaslException e) {
- // got an error, fail this
- throw new MessagingException("Error performing SASL validation", e);
- }
- }
-
- public void handle(Callback[] callBacks) {
- for (int i = 0; i < callBacks.length; i++) {
- Callback callBack = callBacks[i];
- // requesting the user name
- if (callBack instanceof NameCallback) {
- ((NameCallback)callBack).setName(username);
- }
- // need the password
- else if (callBack instanceof PasswordCallback) {
- ((PasswordCallback)callBack).setPassword(password.toCharArray());
- }
- // direct request for the realm information
- else if (callBack instanceof RealmCallback) {
- RealmCallback realmCallback = (RealmCallback)callBack;
- // we might not have a realm, so use the default from the
- // callback item
- if (realm == null) {
- realmCallback.setText(realmCallback.getDefaultText());
- }
- else {
- realmCallback.setText(realm);
- }
- }
- // asked to select the realm information from a list
- else if (callBack instanceof RealmChoiceCallback) {
- RealmChoiceCallback realmCallback = (RealmChoiceCallback)callBack;
- // if we don't have a realm, just tell it to use the default
- if (realm == null) {
- realmCallback.setSelectedIndex(realmCallback.getDefaultChoice());
- }
- else {
- // locate our configured one in the list
- String[] choices = realmCallback.getChoices();
-
- for (int j = 0; j < choices.length; j++) {
- // set the index to any match and get out of here.
- if (choices[j].equals(realm)) {
- realmCallback.setSelectedIndex(j);
- break;
- }
- }
- // NB: If there was no match, we don't set anything.
- // this should cause an authentication failure.
- }
- }
- }
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java
deleted file mode 100644
index d0d202a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import javax.activation.ActivationDataFlavor;
-import javax.activation.DataContentHandler;
-import javax.activation.DataSource;
-import javax.activation.UnsupportedDataTypeException;
-import javax.imageio.IIOImage;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageWriter;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * @version $Rev: 1127882 $ $Date: 2011-05-26 08:17:57 -0400 (Thu, 26 May 2011) $
- */
-public class AbstractImageHandler implements DataContentHandler {
- private final ActivationDataFlavor flavour;
-
- public AbstractImageHandler(ActivationDataFlavor flavour) {
- this.flavour = flavour;
- }
-
- public DataFlavor[] getTransferDataFlavors() {
- return new DataFlavor[]{flavour};
- }
-
- public Object getTransferData(DataFlavor dataFlavor, DataSource dataSource) throws UnsupportedFlavorException, IOException {
- return flavour.equals(dataFlavor) ? getContent(dataSource) : null;
- }
-
- public Object getContent(DataSource ds) throws IOException {
- Iterator i = ImageIO.getImageReadersByMIMEType(flavour.getMimeType());
- if (!i.hasNext()) {
- throw new UnsupportedDataTypeException("Unknown image type " + flavour.getMimeType());
- }
- ImageReader reader = (ImageReader) i.next();
- ImageInputStream iis = ImageIO.createImageInputStream(ds.getInputStream());
- reader.setInput(iis);
- return reader.read(0);
- }
-
- public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
- Iterator i = ImageIO.getImageWritersByMIMEType(flavour.getMimeType());
- if (!i.hasNext()) {
- throw new UnsupportedDataTypeException("Unknown image type " + flavour.getMimeType());
- }
- ImageWriter writer = (ImageWriter) i.next();
- writer.setOutput(ImageIO.createImageOutputStream(os));
-
- if (obj instanceof RenderedImage) {
- writer.write((RenderedImage) obj);
- } else if (obj instanceof BufferedImage) {
- BufferedImage buffered = (BufferedImage) obj;
- writer.write(new IIOImage(buffered.getRaster(), null, null));
- } else if (obj instanceof Image) {
- Image image = (Image) obj;
- BufferedImage buffered = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
- Graphics2D graphics = buffered.createGraphics();
- graphics.drawImage(image, 0, 0, null, null);
- writer.write(new IIOImage(buffered.getRaster(), null, null));
- } else {
- throw new UnsupportedDataTypeException("Unknown image type " + obj.getClass().getName());
- }
- os.flush();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java
deleted file mode 100644
index 52afca7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-
-import javax.activation.DataContentHandler;
-import javax.activation.DataSource;
-
-import javax.mail.internet.ContentType;
-import javax.mail.internet.MimeUtility;
-
-/**
- * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
- */
-public class AbstractTextHandler implements DataContentHandler {
- private final DataFlavor flavour;
-
- public AbstractTextHandler(DataFlavor flavour) {
- this.flavour = flavour;
- }
-
- public DataFlavor[] getTransferDataFlavors() {
- return new DataFlavor[] {flavour};
- }
-
- public Object getTransferData(DataFlavor dataFlavor, DataSource dataSource) throws UnsupportedFlavorException, IOException {
- return flavour.equals(dataFlavor) ? getContent(dataSource) : null;
- }
-
- /**
- * Read the content from the DataSource and transform
- * it into a text object (String).
- *
- * @param ds The source DataSource.
- *
- * @return The content object.
- * @exception IOException
- */
- public Object getContent(DataSource ds) throws IOException {
- InputStream is = ds.getInputStream();
- InputStreamReader reader;
- // process any encoding to make sure the chars get transformed into the
- // correct byte types.
- try {
- String charset = getCharSet(ds.getContentType());
- reader = new InputStreamReader(is, charset);
- } catch (Exception ex) {
- throw new UnsupportedEncodingException(ex.toString());
- }
- StringBuffer result = new StringBuffer(1024);
- char[] buffer = new char[32768];
- int count;
- while ((count = reader.read(buffer)) > 0) {
- result.append(buffer, 0, count);
- }
- return result.toString();
- }
-
-
- /**
- * Write an object of "our" type out to the provided
- * output stream. The content type might modify the
- * result based on the content type parameters.
- *
- * @param object The object to write.
- * @param contentType
- * The content mime type, including parameters.
- * @param outputstream
- * The target output stream.
- *
- * @throws IOException
- */
- public void writeTo(Object o, String contentType, OutputStream outputstream) throws IOException {
- String s;
- if (o instanceof String) {
- s = (String) o;
- } else if (o != null) {
- s = o.toString();
- } else {
- return;
- }
- // process any encoding to make sure the chars get transformed into the
- // correct byte types.
- OutputStreamWriter writer;
- try {
- String charset = getCharSet(contentType);
- writer = new OutputStreamWriter(outputstream, charset);
- } catch (Exception ex) {
- ex.printStackTrace();
- throw new UnsupportedEncodingException(ex.toString());
- }
- writer.write(s);
- writer.flush();
- }
-
-
- /**
- * get the character set from content type
- * @param contentType
- * @return
- * @throws ParseException
- */
- protected String getCharSet(String contentType) throws Exception {
- ContentType type = new ContentType(contentType);
- String charset = type.getParameter("charset");
- if (charset == null) {
- charset = "us-ascii";
- }
- return MimeUtility.javaCharset(charset);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java
deleted file mode 100644
index 6cc4d76..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.Image;
-import javax.activation.ActivationDataFlavor;
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class ImageGifHandler extends AbstractImageHandler {
- public ImageGifHandler() {
- super(new ActivationDataFlavor(Image.class, "image/gif", "GIF Image"));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java
deleted file mode 100644
index c3623c8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.Image;
-import javax.activation.ActivationDataFlavor;
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class ImageJpegHandler extends AbstractImageHandler {
- public ImageJpegHandler() {
- super(new ActivationDataFlavor(Image.class, "image/jpeg", "JPEG Image"));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java
deleted file mode 100644
index 015953d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.IOException;
-import java.io.OutputStream;
-import javax.activation.ActivationDataFlavor;
-import javax.activation.DataContentHandler;
-import javax.activation.DataSource;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMultipart;
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class MultipartHandler implements DataContentHandler {
- private final DataFlavor flavour;
-
- public MultipartHandler() {
- flavour = new ActivationDataFlavor(MimeMultipart.class, "multipart/mixed", "Multipart MIME");
- }
-
- public DataFlavor[] getTransferDataFlavors() {
- return new DataFlavor[]{flavour};
- }
-
- public Object getTransferData(DataFlavor df, DataSource ds) throws UnsupportedFlavorException, IOException {
- return flavour.equals(df) ? getContent(ds) : null;
- }
-
- public Object getContent(DataSource ds) throws IOException {
- try {
- return new MimeMultipart(ds);
- } catch (MessagingException e) {
- throw (IOException) new IOException(e.getMessage()).initCause(e);
- }
- }
-
- public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
- if (obj instanceof MimeMultipart) {
- MimeMultipart mp = (MimeMultipart) obj;
- try {
- mp.writeTo(os);
- } catch (MessagingException e) {
- throw (IOException) new IOException(e.getMessage()).initCause(e);
- }
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java
deleted file mode 100644
index 1df03d3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Properties;
-
-import javax.activation.ActivationDataFlavor;
-import javax.activation.DataContentHandler;
-import javax.activation.DataSource;
-import javax.mail.Message;
-import javax.mail.MessageAware;
-import javax.mail.MessageContext;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.MimeMessage;
-
-/**
- * Content handler for RFC-822 compliant messages.
- * @version $Rev: 824701 $ $Date: 2009-10-13 07:25:59 -0400 (Tue, 13 Oct 2009) $
- */
-public class RFC822MessageHandler implements DataContentHandler {
- // the data flavor defines what this looks like, and is fixed once the
- // handler is instantiated
- protected final DataFlavor flavour;
-
- public RFC822MessageHandler() {
- flavour = new ActivationDataFlavor(Message.class, "message/rfc822", "Message");
- }
-
- /**
- * Return all of the flavors processed by this handler. This
- * is just the singleton flavor.
- *
- * @return An array of the transfer flavors supported by this handler.
- */
- public DataFlavor[] getTransferDataFlavors() {
- return new DataFlavor[] { flavour };
- }
-
- /**
- * Retrieve the transfer data from the data source, but
- * only if the requested flavor matches what we support.
- *
- * @param df The requested data flavor.
- * @param ds The source DataSource.
- *
- * @return The extracted content object, or null if there is a
- * mismatch of flavors.
- * @exception UnsupportedFlavorException
- * @exception IOException
- */
- public Object getTransferData(DataFlavor df, DataSource ds) throws UnsupportedFlavorException, IOException {
- return flavour.equals(df) ? getContent(ds) : null;
- }
-
- /**
- * Extract the RFC822 Message content from a DataSource.
- *
- * @param ds The source data source.
- *
- * @return An extracted MimeMessage object.
- * @exception IOException
- */
- public Object getContent(DataSource ds) throws IOException {
- try {
- // creating a MimeMessage instance requires a session. If the DataSource
- // is a MessageAware one, we can get the session information from the MessageContext.
- // This is generally the case, but if it is not available, then just retrieve
- // the default instance and use it.
- if (ds instanceof MessageAware) {
- MessageContext context = ((MessageAware)ds).getMessageContext();
- return new MimeMessage(context.getSession(), ds.getInputStream());
- }
- else {
- return new MimeMessage(Session.getDefaultInstance(new Properties(), null), ds.getInputStream());
- }
- } catch (MessagingException e) {
- throw (IOException) new IOException(e.getMessage()).initCause(e);
- }
- }
-
- /**
- * Write an RFC 822 message object out to an output stream.
- *
- * @param obj The source message object.
- * @param mimeType The target mimetype
- * @param os The target output stream.
- *
- * @exception IOException
- */
- public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
- // we only handle message instances here
- if (obj instanceof Message) {
- Message message = (Message) obj;
- try {
- message.writeTo(os);
- } catch (MessagingException e) {
- throw (IOException) new IOException(e.getMessage()).initCause(e);
- }
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java
deleted file mode 100644
index 59a802e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.handlers;
-
-import javax.activation.ActivationDataFlavor;
-
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class TextHtmlHandler extends AbstractTextHandler {
- public TextHtmlHandler() {
- super(new ActivationDataFlavor(String.class, "text/html", "HTML Text"));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java
deleted file mode 100644
index c2c3b97..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.handlers;
-
-import javax.activation.ActivationDataFlavor;
-
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class TextPlainHandler extends AbstractTextHandler {
- public TextPlainHandler() {
- super(new ActivationDataFlavor(String.class, "text/plain", "Plain Text"));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java
deleted file mode 100644
index 2fdb9d3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.handlers;
-
-import javax.activation.ActivationDataFlavor;
-
-
-/**
- * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
- */
-public class TextXmlHandler extends AbstractTextHandler {
- public TextXmlHandler() {
- super(new ActivationDataFlavor(String.class, "text/xml", "XML Text"));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java
deleted file mode 100644
index ba9a179..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * 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;
-
-/**
- * A named access control list for IMAP resources.
- */
-public class ACL implements Cloneable {
- /**
- * The name of the resource this ACL applies to.
- */
- private String name;
- /**
- * The rights associated with this resource.
- */
- private Rights rights;
-
- /**
- * Create an ACL for a resource. The ACL will have an empty Rights set.
- *
- * @param name The name of the resource.
- */
- public ACL(String name) {
- this.name = name;
- this.rights = new Rights();
- }
-
- /**
- * Create a named ACL instance with an initial Rights set.
- *
- * @param name The name of the resouce this ACL applies to.
- * @param rights The Rights associated with this resource.
- */
- public ACL(String name, Rights rights) {
- this.name = name;
- this.rights = rights;
- }
-
- /**
- * Get the ACL name.
- *
- * @return The string name of the ACL.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Get the Rights associated with this ACL.
- *
- * @return The Rights set supported for this resource.
- */
- public Rights getRights() {
- return rights;
- }
-
- /**
- * Set a new set of Rights for this ACL instance.
- *
- * @param rights The new Rights set.
- */
- public void setRights(Rights rights) {
- this.rights = rights;
- }
-
-
- /**
- * Creates and returns a copy of this object.
- *
- * @return A cloned copy of this object. This is a deep
- * copy, given that a new Rights set is also created.
- * @exception CloneNotSupportedException
- */
- protected Object clone() throws CloneNotSupportedException {
- return new ACL(name, new Rights(rights));
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java
deleted file mode 100644
index 03fc82e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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;
-
-import javax.activation.DataHandler;
-
-import javax.mail.Flags;
-import javax.mail.MessagingException;
-import javax.mail.MethodNotSupportedException;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
-
-/**
- * A nested message attachement inside of another
- * IMAP message. This is a less-functional version
- * of the top-level message.
- */
-public class IMAPAttachedMessage extends IMAPMessage {
- // the parent enclosing message.
- protected IMAPMessage parent;
-
- /**
- * Constructor for an attached message part.
- *
- * @param parent The parent message (outer-most message).
- * @param section The section identifier for this embedded part
- * in IMAP section format. This will identify
- * the part hierarchy used to locate this part within
- * the message.
- * @param envelope The Envelope that describes this part.
- * @param bodyStructure
- * The Body structure element that describes this part.
- */
- public IMAPAttachedMessage(IMAPMessage parent, String section, IMAPEnvelope envelope, IMAPBodyStructure bodyStructure) {
- super((IMAPFolder)parent.getFolder(), parent.store, parent.getMessageNumber(), parent.sequenceNumber);
- this.parent = parent;
- // sets the subset we're looking for
- this.section = section;
- // the envelope and body structure are loaded from the server by the parent
- this.envelope = envelope;
- this.bodyStructure = bodyStructure;
- }
-
- /**
- * Check if this message is still valid. This is
- * delegated to the outer-most message.
- *
- * @exception MessagingException
- */
- protected void checkValidity() throws MessagingException {
- parent.checkValidity();
- }
-
- /**
- * Check if the outer-most message has been expunged.
- *
- * @return true if the message has been expunged.
- */
- public boolean isExpunged() {
- return parent.isExpunged();
- }
-
- /**
- * Get the size of this message part.
- *
- * @return The estimate size of this message part, in bytes.
- */
- public int getSize() {
- return bodyStructure.bodySize;
- }
-
-
- /**
- * Return a copy the flags associated with this message.
- *
- * @return a copy of the flags for this message
- * @throws MessagingException if there was a problem accessing the Store
- */
- public Flags getFlags() throws MessagingException {
- return parent.getFlags();
- }
-
-
- /**
- * Check whether the supplied flag is set.
- * The default implementation checks the flags returned by {@link #getFlags()}.
- *
- * @param flag the flags to check for
- * @return true if the flags is set
- * @throws MessagingException if there was a problem accessing the Store
- */
- public boolean isSet(Flags.Flag flag) throws MessagingException {
- // load the flags, if needed
- return parent.isSet(flag);
- }
-
- /**
- * Set or clear a flag value.
- *
- * @param flags The set of flags to effect.
- * @param set The value to set the flag to (true or false).
- *
- * @exception MessagingException
- */
- public void setFlags(Flags flag, boolean set) throws MessagingException {
- throw new MethodNotSupportedException("Flags cannot be set on message attachements");
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java
deleted file mode 100644
index 62b7fd7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java
+++ /dev/null
@@ -1,2393 +0,0 @@
-/**
- * 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;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-
-import javax.mail.*;
-import javax.mail.event.ConnectionEvent;
-import javax.mail.event.FolderEvent;
-import javax.mail.event.MessageChangedEvent;
-import javax.mail.search.FlagTerm;
-import javax.mail.search.SearchTerm;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPFlags;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPListResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPMailboxStatus;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPSizeResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponseHandler;
-
-/**
- * The base IMAP implementation of the javax.mail.Folder
- * This is a base class for both the Root IMAP server and each IMAP group folder.
- * @see javax.mail.Folder
- *
- * @version $Rev: 761642 $
- */
-public class IMAPFolder extends Folder implements UIDFolder, IMAPUntaggedResponseHandler {
-
- /**
- * Special profile item used for fetching SIZE and HEADER information.
- * These items are extensions that Sun has added to their IMAPFolder immplementation.
- * We're supporting the same set.
- */
- public static class FetchProfileItem extends FetchProfile.Item {
- public static final FetchProfileItem HEADERS = new FetchProfileItem("HEADERS");
- public static final FetchProfileItem SIZE = new FetchProfileItem("SIZE");
-
- protected FetchProfileItem(String name) {
- super(name);
- }
- }
-
- // marker that we don't know the separator yet for this folder.
- // This occurs when we obtain a folder reference from the
- // default folder. At that point, we've not queried the
- // server for specifics yet.
- static final protected char UNDETERMINED = 0;
-
- // our attached session
- protected Session session;
- // retrieved messages, mapped by sequence number.
- protected Map messageCache;
- // mappings of UIDs to retrieved messages.
- protected Map uidCache;
-
- // the separator the server indicates is used as the hierarchy separator
- protected char separator;
- // the "full" name of the folder. This is the fully qualified path name for the folder returned by
- // the IMAP server. Elements of the hierarchy are delimited by "separator" characters.
- protected String fullname;
- // the name of this folder. The is the last element of the fully qualified name.
- protected String name;
- // the folder open state
- protected boolean folderOpen = false;
- // the type information on what the folder can hold
- protected int folderType;
- // the subscription status
- protected boolean subscribed = false;
-
- // the message identifier ticker, used to assign message numbers.
- protected int nextMessageID = 1;
- // the current count of messages in our cache.
- protected int maxSequenceNumber = 0;
- // the reported count of new messages (updated as a result of untagged message resposes)
- protected int recentMessages = -1;
- // the reported count of unseen messages
- protected int unseenMessages = 0;
- // the uidValidity value reported back from the server
- protected long uidValidity = 0;
- // the uidNext value reported back from the server
- protected long uidNext = 0;
- // the persistent flags we save in the store
- protected Flags permanentFlags;
- // the settable flags the server reports back to us
- protected Flags availableFlags;
- // Our cached status information. We will only hold this for the timeout interval.
- protected IMAPMailboxStatus cachedStatus;
- // Folder information retrieved from the server. Good info here indicates the
- // folder exists.
- protected IMAPListResponse listInfo;
- // the configured status cache timeout value.
- protected long statusCacheTimeout;
- // the last time we took a status snap shot.
- protected long lastStatusTimeStamp;
- // Our current connection. We get one of these when opened, and release it when closed.
- // We do this because for any folder (and message) operations, the folder must be selected on
- // the connection.
- // Note, however, that there are operations which will require us to borrow a connection
- // temporarily because we need to touch the server when the folder is not open. In those
- // cases, we grab a connection, then immediately return it to the pool.
- protected IMAPConnection currentConnection;
-
-
-
- /**
- * Super class constructor the base IMAPFolder class.
- *
- * @param store The javamail store this folder is attached to.
- * @param fullname The fully qualified name of this folder.
- * @param separator The separtor character used to delimit the different
- * levels of the folder hierarchy. This is used to
- * decompose the full name into smaller parts and
- * create the names of subfolders.
- */
- protected IMAPFolder(IMAPStore store, String fullname, char separator) {
- super(store);
- this.session = store.getSession();
- this.fullname = fullname;
- this.separator = separator;
- // get the status timeout value from the folder.
- statusCacheTimeout = store.statusCacheTimeout;
- }
-
- /**
- * 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() {
- // At the time we create the folder, we might not know the separator character yet.
- // Because of this we need to delay creating the name element until
- // it's required.
- if (name == null) {
- // extract the name from the full name
- int lastLevel = -1;
- try {
- lastLevel = fullname.lastIndexOf(getSeparator());
- } catch (MessagingException e) {
- // not likely to occur, but the link could go down before we
- // get this. Just assume a failure to locate the character
- // occurred.
- }
- if (lastLevel == -1) {
- name = fullname;
- }
- else {
- name = fullname.substring(lastLevel + 1);
- }
- }
- return name;
- }
-
- /**
- * 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;
- }
-
-
-
- /**
- * Return the parent for this folder; if the folder is at the root of a heirarchy
- * this returns null.
- * This can be invoked when the folder is closed.
- *
- * @return this folder's parent
- * @throws MessagingException
- */
- public Folder getParent() throws MessagingException {
- // NB: We need to use the method form because the separator
- // might not have been retrieved from the server yet.
- char separator = getSeparator();
- // we don't hold a reference to the parent folder, as that would pin the instance in memory
- // as long as any any leaf item in the hierarchy is still open.
- int lastLevel = fullname.lastIndexOf(separator);
- // no parent folder? Get the root one from the Store.
- if (lastLevel == -1) {
- return ((IMAPStore)store).getDefaultFolder();
- }
- else {
- // create a folder for the parent.
- return new IMAPFolder((IMAPStore)store, fullname.substring(0, lastLevel), separator);
- }
- }
-
-
- /**
- * Check to see if this folder physically exists in the store.
- * This can be invoked when the folder is closed.
- *
- * @return true if the folder really exists
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized boolean exists() throws MessagingException {
- IMAPConnection connection = getConnection();
- try {
- return checkExistance(connection);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Internal routine for checking existance using an
- * already obtained connection. Used for situations
- * where the list information needs updating but
- * we'd end up acquiring a new connection because
- * the folder isn't open yet.
- *
- * @param connection The connection to use.
- *
- * @return true if the folder exists, false for non-existence.
- * @exception MessagingException
- */
- private boolean checkExistance(IMAPConnection connection) throws MessagingException {
- // get the list response for this folder.
- List responses = connection.list("", fullname);
- // NB, this grabs the latest information and updates
- // the type information also. Note also that we need to
- // use the mailbox name, not the full name. This is so
- // the namespace folders will return the correct response.
- listInfo = findListResponse(responses, getMailBoxName());
-
- if (listInfo == null) {
- return false;
- }
-
- // update the type information from the status.
- folderType = 0;
- if (!listInfo.noinferiors) {
- folderType |= HOLDS_FOLDERS;
- }
- if (!listInfo.noselect) {
- folderType |= HOLDS_MESSAGES;
- }
-
- // also update the separator information. This will allow
- // use to skip a call later
- separator = listInfo.separator;
- // this can be omitted in the response, so assume a default
- if (separator == '\0') {
- separator = '/';
- }
-
- // updated ok, so it must be there.
- return true;
- }
-
-
-
- /**
- * Return a list of folders from this Folder's namespace that match the supplied pattern.
- * Patterns may contain the following wildcards:
- * <ul><li>'%' which matches any characater except hierarchy delimiters</li>
- * <li>'*' which matches any character including hierarchy delimiters</li>
- * </ul>
- * This can be invoked when the folder is closed.
- *
- * @param pattern the pattern to search for
- *
- * @return a possibly empty array containing Folders that matched the pattern
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized Folder[] list(String pattern) throws MessagingException {
- // go filter the folders based on the pattern. The server does most of the
- // heavy lifting on the pattern matching.
- return filterFolders(pattern, false);
- }
-
-
- /**
- * Return a list of folders to which the user is subscribed and which match the supplied pattern.
- * If the store does not support the concept of subscription then this should match against
- * all folders; the default implementation of this method achieves this by defaulting to the
- * {@link #list(String)} method.
- *
- * @param pattern the pattern to search for
- *
- * @return a possibly empty array containing subscribed Folders that matched the pattern
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized Folder[] listSubscribed(String pattern) throws MessagingException {
- // go filter the folders based on the pattern. The server does most of the
- // heavy lifting on the pattern matching.
- return filterFolders(pattern, true);
- }
-
-
- /**
- * Return the character used by this folder's Store to separate path components.
- *
- * @return the name separater character
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized char getSeparator() throws MessagingException {
- // not determined yet, we need to ask the server for the information
- if (separator == UNDETERMINED) {
- IMAPConnection connection = getConnection();
- try {
- List responses = connection.list("", fullname);
- IMAPListResponse info = findListResponse(responses, fullname);
-
- // if we didn't get any hits, then we just assume a reasonable default.
- if (info == null) {
- separator = '/';
- }
- else {
- separator = info.separator;
- // this can be omitted in the response, so assume a default
- if (separator == '\0') {
- separator = '/';
- }
- }
- } finally {
- releaseConnection(connection);
- }
- }
- return separator;
- }
-
-
- /**
- * Return whether this folder can hold just messages or also
- * subfolders.
- *
- * @return The combination of Folder.HOLDS_MESSAGES and Folder.HOLDS_FOLDERS, depending
- * on the folder capabilities.
- * @exception MessagingException
- */
- public int getType() throws MessagingException {
- // checking the validity will update the type information
- // if it succeeds.
- checkFolderValidity();
- return folderType;
- }
-
-
- /**
- * Create a new folder capable of containing subfolder and/or messages as
- * determined by the type parameter. Any hierarchy defined by the folder
- * name will be recursively created.
- * If the folder was sucessfully created, a {@link FolderEvent#CREATED CREATED FolderEvent}
- * is sent to all FolderListeners registered with this Folder or with the Store.
- *
- * @param newType the type, indicating if this folder should contain subfolders, messages or both
- *
- * @return true if the folder was sucessfully created
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized boolean create(int newType) throws MessagingException {
- IMAPConnection connection = getConnection();
- try {
-
- // by default, just create using the fullname.
- String newPath = fullname;
-
- // if this folder is expected to only hold additional folders, we need to
- // add a separator on to the end when we create this.
- if ((newType & HOLDS_MESSAGES) == 0) {
- newPath = fullname + separator;
- }
- try {
- // go create this
- connection.createMailbox(newPath);
- // verify this exists...also updates some of the status
- boolean reallyCreated = checkExistance(connection);
- // broadcast a creation event.
- notifyFolderListeners(FolderEvent.CREATED);
- return reallyCreated;
- } catch (MessagingException e) {
- //TODO add folder level debug logging.
- }
- // we have a failure
- return false;
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * Return the subscription status of this folder.
- *
- * @return true if the folder is marked as subscribed, false for
- * unsubscribed.
- */
- public synchronized boolean isSubscribed() {
- try {
- IMAPConnection connection = getConnection();
- try {
- // get the lsub response for this folder.
- List responses = connection.listSubscribed("", fullname);
-
- IMAPListResponse response = findListResponse(responses, fullname);
- if (response == null) {
- return false;
- }
- else {
- // a NOSELECT flag response indicates the mailbox is no longer
- // selectable, so it's also no longer subscribed to.
- return !response.noselect;
- }
- } finally {
- releaseConnection(connection);
- }
- } catch (MessagingException e) {
- // Can't override to throw a MessagingException on this method, so
- // just swallow any exceptions and assume false is the answer.
- }
- return false;
- }
-
-
- /**
- * Set or clear the subscription status of a file.
- *
- * @param flag
- * The new subscription state.
- */
- public synchronized void setSubscribed(boolean flag) throws MessagingException {
- IMAPConnection connection = getConnection();
- try {
- if (flag) {
- connection.subscribe(fullname);
- }
- else {
- connection.unsubscribe(fullname);
- }
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Check to see if this Folder conatins messages with the {@link Flag.RECENT} flag set.
- * This can be used when the folder is closed to perform a light-weight check for new mail;
- * to perform an incremental check for new mail the folder must be opened.
- *
- * @return true if the Store has recent messages
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized boolean hasNewMessages() throws MessagingException {
- // the folder must exist for this to work.
- checkFolderValidity();
-
- // get the freshest status information.
- refreshStatus(true);
- // return the indicator from the message state.
- return recentMessages > 0;
- }
-
- /**
- * Get the Folder determined by the supplied name; if the name is relative
- * then it is interpreted relative to this folder. This does not check that
- * the named folder actually exists.
- *
- * @param name the name of the folder to return
- * @return the named folder
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder getFolder(String name) throws MessagingException {
- // this must be a real, valid folder to hold a subfolder
- checkFolderValidity();
- if (!holdsFolders()) {
- throw new MessagingException("Folder " + fullname + " cannot hold subfolders");
- }
- // our separator does not get determined until we ping the server for it. We
- // might need to do that now, so we need to use the getSeparator() method to retrieve this.
- char separator = getSeparator();
-
- return new IMAPFolder((IMAPStore)store, fullname + separator + name, separator);
- }
-
-
- /**
- * Delete this folder and possibly any subfolders. This operation can only be
- * performed on a closed folder.
- * If recurse is true, then all subfolders are deleted first, then any messages in
- * this folder are removed and it is finally deleted; {@link FolderEvent#DELETED}
- * events are sent as appropriate.
- * If recurse is false, then the behaviour depends on the folder type and store
- * implementation as followd:
- * <ul>
- * <li>If the folder can only conrain messages, then all messages are removed and
- * then the folder is deleted; a {@link FolderEvent#DELETED} event is sent.</li>
- * <li>If the folder can onlu contain subfolders, then if it is empty it will be
- * deleted and a {@link FolderEvent#DELETED} event is sent; if the folder is not
- * empty then the delete fails and this method returns false.</li>
- * <li>If the folder can contain both subfolders and messages, then if the folder
- * does not contain any subfolders, any messages are deleted, the folder itself
- * is deleted and a {@link FolderEvent#DELETED} event is sent; if the folder does
- * contain subfolders then the implementation may choose from the following three
- * behaviors:
- * <ol>
- * <li>it may return false indicting the operation failed</li>
- * <li>it may remove all messages within the folder, send a {@link FolderEvent#DELETED}
- * event, and then return true to indicate the delete was performed. Note this does
- * not delete the folder itself and the {@link #exists()} operation for this folder
- * will return true</li>
- * <li>it may remove all messages within the folder as per the previous option; in
- * addition it may change the type of the Folder to only HOLDS_FOLDERS indictaing
- * that messages may no longer be added</li>
- * </li>
- * </ul>
- * FolderEvents are sent to all listeners registered with this folder or
- * with the Store.
- *
- * @param recurse whether subfolders should be recursively deleted as well
- * @return true if the delete operation succeeds
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized boolean delete(boolean recurse) throws MessagingException {
- // we must be in the closed state.
- checkClosed();
-
- // if recursive, get the list of subfolders and delete them first.
- if (recurse) {
-
- Folder[] subfolders = list();
- for (int i = 0; i < subfolders.length; i++) {
- // this is a recursive delete also
- subfolders[i].delete(true);
- }
- }
-
- IMAPConnection connection = getConnection();
- try {
- // delete this one now.
- connection.deleteMailbox(fullname);
- // this folder no longer exists on the server.
- listInfo = null;
-
- // notify interested parties about the deletion.
- notifyFolderListeners(FolderEvent.DELETED);
- return true;
-
- } catch (MessagingException e) {
- // ignored
- } finally {
- releaseConnection(connection);
- }
- return false;
- }
-
-
- /**
- * Rename this folder; the folder must be closed.
- * If the rename is successfull, a {@link FolderEvent#RENAMED} event is sent to
- * all listeners registered with this folder or with the store.
- *
- * @param newName the new name for this folder
- * @return true if the rename succeeded
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized boolean renameTo(Folder f) throws MessagingException {
- // we must be in the closed state.
- checkClosed();
- // but we must also exist
- checkFolderValidity();
-
- IMAPConnection connection = getConnection();
- try {
- // delete this one now.
- connection.renameMailbox(fullname, f.getFullName());
- // we renamed, so get a fresh set of status
- refreshStatus(false);
-
- // notify interested parties about the deletion.
- notifyFolderRenamedListeners(f);
- return true;
- } catch (MessagingException e) {
- // ignored
- } finally {
- releaseConnection(connection);
- }
- return false;
- }
-
-
- /**
- * Open this folder; the folder must be able to contain messages and
- * must currently be closed. If the folder is opened successfully then
- * a {@link ConnectionEvent#OPENED} event is sent to listeners registered
- * with this Folder.
- * <p/>
- * Whether the Store allows multiple connections or if it allows multiple
- * writers is implementation defined.
- *
- * @param mode READ_ONLY or READ_WRITE
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized void open(int mode) throws MessagingException {
-
- // we use a synchronized block rather than use a synchronized method so that we
- // can notify the event listeners while not holding the lock.
- synchronized(this) {
- // can only be performed on a closed folder
- checkClosed();
- // ask the store to kindly hook us up with a connection.
- // We're going to hang on to this until we're closed, so store it in
- // the Folder field. We need to make sure our mailbox is selected while
- // we're working things.
- currentConnection = ((IMAPStore)store).getFolderConnection(this);
- // we need to make ourselves a handler of unsolicited responses
- currentConnection.addResponseHandler(this);
- // record our open mode
- this.mode = mode;
-
-
- try {
- // try to open, which gives us a lot of initial mailbox state.
- IMAPMailboxStatus status = currentConnection.openMailbox(fullname, mode == Folder.READ_ONLY);
-
- // not available in the requested mode?
- if (status.mode != mode) {
- // trying to open READ_WRITE and this isn't available?
- if (mode == READ_WRITE) {
- throw new ReadOnlyFolderException(this, "Cannot open READ_ONLY folder in READ_WRITE mode");
- }
- }
-
- // save this status and when we got it for later updating.
- cachedStatus = status;
- // mark when we got this
- lastStatusTimeStamp = System.currentTimeMillis();
-
- // now copy the status information over and flip over the open sign.
- this.mode = status.mode;
- maxSequenceNumber = status.messages;
- recentMessages = status.recentMessages;
- uidValidity = status.uidValidity;
- uidNext = status.uidNext;
-
- availableFlags = status.availableFlags;
- permanentFlags = status.permanentFlags;
-
- // create a our caches. These are empty initially
- messageCache = new HashMap();
- uidCache = new HashMap();
-
- // we're open for business folks!
- folderOpen = true;
- notifyConnectionListeners(ConnectionEvent.OPENED);
- } finally {
- // NB: this doesn't really release this, but it does drive
- // the processing of any unsolicited responses.
- releaseConnection(currentConnection);
- }
- }
- }
-
-
- /**
- * Close this folder; it must already be open.
- * A @link ConnectionEvent#CLOSED} event is sent to all listeners registered
- {*
- * with this folder.
- *
- * @param expunge whether to expunge all deleted messages
- * @throws MessagingException if there was a problem accessing the store; the folder is still closed
- */
- public synchronized void close(boolean expunge) throws MessagingException {
- // Can only be performed on an open folder
- checkOpen();
- cleanupFolder(expunge, false);
- }
-
-
- /**
- * 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 expunge, boolean disconnected) throws MessagingException {
- folderOpen = false;
- uidCache = null;
- messageCache = null;
- // if we have a connection active at the moment
- if (currentConnection != null) {
- // was this a forced disconnect by the server?
- if (disconnected) {
- currentConnection.setClosed();
- }
- else {
- // The CLOSE operation depends on what mode was used to select the mailbox.
- // If we're open in READ-WRITE mode, we used a SELECT operation. When CLOSE
- // is issued, any deleted messages will be expunged. If we've been asked not
- // to expunge the messages, we have a problem. The solution is to reselect the
- // mailbox using EXAMINE, which will not expunge messages when closed.
- if (mode == READ_WRITE && !expunge) {
- // we can ignore the result...we're just switching modes.
- currentConnection.openMailbox(fullname, true);
- }
-
- // have this close the selected mailbox
- currentConnection.closeMailbox();
- }
- currentConnection.removeResponseHandler(this);
- // we need to release the connection to the Store once we're closed
- ((IMAPStore)store).releaseFolderConnection(this, currentConnection);
- currentConnection = null;
- }
- 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 synchronized Flags getPermanentFlags() {
- if (permanentFlags != null) {
- // we need a copy of our master set.
- return new Flags(permanentFlags);
- }
- else {
- // a null return is expected if not there.
- return null;
- }
- }
-
-
- /**
- * Return the number of messages this folder contains.
- * If this operation is invoked on a closed folder, the implementation
- * may choose to return -1 to avoid the expense of opening the folder.
- *
- * @return the number of messages, or -1 if unknown
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized int getMessageCount() throws MessagingException {
- checkFolderValidity();
-
- // if we haven't opened the folder yet, we might not have good status information.
- // go request some, which updates the folder fields also.
- refreshStatus(false);
- return maxSequenceNumber;
- }
-
- /**
- * Return the numbew of messages in this folder that have the {@link Flag.RECENT} flag set.
- * If this operation is invoked on a closed folder, the implementation
- * may choose to return -1 to avoid the expense of opening the folder.
- * The default implmentation of this method iterates over all messages
- * in the folder; subclasses should override if possible to provide a more
- * efficient implementation.
- *
- * NB: This is an override of the default Folder implementation, which
- * examines each of the messages in the folder. IMAP has more efficient
- * mechanisms for grabbing the information.
- *
- * @return the number of new messages, or -1 if unknown
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized int getNewMessageCount() throws MessagingException {
- // the folder must be a real one for this to work.
- checkFolderValidity();
- // now get current status from the folder
- refreshStatus(false);
- // this should be current now.
- return recentMessages;
- }
-
-
-
- /**
- * Return the number of messages in this folder that do not have the {@link Flag.SEEN} flag set.
- * If this operation is invoked on a closed folder, the implementation
- * may choose to return -1 to avoid the expense of opening the folder.
- * The default implmentation of this method iterates over all messages
- * in the folder; subclasses should override if possible to provide a more
- * efficient implementation.
- *
- * NB: This is an override of the default Folder implementation, which
- * examines each of the messages in the folder. IMAP has more efficient
- * mechanisms for grabbing the information.
- *
- * @return the number of new messages, or -1 if unknown
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized int getUnreadMessageCount() throws MessagingException {
- checkFolderValidity();
- // if we haven't opened the folder yet, we might not have good status information.
- // go request some, which updates the folder fields also.
- if (!folderOpen) {
- refreshStatus(false);
- }
- else {
- // if we have an open connection, then search the folder for any messages
- // marked UNSEEN.
-
- // UNSEEN is a false test on SEEN using the search criteria.
- SearchTerm criteria = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
- try {
- // search using the connection directly rather than calling our search() method so we don't
- // need to instantiate each of the matched messages. We're really only interested in the count
- // right now.
- int[] matches = connection.searchMailbox(criteria);
- // update the unseen count.
- unseenMessages = matches == null ? 0 : matches.length;
- } finally {
- releaseConnection(connection);
- }
- }
- // return our current message count.
- return unseenMessages;
- }
-
-
-
- /**
- * Return the number of messages in this folder that have the {@link Flag.DELETED} flag set.
- * If this operation is invoked on a closed folder, the implementation
- * may choose to return -1 to avoid the expense of opening the folder.
- * The default implmentation of this method iterates over all messages
- * in the folder; subclasses should override if possible to provide a more
- * efficient implementation.
- *
- * @return the number of new messages, or -1 if unknown
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized int getDeletedMessageCount() throws MessagingException {
- checkFolderValidity();
-
- // if we haven't opened the folder yet, we might not have good status information.
- // go request some, which updates the folder fields also.
- if (!folderOpen) {
- // the status update doesn't return deleted messages. These can only be obtained by
- // searching an open folder. Just return a bail-out response
- return -1;
- }
- else {
- // if we have an open connection, then search the folder for any messages
- // marked DELETED.
-
- // UNSEEN is a false test on SEEN using the search criteria.
- SearchTerm criteria = new FlagTerm(new Flags(Flags.Flag.DELETED), true);
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
- try {
- // search using the connection directly rather than calling our search() method so we don't
- // need to instantiate each of the matched messages. We're really only interested in the count
- // right now.
- int[] matches = connection.searchMailbox(criteria);
- return matches == null ? 0 : matches.length;
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Retrieve the message with the specified index in this Folder;
- * messages indices start at 1 not zero.
- * Clients should note that the index for a specific message may change
- * if the folder is expunged; {@link Message} objects should be used as
- * references instead.
- *
- * @param msgNum The message sequence number of the target message.
- *
- * @return the message
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized Message getMessage(int msgNum) throws MessagingException {
- // Can only be performed on an Open folder
- checkOpen();
- // Check the validity of the message number. This may require pinging the server to
- // see if there are new messages in the folder.
- checkMessageValidity(msgNum);
- // create the mapping key for this
- Integer messageKey = new Integer(msgNum);
- // ok, if the message number is within range, we should have this in the
- // messages list. Just return the element.
- Message message = (Message)messageCache.get(messageKey);
- // if not in the cache, create a dummy add it in. The message body will be
- // retrieved on demand
- if (message == null) {
- message = new IMAPMessage(this, ((IMAPStore)store), nextMessageID++, msgNum);
- messageCache.put(messageKey, message);
- }
- return message;
- }
-
-
- /**
- * Retrieve a range of messages for this folder.
- * messages indices start at 1 not zero.
- *
- * @param start Index of the first message to fetch, inclusive.
- * @param end Index of the last message to fetch, inclusive.
- *
- * @return An array of the fetched messages.
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized Message[] getMessages(int start, int end) throws MessagingException {
- // Can only be performed on an Open folder
- checkOpen();
- Message[] messageRange = new Message[end - start + 1];
-
- for (int i = 0; i < messageRange.length; i++) {
- // NB: getMessage() requires values that are origin 1, so there's
- // no need to adjust the value by other than the start position.
- messageRange[i] = getMessage(start + i);
- }
- return messageRange;
- }
-
-
- /**
- * Append the supplied messages to this folder. A {@link MessageCountEvent} is sent
- * to all listeners registered with this folder when all messages have been appended.
- * If the array contains a previously expunged message, it must be re-appended to the Store
- * and implementations must not abort this operation.
- *
- * @param msgs The array of messages to append to the folder.
- *
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized void appendMessages(Message[] msgs) throws MessagingException {
- checkFolderValidity();
- for (int i = 0; i < msgs.length; i++) {
- Message msg = msgs[i];
-
- appendMessage(msg);
- }
- }
-
- /**
- * Hint to the store to prefetch information on the supplied messages.
- * Subclasses should override this method to provide an efficient implementation;
- * the default implementation in this class simply returns.
- *
- * @param messages messages for which information should be fetched
- * @param profile the information to fetch
- * @throws MessagingException if there was a problem accessing the store
- * @see FetchProfile
- */
- public void fetch(Message[] messages, FetchProfile profile) throws MessagingException {
-
- // we might already have the information being requested, so ask each of the
- // messages in the list to evaluate itself against the profile. We'll only ask
- // the server to send information that's required.
- List fetchSet = new ArrayList();
-
- for (int i = 0; i < messages.length; i++) {
- Message msg = messages[i];
- // the message is missing some of the information still. Keep this in the list.
- // even if the message is only missing one piece of information, we still fetch everything.
- if (((IMAPMessage)msg).evaluateFetch(profile)) {
- fetchSet.add(msg);
- }
- }
-
- // we've got everything already, no sense bothering the server
- if (fetchSet.isEmpty()) {
- return;
- }
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
- try {
- // ok, from this point onward, we don't want any threads messing with the
- // message cache. A single processed EXPUNGE could make for a very bad day
- synchronized(this) {
- // get the message set for this
- String messageSet = generateMessageSet(fetchSet);
- // fetch all of the responses
- List responses = connection.fetch(messageSet, profile);
-
- // IMPORTANT: We must do our updates while synchronized to keep the
- // cache from getting updated underneath us. This includes
- // not releasing the connection until we're done to delay processing any
- // pending expunge responses.
- for (int i = 0; i < responses.size(); i++) {
- IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
- Message msg = getMessage(response.getSequenceNumber());
- // Belt and Braces. This should never be false.
- if (msg != null) {
- // have the message apply this to itself.
- ((IMAPMessage)msg).updateMessageInformation(response);
- }
- }
- }
- } finally {
- releaseConnection(connection);
- }
- return;
- }
-
- /**
- * Set flags on the messages to the supplied value; all messages must belong to this folder.
- * This method may be overridden by subclasses that can optimize the setting
- * of flags on multiple messages at once; the default implementation simply calls
- * {@link Message#setFlags(Flags, boolean)} for each supplied messages.
- *
- * @param messages whose flags should be set
- * @param flags the set of flags to modify
- * @param set Indicates whether the flags should be set or cleared.
- *
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public void setFlags(Message[] messages, Flags flags, boolean set) throws MessagingException {
- // this is a list of messages for the change broadcast after the update
- List updatedMessages = new ArrayList();
-
- synchronized(this) {
- // the folder must be open and writeable.
- checkOpenReadWrite();
-
- // now make sure these are settable flags.
- if (!availableFlags.contains(flags))
- {
- throw new MessagingException("The IMAP server does not support changing of this flag set");
- }
-
- // turn this into a set of message numbers
- String messageSet = generateMessageSet(messages);
- // if all of the messages have been expunged, nothing to do.
- if (messageSet == null) {
- return;
- }
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // and have the connection set this
- List responses = connection.setFlags(messageSet, flags, set);
- // retrieve each of the messages from our cache, and do the flag update.
- // we need to keep the list so we can broadcast a change update event
- // when we're finished.
- for (int i = 0; i < responses.size(); i++) {
- IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
-
- // get the updated message and update the internal state.
- Message message = getMessage(response.sequenceNumber);
- // this shouldn't happen, but it might have been expunged too.
- if (message != null) {
- ((IMAPMessage)message).updateMessageInformation(response);
- updatedMessages.add(message);
- }
- }
- } finally {
- releaseConnection(connection);
- }
- }
-
- // ok, we're no longer holding the lock. Now go broadcast the update for each
- // of the affected messages.
- for (int i = 0; i < updatedMessages.size(); i++) {
- Message message = (Message)updatedMessages.get(i);
- notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, message);
- }
- }
-
-
- /**
- * Set flags on a range of messages to the supplied value.
- * This method may be overridden by subclasses that can optimize the setting
- * of flags on multiple messages at once; the default implementation simply
- * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
- *
- * @param start first message end set
- * @param end last message end set
- * @param flags the set of flags end modify
- * @param value Indicates whether the flags should be set or cleared.
- *
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized void setFlags(int start, int end, Flags flags, boolean value) throws MessagingException {
- Message[] msgs = new Message[end - start + 1];
-
- for (int i = start; i <= end; i++) {
- msgs[i] = getMessage(i);
- }
- // go do a bulk set operation on these messages
- setFlags(msgs, flags, value);
- }
-
- /**
- * Set flags on a set of messages to the supplied value.
- * This method may be overridden by subclasses that can optimize the setting
- * of flags on multiple messages at once; the default implementation simply
- * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
- *
- * @param ids the indexes of the messages to set
- * @param flags the set of flags end modify
- * @param value Indicates whether the flags should be set or cleared.
- *
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public synchronized void setFlags(int ids[], Flags flags, boolean value) throws MessagingException {
- Message[] msgs = new Message[ids.length];
-
- for (int i = 0; i <ids.length; i++) {
- msgs[i] = getMessage(ids[i]);
- }
- // go do a bulk set operation on these messages
- setFlags(msgs, flags, value);
- }
-
-
- /**
- * Copy the specified messages to another folder.
- * The default implementation simply appends the supplied messages to the
- * target folder using {@link #appendMessages(Message[])}.
- * @param messages the messages to copy
- * @param folder the folder to copy to
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized void copyMessages(Message[] messages, Folder folder) throws MessagingException {
- // the default implementation just appends the messages to the target. If
- // we're copying between two folders of the same store, we can get the server to
- // do most of the work for us without needing to fetch all of the message data.
- // If we're dealing with two different Store instances, we need to do this the
- // hardway.
- if (getStore() != folder.getStore()) {
- super.copyMessages(messages, folder);
- return;
- }
-
- // turn this into a set of message numbers
- String messageSet = generateMessageSet(messages);
- // if all of the messages have been expunged, nothing to do.
- if (messageSet == null) {
- return;
- }
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // ask the server to copy this information over to the other mailbox.
- connection.copyMessages(messageSet, folder.getFullName());
- } finally {
- releaseConnection(connection);
- }
- }
-
-
-
- /**
- * Permanently delete all supplied messages that have the DELETED flag set from the Store.
- * The original message indices of all messages actually deleted are returned and a
- * {@link MessageCountEvent} event is sent to all listeners with this folder. The expunge
- * may cause the indices of all messaged that remain in the folder to change.
- *
- * @return the original indices of messages that were actually deleted
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized Message[] expunge() throws MessagingException {
- // must be open to do this.
- checkOpen();
- // and changes need to be allowed
- checkReadWrite();
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
- List expunges = null;
-
- try {
- // send the expunge notification. This operation results in "nn EXPUNGE" responses getting returned
- // for each expunged messages. These will be dispatched to our response handler, which will process
- // the expunge operation. We could process this directly, but we may have received asynchronous
- // expunge messages that also marked messages as expunged.
- expunges = connection.expungeMailbox();
- } finally {
- releaseConnection(connection);
- }
-
- // we get one EXPUNGE message for each message that's expunged. They MUST be processed in
- // order, as the message sequence numbers represent a relative position that takes into account
- // previous expunge operations. For example, if message sequence numbers 5, 6, and 7 are
- // expunged, we receive 3 expunge messages, all indicating that message 5 has been expunged.
- Message[] messages = new Message[expunges.size()];
-
- // now we need to protect the internal structures
- synchronized (this) {
- // expunge all of the messages from the message cache. This keeps the sequence
- // numbers up to-date.
- for (int i = 0; i < expunges.size(); i++) {
- IMAPSizeResponse response = (IMAPSizeResponse)expunges.get(i);
- messages[i] = expungeMessage(response.getSize());
- }
- }
- // if we have messages that have been removed, broadcast the notification.
- if (messages.length > 0) {
- notifyMessageRemovedListeners(true, messages);
- }
-
- // note, we're expected to return an array in all cases, even if the expunged count was zero.
- return messages;
- }
-
-
-
- /**
- * Search the supplied messages for those that match the supplied criteria;
- * messages must belong to this folder.
- * The default implementation iterates through the messages, returning those
- * whose {@link Message#match(javax.mail.search.SearchTerm)} method returns true;
- * subclasses may provide a more efficient implementation.
- *
- * @param term the search criteria
- * @param messages the messages to search
- * @return an array containing messages that match the criteria
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized Message[] search(SearchTerm term) throws MessagingException {
- // only allowed on open folders
- checkOpen();
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // just search everything
- int[] messageNumbers = connection.searchMailbox(term);
- return resolveMessages(messageNumbers);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
-
- /**
- * Search the supplied messages for those that match the supplied criteria;
- * messages must belong to this folder.
- * The default implementation iterates through the messages, returning those
- * whose {@link Message#match(javax.mail.search.SearchTerm)} method returns true;
- * subclasses may provide a more efficient implementation.
- *
- * @param term the search criteria
- * @param messages the messages to search
- * @return an array containing messages that match the criteria
- * @throws MessagingException if there was a problem accessing the store
- */
- public synchronized Message[] search(SearchTerm term, Message[] messages) throws MessagingException {
- // only allowed on open folders
- checkOpen();
-
- // turn this into a string specifier for these messages. We'll weed out the expunged messages first.
- String messageSet = generateMessageSet(messages);
-
- // If we have no "live" messages to search, just return now. We're required to return a non-null
- // value, so give an empy array back.
- if (messageSet == null) {
- return new Message[0];
- }
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
-
- // now go do the search.
- int[] messageNumbers = connection.searchMailbox(messageSet, term);
- return resolveMessages(messageNumbers);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Get the UID validity value for this Folder.
- *
- * @return The current UID validity value, as a long.
- * @exception MessagingException
- */
- public synchronized long getUIDValidity() throws MessagingException
- {
- // get the latest status to make sure we have the
- // most current.
- refreshStatus(true);
- return uidValidity;
- }
-
- /**
- * Retrieve a message using the UID rather than the
- * message sequence number. Returns null if the message
- * doesn't exist.
- *
- * @param uid The target UID.
- *
- * @return the Message object. Returns null if the message does
- * not exist.
- * @exception MessagingException
- */
- public synchronized Message getMessageByUID(long uid) throws MessagingException
- {
- // only allowed on open folders
- checkOpen();
-
- Long key = new Long(uid);
- // first check to see if we have a cached value for this
- synchronized(messageCache) {
- Message msg = (Message)uidCache.get(key);
- if (msg != null) {
- return msg;
- }
- }
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // locate the message identifier
- IMAPUid imapuid = connection.getSequenceNumberForUid(uid);
- // if nothing is returned, the message doesn't exist
- if (imapuid == null) {
- return null;
- }
-
-
- // retrieve the actual message object and place this in the UID cache
- return retrieveMessageByUid(key, imapuid.messageNumber);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Get a series of messages using a UID range. The
- * special value LASTUID can be used to mark the
- * last available message.
- *
- * @param start The start of the UID range.
- * @param end The end of the UID range. The special value
- * LASTUID can be used to request all messages up
- * to the last UID.
- *
- * @return An array containing all of the messages in the
- * range.
- * @exception MessagingException
- */
- public synchronized Message[] getMessagesByUID(long start, long end) throws MessagingException
- {
- // only allowed on open folders
- checkOpen();
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // locate the message identifier
- List uids = connection.getSequenceNumbersForUids(start, end);
- Message[] msgs = new Message[uids.size()];
-
- // fill in each of the messages based on the returned value
- for (int i = 0; i < msgs.length; i++) {
- IMAPUid uid = (IMAPUid)uids.get(i);
- msgs[i] = retrieveMessageByUid(new Long(uid.uid), uid.messageNumber);
- }
-
- return msgs;
- } finally {
- releaseConnection(connection);
- }
-
-
- }
-
- /**
- * Retrieve a set of messages by explicit UIDs. If
- * any message in the list does not exist, null
- * will be returned for the corresponding item.
- *
- * @param ids An array of UID values to be retrieved.
- *
- * @return An array of Message items the same size as the ids
- * argument array. This array will contain null
- * entries for any UIDs that do not exist.
- * @exception MessagingException
- */
- public synchronized Message[] getMessagesByUID(long[] ids) throws MessagingException
- {
- // only allowed on open folders
- checkOpen();
-
- Message[] msgs = new Message[ids.length];
-
- for (int i = 0; i < msgs.length; i++) {
- msgs[i] = getMessageByUID(ids[i]);
- }
-
- return msgs;
- }
-
- /**
- * Retrieve the UID for a message from this Folder.
- * The argument Message MUST belong to this Folder
- * instance, otherwise a NoSuchElementException will
- * be thrown.
- *
- * @param message The target message.
- *
- * @return The UID associated with this message.
- * @exception MessagingException
- */
- public synchronized long getUID(Message message) throws MessagingException
- {
- // verify this actually is in this folder.
- checkMessageFolder(message);
- IMAPMessage msg = (IMAPMessage)message;
-
- // we might already know this bit of information
- if (msg.getUID() != -1) {
- return msg.getUID();
- }
-
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // locate the message identifier
- IMAPUid imapuid = connection.getUidForSequenceNumber(msg.getMessageNumber());
- // if nothing is returned, the message doesn't exist
- if (imapuid == null) {
- return -1;
- }
- // cache this information now that we've gotten it.
- addToUidCache(new Long(imapuid.uid), getMessage(imapuid.messageNumber));
- // return the UID information.
- return imapuid.uid;
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Retrieve a message from a UID/message mapping.
- *
- * @param key The UID key used for the mapping.
- * @param msgNumber The message sequence number.
- *
- * @return The Message object corresponding to the message.
- * @exception MessagingException
- */
- protected synchronized Message retrieveMessageByUid(Long key, int msgNumber) throws MessagingException
- {
- synchronized (messageCache) {
- // first check the cache...this might have already been added.
- Message msg = (Message)uidCache.get(key);
- if (msg != null) {
- return msg;
- }
-
- // retrieve the message by sequence number
- msg = getMessage(msgNumber);
- // add this to our UID mapping cache.
- addToUidCache(key, msg);
- return msg;
- }
- }
-
-
- /**
- * Add a message to the UID mapping cache, ensuring that
- * the UID value is updated.
- *
- * @param key The UID key.
- * @param msg The message to add.
- */
- protected void addToUidCache(Long key, Message msg) {
- synchronized (messageCache) {
- ((IMAPMessage)msg).setUID(key.longValue());
- uidCache.put(key, msg);
- }
- }
-
-
- /**
- * Append a single message to the IMAP Folder.
- *
- * @param msg The message to append.
- *
- * @exception MessagingException
- */
- protected synchronized void appendMessage(Message msg) throws MessagingException
- {
- // sort out the dates. If no received date, use the sent date.
- Date date = msg.getReceivedDate();
- if (date == null) {
- date = msg.getSentDate();
- }
-
- Flags flags = msg.getFlags();
-
- // convert the message into an array of bytes we can attach as a literal.
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- try {
- msg.writeTo(out);
- } catch (IOException e) {
- }
-
- // now issue the append command
- IMAPConnection connection = getConnection();
- try {
- connection.appendMessage(getFullName(), date, flags, out.toByteArray());
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * Retrieve the list of matching groups from the IMAP server using the LIST
- * or LSUB 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 synchronized Folder[] filterFolders(String pattern, boolean subscribed) throws MessagingException {
- IMAPConnection connection = getConnection();
- // this is used to filter out our own folder from the search
- String root = fullname + getSeparator();
-
- List responses = null;
- try {
-
-
- if (subscribed) {
- // get the lsub response for this folder.
- responses = connection.listSubscribed(root, pattern);
- }
- else {
- // grab using the LIST command.
- responses = connection.list(root, pattern);
- }
- } finally {
- releaseConnection(connection);
- }
-
- List folders = new ArrayList();
-
- for (int i = 0; i < responses.size(); i++) {
- IMAPListResponse response = (IMAPListResponse)responses.get(i);
- // if a full wildcard is specified, the root folder can be returned too. Make sure we
- // filter that one out.
- if (!response.mailboxName.equals(root)) {
- IMAPFolder folder = new IMAPFolder((IMAPStore)store, response.mailboxName, response.separator);
- folders.add(folder);
- }
- }
-
- // convert into an array and return
- return (Folder[])folders.toArray(new Folder[folders.size()]);
- }
-
-
- /**
- * Test if a folder can hold sub folders.
- *
- * @return True if the folder is allowed to have subfolders.
- */
- protected synchronized boolean holdsFolders() throws MessagingException {
- checkFolderValidity();
- return (folderType & HOLDS_FOLDERS) != 0;
- }
-
-
- /**
- * Validate that a target message number is considered valid
- * by the IMAP server. If outside of the range we currently
- * are a ware of, we'll ping the IMAP server to see if there
- * have been any updates.
- *
- * @param messageNumber
- * The message number we're checking.
- *
- * @exception MessagingException
- */
- protected void checkMessageValidity(int messageNumber) throws MessagingException {
- // lower range for a message is 1.
- if (messageNumber < 1) {
- throw new MessagingException("Invalid message number for IMAP folder: " + messageNumber);
- }
- // if within our current known range, we'll accept this
- if (messageNumber <= maxSequenceNumber) {
- return;
- }
-
- IMAPConnection connection = getConnection();
-
- synchronized (this) {
- try {
- // ping the server to see if there's any updates to process. The updates are handled
- // by the response handlers.
- connection.updateMailboxStatus();
- } finally {
- releaseConnection(connection);
- }
- }
-
- // still out of range?
- if (messageNumber > maxSequenceNumber) {
- throw new MessagingException("Message " + messageNumber + " does not exist on server");
- }
- }
-
-
- /**
- * Below is a list of convenience methods that avoid repeated checking for a
- * value and throwing an exception
- */
-
- /**
- * Ensure the folder is open. Throws a MessagingException
- * if not in the correct state for the operation.
- *
- * @exception IllegalStateException
- */
- protected void checkOpen() throws IllegalStateException {
- if (!folderOpen){
- throw new IllegalStateException("Folder is not Open");
- }
- }
-
- /**
- * Ensure the folder is not open for operations
- * that require the folder to be closed.
- *
- * @exception IllegalStateException
- */
- protected void checkClosed() throws IllegalStateException {
- if (folderOpen){
- throw new IllegalStateException("Folder is Open");
- }
- }
-
- /**
- * Ensure that the folder is open for read/write mode before doing
- * an operation that would make a change.
- *
- * @exception IllegalStateException
- */
- protected void checkReadWrite() throws IllegalStateException {
- if (mode != READ_WRITE) {
- throw new IllegalStateException("Folder is opened READY_ONLY");
- }
- }
-
-
- /**
- * Check that the folder is open and in read/write mode.
- *
- * @exception IllegalStateException
- */
- protected void checkOpenReadWrite() throws IllegalStateException {
- checkOpen();
- checkReadWrite();
- }
-
-
-
- /**
- * Notify the message changed listeners that a
- * message contained in the folder has been updated.
- *
- * @param type The type of update made to the message.
- * @param m The message that was updated.
- *
- * @see javax.mail.Folder#notifyMessageChangedListeners(int, javax.mail.Message)
- */
- 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 IMAPConnection getConnection() throws MessagingException {
- // don't have an open connection yet? Just request a pool connection.
- if (currentConnection == null) {
- // request a connection from the central store.
- IMAPConnection connection = ((IMAPStore)store).getFolderConnection(this);
- // we need to make ourselves a handler of unsolicited responses
- connection.addResponseHandler(this);
- return connection;
- }
- // we have a connection for our use. Just return it.
- return currentConnection;
- }
-
-
- /**
- * Release our connection back to the Store.
- *
- * @param connection The connection to release.
- *
- * @exception MessagingException
- */
- protected void releaseConnection(IMAPConnection connection) throws MessagingException {
- // This is a bit of a pain. We need to delay processing of the
- // unsolicited responses until after each user of the connection has
- // finished processing the expected responses. We need to do this because
- // the unsolicited responses may include EXPUNGED messages. The EXPUNGED
- // messages will alter the message sequence numbers for the messages in the
- // cache. Processing the EXPUNGED messages too early will result in
- // updates getting applied to the wrong message instances. So, as a result,
- // we delay that stage of the processing until all expected responses have
- // been handled.
-
- // process any pending messages before returning.
- connection.processPendingResponses();
- // if no cached connection or this is somehow different from the cached one, just
- // return it.
- if (currentConnection == null || connection != currentConnection) {
- connection.removeResponseHandler(this);
- ((IMAPStore)store).releaseFolderConnection(this, connection);
- }
- // if we're open, then we don't have to worry about returning this connection
- // to the Store. This is set up perfectly for our use right now.
- }
-
-
- /**
- * 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 IMAPConnection getMessageConnection() throws MessagingException {
- // if we're not open, the messages can't communicate either
- if (currentConnection == null) {
- throw new FolderClosedException(this, "No Folder connections available");
- }
- // return the current Folder connection. At this point, we'll be sharing the
- // connection between the Folder and the Message (and potentially, other messages). The
- // command operations on the connection are synchronized so only a single command can be
- // issued at one time.
- return currentConnection;
- }
-
-
- /**
- * Release the connection object back to the Folder instance.
- *
- * @param connection The connection being released.
- *
- * @exception MessagingException
- */
- void releaseMessageConnection(IMAPConnection connection) throws MessagingException {
- // release it back to ourselves...this will drive unsolicited message processing.
- releaseConnection(connection);
- }
-
-
- /**
- * Refresh the status information on this folder.
- *
- * @param force Force a status refresh always.
- *
- * @exception MessagingException
- */
- protected void refreshStatus(boolean force) throws MessagingException {
- // first check that any cached status we've received has gotten a little moldy.
- if (cachedStatus != null) {
- // if not forcing, check the time out.
- if (!force) {
- if (statusCacheTimeout > 0) {
- long age = System.currentTimeMillis() - lastStatusTimeStamp;
- if (age < statusCacheTimeout) {
- return;
- }
- }
- }
- // make sure the stale information is cleared out.
- cachedStatus = null;
- }
-
- IMAPConnection connection = getConnection();
- try {
- // ping the server for the list information for this folder
- cachedStatus = connection.getMailboxStatus(fullname);
- // mark when we got this
- lastStatusTimeStamp = System.currentTimeMillis();
- } finally {
- releaseConnection(connection);
- }
-
- // refresh the internal state from the message information
- maxSequenceNumber = cachedStatus.messages;
- recentMessages = cachedStatus.recentMessages;
- unseenMessages = cachedStatus.unseenMessages;
- uidValidity = cachedStatus.uidValidity;
- }
-
-
- /**
- * Process an EXPUNGE response for a message, removing the
- * message from the message cache.
- *
- * @param sequenceNumber
- * The sequence number for the expunged message.
- *
- * @return The Message object corresponding to this expunged
- * message.
- * @exception MessagingException
- */
- protected synchronized Message expungeMessage(int sequenceNumber) throws MessagingException {
-
- // first process the expunged message. We need to return a Message instance, so
- // force this to be added to the cache
- IMAPMessage expungedMessage = (IMAPMessage)getMessage(sequenceNumber);
- // mark the message as expunged.
- expungedMessage.setExpunged(true);
- // have we retrieved a UID for this message? If we have, then it's in the UID cache and
- // needs removal from there also
- long uid = ((IMAPMessage)expungedMessage).getUID();
- if (uid >= 0) {
- uidCache.remove(new Long(uid));
- }
- // because we need to jigger the keys of some of these, we had better have a working
- // copy.
- Map newCache = new HashMap();
-
- // now process each message in the cache, making adjustments as necessary
- Iterator i = messageCache.keySet().iterator();
-
- while (i.hasNext()) {
- Integer key = (Integer)i.next();
- int index = key.intValue();
- // if before the expunged message, just copy over to the
- // new cache
- if (index < sequenceNumber) {
- newCache.put(key, messageCache.get(key));
- }
- // after the expunged message...we need to adjust this
- else if (index > sequenceNumber) {
- // retrieve the message using the current position,
- // adjust the message sequence number, and add to the new
- // message cache under the new key value
- IMAPMessage message = (IMAPMessage)messageCache.get(key);
- message.setSequenceNumber(index - 1);
- newCache.put(new Integer(index - 1), message);
- }
- else {
- // the expunged message. We don't move this over to the new
- // cache, and we've already done all processing of that message that's
- // required
- }
- }
-
- // replace the old cache now that everything has been adjusted
- messageCache = newCache;
-
- // adjust the message count downward
- maxSequenceNumber--;
- return expungedMessage;
- }
-
-
- /**
- * Resolve an array of message numbers into an array of the
- * referenced messages.
- *
- * @param messageNumbers
- * The array of message numbers (can be null).
- *
- * @return An array of Message[] containing the resolved messages from
- * the list. Returns a zero-length array if there are no
- * messages to resolve.
- * @exception MessagingException
- */
- protected Message[] resolveMessages(int[] messageNumbers) throws MessagingException {
- // the connection search returns a null pointer if nothing was found, just convert this into a
- // null array.
- if (messageNumbers == null) {
- return new Message[0];
- }
-
- Message[] messages = new Message[messageNumbers.length];
-
- // retrieve each of the message numbers in turn.
- for (int i = 0; i < messageNumbers.length; i++) {
- messages[i] = getMessage(messageNumbers[i]);
- }
-
- return messages;
- }
-
- /**
- * Generate a message set string from a List of messages rather than an
- * array.
- *
- * @param messages The List of messages.
- *
- * @return The evaluated message set string.
- * @exception MessagingException
- */
- protected String generateMessageSet(List messages) throws MessagingException {
- Message[] msgs = (Message[])messages.toArray(new Message[messages.size()]);
- return generateMessageSet(msgs);
- }
-
-
- /**
- * Take an array of messages and generate a String <message set>
- * argument as specified by RFC 2060. The message set argument
- * is a comma-separated list of message number ranges. A
- * single element range is just one number. A longer range is
- * a pair of numbers separated by a ":". The generated string
- * should not have any blanks. This will attempt to locate
- * consequetive ranges of message numbers, but will only do this
- * for messages that are already ordered in the array (i.e., we
- * don't try to sort). Expunged messages are excluded from the
- * search, since they don't exist anymore. A valid search string
- * will look something like this:
- *
- * "3,6:10,15,21:35"
- *
- * @param messages The array of messages we generate from.
- *
- * @return A string formatted version of these message identifiers that
- * can be used on an IMAP command.
- */
- protected String generateMessageSet(Message[] messages) throws MessagingException {
- StringBuffer set = new StringBuffer();
-
- for (int i = 0; i < messages.length; i++) {
- // first scan the list looking for a "live" message.
- IMAPMessage start = (IMAPMessage)messages[i];
- if (!start.isExpunged()) {
-
- // we can go ahead and add this to the list now. If we find this is the start of a
- // range, we'll tack on the ":end" bit once we find the last message in the range.
- if (set.length() != 0) {
- // only append the comma if not the first element of the list
- set.append(',');
- }
-
- // append the first number. NOTE: We append this directly rather than
- // use appendInteger(), which appends it using atom rules.
- set.append(Integer.toString(start.getSequenceNumber()));
-
- // ok, we have a live one. Now scan the list from here looking for the end of
- // a range of consequetive messages.
- int endIndex = -1; ;
- // get the number we're checking against.
- int previousSequence = start.getSequenceNumber();
- for (int j = i + 1; j < messages.length; j++) {
- IMAPMessage message = (IMAPMessage)messages[j];
- if (!message.isExpunged()) {
- // still consequetive?
- if (message.getSequenceNumber() == previousSequence + 1) {
- // step this for the next check.
- previousSequence++;
- // record this as the current end of the range.
- endIndex = j;
- }
- else {
- // found a non-consequetive one, stop here
- break;
- }
- }
- }
-
- // have a range end point? Add the range specifier and step the loop index point
- // to skip over this
- if (endIndex != -1) {
- // pick up the scan at the next location
- i = endIndex;
-
- set.append(':');
- set.append(Integer.toString(((IMAPMessage)messages[endIndex]).getSequenceNumber()));
- }
- }
- }
-
- // return null for an empty list. This is possible because either an empty array has been handed to
- // us or all of the messages in the array have been expunged.
- if (set.length() == 0) {
- return null;
- }
- return set.toString();
- }
-
- /**
- * Verify that this folder exists on the server before
- * performning an operation that requires a valid
- * Folder instance.
- *
- * @exception MessagingException
- */
- protected void checkFolderValidity() throws MessagingException {
- // if we are holding a current listinfo response, then
- // we have chached existance information. In that case,
- // all of our status is presumed up-to-date and we can go
- // with that. If we don't have the information, then we
- // ping the server for it.
- if (listInfo == null && !exists()) {
- throw new FolderNotFoundException(this, "Folder " + fullname + " not found on server");
- }
- }
-
-
- /**
- * Check if a Message is properly within the target
- * folder.
- *
- * @param msg The message we're checking.
- *
- * @exception MessagingException
- */
- protected void checkMessageFolder(Message msg) throws MessagingException {
- if (msg.getFolder() != this) {
- throw new NoSuchElementException("Message is not within the target Folder");
- }
- }
-
-
- /**
- * Search a list of LIST responses for one containing information
- * for a particular mailbox name.
- *
- * @param responses The list of responses.
- * @param name The desired mailbox name.
- *
- * @return The IMAPListResponse information for the requested name.
- */
- protected IMAPListResponse findListResponse(List responses, String name) {
- for (int i = 0; i < responses.size(); i++) {
- IMAPListResponse response = (IMAPListResponse)responses.get(i);
- if (response.mailboxName.equals(name)) {
- return response;
- }
- }
- return null;
- }
-
-
- /**
- * Protected class intended for subclass overrides. For normal folders,
- * the mailbox name is fullname. For Namespace root folders, the mailbox
- * name is the prefix + separator.
- *
- * @return The string name to use as the mailbox name for exists() and issubscribed()
- * calls.
- */
- protected String getMailBoxName() {
- return fullname;
- }
-
- /**
- * Handle an unsolicited response from the server. Most unsolicited responses
- * are replies to specific commands sent to the server. The remainder must
- * be handled by the Store or the Folder using the connection. These are
- * critical to handle, as events such as expunged messages will alter the
- * sequence numbers of the live messages. We need to keep things in sync.
- *
- * @param response The UntaggedResponse to process.
- *
- * @return true if we handled this response and no further handling is required. false
- * means this one wasn't one of ours.
- */
- public boolean handleResponse(IMAPUntaggedResponse response) {
- // "you've got mail". The message count has been updated. There
- // are two posibilities. Either there really are new messages, or
- // this is an update following an expunge. If there are new messages,
- // we need to update the message cache and broadcast the change to
- // any listeners.
- if (response.isKeyword("EXISTS")) {
- // we need to update our cache, and also retrieve the new messages and
- // send them out in a broadcast update.
- int oldCount = maxSequenceNumber;
- maxSequenceNumber = ((IMAPSizeResponse)response).getSize();
- // has the size grown? We have to send the "you've got mail" announcement.
- if (oldCount < maxSequenceNumber) {
- try {
- Message[] messages = getMessages(oldCount + 1, maxSequenceNumber);
- notifyMessageAddedListeners(messages);
- } catch (MessagingException e) {
- // should never happen in this context
- }
- }
- return true;
- }
- // "you had mail". A message was expunged from the server. This MUST
- // be processed immediately, as any subsequent expunge messages will
- // shift the message numbers as a result of previous messages getting
- // removed. We need to keep our internal cache in sync with the server.
- else if (response.isKeyword("EXPUNGE")) {
- int messageNumber = ((IMAPSizeResponse)response).getSize();
- try {
- Message message = expungeMessage(messageNumber);
-
- // broadcast the message update.
- notifyMessageRemovedListeners(false, new Message[] {message});
- } catch (MessagingException e) {
- }
- // we handled this one.
- return true;
- }
- // just an update of recently arrived stuff? Just update the field.
- else if (response.isKeyword("RECENT")) {
- recentMessages = ((IMAPSizeResponse)response).getSize();
- return true;
- }
- // The spec is not particularly clear what types of unsolicited
- // FETCH response can be sent. The only one that is specifically
- // spelled out is flag updates. If this is one of those, then
- // handle it.
- else if (response.isKeyword("FETCH")) {
- IMAPFetchResponse fetch = (IMAPFetchResponse)response;
- IMAPFlags flags = (IMAPFlags)fetch.getDataItem(IMAPFetchDataItem.FLAGS);
- // if this is a flags response, get the message and update
- if (flags != null) {
- try {
- // get the updated message and update the internal state.
- IMAPMessage message = (IMAPMessage)getMessage(fetch.sequenceNumber);
- // this shouldn't happen, but it might have been expunged too.
- if (message != null) {
- message.updateMessageInformation(fetch);
- }
- notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, message);
- } catch (MessagingException e) {
- }
- return true;
- }
- }
- // this is a BYE response on our connection. This forces us to close, but
- // when we return the connection, the pool needs to get rid of it.
- else if (response.isKeyword("BYE")) {
- // this is essentially a close event. We need to clean everything up
- // and make sure our connection is not returned to the general pool.
- try {
- cleanupFolder(false, true);
- } catch (MessagingException e) {
- }
- return true;
- }
-
- // not a response the folder knows how to deal with.
- return false;
- }
-
-// The following set of methods are extensions that exist in the Sun implementation. They
-// match the Sun version in intent, but are not 100% compatible because the Sun implementation
-// uses com.sun.* class instances as opposed to the org.apache.geronimo.* classes.
-
-
-
- /**
- * Remove an entry from the access control list for this folder.
- *
- * @param acl The ACL element to remove.
- *
- * @exception MessagingException
- */
- public synchronized void removeACL(ACL acl) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- connection.removeACLRights(fullname, acl);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * Add an entry to the access control list for this folder.
- *
- * @param acl The new ACL to add.
- */
- public synchronized void addACL(ACL acl) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- connection.setACLRights(fullname, acl);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * Add Rights to a given ACL entry.
- *
- * @param acl The target ACL to update.
- *
- * @exception MessagingException
- */
- public synchronized void addRights(ACL acl) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- connection.addACLRights(fullname, acl);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * Remove ACL Rights from a folder.
- *
- * @param acl The ACL describing the Rights to remove.
- *
- * @exception MessagingException
- */
- public synchronized void removeRights(ACL acl) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- connection.removeACLRights(fullname, acl);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * List the rights associated with a given name.
- *
- * @param name The user name for the Rights.
- *
- * @return The set of Rights associated with the user name.
- * @exception MessagingException
- */
- public synchronized Rights[] listRights(String name) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- return connection.listACLRights(fullname, name);
- } finally {
- releaseConnection(connection);
- }
- }
-
-
- /**
- * List the rights for the currently authenticated user.
- *
- * @return The set of Rights for the current user.
- * @exception MessagingException
- */
- public synchronized Rights myRights() throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- return connection.getMyRights(fullname);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Get the quota values assigned to the current folder.
- *
- * @return The Quota information for the folder.
- * @exception MessagingException
- */
- public synchronized Quota[] getQuota() throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- return connection.fetchQuotaRoot(fullname);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Set the quota value for a quota root
- *
- * @param quota The new quota information to set.
- *
- * @exception MessagingException
- */
- public synchronized void setQuota(Quota quota) throws MessagingException {
- // ask the store to kindly hook us up with a connection.
- IMAPConnection connection = getConnection();
-
- try {
- // the connection does the heavy lifting
- connection.setQuota(quota);
- } finally {
- releaseConnection(connection);
- }
- }
-
- /**
- * Get the set of attributes defined for the folder
- * as the set of capabilities returned when the folder
- * was opened.
- *
- * @return The set of attributes associated with the folder.
- * @exception MessagingException
- */
- public synchronized String[] getAttributes() throws MessagingException {
- // if we don't have the LIST command information for this folder yet,
- // call exists() to force this to be updated so we can return.
- if (listInfo == null) {
- // return a null reference if this is not valid.
- if (!exists()) {
- return null;
- }
- }
- // return a copy of the attributes array.
- return (String[])listInfo.attributes.clone();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
deleted file mode 100644
index 44cfb45..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
+++ /dev/null
@@ -1,1300 +0,0 @@
-/**
- * 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;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.activation.DataHandler;
-
-import javax.mail.Address;
-import javax.mail.FetchProfile;
-import javax.mail.Flags;
-import javax.mail.Folder;
-import javax.mail.Header;
-import javax.mail.IllegalWriteException;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.MessageRemovedException;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.UIDFolder;
-import javax.mail.event.MessageChangedEvent;
-
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.InternetHeaders;
-import javax.mail.internet.MailDateFormat;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeUtility;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBody;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPInternalDate;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPInternetHeader;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPMessageSize;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
-import org.apache.geronimo.javamail.util.MailConnection;
-
-/**
- * IMAP 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: 946314 $ $Date: 2010-05-19 14:01:55 -0400 (Wed, 19 May 2010) $
- */
-public class IMAPMessage extends MimeMessage {
-
- private static final byte[] CRLF = new byte[]{'\r', '\n'};
-
- // the Store we're stored in (which manages the connection and other stuff).
- protected IMAPStore store;
-
- // the IMAP server sequence number (potentially updated during the life of this message object).
- protected int sequenceNumber;
- // the IMAP uid value;
- protected long uid = -1;
- // the section identifier. This is only really used for nested messages. The toplevel version
- // will be null, and each nested message will set the appropriate part identifier
- protected String section;
- // the loaded message envelope (delayed until needed)
- protected IMAPEnvelope envelope;
- // the body structure information (also lazy loaded).
- protected IMAPBodyStructure bodyStructure;
- // the IMAP INTERNALDATE value.
- protected Date receivedDate;
- // the size item, which is maintained separately from the body structure
- // as it can be retrieved without getting the body structure
- protected int size;
- // turned on once we've requested the entire header set.
- protected boolean allHeadersRetrieved = false;
- // singleton date formatter for this class.
- static protected MailDateFormat dateFormat = new MailDateFormat();
-
-
- /**
- * Contruct an IMAPMessage instance.
- *
- * @param folder The hosting folder for the message.
- * @param store The Store owning the article (and folder).
- * @param msgnum The article message number. This is assigned by the Folder, and is unique
- * for each message in the folder. The message numbers are only valid
- * as long as the Folder is open.
- * @param sequenceNumber The IMAP server manages messages by sequence number, which is subject to
- * change whenever messages are expunged. This is the server retrieval number
- * of the message, which needs to be synchronized with status updates
- * sent from the server.
- *
- * @exception MessagingException
- */
- IMAPMessage(IMAPFolder folder, IMAPStore store, int msgnum, int sequenceNumber) {
- super(folder, msgnum);
- this.sequenceNumber = sequenceNumber;
- this.store = store;
- // The default constructor creates an empty Flags item. We need to clear this out so we
- // know if the flags need to be fetched from the server when requested.
- flags = null;
- // make sure this is a totally fresh set of headers. We'll fill things in as we retrieve them.
- headers = new InternetHeaders();
- }
-
-
- /**
- * Override for the Message class setExpunged() method to allow
- * us to do additional cleanup for expunged messages.
- *
- * @param value The new expunge setting.
- */
- public void setExpunged(boolean value) {
- // super class handles most of the details
- super.setExpunged(value);
- // if we're now expunged, this removes us from the server message sequencing scheme, so
- // we need to invalidate the sequence number.
- if (isExpunged()) {
- sequenceNumber = -1;
- }
- }
-
-
- /**
- * Return a copy the flags associated with this message.
- *
- * @return a copy of the flags for this message
- * @throws MessagingException if there was a problem accessing the Store
- */
- public synchronized Flags getFlags() throws MessagingException {
- // load the flags, if needed
- loadFlags();
- return super.getFlags();
- }
-
-
- /**
- * Check whether the supplied flag is set.
- * The default implementation checks the flags returned by {@link #getFlags()}.
- *
- * @param flag the flags to check for
- * @return true if the flags is set
- * @throws MessagingException if there was a problem accessing the Store
- */
- public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
- // load the flags, if needed
- loadFlags();
- return super.isSet(flag);
- }
-
- /**
- * Set or clear a flag value.
- *
- * @param flags The set of flags to effect.
- * @param set The value to set the flag to (true or false).
- *
- * @exception MessagingException
- */
- public synchronized void setFlags(Flags flag, boolean set) throws MessagingException {
- // make sure this is in a valid state.
- checkValidity();
-
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
-
- try {
- // set the flags for this item and update the
- // internal state with the new values returned from the
- // server.
- flags = connection.setFlags(sequenceNumber, flag, set);
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Return an InputStream instance for accessing the
- * message content.
- *
- * @return An InputStream instance for accessing the content
- * (body) of the message.
- * @exception MessagingException
- * @see javax.mail.internet.MimeMessage#getContentStream()
- */
- protected InputStream getContentStream() throws MessagingException {
-
- // no content loaded yet?
- if (content == null) {
- // make sure we're still valid
- checkValidity();
- // make sure the content is fully loaded
- 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 {
- // no content loaded yet?
- if (content == null) {
- // make sure we're still valid
- checkValidity();
- // make sure the content is fully loaded
- loadContent();
- }
-
- loadHeaders();
-
- Enumeration e = headers.getAllHeaderLines();
- while(e.hasMoreElements()) {
- String line = (String)e.nextElement();
- out.write(line.getBytes("ISO8859-1"));
- out.write(CRLF);
- }
- out.write(CRLF);
- out.write(CRLF);
- out.write(content);
- }
-
- /******************************************************************
- * Following is a set of methods that deal with information in the
- * envelope. These methods ensure the enveloper is loaded and
- * retrieve the information.
- ********************************************************************/
-
-
- /**
- * Get the message "From" addresses. This looks first at the
- * "From" headers, and no "From" header is found, the "Sender"
- * header is checked. Returns null if not found.
- *
- * @return An array of addresses identifying the message from target. Returns
- * null if this is not resolveable from the headers.
- * @exception MessagingException
- */
- public Address[] getFrom() throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
- // make sure we return a copy of the array so this can't be changed.
- Address[] addresses = envelope.from;
- if (addresses == null) {
- return null;
- }
- return (Address[])addresses.clone();
- }
-
-
- /**
- * Return the "Sender" header as an address.
- *
- * @return the "Sender" header as an address, or null if not present
- * @throws MessagingException if there was a problem parsing the header
- */
- public Address getSender() throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
- // make sure we return a copy of the array so this can't be changed.
- Address[] addresses = envelope.sender;
- if (addresses == null) {
- return null;
- }
- // There's only a single sender, despite IMAP potentially returning a list
- return addresses[0];
- }
-
- /**
- * Gets the recipients by type. Returns null if there are no
- * headers of the specified type. Acceptable RecipientTypes are:
- *
- * javax.mail.Message.RecipientType.TO
- * javax.mail.Message.RecipientType.CC
- * javax.mail.Message.RecipientType.BCC
- * javax.mail.internet.MimeMessage.RecipientType.NEWSGROUPS
- *
- * @param type The message RecipientType identifier.
- *
- * @return The array of addresses for the specified recipient types.
- * @exception MessagingException
- */
- public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
- Address[] addresses = null;
-
- if (type == Message.RecipientType.TO) {
- addresses = envelope.to;
- }
- else if (type == Message.RecipientType.CC) {
- addresses = envelope.cc;
- }
- else if (type == Message.RecipientType.BCC) {
- addresses = envelope.bcc;
- }
- else {
- // this could be a newsgroup type, which will tickle the message headers.
- return super.getRecipients(type);
- }
- // make sure we return a copy of the array so this can't be changed.
- if (addresses == null) {
- return null;
- }
- return (Address[])addresses.clone();
- }
-
- /**
- * Get the ReplyTo address information. The headers are parsed
- * using the "mail.mime.address.strict" setting. If the "Reply-To" header does
- * not have any addresses, then the value of the "From" field is used.
- *
- * @return An array of addresses obtained from parsing the header.
- * @exception MessagingException
- */
- public Address[] getReplyTo() throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
- // make sure we return a copy of the array so this can't be changed.
- Address[] addresses = envelope.replyTo;
- if (addresses == null) {
- return null;
- }
- return (Address[])addresses.clone();
- }
-
- /**
- * Returns the value of the "Subject" header. If the subject
- * is encoded as an RFC 2047 value, the value is decoded before
- * return. If decoding fails, the raw string value is
- * returned.
- *
- * @return The String value of the subject field.
- * @exception MessagingException
- */
- public String getSubject() throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
-
- if (envelope.subject == null) {
- return null;
- }
- // the subject could be encoded. If there is a decoding error,
- // return the raw subject string.
- try {
- return MimeUtility.decodeText(envelope.subject);
- } catch (UnsupportedEncodingException e) {
- return envelope.subject;
- }
- }
-
- /**
- * Get the value of the "Date" header field. Returns null if
- * if the field is absent or the date is not in a parseable format.
- *
- * @return A Date object parsed according to RFC 822.
- * @exception MessagingException
- */
- public Date getSentDate() throws MessagingException {
- // make sure we've retrieved the envelope information.
- loadEnvelope();
- // just return that directly
- return envelope.date;
- }
-
-
- /**
- * Get the message received date.
- *
- * @return Always returns the formatted INTERNALDATE, if available.
- * @exception MessagingException
- */
- public Date getReceivedDate() throws MessagingException {
- loadEnvelope();
- return receivedDate;
- }
-
-
- /**
- * 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 envelope information. We load the
- // size when we retrieve that.
- loadEnvelope();
- return size;
- }
-
-
- /**
- * Get a line count for the IMAP 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 {
- loadBodyStructure();
- return bodyStructure.lines;
- }
-
- /**
- * Return the IMAP in reply to information (retrieved with the
- * ENVELOPE).
- *
- * @return The in reply to String value, if available.
- * @exception MessagingException
- */
- public String getInReplyTo() throws MessagingException {
- loadEnvelope();
- return envelope.inReplyTo;
- }
-
- /**
- * Returns the current content type (defined in the "Content-Type"
- * header. If not available, "text/plain" is the default.
- *
- * @return The String name of the message content type.
- * @exception MessagingException
- */
- public String getContentType() throws MessagingException {
- loadBodyStructure();
- return bodyStructure.mimeType.toString();
- }
-
-
- /**
- * Tests to see if this message has a mime-type match with the
- * given type name.
- *
- * @param type The tested type name.
- *
- * @return If this is a type match on the primary and secondare portion of the types.
- * @exception MessagingException
- */
- public boolean isMimeType(String type) throws MessagingException {
- loadBodyStructure();
- return bodyStructure.mimeType.match(type);
- }
-
- /**
- * Retrieve the message "Content-Disposition" header field.
- * This value represents how the part should be represented to
- * the user.
- *
- * @return The string value of the Content-Disposition field.
- * @exception MessagingException
- */
- public String getDisposition() throws MessagingException {
- loadBodyStructure();
- if (bodyStructure.disposition != null) {
- return bodyStructure.disposition.getDisposition();
- }
- return null;
- }
-
- /**
- * Decode the Content-Transfer-Encoding header to determine
- * the transfer encoding type.
- *
- * @return The string name of the required encoding.
- * @exception MessagingException
- */
- public String getEncoding() throws MessagingException {
- loadBodyStructure();
- return bodyStructure.transferEncoding;
- }
-
- /**
- * Retrieve the value of the "Content-ID" header. Returns null
- * if the header does not exist.
- *
- * @return The current header value or null.
- * @exception MessagingException
- */
- public String getContentID() throws MessagingException {
- loadBodyStructure();
- return bodyStructure.contentID;
- }
-
- public String getContentMD5() throws MessagingException {
- loadBodyStructure();
- return bodyStructure.md5Hash;
- }
-
-
- public String getDescription() throws MessagingException {
- loadBodyStructure();
-
- if (bodyStructure.contentDescription == null) {
- return null;
- }
- // the subject could be encoded. If there is a decoding error,
- // return the raw subject string.
- try {
- return MimeUtility.decodeText(bodyStructure.contentDescription);
- } catch (UnsupportedEncodingException e) {
- return bodyStructure.contentDescription;
- }
- }
-
- /**
- * Return the content languages associated with this
- * message.
- *
- * @return
- * @exception MessagingException
- */
- public String[] getContentLanguage() throws MessagingException {
- loadBodyStructure();
-
- if (!bodyStructure.languages.isEmpty()) {
- return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]);
- }
- return null;
- }
-
- public String getMessageID() throws MessagingException {
- loadEnvelope();
- return envelope.messageID;
- }
-
- public void setFrom(Address address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void addFrom(Address[] address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setSender(Address address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setRecipients(Message.RecipientType type, String address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void addRecipients(Message.RecipientType type, Address[] address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setReplyTo(Address[] address) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setSubject(String subject) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setSubject(String subject, String charset) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setSentDate(Date sent) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setDisposition(String disposition) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setContentID(String cid) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setContentMD5(String md5) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setDescription(String description) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setDescription(String description, String charset) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void setContentLanguage(String[] languages) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
-
- /******************************************************************
- * 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("IMAP messages are read-only");
- }
-
- public void setHeader(String name, String value) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
-
- public void removeHeader(String name) throws MessagingException {
- throw new IllegalWriteException("IMAP 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("IMAP messages are read-only");
- }
-
-
- /**
- * Utility method for synchronizing IMAP envelope information and
- * the message headers.
- *
- * @param header The target header name.
- * @param addresses The update addresses.
- */
- protected void updateHeader(String header, InternetAddress[] addresses) throws MessagingException {
- if (addresses != null) {
- headers.addHeader(header, InternetAddress.toString(addresses));
- }
- }
-
- /**
- * Utility method for synchronizing IMAP envelope information and
- * the message headers.
- *
- * @param header The target header name.
- * @param address The update address.
- */
- protected void updateHeader(String header, Address address) throws MessagingException {
- if (address != null) {
- headers.setHeader(header, address.toString());
- }
- }
-
- /**
- * Utility method for synchronizing IMAP envelope information and
- * the message headers.
- *
- * @param header The target header name.
- * @param value The update value.
- */
- protected void updateHeader(String header, String value) throws MessagingException {
- if (value != null) {
- headers.setHeader(header, value);
- }
- }
-
-
- /**
- * Create the DataHandler object for this message.
- *
- * @return The DataHandler object that processes the content set for this
- * message.
- * @exception MessagingException
- */
- public synchronized DataHandler getDataHandler() throws MessagingException {
- // check the validity and make sure we have the body structure information.
- checkValidity();
- loadBodyStructure();
- if (dh == null) {
- // are we working with a multipart message here?
- if (bodyStructure.isMultipart()) {
- dh = new DataHandler(new IMAPMultipartDataSource(this, this, section, bodyStructure));
- return dh;
- }
- else if (bodyStructure.isAttachedMessage()) {
- dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody),
- bodyStructure.mimeType.toString());
- return dh;
- }
- }
-
- // single part messages get handled the normal way.
- return super.getDataHandler();
- }
-
- public void setDataHandler(DataHandler content) throws MessagingException {
- throw new IllegalWriteException("IMAP body parts are read-only");
- }
-
- /**
- * 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);
- allHeadersRetrieved = true;
- }
-
- /**
- * Load the flag set for this message from the server.
- *
- * @exception MessagingeException
- */
- public void loadFlags() throws MessagingException {
- // make sure this is in a valid state.
- checkValidity();
- // if the flags are already loaded, nothing to do
- if (flags != null) {
- return;
- }
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
-
- try {
- // fetch the flags for this item.
- flags = connection.fetchFlags(sequenceNumber);
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Retrieve the message raw message headers from the IMAP server, synchronizing with the existing header set.
- *
- * @exception MessagingException
- */
- protected synchronized void loadHeaders() throws MessagingException {
- // don't retrieve if already loaded.
- if (allHeadersRetrieved) {
- return;
- }
-
- // make sure this is in a valid state.
- checkValidity();
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
-
- try {
- // get the headers and set
- headers = connection.fetchHeaders(sequenceNumber, section);
- // we have the entire header set, not just a subset.
- allHeadersRetrieved = true;
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
- * information.
- *
- * @exception MessagingException
- */
- protected synchronized void loadEnvelope() throws MessagingException {
- // don't retrieve if already loaded.
- if (envelope != null) {
- return;
- }
-
- // make sure this is in a valid state.
- checkValidity();
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
- try {
- // fetch the envelope information for this
- List fetches = connection.fetchEnvelope(sequenceNumber);
- // now process all of the fetch responses before releasing the folder lock.
- // it's possible that an unsolicited update on another thread might try to
- // make an update, causing a potential deadlock.
- for (int i = 0; i < fetches.size(); i++) {
- // get the returned data items from each of the fetch responses
- // and process.
- IMAPFetchResponse fetch = (IMAPFetchResponse)fetches.get(i);
- // update the internal info
- updateMessageInformation(fetch);
- }
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
- * information.
- *
- * @exception MessagingException
- */
- protected synchronized void updateEnvelope(IMAPEnvelope envelope) throws MessagingException {
- // set the envelope item
- this.envelope = envelope;
-
- // copy header type information from the envelope into the headers.
- updateHeader("From", envelope.from);
- if (envelope.sender != null) {
- // we can only have a single sender, even though the envelope theoretically supports more.
- updateHeader("Sender", envelope.sender[0]);
- }
- updateHeader("To", envelope.to);
- updateHeader("Cc", envelope.cc);
- updateHeader("Bcc", envelope.bcc);
- updateHeader("Reply-To", envelope.replyTo);
- // NB: This is already in encoded form, if needed.
- updateHeader("Subject", envelope.subject);
- updateHeader("Message-ID", envelope.messageID);
- }
-
-
- /**
- * Retrieve the BODYSTRUCTURE information from the IMAP server.
- *
- * @exception MessagingException
- */
- protected synchronized void loadBodyStructure() throws MessagingException {
- // don't retrieve if already loaded.
- if (bodyStructure != null) {
- return;
- }
-
- // make sure this is in a valid state.
- checkValidity();
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
- try {
- // fetch the envelope information for this
- bodyStructure = connection.fetchBodyStructure(sequenceNumber);
- // go update all of the information
- } finally {
- releaseConnection(connection);
- }
-
- // update this before we release the folder lock so we can avoid
- // deadlock.
- updateBodyStructure(bodyStructure);
- }
- }
-
-
- /**
- * Update the BODYSTRUCTURE information from the IMAP server.
- *
- * @exception MessagingException
- */
- protected synchronized void updateBodyStructure(IMAPBodyStructure structure) throws MessagingException {
- // save the reference.
- bodyStructure = structure;
- // now update various headers with the information from the body structure
-
- // now update header information with the body structure data.
- if (bodyStructure.lines != -1) {
- updateHeader("Lines", Integer.toString(bodyStructure.lines));
- }
-
- // languages are a little more complicated
- if (bodyStructure.languages != null) {
- // this is a duplicate of what happens in the super class, but
- // the superclass methods call setHeader(), which we override and
- // throw an exception for. We need to set the headers ourselves.
- if (bodyStructure.languages.size() == 1) {
- updateHeader("Content-Language", (String)bodyStructure.languages.get(0));
- }
- else {
- StringBuffer buf = new StringBuffer(bodyStructure.languages.size() * 20);
- buf.append(bodyStructure.languages.get(0));
- for (int i = 1; i < bodyStructure.languages.size(); i++) {
- buf.append(',').append(bodyStructure.languages.get(i));
- }
- updateHeader("Content-Language", buf.toString());
- }
- }
-
- updateHeader("Content-Type", bodyStructure.mimeType.toString());
- if (bodyStructure.disposition != null) {
- updateHeader("Content-Disposition", bodyStructure.disposition.toString());
- }
-
- updateHeader("Content-Transfer-Encoding", bodyStructure.transferEncoding);
- updateHeader("Content-ID", bodyStructure.contentID);
- // NB: This is already in encoded form, if needed.
- updateHeader("Content-Description", bodyStructure.contentDescription);
- }
-
-
- /**
- * Load the message content into the Message object.
- *
- * @exception MessagingException
- */
- protected void loadContent() throws MessagingException {
- // if we've loaded this already, just return
- if (content != null) {
- return;
- }
-
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- synchronized (folder) {
- IMAPConnection connection = getConnection();
- try {
- // load the content from the server.
- content = connection.fetchContent(getSequenceNumber(), section);
- } finally {
- releaseConnection(connection);
- }
- }
- }
-
-
- /**
- * Retrieve the sequence number assigned to this message.
- *
- * @return The messages assigned sequence number. This maps back to the server's assigned number for
- * this message.
- */
- int getSequenceNumber() {
- return sequenceNumber;
- }
-
- /**
- * Set the sequence number for the message. This
- * is updated whenever messages get expunged from
- * the folder.
- *
- * @param s The new sequence number.
- */
- void setSequenceNumber(int s) {
- sequenceNumber = s;
- }
-
-
- /**
- * Retrieve the message UID value.
- *
- * @return The assigned UID value, if we have the information.
- */
- long getUID() {
- return uid;
- }
-
- /**
- * Set the message UID value.
- *
- * @param uid The new UID value.
- */
- void setUID(long uid) {
- this.uid = uid;
- }
-
-
- /**
- * 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 IMAPConnection getConnection() throws MessagingException {
- // the folder owns everything.
- return ((IMAPFolder)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(IMAPConnection connection) throws MessagingException {
- // the folder owns everything.
- ((IMAPFolder)folder).releaseMessageConnection(connection);
- }
-
-
- /**
- * Check the validity of the current message. This ensures that
- * A) the folder is currently open, B) that the message has not
- * been expunged (after getting the latest status from the server).
- *
- * @exception MessagingException
- */
- protected void checkValidity() throws MessagingException {
- checkValidity(false);
- }
-
-
- /**
- * Check the validity of the current message. This ensures that
- * A) the folder is currently open, B) that the message has not
- * been expunged (after getting the latest status from the server).
- *
- * @exception MessagingException
- */
- protected void checkValidity(boolean update) throws MessagingException {
- // we need to ensure that we're the only ones with access to the folder's
- // message cache any time we need to talk to the server. This needs to be
- // held until after we release the connection so that any pending EXPUNGE
- // untagged responses are processed before the next time the folder connection is
- // used.
- if (update) {
- synchronized (folder) {
- // have the connection update the folder status. This might result in this message
- // changing its state to expunged. It might also result in an exception if the
- // folder has been closed.
- IMAPConnection connection = getConnection();
-
- try {
- connection.updateMailboxStatus();
- } finally {
- // this will force any expunged messages to be processed before we release
- // the lock.
- releaseConnection(connection);
- }
- }
- }
-
- // now see if we've been expunged, this is a bad op on the message.
- if (isExpunged()) {
- throw new MessageRemovedException("Illegal opertion on a deleted message");
- }
- }
-
-
- /**
- * Evaluate whether this message requires any of the information
- * in a FetchProfile to be fetched from the server. If the messages
- * already contains the information in the profile, it returns false.
- * This allows IMAPFolder to optimize fetch() requests to just the
- * messages that are missing any of the requested information.
- *
- * NOTE: If any of the items in the profile are missing, then this
- * message will be updated with ALL of the items.
- *
- * @param profile The FetchProfile indicating the information that should be prefetched.
- *
- * @return true if any of the profile information requires fetching. false if this
- * message already contains the given information.
- */
- protected boolean evaluateFetch(FetchProfile profile) {
- // the fetch profile can contain a number of different item types. Validate
- // whether we need any of these and return true on the first mismatch.
-
- // the UID is a common fetch request, put it first.
- if (profile.contains(UIDFolder.FetchProfileItem.UID) && uid == -1) {
- return true;
- }
- if (profile.contains(FetchProfile.Item.ENVELOPE) && envelope == null) {
- return true;
- }
- if (profile.contains(FetchProfile.Item.FLAGS) && flags == null) {
- return true;
- }
- if (profile.contains(FetchProfile.Item.CONTENT_INFO) && bodyStructure == null) {
- return true;
- }
- // The following profile items are our implementation of items that the
- // Sun IMAPFolder implementation supports.
- if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS) && !allHeadersRetrieved) {
- return true;
- }
- if (profile.contains(IMAPFolder.FetchProfileItem.SIZE) && bodyStructure.bodySize < 0) {
- return true;
- }
- // last bit after checking each of the information types is to see if
- // particular headers have been requested and whether those are on the
- // set we do have loaded.
- String [] requestedHeaders = profile.getHeaderNames();
-
- // ok, any missing header in the list is enough to force us to request the
- // information.
- for (int i = 0; i < requestedHeaders.length; i++) {
- if (headers.getHeader(requestedHeaders[i]) == null) {
- return true;
- }
- }
- // this message, at least, does not need anything fetched.
- return false;
- }
-
- /**
- * Update a message instance with information retrieved via an IMAP FETCH
- * command. The command response for this message may contain multiple pieces
- * that we need to process.
- *
- * @param response The response line, which may contain multiple data items.
- *
- * @exception MessagingException
- */
- void updateMessageInformation(IMAPFetchResponse response) throws MessagingException {
- // get the list of data items associated with this response. We can have
- // a large number of items returned in a single update.
- List items = response.getDataItems();
-
- for (int i = 0; i < items.size(); i++) {
- IMAPFetchDataItem item = (IMAPFetchDataItem)items.get(i);
-
- switch (item.getType()) {
- // if the envelope has been requested, we'll end up with all of these items.
- case IMAPFetchDataItem.ENVELOPE:
- // update the envelope and map the envelope items into the headers.
- updateEnvelope((IMAPEnvelope)item);
- break;
- case IMAPFetchDataItem.INTERNALDATE:
- receivedDate = ((IMAPInternalDate)item).getDate();;
- break;
- case IMAPFetchDataItem.SIZE:
- size = ((IMAPMessageSize)item).size;
- break;
- case IMAPFetchDataItem.UID:
- uid = ((IMAPUid)item).uid;
- // make sure the folder knows about the UID update.
- ((IMAPFolder)folder).addToUidCache(new Long(uid), this);
- break;
- case IMAPFetchDataItem.BODYSTRUCTURE:
- updateBodyStructure((IMAPBodyStructure)item);
- break;
- // a partial or full header update
- case IMAPFetchDataItem.HEADER:
- {
- // if we've fetched the complete set, then replace what we have
- IMAPInternetHeader h = (IMAPInternetHeader)item;
- if (h.isComplete()) {
- // we've got a complete header set now.
- this.headers = h.headers;
- allHeadersRetrieved = true;
- }
- else {
- // need to merge the requested headers in with
- // our existing set. We need to be careful, since we
- // don't want to add duplicates.
- mergeHeaders(h.headers);
- }
- }
- default:
- }
- }
- }
-
-
- /**
- * Merge a subset of the requested headers with our existing partial set.
- * The new set will contain all headers requested from the server, plus
- * any of our existing headers that were not included in the retrieved set.
- *
- * @param newHeaders The retrieved set of headers.
- */
- protected synchronized void mergeHeaders(InternetHeaders newHeaders) {
- // This is sort of tricky to manage. The input headers object is a fresh set
- // retrieved from the server, but it's a subset of the headers. Our existing set
- // might not be complete, but it may contain duplicates of information in the
- // retrieved set, plus headers that are not in the retrieved set. To keep from
- // adding duplicates, we'll only add headers that are not in the retrieved set to
- // that set.
-
- // start by running through the list of headers
- Enumeration e = headers.getAllHeaders();
-
- while (e.hasMoreElements()) {
- Header header = (Header)e.nextElement();
- // if there are no headers with this name in the new set, then
- // we can add this. Note that to add the header, we need to
- // retrieve all instances by this name and add them as a unit.
- // When we hit one of the duplicates again with the enumeration,
- // we'll skip it then because the merge target will have everything.
- if (newHeaders.getHeader(header.getName()) == null) {
- // get all occurrences of this name and stuff them into the
- // new list
- String name = header.getName();
- String[] a = headers.getHeader(name);
- for (int i = 0; i < a.length; i++) {
- newHeaders.addHeader(name, a[i]);
- }
- }
- }
- // and replace the current header set
- headers = newHeaders;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java
deleted file mode 100644
index 9370451..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * 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;
-
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Enumeration;
-
-import javax.activation.DataHandler;
-import javax.mail.IllegalWriteException;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeUtility;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
-import org.apache.geronimo.mail.util.SessionUtil;
-
-
-public class IMAPMimeBodyPart extends MimeBodyPart {
- // the message we're part of
- protected IMAPMessage message;
- // the retrieved BODYSTRUCTURE information for this part.
- protected IMAPBodyStructure bodyStructure;
- // the section identifier. This will be in a format such as 1.2.3, which
- // would refer to the "third part contained in the second part of the first part"...
- // got all that? There will be a quiz at the end of class :-)
- protected String section;
- // flag to indicate whether the body part headers have been loaded.
- boolean headersLoaded = false;
-
- /**
- * Create an instance of a MimeBodyPart within an
- * IMAP message.
- *
- * @param message The parent Message instance containing this part.
- * @param bodyStructure
- * The IMAPBodyStructure information describing the part.
- * @param section The numeric section identifier string for this part.
- * This is a hierarchical set of numbers describing
- * how to navigate to the message part on the IMAP
- * server. For example, "2.1.3" would be the third
- * subpart of the first subpart of the second main
- * message part.
- */
- public IMAPMimeBodyPart(IMAPMessage message, IMAPBodyStructure bodyStructure, String section) {
- super();
- this.message = message;
- this.bodyStructure = bodyStructure;
- this.section = section;
- }
-
-
- /**
- * Get the size of the message part.
- *
- * @return The size information returned in the IMAP body structure.
- * @exception MessagingException
- */
- public int getSize() throws MessagingException {
- return bodyStructure.bodySize;
- }
-
- /**
- * Get the estimated line count for the body part.
- *
- * @return The line count information returned by the IMAP
- * server.
- * @exception MessagingException
- */
- public int getLineCount() throws MessagingException {
- return bodyStructure.lines;
- }
-
- /**
- * Get the content type for the body part.
- *
- * @return The mimetype for the body part, in string format.
- * @exception MessagingException
- */
- public String getContentType() throws MessagingException {
- return bodyStructure.mimeType.toString();
- }
-
- /**
- * Test if the body part is of a particular MIME type.
- *
- * @param type The string MIME-type name. A wild card * can be
- * specified for the subpart type.
- *
- * @return true if the body part matches the give MIME-type.
- * @exception MessagingException
- */
- public boolean isMimeType(String type) throws MessagingException {
- return bodyStructure.mimeType.match(type);
- }
-
- /**
- * Retrieve the disposition information about this
- * body part.
- *
- * @return The disposition information, as a string value.
- * @exception MessagingException
- */
- public String getDisposition() throws MessagingException {
- return bodyStructure.disposition.getDisposition();
- }
-
- /**
- * Set the disposition information. The IMAP message
- * is read-only, so this is an error.
- *
- * @param disposition
- * The disposition string.
- *
- * @exception MessagingException
- */
- public void setDisposition(String disposition) throws MessagingException {
- throw new IllegalWriteException("IMAP message parts are read-only");
- }
-
- public String getEncoding() throws MessagingException {
- return bodyStructure.transferEncoding;
- }
-
- public String getContentID() throws MessagingException {
- return bodyStructure.contentID;
- }
-
- public void setContentID(String id) throws MessagingException {
- throw new IllegalWriteException("IMAP message parts are read-only");
- }
-
- public String getContentMD5() throws MessagingException {
- return bodyStructure.md5Hash;
- }
-
- public void setContentMD5(String id) throws MessagingException {
- throw new IllegalWriteException("IMAP message parts are read-only");
- }
-
- public String getDescription() throws MessagingException {
- String description = bodyStructure.contentDescription;
- if (description != null) {
- try {
- // this could be both folded and encoded. Return this to usable form.
- return MimeUtility.decodeText(MimeUtility.unfold(description));
- } catch (UnsupportedEncodingException e) {
- // ignore
- }
- }
- // return the raw version for any errors (this might be null also)
- return description;
- }
-
- public void setDescription(String d, String charset) throws MessagingException {
- throw new IllegalWriteException("IMAP message parts are read-only");
- }
-
- public String getFileName() throws MessagingException {
- String filename = bodyStructure.disposition.getParameter("filename");
- if (filename == null) {
- filename = bodyStructure.mimeType.getParameter("name");
- }
-
- // if we have a name, we might need to decode this if an additional property is set.
- if (filename != null && SessionUtil.getBooleanProperty(MIME_DECODEFILENAME, false)) {
- try {
- filename = MimeUtility.decodeText(filename);
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Unable to decode filename", e);
- }
- }
-
- return filename;
- }
-
- public void setFileName(String name) throws MessagingException {
- throw new IllegalWriteException("IMAP message parts are read-only");
- }
-
- protected InputStream getContentStream() throws MessagingException {
-
- // no content loaded yet?
- if (content == null) {
- // make sure we're still valid
- message.checkValidity();
- // make sure the content is fully loaded
- loadContent();
- }
-
- // allow the super class to handle creating it from the loaded content.
- return super.getContentStream();
- }
-
-
- /**
- * Create the DataHandler object for this message.
- *
- * @return The DataHandler object that processes the content set for this
- * message.
- * @exception MessagingException
- */
- public synchronized DataHandler getDataHandler() throws MessagingException {
- if (dh == null) {
- // are we working with a multipart message here?
- if (bodyStructure.isMultipart()) {
- dh = new DataHandler(new IMAPMultipartDataSource(message, this, section, bodyStructure));
- return dh;
- }
- else if (bodyStructure.isAttachedMessage()) {
- dh = new DataHandler(new IMAPAttachedMessage(message, section, bodyStructure.nestedEnvelope,
- bodyStructure.nestedBody), bodyStructure.mimeType.toString());
- return dh;
- }
- }
-
- // single part messages get handled the normal way.
- return super.getDataHandler();
- }
-
- public void setDataHandler(DataHandler content) throws MessagingException {
- throw new IllegalWriteException("IMAP body parts are read-only");
- }
-
- public void setContent(Object o, String type) throws MessagingException {
- throw new IllegalWriteException("IMAP body parts are read-only");
- }
-
- public void setContent(Multipart mp) throws MessagingException {
- throw new IllegalWriteException("IMAP body parts are read-only");
- }
-
-
- /******************************************************************
- * 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("IMAP messages are read-only");
- }
-
- public void setHeader(String name, String value) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
-
- public void removeHeader(String name) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
- public void addHeaderLine(String line) throws MessagingException {
- throw new IllegalWriteException("IMAP messages are read-only");
- }
-
-
- /**
- * Load the mime part headers into this body part.
- *
- * @exception MessagingException
- */
- protected synchronized void loadHeaders() throws MessagingException {
- // have them already? Super..
- if (headers != null) {
- return;
- }
-
- IMAPConnection connection = message.getConnection();
- try {
- // this asks for the MIME subsection of the given section piece.
- headers = connection.fetchHeaders(message.getSequenceNumber(), section);
- } finally {
- message.releaseConnection(connection);
- }
-
- }
-
-
- /**
- * Load the message content into the BodyPart object.
- *
- * @exception MessagingException
- */
- protected void loadContent() throws MessagingException {
- // if we've loaded this already, just return
- if (content != null) {
- return;
- }
-
- IMAPConnection connection = message.getConnection();
- try {
- // load the content from the server.
- content = connection.fetchContent(message.getSequenceNumber(), section);
- } finally {
- message.releaseConnection(connection);
- }
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java
deleted file mode 100644
index 30c2515..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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;
-
-import javax.mail.BodyPart;
-import javax.mail.MessagingException;
-import javax.mail.MultipartDataSource;
-
-import javax.mail.internet.MimePart;
-import javax.mail.internet.MimePartDataSource;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
-
-public class IMAPMultipartDataSource extends MimePartDataSource implements MultipartDataSource {
- // the list of parts
- protected BodyPart[] parts;
-
- IMAPMultipartDataSource(IMAPMessage message, MimePart parent, String section, IMAPBodyStructure bodyStructure) {
- super(parent);
-
- parts = new BodyPart[bodyStructure.parts.length];
-
- // We're either created from the parent message, in which case we're the top level
- // of the hierarchy, or we're created from a nested message, so we need to apply the
- // parent numbering prefix.
- String sectionBase = section == null ? "" : section + ".";
-
- for (int i = 0; i < parts.length; i++) {
- // create a section id. This is either the count (origin zero) or a subpart of the previous section.
- parts[i] = new IMAPMimeBodyPart(message, (IMAPBodyStructure)bodyStructure.parts[i], sectionBase + (i + 1));
- }
- }
-
- public int getCount() {
- return parts.length;
- }
-
- public BodyPart getBodyPart(int index) throws MessagingException {
- return parts[index];
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java
deleted file mode 100644
index 3349830..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespace;
-
-/**
- * An override of the base IMAPFolder class for folders representing namespace roots.
- * @see javax.mail.Folder
- *
- * @version $Rev: 594520 $
- */
-public class IMAPNamespaceFolder extends IMAPFolder {
-
- IMAPNamespaceFolder(IMAPStore store, IMAPNamespace namespace) {
- // initialize with the namespace information
- super(store, namespace.prefix, namespace.separator);
- }
-
-
- /**
- * Override of the default IMAPFolder method to provide the mailbox name
- * as the prefix + delimiter.
- *
- * @return The string name to use as the mailbox name for exists() and issubscribed()
- * calls.
- */
- protected String getMailBoxName() {
- // no delimiter is a possibility, so
- // we need to check.
- if (separator == '\0') {
- return fullname;
- }
- return fullname + separator;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java
deleted file mode 100644
index dce9420..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * 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;
-
-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.imap.connection.IMAPConnection;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
-
-/**
- * An IMAP folder instance for the root of IMAP folder tree. This has
- * some of the folder operations disabled.
- */
-public class IMAPRootFolder extends IMAPFolder {
-
- /**
- * Create a default IMAPRootFolder attached to a specific Store instance.
- *
- * @param store The Store instance this is the root for.
- */
- public IMAPRootFolder(IMAPStore store) {
- // create a folder with a null string name and the default separator.
- super(store, "", '/');
- // this only holds folders
- folderType = HOLDS_FOLDERS;
- }
-
- /**
- * Get the Folder determined by the supplied name; if the name is relative
- * then it is interpreted relative to this folder. This does not check that
- * the named folder actually exists.
- *
- * @param name the name of the folder to return
- * @return the named folder
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder getFolder(String name) throws MessagingException {
- // The root folder is a dummy one. Any getFolder() request starting
- // at the root will use the request name for the full name. The separator
- // used in that folder's namespace will be determined when the folder is
- // first opened.
- return new IMAPFolder((IMAPStore)store, name, UNDETERMINED);
- }
-
-
- public Folder getParent() {
- // we never have a parent folder
- return null;
- }
-
-
- public boolean exists() throws MessagingException {
- // this always exists
- return true;
- }
-
- public boolean hasNewMessages() {
- // we don't really exist, so the answer is always false.
- return false;
- }
-
-
- public int getMessagesCount() {
- // we don't really exist, so the answer is always 0;
- return 0;
- }
-
-
- public int getNewMessagesCount() {
- // we don't really exist, so the answer is always 0;
- return 0;
- }
-
-
- public int getUnreadMessagesCount() {
- // we don't really exist, so the answer is always 0;
- return 0;
- }
-
-
- public int getDeletedMessagesCount() {
- // we don't really exist, so the answer is always 0;
- return 0;
- }
-
-
- public boolean create(int newType) throws MessagingException {
- throw new MethodNotSupportedException("Default IMAP folder cannot be created");
- }
-
- public boolean delete(boolean recurse) throws MessagingException {
- throw new MethodNotSupportedException("Default IMAP folder cannot be deleted");
- }
-
-
- public boolean rename(boolean recurse) throws MessagingException {
- throw new MethodNotSupportedException("Default IMAP folder cannot be renamed");
- }
-
-
- public void appendMessages(Message[] msgs) throws MessagingException {
- throw new MethodNotSupportedException("Messages cannot be appended to Default IMAP folder");
- }
-
-
- public Message[] expunge() throws MessagingException {
- throw new MethodNotSupportedException("Messages cannot be expunged from Default IMAP folder");
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java
deleted file mode 100644
index 110f3c3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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;
-
-import javax.mail.Session;
-import javax.mail.URLName;
-
-/**
- * IMAP implementation of javax.mail.Store for SSL connections.
- *
- * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-public class IMAPSSLStore extends IMAPStore {
- /**
- * Construct an IMAPSSLStore item.
- *
- * @param session The owning javamail Session.
- * @param urlName The Store urlName, which can contain server target information.
- */
- public IMAPSSLStore(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, "imaps", true, DEFAULT_IMAP_SSL_PORT);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java
deleted file mode 100644
index 215557b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * 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;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.mail.AuthenticationFailedException;
-import javax.mail.Folder;
-import javax.mail.MessagingException;
-import javax.mail.Quota;
-import javax.mail.QuotaAwareStore;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.URLName;
-import javax.mail.event.StoreEvent;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPConnectionPool;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPOkResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespaceResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespace;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPServerStatusResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponse;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponseHandler;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-/**
- * IMAP implementation of javax.mail.Store
- * POP protocol spec is implemented in
- * org.apache.geronimo.javamail.store.pop3.IMAPConnection
- *
- * @version $Rev: 707037 $ $Date: 2008-10-22 07:34:53 -0400 (Wed, 22 Oct 2008) $
- */
-
-public class IMAPStore extends Store implements QuotaAwareStore, IMAPUntaggedResponseHandler {
- // the default connection ports for secure and non-secure variations
- protected static final int DEFAULT_IMAP_PORT = 143;
- protected static final int DEFAULT_IMAP_SSL_PORT = 993;
-
- protected static final String MAIL_STATUS_TIMEOUT = "statuscacheimeout";
- protected static final int DEFAULT_STATUS_TIMEOUT = 1000;
-
- // our accessor for protocol properties and the holder of
- // protocol-specific information
- protected ProtocolProperties props;
-
- // the connection pool we use for access
- protected IMAPConnectionPool connectionPool;
-
- // the root folder
- protected IMAPRootFolder root;
-
- // the list of open folders (which also represents an open connection).
- protected List openFolders = new LinkedList();
-
- // our session provided debug output stream.
- protected PrintStream debugStream;
- // the debug flag
- protected boolean debug;
- // until we're connected, we're closed
- boolean closedForBusiness = true;
- // The timeout value for our status cache
- long statusCacheTimeout = 0;
-
- /**
- * Construct an IMAPStore item.
- *
- * @param session The owning javamail Session.
- * @param urlName The Store urlName, which can contain server target information.
- */
- public IMAPStore(Session session, URLName urlName) {
- // we're the imap protocol, our default connection port is 119, and don't use
- // an SSL connection for the initial hookup
- this(session, urlName, "imap", false, DEFAULT_IMAP_PORT);
- }
-
- /**
- * Protected common constructor used by both the IMAPStore and the IMAPSSLStore
- * to initialize the Store instance.
- *
- * @param session The Session we're attached to.
- * @param urlName The urlName.
- * @param protocol The protocol name.
- * @param sslConnection
- * The sslConnection flag.
- * @param defaultPort
- * The default connection port.
- */
- protected IMAPStore(Session session, URLName urlName, String protocol, boolean sslConnection, int defaultPort) {
- super(session, urlName);
- // create the protocol property holder. This gives an abstraction over the different
- // flavors of the protocol.
- props = new ProtocolProperties(session, protocol, sslConnection, defaultPort);
-
- // get the status timeout value for the folders.
- statusCacheTimeout = props.getIntProperty(MAIL_STATUS_TIMEOUT, DEFAULT_STATUS_TIMEOUT);
-
- // get our debug settings
- debugStream = session.getDebugOut();
- debug = session.getDebug();
-
- // create a connection pool we can retrieve connections from
- connectionPool = new IMAPConnectionPool(this, props);
- }
-
-
- /**
- * Attempt the protocol-specific connection; subclasses should override this to establish
- * a connection in the appropriate manner.
- *
- * This method should return true if the connection was established.
- * It may return false to cause the {@link #connect(String, int, String, String)} method to
- * reattempt the connection after trying to obtain user and password information from the user.
- * Alternatively it may throw a AuthenticatedFailedException to abandon the conection attempt.
- *
- * @param host The target host name of the service.
- * @param port The connection port for the service.
- * @param user The user name used for the connection.
- * @param password The password used for the connection.
- *
- * @return true if a connection was established, false if there was authentication
- * error with the connection.
- * @throws AuthenticationFailedException
- * if authentication fails
- * @throws MessagingException
- * for other failures
- */
- protected synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
- if (debug) {
- debugOut("Connecting to server " + host + ":" + port + " for user " + username);
- }
-
- // the connection pool handles all of the details here.
- if (connectionPool.protocolConnect(host, port, username, password))
- {
- // the store is now open
- closedForBusiness = false;
- return true;
- }
- return false;
- }
-
-
- /**
- * Close this service and terminate its physical connection.
- * The default implementation simply calls setConnected(false) and then
- * sends a CLOSED event to all registered ConnectionListeners.
- * Subclasses overriding this method should still ensure it is closed; they should
- * also ensure that it is called if the connection is closed automatically, for
- * for example in a finalizer.
- *
- *@throws MessagingException if there were errors closing; the connection is still closed
- */
- public synchronized void close() throws MessagingException{
- // if already closed, nothing to do.
- if (closedForBusiness) {
- return;
- }
-
- // close the folders first, then shut down the Store.
- closeOpenFolders();
-
- connectionPool.close();
- connectionPool = null;
-
- // make sure we do the superclass close operation first so
- // notification events get broadcast properly.
- super.close();
- }
-
-
- /**
- * Return a Folder object that represents the root of the namespace for the current user.
- *
- * Note that in some store configurations (such as IMAP4) the root folder might
- * not be the INBOX folder.
- *
- * @return the root Folder
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder getDefaultFolder() throws MessagingException {
- checkConnectionStatus();
- // if no root yet, create a root folder instance.
- if (root == null) {
- return new IMAPRootFolder(this);
- }
- return root;
- }
-
- /**
- * Return the Folder corresponding to the given name.
- * The folder might not physically exist; the {@link Folder#exists()} method can be used
- * to determine if it is real.
- *
- * @param name the name of the Folder to return
- *
- * @return the corresponding folder
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public Folder getFolder(String name) throws MessagingException {
- return getDefaultFolder().getFolder(name);
- }
-
-
- /**
- * Return the folder identified by the URLName; the URLName must refer to this Store.
- * Implementations may use the {@link URLName#getFile()} method to determined the folder name.
- *
- * @param url
- *
- * @return the corresponding folder
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public Folder getFolder(URLName url) throws MessagingException {
- return getDefaultFolder().getFolder(url.getFile());
- }
-
-
- /**
- * Return the root folders of the personal namespace belonging to the current user.
- *
- * The default implementation simply returns an array containing the folder returned by {@link #getDefaultFolder()}.
- * @return the root folders of the user's peronal namespaces
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder[] getPersonalNamespaces() throws MessagingException {
- IMAPNamespaceResponse namespaces = getNamespaces();
-
- // if nothing is returned, then use the API-defined default for this
- if (namespaces.personalNamespaces.size() == 0) {
- return super.getPersonalNamespaces();
- }
-
- // convert the list into an array of Folders.
- return getNamespaceFolders(namespaces.personalNamespaces);
- }
-
-
- /**
- * Return the root folders of the personal namespaces belonging to the supplied user.
- *
- * The default implementation simply returns an empty array.
- *
- * @param user the user whose namespaces should be returned
- * @return the root folders of the given user's peronal namespaces
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder[] getUserNamespaces(String user) throws MessagingException {
- IMAPNamespaceResponse namespaces = getNamespaces();
-
- // if nothing is returned, then use the API-defined default for this
- if (namespaces.otherUserNamespaces == null || namespaces.otherUserNamespaces.isEmpty()) {
- return super.getUserNamespaces(user);
- }
-
- // convert the list into an array of Folders.
- return getNamespaceFolders(namespaces.otherUserNamespaces);
- }
-
-
- /**
- * Return the root folders of namespaces that are intended to be shared between users.
- *
- * The default implementation simply returns an empty array.
- * @return the root folders of all shared namespaces
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder[] getSharedNamespaces() throws MessagingException {
- IMAPNamespaceResponse namespaces = getNamespaces();
-
- // if nothing is returned, then use the API-defined default for this
- if (namespaces.sharedNamespaces == null || namespaces.sharedNamespaces.isEmpty()) {
- return super.getSharedNamespaces();
- }
-
- // convert the list into an array of Folders.
- return getNamespaceFolders(namespaces.sharedNamespaces);
- }
-
-
- /**
- * Get the quotas for the specified root element.
- *
- * @param root The root name for the quota information.
- *
- * @return An array of Quota objects defined for the root.
- * @throws MessagingException if the quotas cannot be retrieved
- */
- public Quota[] getQuota(String root) throws javax.mail.MessagingException {
- // get our private connection for access
- IMAPConnection connection = getStoreConnection();
- try {
- // request the namespace information from the server
- return connection.fetchQuota(root);
- } finally {
- releaseStoreConnection(connection);
- }
- }
-
- /**
- * Set a quota item. The root contained in the Quota item identifies
- * the quota target.
- *
- * @param quota The source quota item.
- * @throws MessagingException if the quota cannot be set
- */
- public void setQuota(Quota quota) throws javax.mail.MessagingException {
- // get our private connection for access
- IMAPConnection connection = getStoreConnection();
- try {
- // request the namespace information from the server
- connection.setQuota(quota);
- } finally {
- releaseStoreConnection(connection);
- }
- }
-
- /**
- * Verify that the server is in a connected state before
- * performing operations that required that status.
- *
- * @exception MessagingException
- */
- private void checkConnectionStatus() throws MessagingException {
- // we just check the connection status with the superclass. This
- // tells us we've gotten a connection. We don't want to do the
- // complete connection checks that require pinging the server.
- if (!super.isConnected()){
- throw new MessagingException("Not connected ");
- }
- }
-
-
- /**
- * Test to see if we're still connected. This will ping the server
- * to see if we're still alive.
- *
- * @return true if we have a live, active culture, false otherwise.
- */
- public synchronized boolean isConnected() {
- // check if we're in a presumed connected state. If not, we don't really have a connection
- // to check on.
- if (!super.isConnected()) {
- return false;
- }
-
- try {
- IMAPConnection connection = getStoreConnection();
- try {
- // check with the connecition to see if it's still alive.
- // we use a zero timeout value to force it to check.
- return connection.isAlive(0);
- } finally {
- releaseStoreConnection(connection);
- }
- } catch (MessagingException e) {
- return false;
- }
-
- }
-
- /**
- * Internal debug output routine.
- *
- * @param value The string value to output.
- */
- void debugOut(String message) {
- debugStream.println("IMAPStore DEBUG: " + message);
- }
-
- /**
- * Internal debugging routine for reporting exceptions.
- *
- * @param message A message associated with the exception context.
- * @param e The received exception.
- */
- void debugOut(String message, Throwable e) {
- debugOut("Received exception -> " + message);
- debugOut("Exception message -> " + e.getMessage());
- e.printStackTrace(debugStream);
- }
-
-
- /**
- * Retrieve the server connection created by this store.
- *
- * @return The active connection object.
- */
- protected IMAPConnection getStoreConnection() throws MessagingException {
- return connectionPool.getStoreConnection();
- }
-
- protected void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
- // This is a bit of a pain. We need to delay processing of the
- // unsolicited responses until after each user of the connection has
- // finished processing the expected responses. We need to do this because
- // the unsolicited responses may include EXPUNGED messages. The EXPUNGED
- // messages will alter the message sequence numbers for the messages in the
- // cache. Processing the EXPUNGED messages too early will result in
- // updates getting applied to the wrong message instances. So, as a result,
- // we delay that stage of the processing until all expected responses have
- // been handled.
-
- // process any pending messages before returning.
- connection.processPendingResponses();
- // return this to the connectin pool
- connectionPool.releaseStoreConnection(connection);
- }
-
- synchronized IMAPConnection getFolderConnection(IMAPFolder folder) throws MessagingException {
- IMAPConnection connection = connectionPool.getFolderConnection();
- openFolders.add(folder);
- return connection;
- }
-
-
- synchronized void releaseFolderConnection(IMAPFolder folder, IMAPConnection connection) throws MessagingException {
- openFolders.remove(folder);
- // return this to the connectin pool
- // NB: It is assumed that the Folder has already triggered handling of
- // unsolicited responses on this connection before returning it.
- connectionPool.releaseFolderConnection(connection);
- }
-
-
- /**
- * Retrieve the Session object this Store is operating under.
- *
- * @return The attached Session instance.
- */
- Session getSession() {
- return session;
- }
-
- /**
- * Close all open folders. We have a small problem here with a race condition. There's no safe, single
- * synchronization point for us to block creation of new folders while we're closing. So we make a copy of
- * the folders list, close all of those folders, and keep repeating until we're done.
- */
- protected void closeOpenFolders() {
- // we're no longer accepting additional opens. Any folders that open after this point will get an
- // exception trying to get a connection.
- closedForBusiness = true;
-
- while (true) {
- List folders = null;
-
- // grab our lock, copy the open folders reference, and null this out. Once we see a null
- // open folders ref, we're done closing.
- synchronized(connectionPool) {
- folders = openFolders;
- openFolders = new LinkedList();
- }
-
- // null folder, we're done
- if (folders.isEmpty()) {
- return;
- }
- // now close each of the open folders.
- for (int i = 0; i < folders.size(); i++) {
- IMAPFolder folder = (IMAPFolder)folders.get(i);
- try {
- folder.close(false);
- } catch (MessagingException e) {
- }
- }
- }
- }
-
- /**
- * Get the namespace information from the IMAP server.
- *
- * @return An IMAPNamespaceResponse with the namespace information.
- * @exception MessagingException
- */
- protected IMAPNamespaceResponse getNamespaces() throws MessagingException {
- // get our private connection for access
- IMAPConnection connection = getStoreConnection();
- try {
- // request the namespace information from the server
- return connection.getNamespaces();
- } finally {
- releaseStoreConnection(connection);
- }
- }
-
-
- /**
- * Convert a List of IMAPNamespace definitions into an array of Folder
- * instances.
- *
- * @param namespaces The namespace List
- *
- * @return An array of the same size as the namespace list containing a Folder
- * instance for each defined namespace.
- * @exception MessagingException
- */
- protected Folder[] getNamespaceFolders(List namespaces) throws MessagingException {
- Folder[] folders = new Folder[namespaces.size()];
-
- // convert each of these to a Folder instance.
- for (int i = 0; i < namespaces.size(); i++) {
- IMAPNamespace namespace = (IMAPNamespace)namespaces.get(i);
- folders[i] = new IMAPNamespaceFolder(this, namespace);
- }
- return folders;
- }
-
-
- /**
- * Test if this connection has a given capability.
- *
- * @param capability The capability name.
- *
- * @return true if this capability is in the list, false for a mismatch.
- */
- public boolean hasCapability(String capability) {
- return connectionPool.hasCapability(capability);
- }
-
-
- /**
- * Handle an unsolicited response from the server. Most unsolicited responses
- * are replies to specific commands sent to the server. The remainder must
- * be handled by the Store or the Folder using the connection. These are
- * critical to handle, as events such as expunged messages will alter the
- * sequence numbers of the live messages. We need to keep things in sync.
- *
- * @param response The UntaggedResponse to process.
- *
- * @return true if we handled this response and no further handling is required. false
- * means this one wasn't one of ours.
- */
- public boolean handleResponse(IMAPUntaggedResponse response) {
- // Some sort of ALERT response from the server?
- // we need to broadcast this to any of the listeners
- if (response.isKeyword("ALERT")) {
- notifyStoreListeners(StoreEvent.ALERT, ((IMAPOkResponse)response).getMessage());
- return true;
- }
- // potentially some sort of unsolicited OK notice. This is also an event.
- else if (response.isKeyword("OK")) {
- String message = ((IMAPOkResponse)response).getMessage();
- if (message.length() > 0) {
- notifyStoreListeners(StoreEvent.NOTICE, message);
- }
- return true;
- }
- // potentially some sort of unsolicited notice. This is also an event.
- else if (response.isKeyword("BAD") || response.isKeyword("NO")) {
- String message = ((IMAPServerStatusResponse)response).getMessage();
- if (message.length() > 0) {
- notifyStoreListeners(StoreEvent.NOTICE, message);
- }
- return true;
- }
- // this is a BYE response on our connection. Folders should be handling the
- // BYE events on their connections, so we should only be seeing this if
- // it's on the store connection.
- else if (response.isKeyword("BYE")) {
- // this is essentially a close event. We need to clean everything up
- try {
- close();
- } catch (MessagingException e) {
- }
- return true;
- }
- return false;
- }
-
- /**
- * Finalizer to perform IMAPStore() cleanup when
- * no longer in use.
- *
- * @exception Throwable
- */
- protected void finalize() throws Throwable {
- super.finalize();
- close();
- }
-
- /**
- * Retrieve the protocol properties for the Store.
- *
- * @return The protocol properties bundle.
- */
- ProtocolProperties getProperties() {
- return props;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java
deleted file mode 100644
index c08ef0f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
- * 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;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Represents a set of rights associated with a user to manipulate the
- * IMAP Store.
- */
-public class Rights implements Cloneable {
-
- /**
- * An individual right for IMAP Store manipulation.
- */
- public static final class Right {
- // The set of created stores. The getInstance() method ensures
- // that each right is a singleton object.
- static private Map rights = new HashMap();
-
- /**
- * lookup (mailbox is visible to LIST/LSUB commands)
- */
- public static final Right LOOKUP = getInstance('l');
- /**
- * read (SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
- * SEARCH, COPY from mailbox)
- */
- public static final Right READ = getInstance('r');
- /**
- * keep seen/unseen information across sessions (STORE SEEN flag)
- */
- public static final Right KEEP_SEEN = getInstance('s');
- /**
- * write (STORE flags other than SEEN and DELETED)
- */
- public static final Right WRITE = getInstance('w');
- /**
- * insert (perform APPEND, COPY into mailbox)
- */
- public static final Right INSERT = getInstance('i');
- /**
- * post (send mail to submission address for mailbox,
- * not enforced by IMAP4 itself)
- */
- public static final Right POST = getInstance('p');
- /**
- * create (CREATE new sub-mailboxes in any implementation-defined
- * hierarchy)
- */
- public static final Right CREATE = getInstance('c');
- /**
- * delete (STORE DELETED flag, perform EXPUNGE)
- */
- public static final Right DELETE = getInstance('d');
- /**
- * administer (perform SETACL)
- */
- public static final Right ADMINISTER = getInstance('a');
-
- // the actual right definition
- String right;
-
- /**
- * Private constructor for an individual Right. Used by getInstance().
- *
- * @param right The String name of the right (a single character).
- */
- private Right(String right) {
- this.right = right;
- }
-
- /**
- * Get an instance for a right from the single character right value. The
- * returned instance will be a singleton for that character value.
- *
- * @param right The right character value.
- *
- * @return A Right instance that's the mapping for the character value.
- */
- public static synchronized Right getInstance(char right) {
- String name = String.valueOf(right);
- Right instance = (Right)rights.get(name);
- if (instance == null) {
- instance = new Right(name);
- rights.put(name, instance);
- }
- return instance;
- }
-
- /**
- * Return the string value of the Right. The string value is the character
- * used to create the Right with newInstance().
- *
- * @return The string representation of the Right.
- */
- public String toString() {
- return right;
- }
- }
-
- /**
- * The set of Rights contained in this instance. This is a TreeSet so that
- * we can create the string value more consistently.
- */
- private SortedSet rights = new TreeSet(new RightComparator());
-
- /**
- * Construct an empty set of Rights.
- */
- public Rights() {
- }
-
- /**
- * Construct a Rights set from a single Right instance.
- *
- * @param right The source Right.
- */
- public Rights(Right right) {
- rights.add(right);
- }
-
- /**
- * Construct a set of rights from an existing Rights set. This will copy
- * the rights values.
- *
- * @param list The source Rights instance.
- */
- public Rights(Rights list) {
- add(list);
- Rights[] otherRights = list.getRights();
- for (int i = 0; i < otherRights.length; i++) {
- rights.add(otherRights[i]);
- }
- }
-
- /**
- * Construct a Rights et from a character string. Each character in the
- * string represents an individual Right.
- *
- * @param list The source set of rights.
- */
- public Rights(String list) {
- for (int i = 0; i < list.length(); i++) {
- rights.add(Right.getInstance(list.charAt(i)));
- }
- }
-
- /**
- * Add a single Right to the set.
- *
- * @param right The new Right. If the Rigtht is already part of the Set, this is a nop.
- */
- public void add(Right right) {
- rights.add(right);
- }
-
- /**
- * Merge a Rights set with this set. Duplicates are eliminated.
- *
- * @param list The source for the added Rights.
- */
- public void add(Rights list) {
- Rights[] otherRights = list.getRights();
- for (int i = 0; i < otherRights.length; i++) {
- rights.add(otherRights[i]);
- }
- }
-
- /**
- * Clone a set of Rights.
- */
- public Object clone() {
- return new Rights(this);
- }
-
- /**
- * Test if a Rights set contains a given Right.
- *
- * @param right The Right instance to test.
- *
- * @return true if the Right exists in the Set, false otherwise.
- */
- public boolean contains(Right right) {
- return rights.contains(right);
- }
-
- /**
- * Test if this Rights set contains all of the Rights contained in another
- * set.
- *
- * @param list The source Rights set for the test.
- *
- * @return true if all of the Rights in the source set exist in the target set.
- */
- public boolean contains(Rights list) {
- return rights.containsAll(list.rights);
- }
-
- /**
- * Test if two Rights sets are equivalent.
- *
- * @param list The source rights set.
- *
- * @return true if both Rigths sets contain the same Rights values.
- */
- public boolean equals(Rights list) {
- return rights.equals(list.rights);
- }
-
- /**
- * Get an array of Rights contained in the set.
- *
- * @return An array of Rights[] values.
- */
- public Rights[] getRights() {
- Rights[] list = new Rights[rights.size()];
- return (Rights[])rights.toArray(list);
- }
-
- /**
- * Compute a hashCode for the Rights set.
- *
- * @return The computed hashCode.
- */
- public int hashCode() {
- return rights.hashCode();
- }
-
- /**
- * Remove a Right from the set.
- *
- * @param right The single Right to remove.
- */
- public void remove(Right right) {
- rights.remove(right);
- }
-
- /**
- * Remove a set of rights from the set.
- *
- * @param list The list of rights to be removed.
- */
- public void remove(Rights list) {
- rights.removeAll(list.rights);
- }
-
- /**
- * Return a string value for the Rights set. The string value is the
- * concatenation of the single-character Rights names.
- *
- * @return The string representation of this Rights set.
- */
- public String toString() {
- StringBuffer buff = new StringBuffer();
- Iterator i = rights.iterator();
- while (i.hasNext()) {
- buff.append(i.next().toString());
- }
- return buff.toString();
- }
-
- class RightComparator implements Comparator {
- /**
- * Perform a sort comparison to order two Right objects.
- * The sort is performed using the string value.
- *
- * @param o1 The left comparator
- * @param o2 The right comparator.
- *
- * @return 0 if the two items have equal ordering, -1 if the
- * left item is lower, 1 if the left item is greater.
- */
- public int compare(Object o1, Object o2) {
- // compare on the string value
- String left = o1.toString();
- return left.compareTo(o2.toString());
- }
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java
deleted file mode 100644
index 46ed792..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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.ACL;
-import org.apache.geronimo.javamail.store.imap.Rights;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-
-/**
- * Utility class to aggregate status responses for a mailbox.
- */
-public class IMAPACLResponse extends IMAPUntaggedResponse {
- public String mailbox;
- public ACL[] acls;
-
- public IMAPACLResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("ACL", data);
-
- mailbox = source.readEncodedString();
- List temp = new ArrayList();
-
- while (source.hasMore()) {
- String name = source.readString();
- String rights = source.readString();
- temp.add(new ACL(name, new Rights(rights)));
- }
-
- acls = new ACL[temp.size()];
- acls = (ACL[])temp.toArray(acls);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java
deleted file mode 100644
index 9efe633..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-import javax.mail.MessagingException;
-
-
-/**
- * The full body content of a message.
- */
-public class IMAPBody extends IMAPFetchBodyPart {
- // the body content data
- byte[] content = null;
-
- /**
- * Construct a top-level MessageText data item.
- *
- * @param data The data for the Message Text
- *
- * @exception MessagingException
- */
- public IMAPBody(byte[] data) throws MessagingException {
- this(new IMAPBodySection(IMAPBodySection.BODY), data);
- }
-
- /**
- * Create a Message Text instance.
- *
- * @param section The section information. This may include substring information if this
- * was just a partical fetch.
- * @param data The message content data.
- *
- * @exception MessagingException
- */
- public IMAPBody(IMAPBodySection section, byte[] data) throws MessagingException {
- super(BODY, section);
- // save the content
- content = data;
- }
-
-
- /**
- * Get the part content as a byte array.
- *
- * @return The part content as a byte array.
- */
- public byte[] getContent() {
- return content;
- }
-
- /**
- * Get an input stream for reading the part content.
- *
- * @return An ByteArrayInputStream sourced to the part content.
- */
- public InputStream getInputStream() {
- return new ByteArrayInputStream(content);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java
deleted file mode 100644
index cb2dc35..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * 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 java.util.ArrayList;
-import java.util.StringTokenizer;
-
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.javamail.util.ResponseFormatException;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-
-/**
- * Class to represent a FETCH response BODY segment qualifier. The qualifier is
- * of the form "BODY[<section>]<<partial>>". The optional section qualifier is
- * a "." separated part specifiers. A part specifier is either a number, or
- * one of the tokens HEADER, HEADER.FIELD, HEADER.FIELD.NOT, MIME, and TEXT.
- * The partial specification is in the form "<start.length>".
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-public class IMAPBodySection {
- // the section type qualifiers
- static public final int BODY = 0;
- static public final int HEADERS = 1;
- static public final int HEADERSUBSET = 2;
- static public final int MIME = 3;
- static public final int TEXT = 4;
-
- // the optional part number
- public String partNumber = "1";
- // the string name of the section
- public String sectionName = "";
- // the section qualifier
- public int section;
- // the starting substring position
- public int start = -1;
- // the substring length (requested)
- public int length = -1;
- // the list of any explicit header names
- public List headers = null;
-
- /**
- * Construct a simple-toplevel BodySection tag.
- *
- * @param section The section identifier.
- */
- public IMAPBodySection(int section) {
- this.section = section;
- partNumber = "1";
- start = -1;
- length = -1;
- }
-
- /**
- * construct a BodySegment descriptor from the FETCH returned name.
- *
- * @param name The name code, which may be encoded with a section identifier and
- * substring qualifiers.
- *
- * @exception MessagingException
- */
- public IMAPBodySection(IMAPResponseTokenizer source) throws MessagingException {
-
- // this could be just "BODY" alone.
- if (!source.peek(false, true).isType('[')) {
- // complete body, all other fields take default
- section = BODY;
- return;
- }
-
- // now we need to scan along this, building up the pieces as we go.
- // NOTE: The section identifiers use "[", "]", "." as delimiters, which
- // are normally acceptable in ATOM names. We need to use the expanded
- // delimiter set to parse these tokens off.
- Token token = source.next(false, true);
- // the first token was the "[", now step to the next token in line.
- token = source.next(false, true);
-
- if (token.isType(Token.NUMERIC)) {
- token = parsePartNumber(token, source);
- }
-
- // have a potential name here?
- if (token.isType(Token.ATOM)) {
- token = parseSectionName(token, source);
- }
-
- // the HEADER.FIELD and HEADER.FIELD.NOT section types
- // are followed by a list of header names.
- if (token.isType('(')) {
- token = parseHeaderList(source);
- }
-
- // ok, in theory, our current token should be a ']'
- if (!token.isType(']')) {
- throw new ResponseFormatException("Invalid section identifier on FETCH response");
- }
-
- // do we have a substring qualifier?
- // that needs to be stripped off too
- parseSubstringValues(source);
-
- // now fill in the type information
- if (sectionName.equals("")) {
- section = BODY;
- }
- else if (sectionName.equals("HEADER")) {
- section = HEADERS;
- }
- else if (sectionName.equals("HEADER.FIELDS")) {
- section = HEADERSUBSET;
- }
- else if (sectionName.equals("HEADER.FIELDS.NOT")) {
- section = HEADERSUBSET;
- }
- else if (sectionName.equals("TEXT")) {
- section = TEXT;
- }
- else if (sectionName.equals("MIME")) {
- section = MIME;
- }
- }
-
-
- /**
- * Strip the part number off of a BODY section identifier. The part number
- * is a series of "." separated tokens. So "BODY[3.2.1]" would be the BODY for
- * section 3.2.1 of a multipart message. The section may also have a qualifier
- * name on the end. "BODY[3.2.1.HEADER}" would be the HEADERS for that
- * body section. The return value is the name of the section, which can
- * be a "" or the the section qualifier (e.g., "HEADER").
- *
- * @param name The section name.
- *
- * @return The remainder of the section name after the numeric part number has
- * been removed.
- */
- private Token parsePartNumber(Token token, IMAPResponseTokenizer source) throws MessagingException {
- StringBuffer part = new StringBuffer(token.getValue());
- // NB: We're still parsing with the expanded delimiter set
- token = source.next(false, true);
-
- while (true) {
- // Not a period? We've reached the end of the section number,
- // finalize the part number and let the caller figure out what
- // to do from here.
- if (!token.isType('.')) {
- partNumber = part.toString();
- return token;
- }
- // might have another number section
- else {
- // step to the next token
- token = source.next(false, true);
- // another section number piece?
- if (token.isType(Token.NUMERIC)) {
- // add this to the collection, and continue
- part.append('.');
- part.append(token.getValue());
- token = source.next(false, true);
- }
- else {
- partNumber = part.toString();
- // this is likely the start of the section name
- return token;
- }
- }
- }
- }
-
-
- /**
- * Parse the section name, if any, in a BODY section qualifier. The
- * section name may stand alone within the body section (e.g.,
- * "BODY[HEADERS]" or follow the section number (e.g.,
- * "BODY[1.2.3.HEADERS.FIELDS.NOT]".
- *
- * @param token The first token of the name sequence.
- * @param source The source tokenizer.
- *
- * @return The first non-name token in the response.
- */
- private Token parseSectionName(Token token, IMAPResponseTokenizer source) throws MessagingException {
- StringBuffer part = new StringBuffer(token.getValue());
- // NB: We're still parsing with the expanded delimiter set
- token = source.next(false, true);
-
- while (true) {
- // Not a period? We've reached the end of the section number,
- // finalize the part number and let the caller figure out what
- // to do from here.
- if (!token.isType('.')) {
- sectionName = part.toString();
- return token;
- }
- // might have another number section
- else {
- // add this to the collection, and continue
- part.append('.');
- part.append(source.readString());
- token = source.next(false, true);
- }
- }
- }
-
-
- /**
- * Parse a header list that may follow the HEADER.FIELD or HEADER.FIELD.NOT
- * name qualifier. This is a list of string values enclosed in parens.
- *
- * @param source The source tokenizer.
- *
- * @return The next token in the response (which should be the section terminator, ']')
- * @exception MessagingException
- */
- private Token parseHeaderList(IMAPResponseTokenizer source) throws MessagingException {
- headers = new ArrayList();
-
- // normal parsing rules going on here
- while (source.notListEnd()) {
- String value = source.readString();
- headers.add(value);
- }
- // step over the closing paren
- source.next();
- // NB, back to the expanded token rules again
- return source.next(false, true);
- }
-
-
- /**
- * Parse off the substring values following the section identifier, if
- * any. If present, they will be in the format "<start.len>".
- *
- * @param source The source tokenizer.
- *
- * @exception MessagingException
- */
- private void parseSubstringValues(IMAPResponseTokenizer source) throws MessagingException {
- // We rarely have one of these, so it's a quick out
- if (!source.peek(false, true).isType('<')) {
- return;
- }
- // step over the angle bracket.
- source.next(false, true);
- // pull out the start information
- start = source.next(false, true).getInteger();
- // step over the period
- source.next(false, true);
- // now the length bit
- length = source.next(false, true).getInteger();
- // and consume the closing angle bracket
- source.next(false, true);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java
deleted file mode 100644
index 80cf50e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * 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.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.ContentDisposition;
-import javax.mail.internet.ContentType;
-
-import org.apache.geronimo.javamail.util.ResponseFormatException;
-
-
-public class IMAPBodyStructure extends IMAPFetchDataItem {
-
- // the MIME type information
- public ContentType mimeType = new ContentType();
- // the content disposition info
- public ContentDisposition disposition = null;
- // the message ID
- public String contentID;
- public String contentDescription;
- public String transferEncoding;
- // size of the message
- public int bodySize;
- // number of lines, which only applies to text types.
- public int lines = -1;
-
- // "parts is parts". If this is a multipart message, we have a body structure item for each subpart.
- public IMAPBodyStructure[] parts;
- // optional dispostiion parameters
- public Map dispositionParameters;
- // language parameters
- public List languages;
- // the MD5 hash
- public String md5Hash;
-
- // references to nested message information.
- public IMAPEnvelope nestedEnvelope;
- public IMAPBodyStructure nestedBody;
-
-
- public IMAPBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
- super(BODYSTRUCTURE);
- parseBodyStructure(source);
- }
-
-
- protected void parseBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
- // the body structure needs to start with a left paren
- source.checkLeftParen();
-
- // if we start with a parentized item, we have a multipart content type. We need to
- // recurse on each of those as appropriate
- if (source.peek().getType() == '(') {
- parseMultipartBodyStructure(source);
- }
- else {
- parseSinglepartBodyStructure(source);
- }
- }
-
-
- protected void parseMultipartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
- mimeType.setPrimaryType("multipart");
- ArrayList partList = new ArrayList();
-
- do {
- // parse the subpiece (which might also be a multipart).
- IMAPBodyStructure part = new IMAPBodyStructure(source);
- partList.add(part);
- // we keep doing this as long as we seen parenthized items.
- } while (source.peek().getType() == '(');
-
- parts = (IMAPBodyStructure[])partList.toArray(new IMAPBodyStructure[partList.size()]);
-
- // get the subtype (required)
- mimeType.setSubType(source.readString());
-
- // if the next token is the list terminator, we're done. Otherwise, we need to read extension
- // data.
- if (source.checkListEnd()) {
- return;
- }
- // read the content parameter information and copy into the ContentType.
- mimeType.setParameterList(source.readParameterList());
-
- // more optional stuff
- if (source.checkListEnd()) {
- return;
- }
-
- // go parse the extensions that are common to both single- and multi-part messages.
- parseMessageExtensions(source);
- }
-
-
- protected void parseSinglepartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
- // get the primary and secondary types.
- mimeType.setPrimaryType(source.readString());
- mimeType.setSubType(source.readString());
-
- // read the parameters associated with the content type.
- mimeType.setParameterList(source.readParameterList());
-
- // now a bunch of string value parameters
- contentID = source.readStringOrNil();
- contentDescription = source.readStringOrNil();
- transferEncoding = source.readStringOrNil();
- bodySize = source.readInteger();
-
- // is this an embedded message type? Embedded messages include envelope and body structure
- // information for the embedded message next.
- if (mimeType.match("message/rfc822")) {
- // parse the nested information
- nestedEnvelope = new IMAPEnvelope(source);
- nestedBody = new IMAPBodyStructure(source);
- lines = source.readInteger();
- }
- // text types include a line count
- else if (mimeType.match("text/*")) {
- lines = source.readInteger();
- }
-
- // now the optional extension data. All of these are optional, but must be in the specified order.
- if (source.checkListEnd()) {
- return;
- }
-
- md5Hash = source.readString();
-
- // go parse the extensions that are common to both single- and multi-part messages.
- parseMessageExtensions(source);
- }
-
- /**
- * Parse common message extension information shared between
- * single part and multi part messages.
- *
- * @param source The source tokenizer..
- */
- protected void parseMessageExtensions(IMAPResponseTokenizer source) throws MessagingException {
-
- // now the optional extension data. All of these are optional, but must be in the specified order.
- if (source.checkListEnd()) {
- return;
- }
-
- disposition = new ContentDisposition();
- // now the dispostion. This is a string, followed by a parameter list.
- if (source.peek(true).getType() == '(') {
- source.checkLeftParen();
- disposition.setDisposition(source.readString());
- disposition.setParameterList(source.readParameterList());
- source.checkRightParen();
- } else if (source.peek(true) == IMAPResponseTokenizer.NIL) {
- source.next();
- } else {
- throw new ResponseFormatException("Expecting NIL or '(' in response");
- }
-
- // once more
- if (source.checkListEnd()) {
- return;
- }
- // read the language info.
- languages = source.readStringList();
- // next is the body location information. The Javamail APIs don't really expose that, so
- // we'll just skip over that.
-
- // once more
- if (source.checkListEnd()) {
- return;
- }
- // read the location info.
- source.readStringList();
-
- // we don't recognize any other forms of extension, so just skip over these.
- while (source.notListEnd()) {
- source.skipExtensionItem();
- }
-
- // step over the closing paren
- source.next();
- }
-
-
- /**
- * Tests if a body structure is for a multipart body.
- *
- * @return true if this is a multipart body part, false for a single part.
- */
- public boolean isMultipart() {
- return parts != null;
- }
-
-
- /**
- * Test if this body structure represents an attached message. If it's a
- * message, this will be a single part of MIME type message/rfc822.
- *
- * @return True if this is a nested message type, false for either a multipart or
- * a single part of another type.
- */
- public boolean isAttachedMessage() {
- return !isMultipart() && mimeType.match("message/rfc822");
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java
deleted file mode 100644
index c0012ea..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * 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.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-
-/**
- * Util class to represent a CAPABILITY response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-public class IMAPCapabilityResponse extends IMAPUntaggedResponse {
- // the advertised capabilities
- protected Map capabilities = new HashMap();
- // the authentication mechanisms. The order is important with
- // the authentications, as we a) want to process these in the
- // order presented, and b) need to convert them into String arrays
- // for Sasl API calls.
- protected List authentications = new ArrayList();
-
- /**
- * 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 IMAPCapabilityResponse(IMAPResponseTokenizer source, byte [] response) throws MessagingException {
- super("CAPABILITY", response);
-
- // parse each of the capability tokens. We're using the default RFC822 parsing rules,
- // which does not consider "=" to be a delimiter token, so all "AUTH=" capabilities will
- // come through as a single token.
- while (source.hasMore()) {
- // the capabilities are always ATOMs.
- String value = source.readAtom().toUpperCase();
- // is this an authentication option?
- if (value.startsWith("AUTH=")) {
- // parse off the mechanism that fillows the "=", and add this to the supported list.
- String mechanism = value.substring(5);
- authentications.add(mechanism);
- }
- else {
- // just add this to the capabilities map.
- capabilities.put(value, value);
- }
- }
- }
-
-
- /**
- * Return the capability map for the server.
- *
- * @return A map of the capability items.
- */
- public Map getCapabilities() {
- return capabilities;
- }
-
- /**
- * Retrieve the map of the server-supported authentication
- * mechanisms.
- *
- * @return
- */
- public List getAuthentications() {
- return authentications;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
deleted file mode 100644
index d49b513..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/**
- * 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.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Vector;
-
-import javax.mail.FetchProfile;
-import javax.mail.Flags;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Quota;
-import javax.mail.UIDFolder;
-
-import javax.mail.search.AddressTerm;
-import javax.mail.search.AndTerm;
-import javax.mail.search.BodyTerm;
-import javax.mail.search.ComparisonTerm;
-import javax.mail.search.DateTerm;
-import javax.mail.search.FlagTerm;
-import javax.mail.search.FromTerm;
-import javax.mail.search.FromStringTerm;
-import javax.mail.search.HeaderTerm;
-import javax.mail.search.MessageIDTerm;
-import javax.mail.search.MessageNumberTerm;
-import javax.mail.search.NotTerm;
-import javax.mail.search.OrTerm;
-import javax.mail.search.ReceivedDateTerm;
-import javax.mail.search.RecipientTerm;
-import javax.mail.search.RecipientStringTerm;
-import javax.mail.search.SearchException;
-import javax.mail.search.SearchTerm;
-import javax.mail.search.SentDateTerm;
-import javax.mail.search.SizeTerm;
-import javax.mail.search.StringTerm;
-import javax.mail.search.SubjectTerm;
-
-import org.apache.geronimo.javamail.store.imap.ACL;
-import org.apache.geronimo.javamail.store.imap.IMAPFolder;
-import org.apache.geronimo.javamail.store.imap.Rights;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-
-import org.apache.geronimo.javamail.util.CommandFailedException;
-
-
-/**
- * Utility class for building up what might be complex arguments
- * to a command. This includes the ability to directly write out
- * binary arrays of data and have them constructed as IMAP
- * literals.
- */
-public class IMAPCommand {
-
- // digits table for encoding IMAP modified Base64. Note that this differs
- // from "normal" base 64 by using ',' instead of '/' for the last digit.
- public static final char[] encodingTable = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
- 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u',
- 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6',
- '7', '8', '9',
- '+', ','
- };
-
- protected boolean needWhiteSpace = false;
-
- // our utility writer stream
- protected DataOutputStream out;
- // the real output target
- protected ByteArrayOutputStream sink;
- // our command segment set. If the command contains literals, then the literal
- // data must be sent after receiving an continue response back from the server.
- protected List segments = null;
- // the append tag for the response
- protected String tag;
-
- // our counter used to generate command tags.
- static protected int tagCounter = 0;
-
- /**
- * Create an empty command.
- */
- public IMAPCommand() {
- try {
- sink = new ByteArrayOutputStream();
- out = new DataOutputStream(sink);
-
- // write the tag data at the beginning of the command.
- out.writeBytes(getTag());
- // need a blank separator
- out.write(' ');
- } catch (IOException e ) {
- }
- }
-
- /**
- * Create a command with an initial command string.
- *
- * @param command The command string used to start this command.
- */
- public IMAPCommand(String command) {
- this();
- append(command);
- }
-
- public String getTag() {
- if (tag == null) {
- // the tag needs to be non-numeric, so tack a convenient alpha character on the front.
- tag = "a" + tagCounter++;
- }
- return tag;
- }
-
-
- /**
- * Save the current segment of the command we've accumulated. This
- * generally occurs because we have a literal element in the command
- * that's going to require a continuation response from the server before
- * we can send it.
- */
- private void saveCurrentSegment()
- {
- try {
- out.flush(); // make sure everything is written
- // get the data so far and reset the sink
- byte[] segment = sink.toByteArray();
- sink.reset();
- // most commands don't have segments, so don't create the list until we do.
- if (segments == null) {
- segments = new ArrayList();
- }
- // ok, we need to issue this command as a conversation.
- segments.add(segment);
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Write all of the command data to the stream. This includes the
- * leading tag data.
- *
- * @param outStream
- * @param connection
- *
- * @exception IOException
- * @exception MessagingException
- */
- public void writeTo(OutputStream outStream, IMAPConnection connection) throws IOException, MessagingException
- {
-
- // just a simple, single string-encoded command?
- if (segments == null) {
- // make sure the output stream is flushed
- out.flush();
- // just copy the command data to the output stream
- sink.writeTo(outStream);
- // we need to end the command with a CRLF sequence.
- outStream.write('\r');
- outStream.write('\n');
- }
- // multiple-segment mode, which means we need to deal with continuation responses at
- // each of the literal boundaries.
- else {
- // at this point, we have a list of command pieces that must be written out, then a
- // continuation response checked for after each write. Once each of these pieces is
- // written out, we still have command stuff pending in the out stream, which we'll tack
- // on to the end.
- for (int i = 0; i < segments.size(); i++) {
- outStream.write((byte [])segments.get(i));
- // now wait for a response from the connection. We should be getting a
- // continuation response back (and might have also received some asynchronous
- // replies, which we'll leave in the queue for now. If we get some status back
- // other than than a continue, we've got an error in our command somewhere.
- IMAPTaggedResponse response = connection.receiveResponse();
- if (!response.isContinuation()) {
- throw new CommandFailedException("Error response received on a IMAP continued command: " + response);
- }
- }
- out.flush();
- // all leading segments written with the appropriate continuation received in reply.
- // just copy the command data to the output stream
- sink.writeTo(outStream);
- // we need to end the command with a CRLF sequence.
- outStream.write('\r');
- outStream.write('\n');
- }
- }
-
-
- /**
- * Directly append a value to the buffer without attempting
- * to insert whitespace or figure out any format encodings.
- *
- * @param value The value to append.
- */
- public void append(String value) {
- try {
- // add the bytes direcly
- out.writeBytes(value);
- // assume we're needing whitespace after this (pretty much unknown).
- needWhiteSpace = true;
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append a string value to a command buffer. This sorts out
- * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
- * or ATOM).
- *
- * @param target The target buffer for appending the string.
- * @param value The value to append.
- */
- public void appendString(String value) {
- try {
- // work off the byte values
- appendString(value.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
-
- /**
- * Append a string value to a command buffer. This always appends as
- * a QUOTEDSTRING
- *
- * @param value The value to append.
- */
- public void appendQuotedString(String value) {
- try {
- // work off the byte values
- appendQuotedString(value.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
-
- /**
- * Append a string value to a command buffer, with encoding. This sorts out
- * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
- * or ATOM).
- *
- * @param target The target buffer for appending the string.
- * @param value The value to append.
- */
- public void appendEncodedString(String value) {
- // encode first.
- value = encode(value);
- try {
- // work off the byte values
- appendString(value.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
-
- /**
- * Encode a string using the modified UTF-7 encoding.
- *
- * @param original The original string.
- *
- * @return The original string encoded with modified UTF-7 encoding.
- */
- public String encode(String original) {
-
- // buffer for encoding sections of data
- byte[] buffer = new byte[4];
- int bufferCount = 0;
-
- StringBuffer result = new StringBuffer();
-
- // state flag for the type of section we're in.
- boolean encoding = false;
-
- for (int i = 0; i < original.length(); i++) {
- char ch = original.charAt(i);
-
- // processing an encoded section?
- if (encoding) {
- // is this a printable character?
- if (ch > 31 && ch < 127) {
- // encode anything in the buffer
- encode(buffer, bufferCount, result);
- // add the section terminator char
- result.append('-');
- encoding = false;
- // we now fall through to the printable character section.
- }
- // still an unprintable
- else {
- // add this char to the working buffer?
- buffer[++bufferCount] = (byte)(ch >> 8);
- buffer[++bufferCount] = (byte)(ch & 0xff);
- // if we have enough to encode something, do it now.
- if (bufferCount >= 3) {
- bufferCount = encode(buffer, bufferCount, result);
- }
- // go back to the top of the loop.
- continue;
- }
- }
- // is this the special printable?
- if (ch == '&') {
- // this is the special null escape sequence
- result.append('&');
- result.append('-');
- }
- // is this a printable character?
- else if (ch > 31 && ch < 127) {
- // just add to the result
- result.append(ch);
- }
- else {
- // write the escape character
- result.append('&');
-
- // non-printable ASCII character, we need to switch modes
- // both bytes of this character need to be encoded. Each
- // encoded digit will basically be a "character-and-a-half".
- buffer[0] = (byte)(ch >> 8);
- buffer[1] = (byte)(ch & 0xff);
- bufferCount = 2;
- encoding = true;
- }
- }
- // were we in a non-printable section at the end?
- if (encoding) {
- // take care of any remaining characters
- encode(buffer, bufferCount, result);
- // add the section terminator char
- result.append('-');
- }
- // convert the encoded string.
- return result.toString();
- }
-
-
- /**
- * Encode a single buffer of characters. This buffer will have
- * between 0 and 4 bytes to encode.
- *
- * @param buffer The buffer to encode.
- * @param count The number of characters in the buffer.
- * @param result The accumulator for appending the result.
- *
- * @return The remaining number of bytes remaining in the buffer (return 0
- * unless the count was 4 at the beginning).
- */
- protected static int encode(byte[] buffer, int count, StringBuffer result) {
- byte b1 = 0;
- byte b2 = 0;
- byte b3 = 0;
-
- // different processing based on how much we have in the buffer
- switch (count) {
- // ended at a boundary. This is cool, not much to do.
- case 0:
- // no residual in the buffer
- return 0;
-
- // just a single left over byte from the last encoding op.
- case 1:
- b1 = buffer[0];
- result.append(encodingTable[(b1 >>> 2) & 0x3f]);
- result.append(encodingTable[(b1 << 4) & 0x30]);
- return 0;
-
- // one complete char to encode
- case 2:
- b1 = buffer[0];
- b2 = buffer[1];
- result.append(encodingTable[(b1 >>> 2) & 0x3f]);
- result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
- result.append(encodingTable[((b2 << 2) & (0x3c))]);
- return 0;
-
- // at least a full triplet of bytes to encode
- case 3:
- case 4:
- b1 = buffer[0];
- b2 = buffer[1];
- b3 = buffer[2];
- result.append(encodingTable[(b1 >>> 2) & 0x3f]);
- result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
- result.append(encodingTable[((b2 << 2) & 0x3c) + ((b3 >>> 6) & 0x03)]);
- result.append(encodingTable[b3 & 0x3f]);
-
- // if we have more than the triplet, we need to move the extra one into the first
- // position and return the residual indicator
- if (count == 4) {
- buffer[0] = buffer[4];
- return 1;
- }
- return 0;
- }
- return 0;
- }
-
-
- /**
- * Append a string value to a command buffer. This sorts out
- * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
- * or ATOM).
- *
- * @param target The target buffer for appending the string.
- * @param value The value to append.
- */
- public void appendString(String value, String charset) throws MessagingException {
- if (charset == null) {
- try {
- // work off the byte values
- appendString(value.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
- else {
- try {
- // use the charset to extract the bytes
- appendString(value.getBytes(charset));
- throw new MessagingException("Invalid text encoding");
- } catch (UnsupportedEncodingException e) {
- }
- }
- }
-
-
- /**
- * Append a value in a byte array to a command buffer. This sorts out
- * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
- * or ATOM).
- *
- * @param target The target buffer for appending the string.
- * @param value The value to append.
- */
- public void appendString(byte[] value) {
- // sort out how we need to append this
- switch (IMAPResponseTokenizer.getEncoding(value)) {
- case Token.LITERAL:
- appendLiteral(value);
- break;
- case Token.QUOTEDSTRING:
- appendQuotedString(value);
- break;
- case Token.ATOM:
- appendAtom(value);
- break;
- }
- }
-
-
- /**
- * Append an integer value to the command, converting
- * the integer into string form.
- *
- * @param value The value to append.
- */
- public void appendInteger(int value) {
- appendAtom(Integer.toString(value));
- }
-
-
- /**
- * Append a long value to the command, converting
- * the integer into string form.
- *
- * @param value The value to append.
- */
- public void appendLong(long value) {
- appendAtom(Long.toString(value));
- }
-
-
- /**
- * Append an atom value to the command. Atoms are directly
- * appended without using literal encodings.
- *
- * @param value The value to append.
- */
- public void appendAtom(String value) {
- try {
- appendAtom(value.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
-
-
- /**
- * Append an atom to the command buffer. Atoms are directly
- * appended without using literal encodings. White space is
- * accounted for with the append operation.
- *
- * @param value The value to append.
- */
- public void appendAtom(byte[] value) {
- try {
- // give a token separator
- conditionalWhitespace();
- // ATOMs are easy
- out.write(value);
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append an IMAP literal values to the command.
- * literals are written using a header with the length
- * specified, followed by a CRLF sequence, followed
- * by the literal data.
- *
- * @param value The literal data to write.
- */
- public void appendLiteral(byte[] value) {
- try {
- appendLiteralHeader(value.length);
- out.write(value);
- } catch (IOException e) {
- }
- }
-
- /**
- * Add a literal header to the buffer. The literal
- * header is the literal length enclosed in a
- * "{n}" pair, followed by a CRLF sequence.
- *
- * @param size The size of the literal value.
- */
- protected void appendLiteralHeader(int size) {
- try {
- conditionalWhitespace();
- out.writeByte('{');
- out.writeBytes(Integer.toString(size));
- out.writeBytes("}\r\n");
- // the IMAP client is required to send literal data to the server by
- // writing the command up to the header, then waiting for a continuation
- // response to send the rest.
- saveCurrentSegment();
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append literal data to the command where the
- * literal sourcd is a ByteArrayOutputStream.
- *
- * @param value The source of the literal data.
- */
- public void appendLiteral(ByteArrayOutputStream value) {
- try {
- appendLiteralHeader(value.size());
- // have this output stream write directly into our stream
- value.writeTo(out);
- } catch (IOException e) {
- }
- }
-
- /**
- * Write out a string of literal data, taking into
- * account the need to escape both '"' and '\'
- * characters.
- *
- * @param value The bytes of the string to write.
- */
- public void appendQuotedString(byte[] value) {
- try {
- conditionalWhitespace();
- out.writeByte('"');
-
- // look for chars requiring escaping
- for (int i = 0; i < value.length; i++) {
- byte ch = value[i];
-
- if (ch == '"' || ch == '\\') {
- out.writeByte('\\');
- }
- out.writeByte(ch);
- }
-
- out.writeByte('"');
- } catch (IOException e) {
- }
- }
-
- /**
- * Mark the start of a list value being written to
- * the command. A list is a sequences of different
- * tokens enclosed in "(" ")" pairs. Lists can
- * be nested.
- */
- public void startList() {
- try {
- conditionalWhitespace();
- out.writeByte('(');
- needWhiteSpace = false;
- } catch (IOException e) {
- }
- }
-
- /**
- * Write out the end of the list.
- */
- public void endList() {
- try {
- out.writeByte(')');
- needWhiteSpace = true;
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Add a whitespace character to the command if the
- * previous token was a type that required a
- * white space character to mark the boundary.
- */
- protected void conditionalWhitespace() {
- try {
- if (needWhiteSpace) {
- out.writeByte(' ');
- }
- // all callers of this are writing a token that will need white space following, so turn this on
- // every time we're called.
- needWhiteSpace = true;
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append a body section specification to a command string. Body
- * section specifications are of the form "[section]<start.count>".
- *
- * @param section The section numeric identifier.
- * @param partName The name of the body section we want (e.g. "TEST", "HEADERS").
- */
- public void appendBodySection(String section, String partName) {
- try {
- // we sometimes get called from the top level
- if (section == null) {
- appendBodySection(partName);
- return;
- }
-
- out.writeByte('[');
- out.writeBytes(section);
- if (partName != null) {
- out.writeByte('.');
- out.writeBytes(partName);
- }
- out.writeByte(']');
- needWhiteSpace = true;
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append a body section specification to a command string. Body
- * section specifications are of the form "[section]".
- *
- * @param partName The partname we require.
- */
- public void appendBodySection(String partName) {
- try {
- out.writeByte('[');
- out.writeBytes(partName);
- out.writeByte(']');
- needWhiteSpace = true;
- } catch (IOException e) {
- }
- }
-
-
- /**
- * Append a set of flags to a command buffer.
- *
- * @param flags The flag set to append.
- */
- public void appendFlags(Flags flags) {
- startList();
-
- Flags.Flag[] systemFlags = flags.getSystemFlags();
-
- // process each of the system flag names
- for (int i = 0; i < systemFlags.length; i++) {
- Flags.Flag flag = systemFlags[i];
-
- if (flag == Flags.Flag.ANSWERED) {
- appendAtom("\\Answered");
- }
- else if (flag == Flags.Flag.DELETED) {
- appendAtom("\\Deleted");
- }
- else if (flag == Flags.Flag.DRAFT) {
- appendAtom("\\Draft");
- }
- else if (flag == Flags.Flag.FLAGGED) {
- appendAtom("\\Flagged");
- }
- else if (flag == Flags.Flag.RECENT) {
- appendAtom("\\Recent");
- }
- else if (flag == Flags.Flag.SEEN) {
- appendAtom("\\Seen");
- }
- }
-
- // now process the user flags, which just get appended as is.
- String[] userFlags = flags.getUserFlags();
-
- for (int i = 0; i < userFlags.length; i++) {
- appendAtom(userFlags[i]);
- }
-
- // close the list off
- endList();
- }
-
-
- /**
- * Format a date into the form required for IMAP commands.
- *
- * @param d The source Date.
- */
- public void appendDate(Date d) {
- // get a formatter to create IMAP dates. Use the US locale, as the dates are not localized.
- IMAPDateFormat formatter = new IMAPDateFormat();
- // date_time strings need to be done as quoted strings because they contain blanks.
- appendString(formatter.format(d));
- }
-
-
- /**
- * Format a date into the form required for IMAP search commands.
- *
- * @param d The source Date.
- */
- public void appendSearchDate(Date d) {
- // get a formatter to create IMAP dates. Use the US locale, as the dates are not localized.
- IMAPSearchDateFormat formatter = new IMAPSearchDateFormat();
- // date_time strings need to be done as quoted strings because they contain blanks.
- appendString(formatter.format(d));
- }
-
-
- /**
- * append an IMAP search sequence from a SearchTerm. SearchTerms
- * terms can be complex sets of terms in a tree form, so this
- * may involve some recursion to completely translate.
- *
- * @param term The search term we're processing.
- * @param charset The charset we need to use when generating the sequence.
- *
- * @exception MessagingException
- */
- public void appendSearchTerm(SearchTerm term, String charset) throws MessagingException {
- // we need to do this manually, by inspecting the term object against the various SearchTerm types
- // defined by the javamail spec.
-
- // Flag searches are used internally by other operations, so this is a good one to check first.
- if (term instanceof FlagTerm) {
- appendFlag((FlagTerm)term, charset);
- }
- // after that, I'm not sure there's any optimal order to these. Let's start with the conditional
- // modifiers (AND, OR, NOT), then just hit each of the header types
- else if (term instanceof AndTerm) {
- appendAnd((AndTerm)term, charset);
- }
- else if (term instanceof OrTerm) {
- appendOr((OrTerm)term, charset);
- }
- else if (term instanceof NotTerm) {
- appendNot((NotTerm)term, charset);
- }
- // multiple forms of From: search
- else if (term instanceof FromTerm) {
- appendFrom((FromTerm)term, charset);
- }
- else if (term instanceof FromStringTerm) {
- appendFrom((FromStringTerm)term, charset);
- }
- else if (term instanceof HeaderTerm) {
- appendHeader((HeaderTerm)term, charset);
- }
- else if (term instanceof RecipientTerm) {
- appendRecipient((RecipientTerm)term, charset);
- }
- else if (term instanceof RecipientStringTerm) {
- appendRecipient((RecipientStringTerm)term, charset);
- }
- else if (term instanceof SubjectTerm) {
- appendSubject((SubjectTerm)term, charset);
- }
- else if (term instanceof BodyTerm) {
- appendBody((BodyTerm)term, charset);
- }
- else if (term instanceof SizeTerm) {
- appendSize((SizeTerm)term, charset);
- }
- else if (term instanceof SentDateTerm) {
- appendSentDate((SentDateTerm)term, charset);
- }
- else if (term instanceof ReceivedDateTerm) {
- appendReceivedDate((ReceivedDateTerm)term, charset);
- }
- else if (term instanceof MessageIDTerm) {
- appendMessageID((MessageIDTerm)term, charset);
- }
- else {
- // don't know what this is
- throw new SearchException("Unsupported search type");
- }
- }
-
- /**
- * append IMAP search term information from a FlagTerm item.
- *
- * @param term The source FlagTerm
- * @param charset target charset for the search information (can be null).
- * @param out The target command buffer.
- */
- protected void appendFlag(FlagTerm term, String charset) {
- // decide which one we need to test for
- boolean set = term.getTestSet();
-
- Flags flags = term.getFlags();
- Flags.Flag[] systemFlags = flags.getSystemFlags();
-
- String[] userFlags = flags.getUserFlags();
-
- // empty search term? not sure if this is an error. The default search implementation would
- // not consider this an error, so we'll just ignore this.
- if (systemFlags.length == 0 && userFlags.length == 0) {
- return;
- }
-
- if (set) {
- for (int i = 0; i < systemFlags.length; i++) {
- Flags.Flag flag = systemFlags[i];
-
- if (flag == Flags.Flag.ANSWERED) {
- appendAtom("ANSWERED");
- }
- else if (flag == Flags.Flag.DELETED) {
- appendAtom("DELETED");
- }
- else if (flag == Flags.Flag.DRAFT) {
- appendAtom("DRAFT");
- }
- else if (flag == Flags.Flag.FLAGGED) {
- appendAtom("FLAGGED");
- }
- else if (flag == Flags.Flag.RECENT) {
- appendAtom("RECENT");
- }
- else if (flag == Flags.Flag.SEEN) {
- appendAtom("SEEN");
- }
- }
- }
- else {
- for (int i = 0; i < systemFlags.length; i++) {
- Flags.Flag flag = systemFlags[i];
-
- if (flag == Flags.Flag.ANSWERED) {
- appendAtom("UNANSWERED");
- }
- else if (flag == Flags.Flag.DELETED) {
- appendAtom("UNDELETED");
- }
- else if (flag == Flags.Flag.DRAFT) {
- appendAtom("UNDRAFT");
- }
- else if (flag == Flags.Flag.FLAGGED) {
- appendAtom("UNFLAGGED");
- }
- else if (flag == Flags.Flag.RECENT) {
- // not UNRECENT?
- appendAtom("OLD");
- }
- else if (flag == Flags.Flag.SEEN) {
- appendAtom("UNSEEN");
- }
- }
- }
-
-
- // User flags are done as either "KEYWORD name" or "UNKEYWORD name"
- for (int i = 0; i < userFlags.length; i++) {
- appendAtom(set ? "KEYWORD" : "UNKEYWORD");
- appendAtom(userFlags[i]);
- }
- }
-
-
- /**
- * append IMAP search term information from an AndTerm item.
- *
- * @param term The source AndTerm
- * @param charset target charset for the search information (can be null).
- * @param out The target command buffer.
- */
- protected void appendAnd(AndTerm term, String charset) throws MessagingException {
- // ANDs are pretty easy. Just append all of the terms directly to the
- // command as is.
-
- SearchTerm[] terms = term.getTerms();
-
- for (int i = 0; i < terms.length; i++) {
- appendSearchTerm(terms[i], charset);
- }
- }
-
-
- /**
- * append IMAP search term information from an OrTerm item.
- *
- * @param term The source OrTerm
- * @param charset target charset for the search information (can be null).
- * @param out The target command buffer.
- */
- protected void appendOr(OrTerm term, String charset) throws MessagingException {
- SearchTerm[] terms = term.getTerms();
-
- // OrTerms are a bit of a pain to translate to IMAP semantics. The IMAP OR operation only allows 2
- // search keys, while OrTerms can have n keys (including, it appears, just one! If we have more than
- // 2, it's easiest to convert this into a tree of OR keys and let things generate that way. The
- // resulting IMAP operation would be OR (key1) (OR (key2) (key3))
-
- // silly rabbit...somebody doesn't know how to use OR
- if (terms.length == 1) {
- // just append the singleton in place without the OR operation.
- appendSearchTerm(terms[0], charset);
- return;
- }
-
- // is this a more complex operation?
- if (terms.length > 2) {
- // have to chain these together (shazbat).
- SearchTerm current = terms[0];
-
- for (int i = 1; i < terms.length; i++) {
- current = new OrTerm(current, terms[i]);
- }
-
- // replace the term array with the newly generated top array
- terms = ((OrTerm)current).getTerms();
- }
-
- // we're going to generate this with parenthetical search keys, even if it is just a simple term.
- appendAtom("OR");
- startList();
- // generated OR argument 1
- appendSearchTerm(terms[0], charset);
- endList();
- startList();
- // generated OR argument 2
- appendSearchTerm(terms[0], charset);
- // and the closing parens
- endList();
- }
-
-
- /**
- * append IMAP search term information from a NotTerm item.
- *
- * @param term The source NotTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendNot(NotTerm term, String charset) throws MessagingException {
- // we're goint to generate this with parenthetical search keys, even if it is just a simple term.
- appendAtom("NOT");
- startList();
- // generated the NOT expression
- appendSearchTerm(term.getTerm(), charset);
- // and the closing parens
- endList();
- }
-
-
- /**
- * append IMAP search term information from a FromTerm item.
- *
- * @param term The source FromTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendFrom(FromTerm term, String charset) throws MessagingException {
- appendAtom("FROM");
- // this may require encoding
- appendString(term.getAddress().toString(), charset);
- }
-
-
- /**
- * append IMAP search term information from a FromStringTerm item.
- *
- * @param term The source FromStringTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendFrom(FromStringTerm term, String charset) throws MessagingException {
- appendAtom("FROM");
- // this may require encoding
- appendString(term.getPattern(), charset);
- }
-
-
- /**
- * append IMAP search term information from a RecipientTerm item.
- *
- * @param term The source RecipientTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendRecipient(RecipientTerm term, String charset) throws MessagingException {
- appendAtom(recipientType(term.getRecipientType()));
- // this may require encoding
- appendString(term.getAddress().toString(), charset);
- }
-
-
- /**
- * append IMAP search term information from a RecipientStringTerm item.
- *
- * @param term The source RecipientStringTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendRecipient(RecipientStringTerm term, String charset) throws MessagingException {
- appendAtom(recipientType(term.getRecipientType()));
- // this may require encoding
- appendString(term.getPattern(), charset);
- }
-
-
- /**
- * Translate a recipient type into it's string name equivalent.
- *
- * @param type The source recipient type
- *
- * @return A string name matching the recipient type.
- */
- protected String recipientType(Message.RecipientType type) throws MessagingException {
- if (type == Message.RecipientType.TO) {
- return "TO";
- }
- if (type == Message.RecipientType.CC) {
- return "CC";
- }
- if (type == Message.RecipientType.BCC) {
- return "BCC";
- }
-
- throw new SearchException("Unsupported RecipientType");
- }
-
-
- /**
- * append IMAP search term information from a HeaderTerm item.
- *
- * @param term The source HeaderTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendHeader(HeaderTerm term, String charset) throws MessagingException {
- appendAtom("HEADER");
- appendString(term.getHeaderName());
- appendString(term.getPattern(), charset);
- }
-
-
-
- /**
- * append IMAP search term information from a SubjectTerm item.
- *
- * @param term The source SubjectTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendSubject(SubjectTerm term, String charset) throws MessagingException {
- appendAtom("SUBJECT");
- appendString(term.getPattern(), charset);
- }
-
-
- /**
- * append IMAP search term information from a BodyTerm item.
- *
- * @param term The source BodyTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendBody(BodyTerm term, String charset) throws MessagingException {
- appendAtom("BODY");
- appendString(term.getPattern(), charset);
- }
-
-
- /**
- * append IMAP search term information from a SizeTerm item.
- *
- * @param term The source SizeTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendSize(SizeTerm term, String charset) throws MessagingException {
-
- // these comparisons can be a real pain. IMAP only supports LARGER and SMALLER. So comparisons
- // other than GT and LT have to be composed of complex sequences of these. For example, an EQ
- // comparison becomes NOT LARGER size NOT SMALLER size
-
- if (term.getComparison() == ComparisonTerm.GT) {
- appendAtom("LARGER");
- appendInteger(term.getNumber());
- }
- else if (term.getComparison() == ComparisonTerm.LT) {
- appendAtom("SMALLER");
- appendInteger(term.getNumber());
- }
- else if (term.getComparison() == ComparisonTerm.EQ) {
- appendAtom("NOT");
- appendAtom("LARGER");
- appendInteger(term.getNumber());
-
- appendAtom("NOT");
- appendAtom("SMALLER");
- // it's just right <g>
- appendInteger(term.getNumber());
- }
- else if (term.getComparison() == ComparisonTerm.NE) {
- // this needs to be an OR comparison
- appendAtom("OR");
- appendAtom("LARGER");
- appendInteger(term.getNumber());
-
- appendAtom("SMALLER");
- appendInteger(term.getNumber());
- }
- else if (term.getComparison() == ComparisonTerm.LE) {
- // just the inverse of LARGER
- appendAtom("NOT");
- appendAtom("LARGER");
- appendInteger(term.getNumber());
- }
- else if (term.getComparison() == ComparisonTerm.GE) {
- // and the reverse.
- appendAtom("NOT");
- appendAtom("SMALLER");
- appendInteger(term.getNumber());
- }
- }
-
-
- /**
- * append IMAP search term information from a MessageIDTerm item.
- *
- * @param term The source MessageIDTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendMessageID(MessageIDTerm term, String charset) throws MessagingException {
-
- // not directly supported by IMAP, but we can compare on the header information.
- appendAtom("HEADER");
- appendString("Message-ID");
- appendString(term.getPattern(), charset);
- }
-
-
- /**
- * append IMAP search term information from a SendDateTerm item.
- *
- * @param term The source SendDateTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendSentDate(SentDateTerm term, String charset) throws MessagingException {
- Date date = term.getDate();
-
- switch (term.getComparison()) {
- case ComparisonTerm.EQ:
- appendAtom("SENTON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.LT:
- appendAtom("SENTBEFORE");
- appendSearchDate(date);
- break;
- case ComparisonTerm.GT:
- appendAtom("SENTSINCE");
- appendSearchDate(date);
- break;
- case ComparisonTerm.GE:
- appendAtom("OR");
- appendAtom("SENTSINCE");
- appendSearchDate(date);
- appendAtom("SENTON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.LE:
- appendAtom("OR");
- appendAtom("SENTBEFORE");
- appendSearchDate(date);
- appendAtom("SENTON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.NE:
- appendAtom("NOT");
- appendAtom("SENTON");
- appendSearchDate(date);
- break;
- default:
- throw new SearchException("Unsupported date comparison type");
- }
- }
-
-
- /**
- * append IMAP search term information from a ReceivedDateTerm item.
- *
- * @param term The source ReceivedDateTerm
- * @param charset target charset for the search information (can be null).
- */
- protected void appendReceivedDate(ReceivedDateTerm term, String charset) throws MessagingException {
- Date date = term.getDate();
-
- switch (term.getComparison()) {
- case ComparisonTerm.EQ:
- appendAtom("ON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.LT:
- appendAtom("BEFORE");
- appendSearchDate(date);
- break;
- case ComparisonTerm.GT:
- appendAtom("SINCE");
- appendSearchDate(date);
- break;
- case ComparisonTerm.GE:
- appendAtom("OR");
- appendAtom("SINCE");
- appendSearchDate(date);
- appendAtom("ON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.LE:
- appendAtom("OR");
- appendAtom("BEFORE");
- appendSearchDate(date);
- appendAtom("ON");
- appendSearchDate(date);
- break;
- case ComparisonTerm.NE:
- appendAtom("NOT");
- appendAtom("ON");
- appendSearchDate(date);
- break;
- default:
- throw new SearchException("Unsupported date comparison type");
- }
- }
-
-
- /**
- * Run the tree of search terms, checking for problems with
- * the terms that may require specifying a CHARSET modifier
- * on a SEARCH command sent to the server.
- *
- * @param term The term to check.
- *
- * @return True if there are 7-bit problems, false if the terms contain
- * only 7-bit ASCII characters.
- */
- static public boolean checkSearchEncoding(SearchTerm term) {
- // StringTerm is the basis of most of the string-valued terms, and are most important ones to check.
- if (term instanceof StringTerm) {
- return checkStringEncoding(((StringTerm)term).getPattern());
- }
- // Address terms are basically string terms also, but we need to check the string value of the
- // addresses, since that's what we're sending along. This covers a lot of the TO/FROM, etc. searches.
- else if (term instanceof AddressTerm) {
- return checkStringEncoding(((AddressTerm)term).getAddress().toString());
- }
- // the NOT contains a term itself, so recurse on that. The NOT does not directly have string values
- // to check.
- else if (term instanceof NotTerm) {
- return checkSearchEncoding(((NotTerm)term).getTerm());
- }
- // AND terms and OR terms have lists of subterms that must be checked.
- else if (term instanceof AndTerm) {
- return checkSearchEncoding(((AndTerm)term).getTerms());
- }
- else if (term instanceof OrTerm) {
- return checkSearchEncoding(((OrTerm)term).getTerms());
- }
-
- // non of the other term types (FlagTerm, SentDateTerm, etc.) pose a problem, so we'll give them
- // a free pass.
- return false;
- }
-
-
- /**
- * Run an array of search term items to check each one for ASCII
- * encoding problems.
- *
- * @param terms The array of terms to check.
- *
- * @return True if any of the search terms contains a 7-bit ASCII problem,
- * false otherwise.
- */
- static public boolean checkSearchEncoding(SearchTerm[] terms) {
- for (int i = 0; i < terms.length; i++) {
- if (checkSearchEncoding(terms[i])) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
- * Check a string to see if this can be processed using just
- * 7-bit ASCII.
- *
- * @param s The string to check
- *
- * @return true if the string contains characters outside the 7-bit ascii range,
- * false otherwise.
- */
- static public boolean checkStringEncoding(String s) {
- for (int i = 0; i < s.length(); i++) {
- // any value greater that 0x7f is a problem char. We're not worried about
- // lower ctl chars (chars < 32) since those are still expressible in 7-bit.
- if (s.charAt(i) > 127) {
- return true;
- }
- }
-
- return false;
- }
-
-
- /**
- * Append a FetchProfile information to an IMAPCommand
- * that's to be issued.
- *
- * @param profile The fetch profile we're using.
- *
- * @exception MessagingException
- */
- public void appendFetchProfile(FetchProfile profile) throws MessagingException {
- // the fetch profile items are a parenthtical list passed on a
- // FETCH command.
- startList();
- if (profile.contains(UIDFolder.FetchProfileItem.UID)) {
- appendAtom("UID");
- }
- if (profile.contains(FetchProfile.Item.ENVELOPE)) {
- // fetching the envelope involves several items
- appendAtom("ENVELOPE");
- appendAtom("INTERNALDATE");
- appendAtom("RFC822.SIZE");
- }
- if (profile.contains(FetchProfile.Item.FLAGS)) {
- appendAtom("FLAGS");
- }
- if (profile.contains(FetchProfile.Item.CONTENT_INFO)) {
- appendAtom("BODYSTRUCTURE");
- }
- if (profile.contains(IMAPFolder.FetchProfileItem.SIZE)) {
- appendAtom("RFC822.SIZE");
- }
- // There are two choices here, that are sort of redundant.
- // if all headers have been requested, there's no point in
- // adding any specifically requested one.
- if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS)) {
- appendAtom("BODY.PEEK[HEADER]");
- }
- else {
- String[] headers = profile.getHeaderNames();
- // have an actual list to retrieve? need to craft this as a sublist
- // of identified fields.
- if (headers.length > 0) {
- appendAtom("BODY.PEEK[HEADER.FIELDS]");
- startList();
- for (int i = 0; i < headers.length; i++) {
- appendAtom(headers[i]);
- }
- endList();
- }
- }
- // end the list.
- endList();
- }
-
-
- /**
- * Append an ACL value to a command. The ACL is the writes string name,
- * followed by the rights value. This version uses no +/- modifier.
- *
- * @param acl The ACL to append.
- */
- public void appendACL(ACL acl) {
- appendACL(acl, null);
- }
-
- /**
- * Append an ACL value to a command. The ACL is the writes string name,
- * followed by the rights value. A +/- modifier can be added to the
- * // result.
- *
- * @param acl The ACL to append.
- * @param modifier The modifer string (can be null).
- */
- public void appendACL(ACL acl, String modifier) {
- appendString(acl.getName());
- String rights = acl.getRights().toString();
-
- if (modifier != null) {
- rights = modifier + rights;
- }
- appendString(rights);
- }
-
-
- /**
- * Append a quota specification to an IMAP command.
- *
- * @param quota The quota value to append.
- */
- public void appendQuota(Quota quota) {
- appendString(quota.quotaRoot);
- startList();
- for (int i = 0; i < quota.resources.length; i++) {
- appendQuotaResource(quota.resources[i]);
- }
- endList();
- }
-
- /**
- * Append a Quota.Resource element to an IMAP command. This converts as
- * the resoure name, the usage value and limit value).
- *
- * @param resource The resource element we're appending.
- */
- public void appendQuotaResource(Quota.Resource resource) {
- appendAtom(resource.name);
- // NB: For command purposes, only the limit is used.
- appendLong(resource.limit);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
deleted file mode 100644
index 9922c68..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
+++ /dev/null
@@ -1,1992 +0,0 @@
-/**
- * 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.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.mail.Address;
-import javax.mail.AuthenticationFailedException;
-import javax.mail.FetchProfile;
-import javax.mail.Flags;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.MethodNotSupportedException;
-import javax.mail.Quota;
-import javax.mail.Session;
-import javax.mail.UIDFolder;
-import javax.mail.URLName;
-
-import javax.mail.internet.InternetHeaders;
-
-import javax.mail.search.SearchTerm;
-
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
-import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
-import org.apache.geronimo.javamail.store.imap.ACL;
-import org.apache.geronimo.javamail.store.imap.Rights;
-
-import org.apache.geronimo.javamail.util.CommandFailedException;
-import org.apache.geronimo.javamail.util.InvalidCommandException;
-import org.apache.geronimo.javamail.util.MailConnection;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-import org.apache.geronimo.javamail.util.TraceInputStream;
-import org.apache.geronimo.javamail.util.TraceOutputStream;
-import org.apache.geronimo.mail.util.Base64;
-
-/**
- * Simple implementation of IMAP transport. Just does plain RFC977-ish
- * delivery.
- * <p/>
- * There is no way to indicate failure for a given recipient (it's possible to have a
- * recipient address rejected). The sun impl throws exceptions even if others successful),
- * but maybe we do a different way...
- * <p/>
- *
- * @version $Rev: 1641706 $ $Date: 2014-11-25 16:39:49 -0500 (Tue, 25 Nov 2014) $
- */
-public class IMAPConnection extends MailConnection {
-
- protected static final String CAPABILITY_LOGIN_DISABLED = "LOGINDISABLED";
-
- // The connection pool we're a member of. This keeps holds most of the
- // connnection parameter information for us.
- protected IMAPConnectionPool pool;
-
- // special input stream for reading individual response lines.
- protected IMAPResponseStream reader;
-
- // connection pool connections.
- protected long lastAccess = 0;
- // our handlers for any untagged responses
- protected LinkedList responseHandlers = new LinkedList();
- // the list of queued untagged responses.
- protected List queuedResponses = new LinkedList();
- // this is set on if we had a forced disconnect situation from
- // the server.
- protected boolean closed = false;
-
- /**
- * Normal constructor for an IMAPConnection() object.
- *
- * @param props The protocol properties abstraction containing our
- * property modifiers.
- * @param pool
- */
- public IMAPConnection(ProtocolProperties props, IMAPConnectionPool pool) {
- super(props);
- this.pool = pool;
- }
-
-
- /**
- * Connect to the server and do the initial handshaking.
- *
- * @exception MessagingException
- */
- public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
- this.serverHost = host;
- this.serverPort = port;
- this.realm = realm;
- this.authid = authid;
- this.username = username;
- this.password = password;
-
- boolean preAuthorized = false;
-
- try {
- // create socket and connect to server.
- getConnection();
-
- // we need to ask the server what its capabilities are. This can be done
- // before we login.
- getCapability();
- // do a preauthoriziation check.
- if (extractResponse("PREAUTH") != null) {
- preAuthorized = true;
- }
-
- // make sure we process these now
- processPendingResponses();
-
- boolean requireTLS = props.getBooleanProperty(MAIL_STARTTLS_REQUIRED, false);
- boolean enableTLS = props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false);
- boolean serverSupportsTLS = hasCapability(CAPABILITY_STARTTLS);
-
- // if we're not already using an SSL connection, and we have permission to issue STARTTLS or its even required
- // try to setup a SSL connection
- if (!sslConnection && (enableTLS || requireTLS)) {
-
- //if the server does not support TLS check if its required.
- //If true then throw an error, if not establish a non SSL connection
- if(requireTLS && !serverSupportsTLS) {
- throw new MessagingException("Server doesn't support required transport level security");
- } else if (serverSupportsTLS){
- // tell the server of our intention to start a TLS session
- sendSimpleCommand("STARTTLS");
-
- // The connection is then handled by the superclass level.
- getConnectedTLSSocket();
-
- // create the special reader for pulling the responses.
- reader = new IMAPResponseStream(inputStream);
-
- // the IMAP spec states that the capability response is independent of login state or
- // user, but I'm not sure I believe that to be the case. It doesn't hurt to refresh
- // the information again after establishing a secure connection.
- getCapability();
- // and we need to repeat this check.
- if (extractResponse("PREAUTH") != null) {
- preAuthorized = true;
- }
- } else {
- if (debug) {
- debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
- }
- }
-
- }
-
- // damn, no login required.
- if (preAuthorized) {
- return true;
- }
-
- // go login with the server
- return login();
- } catch (IOException e) {
- if (debug) {
- debugOut("I/O exception establishing connection", e);
- }
- throw new MessagingException("Connection error", e);
- }
- finally {
- // make sure the queue is cleared
- processPendingResponses();
- }
- }
-
- /**
- * Update the last access time for the connection.
- */
- protected void updateLastAccess() {
- lastAccess = System.currentTimeMillis();
- }
-
- /**
- * Test if the connection has been sitting idle for longer than
- * the set timeout period.
- *
- * @param timeout The allowed "freshness" interval.
- *
- * @return True if the connection has been active within the required
- * interval, false if it has been sitting idle for too long.
- */
- public boolean isStale(long timeout) {
- return (System.currentTimeMillis() - lastAccess) > timeout;
- }
-
-
- /**
- * Close the connection. On completion, we'll be disconnected from
- * the server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // if we're already closed, get outta here.
- if (socket == null) {
- return;
- }
- try {
- // say goodbye
- logout();
- } finally {
- // and close up the connection. We do this in a finally block to make sure the connection
- // is shut down even if quit gets an error.
- closeServerConnection();
- // get rid of our response processor too.
- reader = null;
- }
- }
-
-
- /**
- * Create a transport connection object and connect it to the
- * target server.
- *
- * @exception MessagingException
- */
- protected void getConnection() throws IOException, MessagingException
- {
- // do all of the non-protocol specific set up. This will get our socket established
- // and ready use.
- super.getConnection();
- // create the special reader for pulling the responses.
- reader = new IMAPResponseStream(inputStream);
-
- // set the initial access time stamp
- updateLastAccess();
- }
-
-
- /**
- * Process a simple command/response sequence between the
- * client and the server. These are commands where the
- * client is expecting them to "just work", and also will not
- * directly process the reply information. Unsolicited untagged
- * responses are dispatched to handlers, and a MessagingException
- * will be thrown for any non-OK responses from the server.
- *
- * @param data The command data we're writing out.
- *
- * @exception MessagingException
- */
- public void sendSimpleCommand(String data) throws MessagingException {
- // create a command object and issue the command with that.
- IMAPCommand command = new IMAPCommand(data);
- sendSimpleCommand(command);
- }
-
-
- /**
- * Process a simple command/response sequence between the
- * client and the server. These are commands where the
- * client is expecting them to "just work", and also will not
- * directly process the reply information. Unsolicited untagged
- * responses are dispatched to handlers, and a MessagingException
- * will be thrown for any non-OK responses from the server.
- *
- * @param data The command data we're writing out.
- *
- * @exception MessagingException
- */
- public void sendSimpleCommand(IMAPCommand data) throws MessagingException {
- // the command sending process will raise exceptions for bad responses....
- // we just need to send the command and forget about it.
- sendCommand(data);
- }
-
-
- /**
- * Sends a command down the socket, returning the server response.
- *
- * @param data The String form of the command.
- *
- * @return The tagged response information that terminates the command interaction.
- * @exception MessagingException
- */
- public IMAPTaggedResponse sendCommand(String data) throws MessagingException {
- IMAPCommand command = new IMAPCommand(data);
- return sendCommand(command);
- }
-
-
- /**
- * Sends a command down the socket, returning the server response.
- *
- * @param data An IMAPCommand object with the prepared command information.
- *
- * @return The tagged (or continuation) response information that terminates the
- * command response sequence.
- * @exception MessagingException
- */
- public synchronized IMAPTaggedResponse sendCommand(IMAPCommand data) throws MessagingException {
- // check first
- checkConnected();
- try {
- // have the command write the command data. This also prepends a tag.
- data.writeTo(outputStream, this);
- outputStream.flush();
- // update the activity timestamp
- updateLastAccess();
- // get the received response
- return receiveResponse();
- } catch (IOException e) {
- throw new MessagingException(e.toString(), e);
- }
- }
-
-
- /**
- * Sends a message down the socket and terminates with the
- * appropriate CRLF
- *
- * @param data The string data to send.
- *
- * @return An IMAPTaggedResponse item returned from the server.
- * @exception MessagingException
- */
- public IMAPTaggedResponse sendLine(String data) throws MessagingException {
- try {
- return sendLine(data.getBytes("ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- // should never happen
- return null;
- }
- }
-
-
- /**
- * Sends a message down the socket and terminates with the
- * appropriate CRLF
- *
- * @param data The array of data to send to the server.
- *
- * @return The response item returned from the IMAP server.
- * @exception MessagingException
- */
- public IMAPTaggedResponse sendLine(byte[] data) throws MessagingException {
- return sendLine(data, 0, data.length);
- }
-
-
- /**
- * Sends a message down the socket and terminates with the
- * appropriate CRLF
- *
- * @param data The source data array.
- * @param offset The offset within the data array.
- * @param length The length of data to send.
- *
- * @return The response line returned from the IMAP server.
- * @exception MessagingException
- */
- public synchronized IMAPTaggedResponse sendLine(byte[] data, int offset, int length) throws MessagingException {
- // check first
- checkConnected();
-
- try {
- outputStream.write(data, offset, length);
- outputStream.write(CR);
- outputStream.write(LF);
- outputStream.flush();
- // update the activity timestamp
- updateLastAccess();
- return receiveResponse();
- } catch (IOException e) {
- throw new MessagingException(e.toString(), e);
- }
- }
-
-
- /**
- * Get a reply line for an IMAP command.
- *
- * @return An IMAP reply object from the stream.
- */
- public IMAPTaggedResponse receiveResponse() throws MessagingException {
- while (true) {
- // read and parse a response from the server.
- IMAPResponse response = reader.readResponse();
- // The response set is terminated by either a continuation response or a
- // tagged response (we only have a single command active at one time).
- if (response instanceof IMAPTaggedResponse) {
- // update the access time stamp for later timeout processing.
- updateLastAccess();
- IMAPTaggedResponse tagged = (IMAPTaggedResponse)response;
- // we turn these into exceptions here, which means the issuer doesn't have to
- // worry about checking status.
- if (tagged.isBAD()) {
- throw new InvalidCommandException("Unexpected command IMAP command error");
- }
- else if (tagged.isNO()) {
- throw new CommandFailedException("Unexpected error executing IMAP command");
- }
- return tagged;
- }
- else {
- // all other unsolicited responses are either async status updates or
- // additional elements of a command we just sent. These will be processed
- // either during processing of the command response, or at the end of the
- // current command processing.
- queuePendingResponse((IMAPUntaggedResponse)response);
- }
- }
- }
-
-
- /**
- * Get the servers capabilities from the wire....
- */
- public void getCapability() throws MessagingException {
- sendCommand("CAPABILITY");
- // get the capabilities from the response.
- IMAPCapabilityResponse response = (IMAPCapabilityResponse)extractResponse("CAPABILITY");
- capabilities = response.getCapabilities();
- authentications = response.getAuthentications();
- }
-
- /**
- * Logs out from the server.
- */
- public void logout() throws MessagingException {
- // We can just send the command and generally ignore the
- // status response.
- sendCommand("LOGOUT");
- }
-
- /**
- * Deselect a mailbox when a folder returns a connection.
- *
- * @exception MessagingException
- */
- public void closeMailbox() throws MessagingException {
- // We can just send the command and generally ignore the
- // status response.
- sendCommand("CLOSE");
- }
-
-
- /**
- * Authenticate with the server, if necessary (or possible).
- *
- * @return true if we were able to authenticate correctly, false for authentication failures.
- * @exception MessagingException
- */
- protected boolean login() throws MessagingException
- {
- // if no username or password, fail this immediately.
- // the base connect property should resolve a username/password combo for us and
- // try again.
- if (username == null || password == null) {
- return false;
- }
-
- // are we permitted to use SASL mechanisms?
- if (props.getBooleanProperty(MAIL_SASL_ENABLE, false)) {
- // we might be enable for SASL, but the client and the server might
- // not have any supported mechanisms in common. Try again with another
- // mechanism.
- if (processSaslAuthentication()) {
- return true;
- }
- }
-
- // see if we're allowed to try plain.
- if (!props.getBooleanProperty(MAIL_PLAIN_DISABLE, false) && supportsMechanism(AUTHENTICATION_PLAIN)) {
- return processPlainAuthentication();
- }
-
- // see if we're allowed to try login.
- if (!props.getBooleanProperty(MAIL_LOGIN_DISABLE, false) && supportsMechanism(AUTHENTICATION_LOGIN)) {
- // no authzid capability with this authentication method.
- return processLoginAuthentication();
- }
-
- // the server can choose to disable the LOGIN command. If not disabled, try
- // using LOGIN rather than AUTHENTICATE.
- if (!hasCapability(CAPABILITY_LOGIN_DISABLED)) {
- return processLogin();
- }
-
- throw new MessagingException("No supported LOGIN methods enabled");
- }
-
-
- /**
- * Process SASL-type authentication.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected boolean processSaslAuthentication() throws MessagingException {
- // if unable to get an appropriate authenticator, just fail it.
- ClientAuthenticator authenticator = getSaslAuthenticator();
- if (authenticator == null) {
- return false;
- }
-
- // go process the login.
- return processLogin(authenticator);
- }
-
- protected ClientAuthenticator getSaslAuthenticator() {
- return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
- }
-
- /**
- * Process SASL-type PLAIN authentication.
- *
- * @return Returns true if the login is accepted.
- * @exception MessagingException
- */
- protected boolean processPlainAuthentication() throws MessagingException {
- // go process the login.
- return processLogin(new PlainAuthenticator(authid, username, password));
- }
-
-
- /**
- * Process SASL-type LOGIN authentication.
- *
- * @return Returns true if the login is accepted.
- * @exception MessagingException
- */
- protected boolean processLoginAuthentication() throws MessagingException {
- // go process the login.
- return processLogin(new LoginAuthenticator(username, password));
- }
-
-
- /**
- * Process a LOGIN using the LOGIN command instead of AUTHENTICATE.
- *
- * @return true if the command succeeded, false for any authentication failures.
- * @exception MessagingException
- */
- protected boolean processLogin() throws MessagingException {
- // arguments are "LOGIN userid password"
- IMAPCommand command = new IMAPCommand("LOGIN");
- command.appendAtom(username);
- command.appendAtom(password);
-
- // go issue the command
- try {
- sendCommand(command);
- } catch (CommandFailedException e) {
- // we'll get a NO response for a rejected login
- return false;
- }
- // seemed to work ok....
- return true;
- }
-
-
- /**
- * Process a login using the provided authenticator object.
- *
- * NB: This method is synchronized because we have a multi-step process going on
- * here. No other commands should be sent to the server until we complete.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
- if (debug) {
- debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
- }
-
- IMAPCommand command = new IMAPCommand("AUTHENTICATE");
- // and tell the server which mechanism we're using.
- command.appendAtom(authenticator.getMechanismName());
- // send the command now
-
- try {
- IMAPTaggedResponse response = sendCommand(command);
-
- // now process the challenge sequence. We get a 235 response back when the server accepts the
- // authentication, and a 334 indicates we have an additional challenge.
- while (true) {
- // this should be a continuation reply, if things are still good.
- if (response.isContinuation()) {
- // we're passed back a challenge value, Base64 encoded.
- byte[] challenge = response.decodeChallengeResponse();
-
- // have the authenticator evaluate and send back the encoded response.
- response = sendLine(Base64.encode(authenticator.evaluateChallenge(challenge)));
- }
- else {
- // there are only two choices here, OK or a continuation. OK means
- // we've passed muster and are in.
- return true;
- }
- }
- } catch (CommandFailedException e ) {
- // a failure at any point in this process will result in a "NO" response.
- // That causes an exception to get thrown, so just fail the login
- // if we get one.
- return false;
- }
- }
-
-
- /**
- * Return the server host for this connection.
- *
- * @return The String name of the server host.
- */
- public String getHost() {
- return serverHost;
- }
-
-
- /**
- * Attach a handler for untagged responses to this connection.
- *
- * @param h The new untagged response handler.
- */
- public synchronized void addResponseHandler(IMAPUntaggedResponseHandler h) {
- responseHandlers.add(h);
- }
-
-
- /**
- * Remove a response handler from the connection.
- *
- * @param h The handler to remove.
- */
- public synchronized void removeResponseHandler(IMAPUntaggedResponseHandler h) {
- responseHandlers.remove(h);
- }
-
-
- /**
- * Add a response to the pending untagged response queue.
- *
- * @param response The response to add.
- */
- public synchronized void queuePendingResponse(IMAPUntaggedResponse response) {
- queuedResponses.add(response);
- }
-
- /**
- * Process any untagged responses in the queue. This will clear out
- * the queue, and send each response to the registered
- * untagged response handlers.
- */
- public void processPendingResponses() throws MessagingException {
- List pendingResponses = null;
- List handlerList = null;
-
- synchronized(this) {
- if (queuedResponses.isEmpty()) {
- return;
- }
- pendingResponses = queuedResponses;
- queuedResponses = new LinkedList();
- // get a copy of the response handlers so we can
- // release the connection lock before broadcasting
- handlerList = (List)responseHandlers.clone();
- }
-
- for (int i = 0; i < pendingResponses.size(); i++) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)pendingResponses.get(i);
- for (int j = 0; j < handlerList.size(); j++) {
- // broadcast to each handler. If a handler returns true, then it
- // handled whatever this message required and we should skip sending
- // it to other handlers.
- IMAPUntaggedResponseHandler h = (IMAPUntaggedResponseHandler)handlerList.get(j);
- if (h.handleResponse(response)) {
- break;
- }
- }
- }
- }
-
- /**
- * Extract a single response from the pending queue that
- * match a give keyword type. All matching responses
- * are removed from the pending queue.
- *
- * @param type The string name of the keyword.
- *
- * @return A List of all matching queued responses.
- */
- public IMAPUntaggedResponse extractResponse(String type) {
- Iterator i = queuedResponses.iterator();
- while (i.hasNext()) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
- // if this is of the target type, move it to the response set.
- if (response.isKeyword(type)) {
- i.remove();
- return response;
- }
- }
- return null;
- }
-
- /**
- * Extract all responses from the pending queue that
- * match a give keyword type. All matching responses
- * are removed from the pending queue.
- *
- * @param type The string name of the keyword.
- *
- * @return A List of all matching queued responses.
- */
- public List extractResponses(String type) {
- List responses = new ArrayList();
-
- Iterator i = queuedResponses.iterator();
- while (i.hasNext()) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
- // if this is of the target type, move it to the response set.
- if (response.isKeyword(type)) {
- i.remove();
- responses.add(response);
- }
- }
- return responses;
- }
-
-
- /**
- * Extract all responses from the pending queue that
- * are "FETCH" responses for a given message number. All matching responses
- * are removed from the pending queue.
- *
- * @param type The string name of the keyword.
- *
- * @return A List of all matching queued responses.
- */
- public List extractFetchResponses(int sequenceNumber) {
- List responses = new ArrayList();
-
- Iterator i = queuedResponses.iterator();
- while (i.hasNext()) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
- // if this is of the target type, move it to the response set.
- if (response.isKeyword("FETCH")) {
- IMAPFetchResponse fetch = (IMAPFetchResponse)response;
- // a response for the correct message number?
- if (fetch.sequenceNumber == sequenceNumber) {
- // pluck these from the list and add to the response set.
- i.remove();
- responses.add(response);
- }
- }
- }
- return responses;
- }
-
- /**
- * Extract a fetch response data item from the queued elements.
- *
- * @param sequenceNumber
- * The message number we're interested in. Fetch responses for other messages
- * will be skipped.
- * @param type The type of body element we need. It is assumed that only one item for
- * the given message number will exist in the queue. The located item will
- * be returned, and that fetch response will be removed from the pending queue.
- *
- * @return The target data item, or null if a match is not found.
- */
- protected IMAPFetchDataItem extractFetchDataItem(long sequenceNumber, int type)
- {
- Iterator i = queuedResponses.iterator();
- while (i.hasNext()) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
- // if this is of the target type, move it to the response set.
- if (response.isKeyword("FETCH")) {
- IMAPFetchResponse fetch = (IMAPFetchResponse)response;
- // a response for the correct message number?
- if (fetch.sequenceNumber == sequenceNumber) {
- // does this response have the item we're looking for?
- IMAPFetchDataItem item = fetch.getDataItem(type);
- if (item != null) {
- // remove this from the pending queue and return the
- // located item
- i.remove();
- return item;
- }
- }
- }
- }
- // not located, sorry
- return null;
- }
-
- /**
- * Extract a all fetch responses that contain a given data item.
- *
- * @param type The type of body element we need. It is assumed that only one item for
- * the given message number will exist in the queue. The located item will
- * be returned, and that fetch response will be removed from the pending queue.
- *
- * @return A List of all matching Fetch responses.
- */
- protected List extractFetchDataItems(int type)
- {
- Iterator i = queuedResponses.iterator();
- List items = new ArrayList();
-
- while (i.hasNext()) {
- IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
- // if this is of the target type, move it to the response set.
- if (response.isKeyword("FETCH")) {
- IMAPFetchResponse fetch = (IMAPFetchResponse)response;
- // does this response have the item we're looking for?
- IMAPFetchDataItem item = fetch.getDataItem(type);
- if (item != null) {
- // remove this from the pending queue and return the
- // located item
- i.remove();
- // we want the fetch response, not the data item, because
- // we're going to require the message sequence number information
- // too.
- items.add(fetch);
- }
- }
- }
- // return whatever we have.
- return items;
- }
-
- /**
- * Make sure we have the latest status information available. We
- * retreive this by sending a NOOP command to the server, and
- * processing any untagged responses we get back.
- */
- public void updateMailboxStatus() throws MessagingException {
- sendSimpleCommand("NOOP");
- }
-
-
- /**
- * check to see if this connection is truely alive.
- *
- * @param timeout The timeout value to control how often we ping
- * the server to see if we're still good.
- *
- * @return true if the server is responding to requests, false for any
- * connection errors. This will also update the folder status
- * by processing returned unsolicited messages.
- */
- public synchronized boolean isAlive(long timeout) {
- long lastUsed = System.currentTimeMillis() - lastAccess;
- if (lastUsed < timeout) {
- return true;
- }
-
- try {
- sendSimpleCommand("NOOP");
- return true;
- } catch (MessagingException e) {
- // the NOOP command will throw a MessagingException if we get anything
- // other than an OK response back from the server.
- }
- return false;
- }
-
-
- /**
- * Issue a fetch command to retrieve the message ENVELOPE structure.
- *
- * @param sequenceNumber The sequence number of the message.
- *
- * @return The IMAPResponse item containing the ENVELOPE information.
- */
- public synchronized List fetchEnvelope(int sequenceNumber) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("ENVELOPE INTERNALDATE RFC822.SIZE");
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- // these are fairly involved sets, so the caller needs to handle these.
- // we just return all of the FETCH results matching the target message number.
- return extractFetchResponses(sequenceNumber);
- }
-
- /**
- * Issue a FETCH command to retrieve the message BODYSTRUCTURE structure.
- *
- * @param sequenceNumber The sequence number of the message.
- *
- * @return The IMAPBodyStructure item for the message.
- * All other untagged responses are queued for processing.
- */
- public synchronized IMAPBodyStructure fetchBodyStructure(int sequenceNumber) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("BODYSTRUCTURE");
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- // locate the response from this
- IMAPBodyStructure bodyStructure = (IMAPBodyStructure)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.BODYSTRUCTURE);
-
- if (bodyStructure == null) {
- throw new MessagingException("No BODYSTRUCTURE information received from IMAP server");
- }
- // and return the body structure directly.
- return bodyStructure;
- }
-
-
- /**
- * Issue a FETCH command to retrieve the message RFC822.HEADERS structure containing the message headers (using PEEK).
- *
- * @param sequenceNumber The sequence number of the message.
- *
- * @return The IMAPRFC822Headers item for the message.
- * All other untagged responses are queued for processing.
- */
- public synchronized InternetHeaders fetchHeaders(int sequenceNumber, String part) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("BODY.PEEK");
- command.appendBodySection(part, "HEADER");
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- IMAPInternetHeader header = (IMAPInternetHeader)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.HEADER);
-
- if (header == null) {
- throw new MessagingException("No HEADER information received from IMAP server");
- }
- // and return the body structure directly.
- return header.headers;
- }
-
-
- /**
- * Issue a FETCH command to retrieve the message text
- *
- * @param sequenceNumber The sequence number of the message.
- *
- * @return The IMAPMessageText item for the message.
- * All other untagged responses are queued for processing.
- */
- public synchronized IMAPMessageText fetchText(int sequenceNumber) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("BODY.PEEK");
- command.appendBodySection("TEXT");
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- IMAPMessageText text = (IMAPMessageText)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.TEXT);
-
- if (text == null) {
- throw new MessagingException("No TEXT information received from IMAP server");
- }
- // and return the body structure directly.
- return text;
- }
-
-
- /**
- * Issue a FETCH command to retrieve the message text
- *
- * @param sequenceNumber The sequence number of the message.
- *
- * @return The IMAPMessageText item for the message.
- * All other untagged responses are queued for processing.
- */
- public synchronized IMAPMessageText fetchBodyPartText(int sequenceNumber, String section) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("BODY.PEEK");
- command.appendBodySection(section, "TEXT");
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- IMAPMessageText text = (IMAPMessageText)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.TEXT);
-
- if (text == null) {
- throw new MessagingException("No TEXT information received from IMAP server");
- }
- // and return the body structure directly.
- return text;
- }
-
-
- /**
- * Issue a FETCH command to retrieve the entire message body in one shot.
- * This may also be used to fetch an embedded message part as a unit.
- *
- * @param sequenceNumber
- * The sequence number of the message.
- * @param section The section number to fetch. If null, the entire body of the message
- * is retrieved.
- *
- * @return The IMAPBody item for the message.
- * All other untagged responses are queued for processing.
- * @exception MessagingException
- */
- public synchronized IMAPBody fetchBody(int sequenceNumber, String section) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.startList();
- command.appendAtom("BODY.PEEK");
- // no part name here, only the section identifier. This will fetch
- // the entire body, with all of the bits in place.
- command.appendBodySection(section, null);
- command.endList();
-
- // we want all of the envelope information about the message, which involves multiple FETCH chunks.
- sendCommand(command);
- IMAPBody body = (IMAPBody)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.BODY);
-
- if (body == null) {
- throw new MessagingException("No BODY information received from IMAP server");
- }
- // and return the body structure directly.
- return body;
- }
-
-
- /**
- * Fetch the message content. This sorts out which method should be used
- * based on the server capability.
- *
- * @param sequenceNumber
- * The sequence number of the target message.
- *
- * @return The byte[] content information.
- * @exception MessagingException
- */
- public byte[] fetchContent(int sequenceNumber) throws MessagingException {
- // fetch the text item and return the data
- IMAPMessageText text = fetchText(sequenceNumber);
- return text.getContent();
- }
-
-
- /**
- * Fetch the message content. This sorts out which method should be used
- * based on the server capability.
- *
- * @param sequenceNumber
- * The sequence number of the target message.
- *
- * @return The byte[] content information.
- * @exception MessagingException
- */
- public byte[] fetchContent(int sequenceNumber, String section) throws MessagingException {
- if (section == null) {
- IMAPMessageText text = fetchText(sequenceNumber);
- return text.getContent();
- } else {
- IMAPBody body = fetchBody(sequenceNumber, section);
- return body.getContent();
- }
- }
-
-
- /**
- * Send an LIST command to the IMAP server, returning all LIST
- * response information.
- *
- * @param mailbox The reference mailbox name sent on the command.
- * @param pattern The match pattern used on the name.
- *
- * @return A List of all LIST response information sent back from the server.
- */
- public synchronized List list(String mailbox, String pattern) throws MessagingException {
- IMAPCommand command = new IMAPCommand("LIST");
-
- // construct the command, encoding the tokens as required by the content.
- command.appendEncodedString(mailbox);
- command.appendEncodedString(pattern);
-
- sendCommand(command);
-
- // pull out the ones we're interested in
- return extractResponses("LIST");
- }
-
-
- /**
- * Send an LSUB command to the IMAP server, returning all LSUB
- * response information.
- *
- * @param mailbox The reference mailbox name sent on the command.
- * @param pattern The match pattern used on the name.
- *
- * @return A List of all LSUB response information sent back from the server.
- */
- public List listSubscribed(String mailbox, String pattern) throws MessagingException {
- IMAPCommand command = new IMAPCommand("LSUB");
-
- // construct the command, encoding the tokens as required by the content.
- command.appendEncodedString(mailbox);
- command.appendEncodedString(pattern);
-
- sendCommand(command);
- // pull out the ones we're interested in
- return extractResponses("LSUB");
- }
-
-
- /**
- * Subscribe to a give mailbox.
- *
- * @param mailbox The desired mailbox name.
- *
- * @exception MessagingException
- */
- public void subscribe(String mailbox) throws MessagingException {
- IMAPCommand command = new IMAPCommand("SUBSCRIBE");
- // add on the encoded mailbox name, as the appropriate token type.
- command.appendEncodedString(mailbox);
-
- // send this, and ignore the response.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Unsubscribe from a mailbox.
- *
- * @param mailbox The mailbox to remove.
- *
- * @exception MessagingException
- */
- public void unsubscribe(String mailbox) throws MessagingException {
- IMAPCommand command = new IMAPCommand("UNSUBSCRIBE");
- // add on the encoded mailbox name, as the appropriate token type.
- command.appendEncodedString(mailbox);
-
- // send this, and ignore the response.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Create a mailbox.
- *
- * @param mailbox The desired new mailbox name (fully qualified);
- *
- * @exception MessagingException
- */
- public void createMailbox(String mailbox) throws MessagingException {
- IMAPCommand command = new IMAPCommand("CREATE");
- // add on the encoded mailbox name, as the appropriate token type.
- command.appendEncodedString(mailbox);
-
- // send this, and ignore the response.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Delete a mailbox.
- *
- * @param mailbox The target mailbox name (fully qualified);
- *
- * @exception MessagingException
- */
- public void deleteMailbox(String mailbox) throws MessagingException {
- IMAPCommand command = new IMAPCommand("DELETE");
- // add on the encoded mailbox name, as the appropriate token type.
- command.appendEncodedString(mailbox);
-
- // send this, and ignore the response.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Rename a mailbox.
- *
- * @param mailbox The target mailbox name (fully qualified);
- *
- * @exception MessagingException
- */
- public void renameMailbox(String oldName, String newName) throws MessagingException {
- IMAPCommand command = new IMAPCommand("RENAME");
- // add on the encoded mailbox name, as the appropriate token type.
- command.appendEncodedString(oldName);
- command.appendEncodedString(newName);
-
- // send this, and ignore the response.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Retrieve a complete set of status items for a mailbox.
- *
- * @param mailbox The mailbox name.
- *
- * @return An IMAPMailboxStatus item filled in with the STATUS responses.
- * @exception MessagingException
- */
- public synchronized IMAPMailboxStatus getMailboxStatus(String mailbox) throws MessagingException {
- IMAPCommand command = new IMAPCommand("STATUS");
-
- // construct the command, encoding the tokens as required by the content.
- command.appendEncodedString(mailbox);
- // request all of the status items
- command.append(" (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)");
-
- sendCommand(command);
-
- // now harvest each of the respon
- IMAPMailboxStatus status = new IMAPMailboxStatus();
- status.mergeSizeResponses(extractResponses("EXISTS"));
- status.mergeSizeResponses(extractResponses("RECENT"));
- status.mergeOkResponses(extractResponses("UIDNEXT"));
- status.mergeOkResponses(extractResponses("UIDVALIDITY"));
- status.mergeOkResponses(extractResponses("UNSEEN"));
- status.mergeStatus((IMAPStatusResponse)extractResponse("STATUS"));
- status.mergeStatus((IMAPPermanentFlagsResponse)extractResponse("PERMANENTFLAGS"));
-
- return status;
- }
-
-
- /**
- * Select a mailbox, returning the accumulated status information
- * about the mailbox returned with the response.
- *
- * @param mailbox The desired mailbox name.
- * @param readOnly The open mode. If readOnly is true, the mailbox is opened
- * using EXAMINE rather than SELECT.
- *
- * @return A status object containing the mailbox particulars.
- * @exception MessagingException
- */
- public synchronized IMAPMailboxStatus openMailbox(String mailbox, boolean readOnly) throws MessagingException {
- IMAPCommand command = new IMAPCommand();
-
- // if readOnly is required, we use EXAMINE to switch to the mailbox rather than SELECT.
- // This returns the same response information, but the mailbox will not accept update operations.
- if (readOnly) {
- command.appendAtom("EXAMINE");
- }
- else {
- command.appendAtom("SELECT");
- }
-
- // construct the command, encoding the tokens as required by the content.
- command.appendEncodedString(mailbox);
-
- // issue the select
- IMAPTaggedResponse response = sendCommand(command);
-
- IMAPMailboxStatus status = new IMAPMailboxStatus();
- // set the mode to the requested open mode.
- status.mode = readOnly ? Folder.READ_ONLY : Folder.READ_WRITE;
-
- // the server might disagree on the mode, so check to see if
- // it's telling us READ-ONLY.
- if (response.hasStatus("READ-ONLY")) {
- status.mode = Folder.READ_ONLY;
- }
-
- // some of these are required, some are optional.
- status.mergeFlags((IMAPFlagsResponse)extractResponse("FLAGS"));
- status.mergeStatus((IMAPSizeResponse)extractResponse("EXISTS"));
- status.mergeStatus((IMAPSizeResponse)extractResponse("RECENT"));
- status.mergeStatus((IMAPOkResponse)extractResponse("UIDVALIDITY"));
- status.mergeStatus((IMAPOkResponse)extractResponse("UNSEEN"));
- status.mergeStatus((IMAPPermanentFlagsResponse)extractResponse("PERMANENTFLAGS"));
- // mine the response for status information about the selected mailbox.
- return status;
- }
-
-
- /**
- * Tells the IMAP server to expunge messages marked for deletion.
- * The server will send us an untagged EXPUNGE message back for
- * each deleted message. For explicit expunges we request, we'll
- * grabbed the untagged responses here, rather than force them to
- * be handled as pending responses. The caller will handle the
- * updates directly.
- *
- * @exception MessagingException
- */
- public synchronized List expungeMailbox() throws MessagingException {
- // send the message, and make sure we got an OK response
- sendCommand("EXPUNGE");
- // extract all of the expunged responses and return.
- return extractResponses("EXPUNGED");
- }
-
- public int[] searchMailbox(SearchTerm term) throws MessagingException {
- return searchMailbox("ALL", term);
- }
-
- /**
- * Send a search to the IMAP server using the specified
- * messages selector and search term. This figures out what
- * to do with CHARSET on the SEARCH command.
- *
- * @param messages The list of messages (comma-separated numbers or "ALL").
- * @param term The desired search criteria
- *
- * @return Returns an int[] array of message numbers for all matched messages.
- * @exception MessagingException
- */
- public int[] searchMailbox(String messages, SearchTerm term) throws MessagingException {
- // don't use a charset by default, but we need to look at the data to see if we have a problem.
- String charset = null;
-
- if (IMAPCommand.checkSearchEncoding(term)) {
- // not sure exactly how to decide what to use here. Two immediate possibilities come to mind,
- // UTF-8 or the MimeUtility.getDefaultJavaCharset() value. Running a small test against the
- // Sun impl shows them sending a CHARSET value of UTF-8, so that sounds like the winner. I don't
- // believe there's anything in the CAPABILITY response that would tell us what to use.
- charset = "UTF-8";
- }
-
- return searchMailbox(messages, term, charset);
- }
-
- /**
- * Send a search to the IMAP server using the specified
- * messages selector and search term.
- *
- * @param messages The list of messages (comma-separated numbers or "ALL").
- * @param charset The charset specifier to send to the server. If null, then
- * the CHARSET keyword is omitted.
- * @param term The desired search criteria
- *
- * @return Returns an int[] array of message numbers for all matched messages.
- * @exception MessagingException
- */
- public synchronized int[] searchMailbox(String messages, SearchTerm term, String charset) throws MessagingException {
- IMAPCommand command = new IMAPCommand("SEARCH");
-
- // if we have an explicit charset to use, append that.
- if (charset != null) {
- command.appendAtom("CHARSET");
- command.appendAtom(charset);
- }
-
- // now go through the process of translating the javamail SearchTerm objects into
- // the IMAP command sequence. The SearchTerm sequence may be a complex tree of comparison terms,
- // so this is not a simple process.
- command.appendSearchTerm(term, charset);
- // need to append the message set
- command.appendAtom(messages);
-
- // now issue the composed command.
- sendCommand(command);
-
- // get the list of search responses
- IMAPSearchResponse hits = (IMAPSearchResponse)extractResponse("SEARCH");
- // and return the message hits
- return hits.messageNumbers;
- }
-
-
- /**
- * Append a message to a mailbox, given the direct message data.
- *
- * @param mailbox The target mailbox name.
- * @param messageFlags
- * The initial flag set for the appended message.
- * @param messageDate
- * The received date the message is created with,
- * @param messageData
- * The RFC822 Message data stored on the server.
- *
- * @exception MessagingException
- */
- public void appendMessage(String mailbox, Date messageDate, Flags messageFlags, byte[] messageData) throws MessagingException {
- IMAPCommand command = new IMAPCommand("APPEND");
-
- // the mailbox is encoded.
- command.appendEncodedString(mailbox);
-
- if (messageFlags != null) {
- // the flags are pulled from an existing object. We can set most flag values, but the servers
- // reserve RECENT for themselves. We need to force that one off.
- messageFlags.remove(Flags.Flag.RECENT);
- // and add the flag list to the commmand.
- command.appendFlags(messageFlags);
- }
-
- if (messageDate != null) {
- command.appendDate(messageDate);
- }
-
- // this gets appended as a literal.
- command.appendLiteral(messageData);
- // just send this as a simple command...we don't deal with the response other than to verifiy
- // it was ok.
- sendSimpleCommand(command);
- }
-
- /**
- * Fetch the flag set for a given message sequence number.
- *
- * @param sequenceNumber
- * The message sequence number.
- *
- * @return The Flags defined for this message.
- * @exception MessagingException
- */
- public synchronized Flags fetchFlags(int sequenceNumber) throws MessagingException {
- // we want just the flag item here.
- sendCommand("FETCH " + String.valueOf(sequenceNumber) + " (FLAGS)");
- // get the return data item, and get the flags from within it
- IMAPFlags flags = (IMAPFlags)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.FLAGS);
- return flags.flags;
- }
-
-
- /**
- * Set the flags for a range of messages.
- *
- * @param messageSet The set of message numbers.
- * @param flags The new flag settings.
- * @param set true if the flags should be set, false for a clear operation.
- *
- * @return A list containing all of the responses with the new flag values.
- * @exception MessagingException
- */
- public synchronized List setFlags(String messageSet, Flags flags, boolean set) throws MessagingException {
- IMAPCommand command = new IMAPCommand("STORE");
- command.appendAtom(messageSet);
- // the command varies depending on whether this is a set or clear operation
- if (set) {
- command.appendAtom("+FLAGS");
- }
- else {
- command.appendAtom("-FLAGS");
- }
-
- // append the flag set
- command.appendFlags(flags);
-
- // we want just the flag item here.
- sendCommand(command);
- // we should have a FETCH response for each of the updated messages. Return this
- // response, and update the message numbers.
- return extractFetchDataItems(IMAPFetchDataItem.FLAGS);
- }
-
-
- /**
- * Set the flags for a single message.
- *
- * @param sequenceNumber
- * The sequence number of target message.
- * @param flags The new flag settings.
- * @param set true if the flags should be set, false for a clear operation.
- *
- * @exception MessagingException
- */
- public synchronized Flags setFlags(int sequenceNumber, Flags flags, boolean set) throws MessagingException {
- IMAPCommand command = new IMAPCommand("STORE");
- command.appendInteger(sequenceNumber);
- // the command varies depending on whether this is a set or clear operation
- if (set) {
- command.appendAtom("+FLAGS");
- }
- else {
- command.appendAtom("-FLAGS");
- }
-
- // append the flag set
- command.appendFlags(flags);
-
- // we want just the flag item here.
- sendCommand(command);
- // get the return data item, and get the flags from within it
- IMAPFlags flagResponse = (IMAPFlags)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.FLAGS);
- return flagResponse.flags;
- }
-
-
- /**
- * Copy a range of messages to a target mailbox.
- *
- * @param messageSet The set of message numbers.
- * @param target The target mailbox name.
- *
- * @exception MessagingException
- */
- public void copyMessages(String messageSet, String target) throws MessagingException {
- IMAPCommand command = new IMAPCommand("COPY");
- // the auth command initiates the handshaking.
- command.appendAtom(messageSet);
- // the mailbox is encoded.
- command.appendEncodedString(target);
- // just send this as a simple command...we don't deal with the response other than to verifiy
- // it was ok.
- sendSimpleCommand(command);
- }
-
-
- /**
- * Fetch the message number for a give UID.
- *
- * @param uid The target UID
- *
- * @return An IMAPUid object containing the mapping information.
- */
- public synchronized IMAPUid getSequenceNumberForUid(long uid) throws MessagingException {
- IMAPCommand command = new IMAPCommand("UID FETCH");
- command.appendLong(uid);
- command.appendAtom("(UID)");
-
- // this situation is a little strange, so it deserves a little explanation.
- // We need the message sequence number for this message from a UID value.
- // we're going to send a UID FETCH command, requesting the UID value back.
- // That seems strange, but the * nnnn FETCH response for the request will
- // be tagged with the message sequence number. THAT'S the information we
- // really want, and it will be included in the IMAPUid object.
-
- sendCommand(command);
- // ok, now we need to search through these looking for a FETCH response with a UID element.
- List responses = extractResponses("FETCH");
-
- // we're looking for a fetch response with a UID data item with the UID information
- // inside of it.
- for (int i = 0; i < responses.size(); i++) {
- IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
- IMAPUid item = (IMAPUid)response.getDataItem(IMAPFetchDataItem.UID);
- // is this the response we're looking for? The information we
- // need is the message number returned with the response, which is
- // also contained in the UID item.
- if (item != null && item.uid == uid) {
- return item;
- }
- // not one meant for us, add it back to the pending queue.
- queuePendingResponse(response);
- }
- // didn't find this one
- return null;
- }
-
-
- /**
- * Fetch the message numbers for a consequetive range
- * of UIDs.
- *
- * @param start The start of the range.
- * @param end The end of the uid range.
- *
- * @return A list of UID objects containing the mappings.
- */
- public synchronized List getSequenceNumbersForUids(long start, long end) throws MessagingException {
- IMAPCommand command = new IMAPCommand("UID FETCH");
- // send the request for the range "start:end" so we can fetch all of the info
- // at once.
- command.appendLong(start);
- command.append(":");
- // not the special range marker? Just append the
- // number. The LASTUID value needs to be "*" on the command.
- if (end != UIDFolder.LASTUID) {
- command.appendLong(end);
- }
- else {
- command.append("*");
- }
- command.appendAtom("(UID)");
-
- // this situation is a little strange, so it deserves a little explanation.
- // We need the message sequence number for this message from a UID value.
- // we're going to send a UID FETCH command, requesting the UID value back.
- // That seems strange, but the * nnnn FETCH response for the request will
- // be tagged with the message sequence number. THAT'S the information we
- // really want, and it will be included in the IMAPUid object.
-
- sendCommand(command);
- // ok, now we need to search through these looking for a FETCH response with a UID element.
- List responses = extractResponses("FETCH");
-
- List uids = new ArrayList((int)(end - start + 1));
-
- // we're looking for a fetch response with a UID data item with the UID information
- // inside of it.
- for (int i = 0; i < responses.size(); i++) {
- IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
- IMAPUid item = (IMAPUid)response.getDataItem(IMAPFetchDataItem.UID);
- // is this the response we're looking for? The information we
- // need is the message number returned with the response, which is
- // also contained in the UID item.
- if (item != null) {
- uids.add(item);
- }
- else {
- // not one meant for us, add it back to the pending queue.
- queuePendingResponse(response);
- }
- }
- // return the list of uids we located.
- return uids;
- }
-
-
- /**
- * Fetch the UID value for a target message number
- *
- * @param sequenceNumber
- * The target message number.
- *
- * @return An IMAPUid object containing the mapping information.
- */
- public synchronized IMAPUid getUidForSequenceNumber(int sequenceNumber) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendInteger(sequenceNumber);
- command.appendAtom("(UID)");
-
- // similar to the other fetches, but without the strange bit. We're starting
- // with the message number in this case.
-
- sendCommand(command);
-
- // ok, now we need to search through these looking for a FETCH response with a UID element.
- return (IMAPUid)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.UID);
- }
-
-
- /**
- * Retrieve the user name space info from the server.
- *
- * @return An IMAPNamespace response item with the information. If the server
- * doesn't support the namespace extension, an empty one is returned.
- */
- public synchronized IMAPNamespaceResponse getNamespaces() throws MessagingException {
- // if no namespace capability, then return an empty
- // response, which will trigger the default behavior.
- if (!hasCapability("NAMESPACE")) {
- return new IMAPNamespaceResponse();
- }
- // no arguments on this command, so just send an hope it works.
- sendCommand("NAMESPACE");
-
- // this should be here, since it's a required response when the
- // command worked. Just extract, and return.
- return (IMAPNamespaceResponse)extractResponse("NAMESPACE");
- }
-
-
- /**
- * Prefetch message information based on the request profile. We'll return
- * all of the fetch information to the requesting Folder, which will sort
- * out what goes where.
- *
- * @param messageSet The set of message numbers we need to fetch.
- * @param profile The profile of the required information.
- *
- * @return All FETCH responses resulting from the command.
- * @exception MessagingException
- */
- public synchronized List fetch(String messageSet, FetchProfile profile) throws MessagingException {
- IMAPCommand command = new IMAPCommand("FETCH");
- command.appendAtom(messageSet);
- // this is the set of items to append
- command.appendFetchProfile(profile);
-
- // now send the fetch command, which will likely send back a lot of "FETCH" responses.
- // Suck all of those reponses out of the queue and send them back for processing.
- sendCommand(command);
- // we can have a large number of messages here, so just grab all of the fetches
- // we get back, and let the Folder sort out who gets what.
- return extractResponses("FETCH");
- }
-
-
- /**
- * Set the ACL rights for a mailbox. This replaces
- * any existing ACLs defined.
- *
- * @param mailbox The target mailbox.
- * @param acl The new ACL to be used for the mailbox.
- *
- * @exception MessagingException
- */
- public synchronized void setACLRights(String mailbox, ACL acl) throws MessagingException {
- IMAPCommand command = new IMAPCommand("SETACL");
- command.appendEncodedString(mailbox);
-
- command.appendACL(acl);
-
- sendSimpleCommand(command);
- }
-
-
- /**
- * Add a set of ACL rights to a mailbox.
- *
- * @param mailbox The mailbox to alter.
- * @param acl The ACL to add.
- *
- * @exception MessagingException
- */
- public synchronized void addACLRights(String mailbox, ACL acl) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("SETACL");
- command.appendEncodedString(mailbox);
-
- command.appendACL(acl, "+");
-
- sendSimpleCommand(command);
- }
-
-
- /**
- * Remove an ACL from a given mailbox.
- *
- * @param mailbox The mailbox to alter.
- * @param acl The particular ACL to revoke.
- *
- * @exception MessagingException
- */
- public synchronized void removeACLRights(String mailbox, ACL acl) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("SETACL");
- command.appendEncodedString(mailbox);
-
- command.appendACL(acl, "-");
-
- sendSimpleCommand(command);
- }
-
-
- /**
- * Get the ACL rights assigned to a given mailbox.
- *
- * @param mailbox The target mailbox.
- *
- * @return The an array of ACL items describing the access
- * rights to the mailbox.
- * @exception MessagingException
- */
- public synchronized ACL[] getACLRights(String mailbox) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("GETACL");
- command.appendEncodedString(mailbox);
-
- // now send the GETACL command, which will return a single ACL untagged response.
- sendCommand(command);
- // there should be just a single ACL response back from this command.
- IMAPACLResponse response = (IMAPACLResponse)extractResponse("ACL");
- return response.acls;
- }
-
-
- /**
- * Get the current user's ACL rights to a given mailbox.
- *
- * @param mailbox The target mailbox.
- *
- * @return The Rights associated with this mailbox.
- * @exception MessagingException
- */
- public synchronized Rights getMyRights(String mailbox) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("MYRIGHTS");
- command.appendEncodedString(mailbox);
-
- // now send the MYRIGHTS command, which will return a single MYRIGHTS untagged response.
- sendCommand(command);
- // there should be just a single MYRIGHTS response back from this command.
- IMAPMyRightsResponse response = (IMAPMyRightsResponse)extractResponse("MYRIGHTS");
- return response.rights;
- }
-
-
- /**
- * List the ACL rights that a particular user has
- * to a mailbox.
- *
- * @param mailbox The target mailbox.
- * @param name The user we're querying.
- *
- * @return An array of rights the use has to this mailbox.
- * @exception MessagingException
- */
- public synchronized Rights[] listACLRights(String mailbox, String name) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("LISTRIGHTS");
- command.appendEncodedString(mailbox);
- command.appendString(name);
-
- // now send the GETACL command, which will return a single ACL untagged response.
- sendCommand(command);
- // there should be just a single ACL response back from this command.
- IMAPListRightsResponse response = (IMAPListRightsResponse)extractResponse("LISTRIGHTS");
- return response.rights;
- }
-
-
- /**
- * Delete an ACL item for a given user name from
- * a target mailbox.
- *
- * @param mailbox The mailbox we're altering.
- * @param name The user name.
- *
- * @exception MessagingException
- */
- public synchronized void deleteACL(String mailbox, String name) throws MessagingException {
- if (!hasCapability("ACL")) {
- throw new MethodNotSupportedException("ACL not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("DELETEACL");
- command.appendEncodedString(mailbox);
- command.appendString(name);
-
- // just send the command. No response to handle.
- sendSimpleCommand(command);
- }
-
- /**
- * Fetch the quota root information for a target mailbox.
- *
- * @param mailbox The mailbox of interest.
- *
- * @return An array of quotas describing all of the quota roots
- * that apply to the target mailbox.
- * @exception MessagingException
- */
- public synchronized Quota[] fetchQuotaRoot(String mailbox) throws MessagingException {
- if (!hasCapability("QUOTA")) {
- throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("GETQUOTAROOT");
- command.appendEncodedString(mailbox);
-
- // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
- // each root names in the first response.
- sendCommand(command);
- // we don't really need this, but pull it from the response queue anyway.
- extractResponse("QUOTAROOT");
-
- // now get the real meat of the matter
- List responses = extractResponses("QUOTA");
-
- // now copy all of the returned quota items into the response array.
- Quota[] quotas = new Quota[responses.size()];
- for (int i = 0; i < quotas.length; i++) {
- IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
- quotas[i] = q.quota;
- }
-
- return quotas;
- }
-
- /**
- * Fetch QUOTA information from a named QUOTE root.
- *
- * @param root The target root name.
- *
- * @return An array of Quota items associated with that root name.
- * @exception MessagingException
- */
- public synchronized Quota[] fetchQuota(String root) throws MessagingException {
- if (!hasCapability("QUOTA")) {
- throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("GETQUOTA");
- command.appendString(root);
-
- // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
- // each root names in the first response.
- sendCommand(command);
-
- // now get the real meat of the matter
- List responses = extractResponses("QUOTA");
-
- // now copy all of the returned quota items into the response array.
- Quota[] quotas = new Quota[responses.size()];
- for (int i = 0; i < quotas.length; i++) {
- IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
- quotas[i] = q.quota;
- }
-
- return quotas;
- }
-
- /**
- * Set a Quota item for the currently accessed
- * userid/folder resource.
- *
- * @param quota The new QUOTA information.
- *
- * @exception MessagingException
- */
- public synchronized void setQuota(Quota quota) throws MessagingException {
- if (!hasCapability("QUOTA")) {
- throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
- }
- IMAPCommand command = new IMAPCommand("GETQUOTA");
- // this gets appended as a list of resource values
- command.appendQuota(quota);
-
- // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
- // each root names in the first response.
- sendCommand(command);
- // we don't really need this, but pull it from the response queue anyway.
- extractResponses("QUOTA");
- }
-
-
- /**
- * Test if this connection has a given capability.
- *
- * @param capability The capability name.
- *
- * @return true if this capability is in the list, false for a mismatch.
- */
- public boolean hasCapability(String capability) {
- if (capabilities == null) {
- return false;
- }
- return capabilities.containsKey(capability);
- }
-
- /**
- * Tag this connection as having been closed by the
- * server. This will not be returned to the
- * connection pool.
- */
- public void setClosed() {
- closed = true;
- }
-
- /**
- * Test if the connnection has been forcibly closed.
- *
- * @return True if the server disconnected the connection.
- */
- public boolean isClosed() {
- return closed;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
deleted file mode 100644
index f89619c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/**
- * 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.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Store;
-
-import javax.mail.StoreClosedException;
-
-import org.apache.geronimo.javamail.store.imap.IMAPStore;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-public class IMAPConnectionPool {
-
- protected static final String MAIL_PORT = "port";
- protected static final String MAIL_POOL_SIZE = "connectionpoolsize";
- protected static final String MAIL_POOL_TIMEOUT = "connectionpooltimeout";
- protected static final String MAIL_SEPARATE_STORE_CONNECTION = "separatestoreconnection";
-
- protected static final String MAIL_SASL_REALM = "sasl.realm";
- protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid";
-
- // 45 seconds, by default.
- protected static final int DEFAULT_POOL_TIMEOUT = 45000;
- protected static final String DEFAULT_MAIL_HOST = "localhost";
-
- protected static final int MAX_CONNECTION_RETRIES = 3;
- protected static final int MAX_POOL_WAIT = 500;
-
-
- // Our hosting Store instance
- protected IMAPStore store;
- // our Protocol abstraction
- protected ProtocolProperties props;
- // our list of created connections
- protected List poolConnections = new ArrayList();
- // our list of available connections
- protected List availableConnections = new ArrayList();
-
- // the dedicated Store connection (if we're configured that way)
- protected IMAPConnection storeConnection = null;
-
- // our dedicated Store connection attribute
- protected boolean dedicatedStoreConnection;
- // the size of our connection pool (by default, we only keep a single connection in the pool)
- protected int poolSize = 1;
- // the connection timeout property
- protected long poolTimeout;
- // our debug flag
- protected boolean debug;
-
- // the target host
- protected String host;
- // the target server port.
- protected int port;
- // the username we connect with
- protected String username;
- // the authentication password.
- protected String password;
- // the SASL realm name
- protected String realm;
- // the authorization id. With IMAP, it's possible to
- // log on with another's authorization.
- protected String authid;
- // Turned on when the store is closed for business.
- protected boolean closed = false;
- // the connection capabilities map
- protected Map capabilities;
-
- /**
- * Create a connection pool associated with a give IMAPStore instance. The
- * connection pool manages handing out connections for both the Store and
- * Folder and Message usage.
- *
- * Depending on the session properties, the Store may be given a dedicated
- * connection, or will share connections with the Folders. Connections may
- * be requested from either the Store or Folders. Messages must request
- * their connections from their hosting Folder, and only one connection is
- * allowed per folder.
- *
- * @param store The Store we're creating the pool for.
- * @param props The property bundle that defines protocol properties
- * that alter the connection behavior.
- */
- public IMAPConnectionPool(IMAPStore store, ProtocolProperties props) {
- this.store = store;
- this.props = props;
-
- // get the pool size. By default, we just use a single connection that's
- // shared among Store and all of the Folders. Since most apps that use
- // javamail tend to be single-threaded, this generally poses no great hardship.
- poolSize = props.getIntProperty(MAIL_POOL_SIZE, 1);
- // get the timeout property. Default is 45 seconds.
- poolTimeout = props.getIntProperty(MAIL_POOL_TIMEOUT, DEFAULT_POOL_TIMEOUT);
- // we can create a dedicated connection over and above the pool set that's
- // reserved for the Store instance to use.
- dedicatedStoreConnection = props.getBooleanProperty(MAIL_SEPARATE_STORE_CONNECTION, false);
- // if we have a dedicated pool connection, we allocated that from the pool. Add this to
- // the total pool size so we don't find ourselves stuck if the pool size is 1.
- if (dedicatedStoreConnection) {
- poolSize++;
- }
- }
-
-
- /**
- * Manage the initial connection to the IMAP server. This is the first
- * point where we obtain the information needed to make an actual server
- * connection. Like the Store protocolConnect method, we return false
- * if there's any sort of authentication difficulties.
- *
- * @param host The host of the IMAP server.
- * @param port The IMAP server connection port.
- * @param user The connection user name.
- * @param password The connection password.
- *
- * @return True if we were able to connect and authenticate correctly.
- * @exception MessagingException
- */
- public synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
- // NOTE: We don't check for the username/password being null at this point. It's possible that
- // the server will send back a PREAUTH response, which means we don't need to go through login
- // processing. We'll need to check the capabilities response after we make the connection to decide
- // if logging in is necesssary.
-
- // save this for subsequent connections. All pool connections will use this info.
- // if the port is defaulted, then see if we have something configured in the session.
- // if not configured, we just use the default default.
- if (port == -1) {
- // check for a property and fall back on the default if it's not set.
- port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
- // it's possible that -1 might have been explicitly set, so one last check.
- if (port == -1) {
- port = props.getDefaultPort();
- }
- }
-
- // Before we do anything, let's make sure that we succesfully received a host
- if ( host == null ) {
- host = DEFAULT_MAIL_HOST;
- }
-
- this.host = host;
- this.port = port;
- this.username = username;
- this.password = password;
-
- // make sure we have the realm information
- realm = props.getProperty(MAIL_SASL_REALM);
- // get an authzid value, if we have one. The default is to use the username.
- authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
-
- // go create a connection and just add it to the pool. If there is an authenticaton error,
- // return the connect failure, and we may end up trying again.
- IMAPConnection connection = createPoolConnection();
- if (connection == null) {
- return false;
- }
- // save the capabilities map from the first connection.
- capabilities = connection.getCapabilities();
- // if we're using a dedicated store connection, remove this from the pool and
- // reserve it for the store.
- if (dedicatedStoreConnection)
- {
- storeConnection = connection;
- // make sure this is hooked up to the store.
- connection.addResponseHandler(store);
- }
- else {
- // just put this back in the pool. It's ready for anybody to use now.
- synchronized(this) {
- availableConnections.add(connection);
- }
- }
- // we're connection, authenticated, and ready to go.
- return true;
- }
-
- /**
- * Creates an authenticated pool connection and adds it to
- * the connection pool. If there is an existing connection
- * already in the pool, this returns without creating a new
- * connection.
- *
- * @exception MessagingException
- */
- protected IMAPConnection createPoolConnection() throws MessagingException {
- IMAPConnection connection = new IMAPConnection(props, this);
- if (!connection.protocolConnect(host, port, authid, realm, username, password)) {
- // we only add live connections to the pool. Sever the connections and
- // allow it to go free.
- connection.closeServerConnection();
- return null;
- }
-
- // add this to the master list. We do NOT add this to the
- // available queue because we're handing this out.
- synchronized(this) {
- // uh oh, we closed up shop while we were doing this...clean it up a
- // get out of here
- if (closed) {
- connection.close();
- throw new StoreClosedException(store, "No Store connections available");
- }
-
- poolConnections.add(connection);
- }
- // return that connection
- return connection;
- }
-
-
- /**
- * Get a connection from the pool. We try to retrieve a live
- * connection, but we test the connection's liveness before
- * returning one. If we don't have a viable connection in
- * the pool, we'll create a new one. The returned connection
- * will be in the authenticated state already.
- *
- * @return An IMAPConnection object that is connected to the server.
- */
- protected IMAPConnection getConnection() throws MessagingException {
- int retryCount = 0;
-
- // To keep us from falling into a futile failure loop, we'll only allow
- // a set number of connection failures.
- while (retryCount < MAX_CONNECTION_RETRIES) {
- // first try for an already created one. If this returns
- // null, then we'll probably have to make a new one.
- IMAPConnection connection = getPoolConnection();
- // cool, we got one, the hard part is done.
- if (connection != null) {
- return connection;
- }
- // ok, create a new one. This *should* work, but the server might
- // have gone down, or other problem may occur. If we have a problem,
- // retry the entire process...but only for a bit. No sense
- // being stubborn about it.
- connection = createPoolConnection();
- if (connection != null) {
- return connection;
- }
- // step the retry count
- retryCount++;
- }
-
- throw new MessagingException("Unable to get connection to IMAP server");
- }
-
- /**
- * Obtain a connection from the existing connection pool. If none are
- * available, and we've reached the connection pool limit, we'll wait for
- * some other thread to return one. It generally doesn't take too long, as
- * they're usually only held for the time required to execute a single
- * command. If we're not at the pool limit, return null, which will signal
- * the caller to go ahead and create a new connection outside of the
- * lock.
- *
- * @return Either an active connection instance, or null if the caller should go
- * ahead and try to create a new connection.
- * @exception MessagingException
- */
- protected synchronized IMAPConnection getPoolConnection() throws MessagingException {
- // if the pool is closed, we can't process this
- if (closed) {
- throw new StoreClosedException(store, "No Store connections available");
- }
-
- // we'll retry this a few times if the connection pool is full, but
- // after that, we'll just create a new connection.
- for (int i = 0; i < MAX_CONNECTION_RETRIES; i++) {
- Iterator it = availableConnections.iterator();
- while (it.hasNext()) {
- IMAPConnection connection = (IMAPConnection)it.next();
- // live or dead, we're going to remove this from the
- // available list.
- it.remove();
- if (connection.isAlive(poolTimeout)) {
- // return the connection to the requestor
- return connection;
- }
- else {
- // remove this from the pool...it's toast.
- poolConnections.remove(connection);
- // make sure this cleans up after itself.
- connection.closeServerConnection();
- }
- }
-
- // we've not found something usable in the pool. Now see if
- // we're allowed to add another connection, or must just wait for
- // someone else to return one.
-
- if (poolConnections.size() >= poolSize) {
- // check to see if we've been told to shutdown before waiting
- if (closed) {
- throw new StoreClosedException(store, "No Store connections available");
- }
- // we need to wait for somebody to return a connection
- // once woken up, we'll spin around and try to snag one from
- // the pool again.
- try {
- wait(MAX_POOL_WAIT);
- } catch (InterruptedException e) {
- }
-
- // check to see if we've been told to shutdown while we waited
- if (closed) {
- throw new StoreClosedException(store, "No Store connections available");
- }
- }
- else {
- // exit out and create a new connection. Since
- // we're going to be outside the synchronized block, it's possible
- // we'll go over our pool limit. We'll take care of that when connections start
- // getting returned.
- return null;
- }
- }
- // we've hit the maximum number of retries...just create a new connection.
- return null;
- }
-
- /**
- * Return a connection to the connection pool.
- *
- * @param connection The connection getting returned.
- *
- * @exception MessagingException
- */
- protected void returnPoolConnection(IMAPConnection connection) throws MessagingException
- {
- synchronized(this) {
- // If we're still within the bounds of our connection pool,
- // just add this to the active list and send out a notification
- // in case somebody else is waiting for the connection.
- if (availableConnections.size() < poolSize) {
- availableConnections.add(connection);
- notify();
- return;
- }
- // remove this from the connection pool...we have too many.
- poolConnections.remove(connection);
- }
- // the additional cleanup occurs outside the synchronized block
- connection.close();
- }
-
- /**
- * Release a closed connection.
- *
- * @param connection The connection getting released.
- *
- * @exception MessagingException
- */
- protected void releasePoolConnection(IMAPConnection connection) throws MessagingException
- {
- synchronized(this) {
- // remove this from the connection pool...it's no longer usable.
- poolConnections.remove(connection);
- }
- // the additional cleanup occurs outside the synchronized block
- connection.close();
- }
-
-
- /**
- * Get a connection for the Store. This will be either a
- * dedicated connection object, or one from the pool, depending
- * on the mail.imap.separatestoreconnection property.
- *
- * @return An authenticated connection object.
- */
- public synchronized IMAPConnection getStoreConnection() throws MessagingException {
- if (closed) {
- throw new StoreClosedException(store, "No Store connections available");
- }
- // if we have a dedicated connection created, return it.
- if (storeConnection != null) {
- return storeConnection;
- }
- else {
- IMAPConnection connection = getConnection();
- // add the store as a response handler while it has it.
- connection.addResponseHandler(store);
- return connection;
- }
- }
-
-
- /**
- * Return the Store connection to the connection pool. If we have a dedicated
- * store connection, this is simple. Otherwise, the connection goes back
- * into the general connection pool.
- *
- * @param connection The connection getting returned.
- */
- public synchronized void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
- // have a server disconnect situation?
- if (connection.isClosed()) {
- // we no longer have a dedicated store connection.
- // we need to return to the pool from now on.
- storeConnection = null;
- // throw this away.
- releasePoolConnection(connection);
- }
- else {
- // if we have a dedicated connection, nothing to do really. Otherwise,
- // return this connection to the pool.
- if (storeConnection == null) {
- // unhook the store from the connection.
- connection.removeResponseHandler(store);
- returnPoolConnection(connection);
- }
- }
- }
-
-
- /**
- * Get a connection for Folder.
- *
- * @return An authenticated connection object.
- */
- public IMAPConnection getFolderConnection() throws MessagingException {
- // just get a connection from the pool
- return getConnection();
- }
-
-
- /**
- * Return a Folder connection to the connection pool.
- *
- * @param connection The connection getting returned.
- */
- public void releaseFolderConnection(IMAPConnection connection) throws MessagingException {
- // potentially, the server may have decided to shut us down.
- // In that case, the connection is no longer usable, so we need
- // to remove it from the list of available ones.
- if (!connection.isClosed()) {
- // back into the pool with yee, matey....arrggghhh
- returnPoolConnection(connection);
- }
- else {
- // can't return this one to the pool. It's been stomped on
- releasePoolConnection(connection);
- }
- }
-
-
- /**
- * Close the entire connection pool.
- *
- * @exception MessagingException
- */
- public synchronized void close() throws MessagingException {
- // first close each of the connections. This also closes the
- // store connection.
- for (int i = 0; i < poolConnections.size(); i++) {
- IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
- connection.close();
- }
- // clear the pool
- poolConnections.clear();
- availableConnections.clear();
- storeConnection = null;
- // turn out the lights, hang the closed sign on the wall.
- closed = true;
- }
-
-
- /**
- * Flush any connections from the pool that have not been used
- * for at least the connection pool timeout interval.
- */
- protected synchronized void closeStaleConnections() {
- Iterator i = poolConnections.iterator();
-
- while (i.hasNext()) {
- IMAPConnection connection = (IMAPConnection)i.next();
- // if this connection is a stale one, remove it from the pool
- // and close it out.
- if (connection.isStale(poolTimeout)) {
- i.remove();
- try {
- connection.close();
- } catch (MessagingException e) {
- // ignored. we're just closing connections that are probably timed out anyway, so errors
- // on those shouldn't have an effect on the real operation we're dealing with.
- }
- }
- }
- }
-
-
- /**
- * Return a connection back to the connection pool. If we're not
- * over our limit, the connection is kept around. Otherwise, it's
- * given a nice burial.
- *
- * @param connection The returned connection.
- */
- protected synchronized void releaseConnection(IMAPConnection connection) {
- // before adding this to the pool, close any stale connections we may
- // have. The connection we're adding is quite likely to be a fresh one,
- // so we should cache that one if we can.
- closeStaleConnections();
- // still over the limit?
- if (poolConnections.size() + 1 > poolSize) {
- try {
- // close this out and forget we ever saw it.
- connection.close();
- } catch (MessagingException e) {
- // ignore....this is a non-critical problem if this fails now.
- }
- }
- else {
- // listen to alerts on this connection, and put it back in the pool.
- poolConnections.add(connection);
- }
- }
-
- /**
- * Cleanup time. Sever and cleanup all of the pool connection
- * objects, including the special Store connection, if we have one.
- */
- protected synchronized void freeAllConnections() {
- for (int i = 0; i < poolConnections.size(); i++) {
- IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
- try {
- // close this out and forget we ever saw it.
- connection.close();
- } catch (MessagingException e) {
- // ignore....this is a non-critical problem if this fails now.
- }
- }
- // everybody, out of the pool!
- poolConnections.clear();
-
- // don't forget the special store connection, if we have one.
- if (storeConnection != null) {
- try {
- // close this out and forget we ever saw it.
- storeConnection.close();
- } catch (MessagingException e) {
- // ignore....this is a non-critical problem if this fails now.
- }
- storeConnection = null;
- }
- }
-
-
- /**
- * Test if this connection has a given capability.
- *
- * @param capability The capability name.
- *
- * @return true if this capability is in the list, false for a mismatch.
- */
- public boolean hasCapability(String capability) {
- if (capabilities == null) {
- return false;
- }
- return capabilities.containsKey(capability);
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
deleted file mode 100644
index 32ea079..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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 a continuation response from an IMAP server.
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-public class IMAPContinuationResponse extends IMAPTaggedResponse {
- /**
- * Create a continuation 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.
- */
- protected IMAPContinuationResponse(byte [] response) {
- super(response);
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
deleted file mode 100644
index c2e947e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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 as specified by
- * draft-ietf-drums-msg-fmt-08 dated January 26, 2000
- * which supercedes RFC822.
- * <p/>
- * <p/>
- * The format used is <code>EEE, d MMM yyyy HH:mm:ss Z</code> and
- * locale is always US-ASCII.
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-public class IMAPDateFormat extends SimpleDateFormat {
- public IMAPDateFormat() {
- super("dd-MMM-yyyy HH:mm:ss Z", 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();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
deleted file mode 100644
index 37b8a3f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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.Date;
-
-import javax.mail.MessagingException;
-
-import javax.mail.internet.InternetAddress;
-
-
-public class IMAPEnvelope extends IMAPFetchDataItem {
- // the following are various fields from the FETCH ENVELOPE structure. These
- // should be self-explanitory.
- public Date date;
- public String subject;
- public InternetAddress[] from;
- public InternetAddress[] sender;
- public InternetAddress[] replyTo;
- public InternetAddress[] to;
- public InternetAddress[] cc;
- public InternetAddress[] bcc;
-
- public String inReplyTo;
- public String messageID;
-
-
- /**
- * Parse an IMAP FETCH ENVELOPE response into the component pieces.
- *
- * @param source The tokenizer for the response we're processing.
- */
- public IMAPEnvelope(IMAPResponseTokenizer source) throws MessagingException {
- super(ENVELOPE);
-
- // these should all be a parenthetical list
- source.checkLeftParen();
- // the following fields are all positional
- // The envelope date is defined in the spec as being an "nstring" value, which
- // means it is either a string value or NIL.
- date = source.readDateOrNil();
- subject = source.readStringOrNil();
- from = source.readAddressList();
- sender = source.readAddressList();
- replyTo = source.readAddressList();
- to = source.readAddressList();
- cc = source.readAddressList();
- bcc = source.readAddressList();
- inReplyTo = source.readStringOrNil();
- messageID = source.readStringOrNil();
-
- // make sure we have a correct close on the field.
- source.checkRightParen();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
deleted file mode 100644
index ec17870..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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 class IMAPFetchBodyPart extends IMAPFetchDataItem {
- // the parse body section information.
- protected IMAPBodySection section;
-
- /**
- * Construct a base BODY section subpiece.
- *
- * @param type The fundamental type of the body section. This will be either BODY, TEXT,
- * or HEADER, depending on the subclass.
- * @param section The section information. This will contain the section numbering information,
- * the section name, and and substring information if this was a partial fetch
- * request.
- */
- public IMAPFetchBodyPart(int type, IMAPBodySection section) {
- super(type);
- this.section = section;
- }
-
- /**
- * Get the part number information associated with this request.
- *
- * @return The string form of the part number.
- */
- public String getPartNumber() {
- return section.partNumber;
- }
-
- /**
- * Get the section type information. This is the qualifier that appears
- * within the "[]" of the body sections.
- *
- * @return The numeric identifier for the type from the IMAPBodySection.
- */
- public int getSectionType() {
- return section.section;
- }
-
- /**
- * Get the substring start location.
- *
- * @return The start location for the substring. Returns -1 if this is not a partial
- * fetch.
- */
- public int getSubstringStart() {
- return section.start;
- }
-
- /**
- * Returns the length of the substring section.
- *
- * @return The length of the substring section. Returns -1 if this was not a partial
- * fetch.
- */
- public int getSubstringLength() {
- return section.length;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
deleted file mode 100644
index 6d15af3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * 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.internet.MailDateFormat;
-
-public class IMAPFetchDataItem {
- public static final int FETCH = 0;
- public static final int ENVELOPE = 1;
- public static final int BODY = 2;
- public static final int BODYSTRUCTURE = 3;
- public static final int INTERNALDATE = 4;
- public static final int SIZE = 5;
- public static final int UID = 6;
- public static final int TEXT = 7;
- public static final int HEADER = 8;
- public static final int FLAGS = 9;
-
- // the type of the FETCH response item.
- protected int type;
-
- public IMAPFetchDataItem(int type) {
- this.type = type;
- }
-
- /**
- * Get the type of the FetchResponse.
- *
- * @return The type indicator.
- */
- public int getType() {
- return type;
- }
-
- /**
- * Test if this fetch response is of the correct type.
- *
- * @param t The type to test against.
- *
- * @return True if the Fetch response contains the requested type information.
- */
- public boolean isType(int t) {
- return type == t;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
deleted file mode 100644
index c556665..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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 a composite FETCH response from an IMAP server. The
- * response may have information about multiple message dataItems.
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-public class IMAPFetchResponse extends IMAPUntaggedResponse {
- // parsed sections within the FETCH response structure
- protected List dataItems = new ArrayList();
- // the message number to which this applies
- public int sequenceNumber;
-
- public IMAPFetchResponse(int sequenceNumber, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("FETCH", data);
-
- this.sequenceNumber = sequenceNumber;
-
- // fetch responses are a list, even if there is just a single member.
- source.checkLeftParen();
-
- // loop until we find the list end.
- while (source.notListEnd()) {
- // the response names are coded as ATOMS. The BODY one's use a special
- // syntax, so we need to use the expanded delimiter set to pull this out.
- String itemName = source.readAtom(true).toUpperCase();
-
- if (itemName.equals("ENVELOPE")) {
- dataItems.add(new IMAPEnvelope(source));
- }
- else if (itemName.equals("BODYSTRUCTURE")) {
- dataItems.add(new IMAPBodyStructure(source));
- }
- else if (itemName.equals("FLAGS")) {
- dataItems.add(new IMAPFlags(source));
- }
- else if (itemName.equals("INTERNALDATE")) {
- dataItems.add(new IMAPInternalDate(source));
- }
- else if (itemName.equals("UID")) {
- dataItems.add(new IMAPUid(sequenceNumber, source));
- }
- else if (itemName.equals("RFC822")) {
- // all of the RFC822 items are of form
- // "RFC822.name". We used the expanded parse above because
- // the BODY names include some complicated bits. If we got one
- // of the RFC822 sections, then parse the rest of the name using
- // the old rules, which will pull in the rest of the name from the period.
- itemName = source.readAtom(false).toUpperCase();
- if (itemName.equals(".SIZE")) {
- dataItems.add(new IMAPMessageSize(source));
- }
- else if (itemName.equals(".HEADER")) {
- dataItems.add(new IMAPInternetHeader(source.readByteArray()));
- }
- else if (itemName.equals(".TEXT")) {
- dataItems.add(new IMAPMessageText(source.readByteArray()));
- }
- }
- // this is just the body alone. Specific body segments
- // have a more complex naming structure. Believe it or
- // not,
- else if (itemName.equals("BODY")) {
- // time to go parse out the section information from the
- // name.
- IMAPBodySection section = new IMAPBodySection(source);
-
- switch (section.section) {
- case IMAPBodySection.BODY:
- // a "full body cast". Just grab the binary data
- dataItems.add(new IMAPBody(section, source.readByteArray()));
- break;
-
- case IMAPBodySection.HEADERS:
- case IMAPBodySection.HEADERSUBSET:
- case IMAPBodySection.MIME:
- // these 3 are all variations of a header request
- dataItems.add(new IMAPInternetHeader(section, source.readByteArray()));
- break;
-
- case IMAPBodySection.TEXT:
- // just the text portion of the body
- // a "full body cast". Just grab the binary data
- dataItems.add(new IMAPMessageText(section, source.readByteArray()));
- break;
- }
- }
- }
- // swallow the terminating right paren
- source.checkRightParen();
- }
-
- /**
- * Retrieve the sequence number for the FETCH item.
- *
- * @return The message sequence number this FETCH applies to.
- */
- public int getSequenceNumber() {
- return sequenceNumber;
- }
-
- /**
- * Get the section count.
- *
- * @return The number of sections in the response.
- */
- public int getCount() {
- return dataItems.size();
- }
-
- /**
- * Get the complete set of response dataItems.
- *
- * @return The List of IMAPFetchResponse values.
- */
- public List getDataItems() {
- return dataItems;
- }
-
-
- /**
- * Fetch a particular response type from the response dataItems.
- *
- * @param type The target FETCH type.
- *
- * @return The first IMAPFetchDataItem item that matches the response type.
- */
- public IMAPFetchDataItem getDataItem(int type) {
- for (int i = 0; i < dataItems.size(); i ++) {
- IMAPFetchDataItem item = (IMAPFetchDataItem)dataItems.get(i);
- if (item.isType(type)) {
- return item;
- }
- }
- return null;
- }
-
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
deleted file mode 100644
index 21f025a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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;
-import javax.mail.Flags;
-
-
-/**
- * A fetched FLAGS value returned on a FETCH response.
- */
-public class IMAPFlags extends IMAPFetchDataItem {
-
- public Flags flags;
-
- public IMAPFlags(IMAPResponseTokenizer source) throws MessagingException {
- super(FLAGS);
-
- // parse the list of flag values and merge each one into the flag set
- flags = source.readFlagList();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
deleted file mode 100644
index ce55057..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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;
-import javax.mail.Flags;
-
-import java.util.List;
-
-/**
- * A parsed FLAGS untagged response.
- */
-public class IMAPFlagsResponse extends IMAPUntaggedResponse {
-
- protected Flags flags = new Flags();
-
- public IMAPFlagsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("FLAGS", data);
-
- // read the flags from the response tokenizer.
- flags = source.readFlagList();
- }
-
- /**
- * Get the parsed flags value.
- *
- * @return The accumulated flags setting.
- */
- public Flags getFlags() {
- return flags;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
deleted file mode 100644
index ce0e088..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * 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.Date;
-
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.javamail.util.ResponseFormatException;
-
-public class IMAPInternalDate extends IMAPFetchDataItem {
- // the parsed date.
- protected Date date;
-
- public IMAPInternalDate(IMAPResponseTokenizer source) throws MessagingException {
- super(INTERNALDATE);
- // read the date from the stream
- date = source.readDate();
- }
-
- /**
- * Retrieved the parsed internal date object.
- *
- * @return The parsed Date object.
- */
- public Date getDate() {
- return date;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
deleted file mode 100644
index 09fde92..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.io.ByteArrayInputStream;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetHeaders;
-
-public class IMAPInternetHeader extends IMAPFetchBodyPart {
- // the parsed headers
- public InternetHeaders headers;
-
- /**
- * Construct a top-level HEADER data item.
- *
- * @param data The data for the InternetHeaders.
- *
- * @exception MessagingException
- */
- public IMAPInternetHeader(byte[] data) throws MessagingException {
- this(new IMAPBodySection(IMAPBodySection.HEADERS), data);
- }
-
-
- /**
- * Construct a HEADER request data item.
- *
- * @param section The Section identifier information.
- * @param data The raw data for the internet headers.
- *
- * @exception MessagingException
- */
- public IMAPInternetHeader(IMAPBodySection section, byte[] data) throws MessagingException {
- super(HEADER, section);
-
- // and convert these into real headers
- ByteArrayInputStream in = new ByteArrayInputStream(data);
- headers = new InternetHeaders(in);
- }
-
- /**
- * Test if this is a complete header fetch, or just a partial list fetch.
- *
- * @return
- */
- public boolean isComplete() {
- return section.section == IMAPBodySection.HEADERS;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
deleted file mode 100644
index 9a7befd..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * 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;
-
-/**
- * Util class to represent a list response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPListResponse extends IMAPUntaggedResponse {
- // parsed flag responses
- public boolean noinferiors = false;
- public boolean noselect = false;
- public boolean marked = false;
- public boolean unmarked = false;
-
- // the name separator character
- public char separator;
- // the mail box name
- public String mailboxName;
- // this is for support of the get attributes command
- public String[] attributes;
-
- /**
- * Construct a LIST response item. This can be either
- * a response from a LIST command or an LSUB command,
- * and will be tagged accordingly.
- *
- * @param type The type of resonse (LIST or LSUB).
- * @param data The raw response data.
- * @param source The tokenizer source.
- *
- * @exception MessagingException
- */
- public IMAPListResponse(String type, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super(type, data);
-
- // parse the list of flag values
- List flags = source.readSystemNameList();
-
- // copy this into the attributes array.
- attributes = new String[flags.size()];
- attributes = (String[])flags.toArray(attributes);
-
- for (int i = 0; i < flags.size(); i++) {
- String flag = ((String)flags.get(i));
-
- if (flag.equalsIgnoreCase("\\Marked")) {
- marked = true;
- }
- else if (flag.equalsIgnoreCase("\\Unmarked")) {
- unmarked = true;
- }
- else if (flag.equalsIgnoreCase("\\Noselect")) {
- noselect = true;
- }
- else if (flag.equalsIgnoreCase("\\Noinferiors")) {
- noinferiors = true;
- }
- }
-
- // set a default sep value
- separator = '\0';
- // get the separator and name tokens
- String separatorString = source.readQuotedStringOrNil();
- if (separatorString != null && separatorString.length() == 1) {
- separator = separatorString.charAt(0);
- }
- mailboxName = source.readEncodedString();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
deleted file mode 100644
index 27fb4d7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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.Rights;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-
-/**
- * Utility class to aggregate status responses for a mailbox.
- */
-public class IMAPListRightsResponse extends IMAPUntaggedResponse {
- public String mailbox;
- public String name;
- public Rights[] rights;
-
- public IMAPListRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("LISTRIGHTS", data);
-
- mailbox = source.readEncodedString();
- name = source.readString();
- List acls = new ArrayList();
-
- while (source.hasMore()) {
- acls.add(new Rights(source.readString()));
- }
-
- rights = new Rights[acls.size()];
- acls.toArray(rights);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
deleted file mode 100644
index d5a9827..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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 a status response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPMailboxResponse {
- // count/message number parameter from the response.
- public int count;
- // the name of the status code
- public String name;
-
- public IMAPMailboxResponse(int count, String name) {
- this.count = count;
- this.name = name;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
deleted file mode 100644
index bf1b712..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * 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.Flags;
-import javax.mail.Folder;
-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 IMAPMailboxStatus {
- // the set of available flag values for this mailbox
- public Flags availableFlags = null;
- // the permanent flags for this mailbox.
- public Flags permanentFlags = null;
- // the open mode flags
- public int mode = Folder.READ_WRITE;
-
- // number of messages in the box
- public int messages = -1;
- // the number of newly added 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 IMAPMailboxStatus() {
- }
-
-
- /**
- * Merge information from a server status message. These
- * messages are in the form "* NAME args". We only handle
- * STATUS and FLAGS messages here.
- *
- * @param source The parsed status message.
- *
- * @exception MessagingException
- */
- public void mergeStatus(IMAPStatusResponse source) throws MessagingException {
- // update any of the values that have changed since the last.
- if (source.messages != -1) {
- messages = source.messages;
- }
- if (source.uidNext != -1L) {
- uidNext = source.uidNext;
- }
- if (source.uidValidity != -1L) {
- uidValidity = source.uidValidity;
- }
- if (source.recentMessages != -1) {
- recentMessages = source.recentMessages;
- }
- if (source.unseenMessages != -1) {
- unseenMessages = source.unseenMessages;
- }
- }
-
- /**
- * Merge in the FLAGS response from an EXAMINE or
- * SELECT mailbox command.
- *
- * @param response The returned FLAGS item.
- *
- * @exception MessagingException
- */
- public void mergeFlags(IMAPFlagsResponse response) throws MessagingException {
- if (response != null) {
- availableFlags = response.getFlags();
- }
- }
-
-
- public void mergeSizeResponses(List responses) throws MessagingException
- {
- for (int i = 0; i < responses.size(); i++) {
- mergeStatus((IMAPSizeResponse)responses.get(i));
- }
- }
-
-
- public void mergeOkResponses(List responses) throws MessagingException {
- for (int i = 0; i < responses.size(); i++) {
- mergeStatus((IMAPOkResponse)responses.get(i));
- }
- }
-
-
- /**
- * Gather mailbox status information from mailbox status
- * messages. These messages come in as untagged messages in the
- * form "* nnn NAME".
- *
- * @param source The parse message information.
- *
- * @exception MessagingException
- */
- public void mergeStatus(IMAPSizeResponse source) throws MessagingException {
- if (source != null) {
- String name = source.getKeyword();
-
- // untagged exists response
- if (source.isKeyword("EXISTS")) {
- messages = source.getSize();
- }
- // untagged resent response
- else if (source.isKeyword("RECENT")) {
- recentMessages = source.getSize();
- }
- }
- }
-
-
-
-
- /**
- * Gather mailbox status information from mailbox status
- * messages. These messages come in as untagged messages in the
- * form "* OK [NAME args]".
- *
- * @param source The parse message information.
- *
- * @exception MessagingException
- */
- public void mergeStatus(IMAPOkResponse source) throws MessagingException {
- if (source != null) {
- String name = source.getKeyword();
-
- // untagged UIDVALIDITY response
- if (source.isKeyword("UIDVALIDITY")) {
- List arguments = source.getStatus();
- uidValidity = ((Token)arguments.get(0)).getLong();
- }
- // untagged UIDNEXT response
- if (source.isKeyword("UIDNEXT")) {
- List arguments = source.getStatus();
- uidNext = ((Token)arguments.get(0)).getLong();
- }
- // untagged unseen response
- else if (source.isKeyword("UNSEEN")) {
- List arguments = source.getStatus();
- uidValidity = ((Token)arguments.get(0)).getInteger();
- }
- }
- }
-
-
- /**
- * Gather mailbox status information from mailbox status
- * messages. These messages come in as untagged messages in the
- * form "* OK [NAME args]".
- *
- * @param source The parse message information.
- *
- * @exception MessagingException
- */
- public void mergeStatus(IMAPPermanentFlagsResponse source) throws MessagingException {
- if (source != null) {
- // this is already parsed.
- permanentFlags = source.flags;
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
deleted file mode 100644
index 5d3cf81..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 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 IMAPMessageSize extends IMAPFetchDataItem {
- // the size information
- public int size;
-
- public IMAPMessageSize(IMAPResponseTokenizer source) throws MessagingException {
- super(SIZE);
-
- // the size is just a single integer
- size = source.readInteger();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
deleted file mode 100644
index f72bdb0..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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 IMAPMessageText extends IMAPFetchBodyPart {
- // the header data
- protected byte[] data;
-
- /**
- * Construct a top-level TEXT data item.
- *
- * @param data The data for the message text.
- *
- * @exception MessagingException
- */
- public IMAPMessageText(byte[] data) throws MessagingException {
- this(new IMAPBodySection(IMAPBodySection.TEXT), data);
- }
-
-
- public IMAPMessageText(IMAPBodySection section, byte[] data) throws MessagingException {
- super(TEXT, section);
- this.data = data;
- }
-
- /**
- * Retrieved the header data.
- *
- * @return The header data.
- */
- public byte[] getContent() {
- return data;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
deleted file mode 100644
index fdb3209..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * 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;
-
-import org.apache.geronimo.javamail.store.imap.Rights;
-
-/**
- * Utility class to aggregate status responses for a mailbox.
- */
-public class IMAPMyRightsResponse extends IMAPUntaggedResponse {
- public String mailbox;
- public Rights rights;
-
- public IMAPMyRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("MYRIGHTS", data);
-
- mailbox = source.readEncodedString();
- rights = new Rights(source.readString());
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
deleted file mode 100644
index 603837a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 a NAMESPACE response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPNamespace {
- // the namespace prefix
- public String prefix;
- // the namespace hierarchy delimiter
- public char separator = '\0';
-
- public IMAPNamespace(IMAPResponseTokenizer source) throws MessagingException {
- source.checkLeftParen();
- // read the two that make up the response and ...
- prefix = source.readString();
- String delim = source.readString();
- // if the delimiter is not a null string, grab the first character.
- if (delim.length() != 0) {
- separator = delim.charAt(0);
- }
- source.checkRightParen();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
deleted file mode 100644
index 866b6e6..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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.Collections;
-import java.util.List;
-
-import javax.mail.MessagingException;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-import org.apache.geronimo.javamail.util.ResponseFormatException;
-
-/**
- * Util class to represent a NAMESPACE response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPNamespaceResponse extends IMAPUntaggedResponse {
- // the personal namespaces defined
- public List personalNamespaces;
- // the other use name spaces this user has access to.
- public List otherUserNamespaces;
- // the list of shared namespaces
- public List sharedNamespaces;
-
- // construct a default IMAPNamespace response for return when the server doesn't support this.
- public IMAPNamespaceResponse()
- {
- super("NAMESPACE", null);
- // fill in default lists to simplify processing
- personalNamespaces = Collections.EMPTY_LIST;
- otherUserNamespaces = Collections.EMPTY_LIST;
- sharedNamespaces = Collections.EMPTY_LIST;
- }
-
- /**
- * Construct a LIST response item. This can be either
- * a response from a LIST command or an LSUB command,
- * and will be tagged accordingly.
- *
- * @param type The type of resonse (LIST or LSUB).
- * @param data The raw response data.
- * @param source The tokenizer source.
- *
- * @exception MessagingException
- */
- public IMAPNamespaceResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("NAMESPACE", data);
- // the namespace response is a set of 3 items, which will be either NIL or a "list of lists".
- // if the item exists, then there will be a set of list parens, with 1 or more subitems inside.
- // Each of the subitems will consist of a namespace prefix and the hierarchy delimiter for that
- // particular namespace.
- personalNamespaces = parseNamespace(source);
- otherUserNamespaces = parseNamespace(source);
- sharedNamespaces = parseNamespace(source);
- }
-
- private List parseNamespace(IMAPResponseTokenizer source) throws MessagingException {
- Token token = source.next(true);
- // is this token the NIL token?
- if (token.getType() == Token.NIL) {
- // no items at this position.
- return null;
- }
- if (token.getType() != '(') {
- throw new ResponseFormatException("Missing '(' in response");
- }
-
- // ok, we're processing a namespace list. Create a list and populate it with IMAPNamespace
- // items.
-
- List namespaces = new ArrayList();
-
- while (source.notListEnd()) {
- namespaces.add(new IMAPNamespace(source));
- }
- // this should always pass, since it terminated the loop
- source.checkRightParen();
- return namespaces;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java
deleted file mode 100644
index 9554ea8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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 IMAPOkResponse extends IMAPUntaggedResponse {
- // the response status value
- protected List status;
- // 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 IMAPOkResponse(String keyword, List status, String message, byte [] response) {
- super(keyword, response);
- this.status = status;
- this.message = message;
- }
-
- /**
- * Get the response code included with the OK
- * response.
- *
- * @return The string name of the response code.
- */
- public String getResponseCode() {
- return getKeyword();
- }
-
- /**
- * Return the status argument values associated with
- * this status response.
- *
- * @return The status value information, as a list of tokens.
- */
- public List getStatus() {
- return status;
- }
-
- /**
- * Get any trailing message associated with this
- * status response.
- *
- * @return
- */
- public String getMessage() {
- return message;
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java
deleted file mode 100644
index a85f491..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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.Flags;
-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 IMAPPermanentFlagsResponse extends IMAPUntaggedResponse {
- // the response flags value
- public Flags flags;
- /**
- * 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 IMAPPermanentFlagsResponse(byte [] response, IMAPResponseTokenizer source) throws MessagingException {
- super("PERMANENTFLAGS", response);
- flags = source.readFlagList();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java
deleted file mode 100644
index 8ea5698..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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 javax.mail.Quota;
-
-/**
- * Util class to represent a list response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPQuotaResponse extends IMAPUntaggedResponse {
- // the returned quota item
- public Quota quota;
-
- /**
- * Construct a LIST response item. This can be either
- * a response from a LIST command or an LSUB command,
- * and will be tagged accordingly.
- *
- * @param type The type of resonse (LIST or LSUB).
- * @param data The raw response data.
- * @param source The tokenizer source.
- *
- * @exception MessagingException
- */
- public IMAPQuotaResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("QUOTA", data);
-
- // first token is the root name, which can be either an atom or a string.
- String tokenName = source.readString();
-
- // create a quota item for this
- quota = new Quota(tokenName);
-
- source.checkLeftParen();
-
- List resources = new ArrayList();
-
- while (source.notListEnd()) {
- // quotas are returned as a set of triplets. The first element is the
- // resource name, followed by the current usage and the limit value.
- Quota.Resource resource = new Quota.Resource(source.readAtom(), source.readLong(), source.readLong());
- resources.add(resource);
- }
-
- quota.resources = (Quota.Resource[])resources.toArray(new Quota.Resource[resources.size()]);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java
deleted file mode 100644
index 44d564f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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;
-
-/**
- * Util class to represent a list response from a IMAP server
- *
- * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
- */
-
-public class IMAPQuotaRootResponse extends IMAPUntaggedResponse {
- // the mailbox this applies to
- public String mailbox;
- // The list of quota roots
- public List roots;
-
-
- /**
- * Construct a LIST response item. This can be either
- * a response from a LIST command or an LSUB command,
- * and will be tagged accordingly.
- *
- * @param type The type of resonse (LIST or LSUB).
- * @param data The raw response data.
- * @param source The tokenizer source.
- *
- * @exception MessagingException
- */
- public IMAPQuotaRootResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
- super("QUOTAROOT", data);
-
- // first token is the mailbox
- mailbox = source.readEncodedString();
- // get the root name list as the remainder of the command.
- roots = source.readStrings();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java
deleted file mode 100644
index 7180402..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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.io.UnsupportedEncodingException;
-
-import javax.mail.MessagingException;
-
-/**
- * Base class for all response messages.
- *
- * @version $Rev: 947075 $ $Date: 2010-05-21 13:12:20 -0400 (Fri, 21 May 2010) $
- */
-public class IMAPResponse {
- // The original (raw) response data
- protected byte[] response;
-
- /**
- * Create a response 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.
- */
- protected IMAPResponse(byte [] response) {
- // set this as the current message and parse.
- this.response = response;
- }
-
- /**
- * Retrieve the raw response line data for this
- * response message. Normally, this will be a complete
- * single line response, unless there are quoted
- * literals in the response data containing octet
- * data.
- *
- * @return The byte array containing the response information.
- */
- public byte[] getResponseData() {
- return response;
- }
-
- /**
- * Return the response message as a string value.
- * This is intended for debugging purposes only. The
- * response data might contain octet data that
- * might not convert to character data appropriately.
- *
- * @return The string version of the response.
- */
- public String toString() {
- try {
- return new String(response, "US-ASCII");
- } catch (UnsupportedEncodingException e) {
- }
- return new String(response);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
deleted file mode 100644
index cd28d54..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * 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.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Simple extension to the ByteArrayOutputStream to allow inspection
- * of the data while it is being accumulated.
- */
-public class IMAPResponseBuffer extends ByteArrayOutputStream {
-
- public IMAPResponseBuffer() {
- super();
- }
-
-
- /**
- * Read a character from the byte array output stream buffer
- * at the give position.
- *
- * @param index The requested index.
- *
- * @return The byte at the target index, or -1 if the index is out of
- * bounds.
- */
- public int read(int index) {
- if (index >= size()) {
- return -1;
- }
- return buf[index];
- }
-
- /**
- * Read a buffer of data from the output stream's accumulator
- * buffer. This will copy the data into a target byte arrain.
- *
- * @param buffer The target byte array for returning the data.
- * @param offset The offset of the source data within the output stream buffer.
- * @param length The desired length.
- *
- * @return The count of bytes transferred into the buffer.
- */
- public int read(byte[] buffer, int offset, int length) {
-
- int available = size() - offset;
- length = Math.min(length, available);
- // nothing to return? quit now.
- if (length <= 0) {
- return 0;
- }
- System.arraycopy(buf, offset, buffer, 0, length);
- return length;
- }
-
- /**
- * Search backwards through the buffer for a given byte.
- *
- * @param target The search character.
- *
- * @return The index relative to the buffer start of the given byte.
- * Returns -1 if not found.
- */
- public int lastIndex(byte target) {
- for (int i = size() - 1; i > 0; i--) {
- if (buf[i] == target) {
- return i;
- }
- }
- return -1;
- }
-
-
- /**
- * Return the last byte written to the output stream. Returns
- * -1 if the stream is empty.
- *
- * @return The last byte written (or -1 if the stream is empty).
- */
- public int lastByte() {
- if (size() > 0) {
- return buf[size() - 1];
- }
- return -1;
- }
-
-
- /**
- * Retrieve an IMAP literal length value from the buffer. We
- * have a literal length value IFF the last characters written
- * to the buffer have the form "{nnnn}". This returns the
- * integer value of the info inside the curly braces. Returns -1
- * if a valid literal length is not found.
- *
- * @return A literal length value, or -1 if we don't have a literal
- * signature at the end.
- */
- public int getLiteralLength() {
- // was the last byte before the line break the close of the literal length?
- if (lastByte() == '}') {
- // locate the length start
- int literalStart = lastIndex((byte)'{');
- // no matching start, this can't be a literal.
- if (literalStart == -1) {
- return -1;
- }
-
- try {
- String lenString = new String(buf, literalStart + 1, size() - (literalStart + 2), "US-ASCII");
- try {
- return Integer.parseInt(lenString);
- } catch (NumberFormatException e) {
- }
- } catch (UnsupportedEncodingException ex) {
- // should never happen
- }
- }
- // not a literal
- return -1;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
deleted file mode 100644
index 420934a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * 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.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.mail.MessagingException;
-import javax.mail.event.FolderEvent;
-
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
-import org.apache.geronimo.javamail.util.ConnectionException;
-
-public class IMAPResponseStream {
- protected final int BUFFER_SIZE = 1024;
-
- // our source input stream
- protected InputStream in;
- // The response buffer
- IMAPResponseBuffer out;
- // the buffer array
- protected byte[] buffer = new byte[BUFFER_SIZE];
- // the current buffer position
- int position;
- // the current buffer read length
- int length;
-
- public IMAPResponseStream(InputStream in) {
- this.in = in;
- out = new IMAPResponseBuffer();
- }
-
- public int read() throws IOException {
- // if we can't read any more, that's an EOF condition.
- if (!fillBufferIfNeeded()) {
- return -1;
- }
- // just grab the next character
- return buffer[position++];
- }
-
- protected boolean fillBufferIfNeeded() throws IOException {
- // used up all of the data in the buffer?
- if (position >= length) {
- int readLength = 0;
- // a read from a network connection can return 0 bytes,
- // so we need to be prepared to handle a spin loop.
- while (readLength == 0) {
- readLength = in.read(buffer, 0, buffer.length);
- }
- // we may have hit the EOF. Indicate the read failure
- if (readLength == -1) {
- return false;
- }
- // set our new buffer positions.
- position = 0;
- length = readLength;
- }
- return true;
- }
-
-
- /**
- * Read a single response line from the input stream, returning
- * a parsed and processed response line.
- *
- * @return A parsed IMAPResponse item using the response data.
- * @exception MessagingException
- */
- public IMAPResponse readResponse() throws MessagingException
- {
- // reset our accumulator
- out.reset();
- // now read a buffer of data
- byte[] data = readData();
-
- // and create a tokenizer for parsing this down.
- IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(data);
- // get the first token.
- Token token = tokenizer.next();
-
- int type = token.getType();
-
- // a continuation response. This will terminate a response set.
- if (type == Token.CONTINUATION) {
- return new IMAPContinuationResponse(data);
- }
- // unsolicited response. There are multiple forms of these, which might actually be
- // part of the response for the last issued command.
- else if (type == Token.UNTAGGED) {
- // step to the next token, which will give us the type
- token = tokenizer.next();
- // if the token is numeric, then this is a size response in the
- // form "* nn type"
- if (token.isType(Token.NUMERIC)) {
- int size = token.getInteger();
-
- token = tokenizer.next();
-
- String keyword = token.getValue();
-
- // FETCH responses require fairly complicated parsing. Other
- // size/message updates are fairly generic.
- if (keyword.equals("FETCH")) {
- return new IMAPFetchResponse(size, data, tokenizer);
- }
- return new IMAPSizeResponse(keyword, size, data);
- }
-
- // this needs to be an ATOM type, which will tell us what format this untagged
- // response is in. There are many different untagged formats, some general, some
- // specific to particular command types.
- if (token.getType() != Token.ATOM) {
- try {
- throw new MessagingException("Unknown server response: " + new String(data, "ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Unknown server response: " + new String(data));
- }
- }
-
- String keyword = token.getValue();
- // many response are in the form "* OK [keyword value] message".
- if (keyword.equals("OK")) {
- return parseUntaggedOkResponse(data, tokenizer);
- }
- // preauth status response
- else if (keyword.equals("PREAUTH")) {
- return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data);
- }
- // preauth status response
- else if (keyword.equals("BYE")) {
- return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data);
- }
- else if (keyword.equals("BAD")) {
- // these are generally ignored.
- return new IMAPServerStatusResponse("BAD", tokenizer.getRemainder(), data);
- }
- else if (keyword.equals("NO")) {
- // these are generally ignored.
- return new IMAPServerStatusResponse("NO", tokenizer.getRemainder(), data);
- }
- // a complex CAPABILITY response
- else if (keyword.equals("CAPABILITY")) {
- return new IMAPCapabilityResponse(tokenizer, data);
- }
- // a complex LIST response
- else if (keyword.equals("LIST")) {
- return new IMAPListResponse("LIST", data, tokenizer);
- }
- // a complex FLAGS response
- else if (keyword.equals("FLAGS")) {
- // parse this into a flags set.
- return new IMAPFlagsResponse(data, tokenizer);
- }
- // a complex LSUB response (identical in format to LIST)
- else if (keyword.equals("LSUB")) {
- return new IMAPListResponse("LSUB", data, tokenizer);
- }
- // a STATUS response, which will contain a list of elements
- else if (keyword.equals("STATUS")) {
- return new IMAPStatusResponse(data, tokenizer);
- }
- // SEARCH requests return an variable length list of message matches.
- else if (keyword.equals("SEARCH")) {
- return new IMAPSearchResponse(data, tokenizer);
- }
- // ACL requests return an variable length list of ACL values .
- else if (keyword.equals("ACL")) {
- return new IMAPACLResponse(data, tokenizer);
- }
- // LISTRIGHTS requests return a variable length list of RIGHTS values .
- else if (keyword.equals("LISTRIGHTS")) {
- return new IMAPListRightsResponse(data, tokenizer);
- }
- // MYRIGHTS requests return a list of user rights for a mailbox name.
- else if (keyword.equals("MYRIGHTS")) {
- return new IMAPMyRightsResponse(data, tokenizer);
- }
- // QUOTAROOT requests return a list of mailbox quota root names
- else if (keyword.equals("QUOTAROOT")) {
- return new IMAPQuotaRootResponse(data, tokenizer);
- }
- // QUOTA requests return a list of quota values for a root name
- else if (keyword.equals("QUOTA")) {
- return new IMAPQuotaResponse(data, tokenizer);
- }
- else if (keyword.equals("NAMESPACE")) {
- return new IMAPNamespaceResponse(data, tokenizer);
- }
- }
- // begins with a word, this should be the tagged response from the last command.
- else if (type == Token.ATOM) {
- String tag = token.getValue();
- token = tokenizer.next();
- String status = token.getValue();
- //handle plain authentication gracefully, see GERONIMO-6526
- if("+".equals(tag) && status == null) {
- return new IMAPContinuationResponse(data);
- }
- // primary information in one of these is the status field, which hopefully
- // is 'OK'
- return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data);
- }
- try {
- throw new MessagingException("Unknown server response: " + new String(data, "ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Unknown server response: " + new String(data));
- }
- }
-
- /**
- * Parse an unsolicited OK status response. These
- * responses are of the form:
- *
- * * OK [keyword arguments ...] message
- *
- * The part in the brackets are optional, but
- * most OK messages will have some sort of update.
- *
- * @param data The raw message data
- * @param tokenizer The tokenizer being used for this message.
- *
- * @return An IMAPResponse instance for this message.
- */
- private IMAPResponse parseUntaggedOkResponse(byte [] data, IMAPResponseTokenizer tokenizer) throws MessagingException {
- Token token = tokenizer.peek();
- // we might have an optional value here
- if (token.getType() != '[') {
- // this has no tagging item, so there's nothing to be processed
- // later.
- return new IMAPOkResponse("OK", null, tokenizer.getRemainder(), data);
- }
- // skip over the "[" token
- tokenizer.next();
- token = tokenizer.next();
- String keyword = token.getValue();
-
- // Permanent flags gets special handling
- if (keyword.equals("PERMANENTFLAGS")) {
- return new IMAPPermanentFlagsResponse(data, tokenizer);
- }
-
- ArrayList arguments = new ArrayList();
-
- // strip off all of the argument tokens until the "]" list terminator.
- token = tokenizer.next();
- while (token.getType() != ']') {
- arguments.add(token);
- token = tokenizer.next();
- }
- // this has a tagged keyword and arguments that will be processed later.
- return new IMAPOkResponse(keyword, arguments, tokenizer.getRemainder(), data);
- }
-
-
- /**
- * Read a "line" of server response data. An individual line
- * may span multiple line breaks, depending on syntax implications.
- *
- * @return
- * @exception MessagingException
- */
- public byte[] readData() throws MessagingException {
- // reset out buffer accumulator
- out.reset();
- // read until the end of the response into our buffer.
- readBuffer();
- // get the accumulated data.
- return out.toByteArray();
- }
-
- /**
- * Read a buffer of data. This accumulates the data into a
- * ByteArrayOutputStream, terminating the processing at a line
- * break. This also handles line breaks that are the result
- * of literal continuations in the stream.
- *
- * @exception MessagingException
- * @exception IOException
- */
- public void readBuffer() throws MessagingException {
- while (true) {
- int ch = nextByte();
- // potential end of line? Check the next character, and if it is an end of line,
- // we need to do literal processing.
- if (ch == '\r') {
- int next = nextByte();
- if (next == '\n') {
- // had a line break, which might be part of a literal marker. Check for the signature,
- // and if we found it, continue with the next line. In any case, we're done with processing here.
- checkLiteral();
- return;
- }
- }
- // write this to the buffer.
- out.write(ch);
- }
- }
-
-
- /**
- * Check the line just read to see if we're processing a line
- * with a literal value. Literals are encoded as "{length}\r\n",
- * so if we've read up to the line break, we can check to see
- * if we need to continue reading.
- *
- * If a literal marker is found, we read that many characters
- * from the reader without looking for line breaks. Once we've
- * read the literal data, we just read the rest of the line
- * as normal (which might also end with a literal marker).
- *
- * @exception MessagingException
- */
- public void checkLiteral() throws MessagingException {
- try {
- // see if we have a literal length signature at the end.
- int length = out.getLiteralLength();
-
- // -1 means no literal length, so we're done reading this particular response.
- if (length == -1) {
- return;
- }
-
- // we need to write out the literal line break marker.
- out.write('\r');
- out.write('\n');
-
- // have something we're supposed to read for the literal?
- if (length > 0) {
- byte[] bytes = new byte[length];
-
- int offset = 0;
-
- // The InputStream can return less than the requested length if it needs to block.
- // This may take a couple iterations to get everything, particularly if it's long.
- while (length > 0) {
- int read = -1;
- try {
- read = in.read(bytes, offset, length);
- } catch (IOException e) {
- throw new MessagingException("Unexpected read error on server connection", e);
- }
- // premature EOF we can't ignore.
- if (read == -1) {
- throw new MessagingException("Unexpected end of stream");
- }
- length -= read;
- offset += read;
- }
-
- // write this out to the output stream.
- out.write(bytes);
- }
- // Now that we have the literal data, we need to read the rest of the response line (which might contain
- // additional literals). Just recurse on the line reading logic.
- readBuffer();
- } catch (IOException e) {
- e.printStackTrace();
- // this is a byte array output stream...should never happen
- }
- }
-
-
- /**
- * Get the next byte from the input stream, handling read errors
- * and EOF conditions as MessagingExceptions.
- *
- * @return The next byte read from the stream.
- * @exception MessagingException
- */
- protected int nextByte() throws MessagingException {
- try {
- int next = in.read();
- if (next == -1) {
- throw new MessagingException("Read error on IMAP server connection");
- }
- return next;
- } catch (IOException e) {
- throw new MessagingException("Unexpected error on server stream", e);
- }
- }
-
-
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
deleted file mode 100644
index 9a5f5c9..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
+++ /dev/null
@@ -1,1469 +0,0 @@
-/**
- * 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.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.mail.Flags;
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MailDateFormat;
-import javax.mail.internet.ParameterList;
-
-import org.apache.geronimo.javamail.util.ResponseFormatException;
-
-/**
- * @version $Rev: 953638 $ $Date: 2010-06-11 06:09:00 -0400 (Fri, 11 Jun 2010) $
- */
-public class IMAPResponseTokenizer {
- /*
- * set up the decoding table.
- */
- protected static final byte[] decodingTable = new byte[256];
-
- protected static void initializeDecodingTable()
- {
- for (int i = 0; i < IMAPCommand.encodingTable.length; i++)
- {
- decodingTable[IMAPCommand.encodingTable[i]] = (byte)i;
- }
- }
-
-
- static {
- initializeDecodingTable();
- }
-
- // a singleton formatter for header dates.
- protected static MailDateFormat dateParser = new MailDateFormat();
-
-
- public static class Token {
- // Constant values from J2SE 1.4 API Docs (Constant values)
- public static final int ATOM = -1;
- public static final int QUOTEDSTRING = -2;
- public static final int LITERAL = -3;
- public static final int NUMERIC = -4;
- public static final int EOF = -5;
- public static final int NIL = -6;
- // special single character markers
- public static final int CONTINUATION = '+';
- public static final int UNTAGGED = '*';
-
- /**
- * The type indicator. This will be either a specific type, represented by
- * a negative number, or the actual character value.
- */
- private int type;
- /**
- * The String value associated with this token. All tokens have a String value,
- * except for the EOF and NIL tokens.
- */
- private String value;
-
- public Token(int type, String value) {
- this.type = type;
- this.value = value;
- }
-
- public int getType() {
- return type;
- }
-
- public String getValue() {
- return value;
- }
-
- public boolean isType(int type) {
- return this.type == type;
- }
-
- /**
- * Return the token as an integer value. If this can't convert, an exception is
- * thrown.
- *
- * @return The integer value of the token.
- * @exception ResponseFormatException
- */
- public int getInteger() throws MessagingException {
- if (value != null) {
- try {
- return Integer.parseInt(value);
- } catch (NumberFormatException e) {
- }
- }
-
- throw new ResponseFormatException("Number value expected in response; fount: " + value);
- }
-
- /**
- * Return the token as a long value. If it can't convert, an exception is
- * thrown.
- *
- * @return The token as a long value.
- * @exception ResponseFormatException
- */
- public long getLong() throws MessagingException {
- if (value != null) {
- try {
- return Long.parseLong(value);
- } catch (NumberFormatException e) {
- }
- }
- throw new ResponseFormatException("Number value expected in response; fount: " + value);
- }
-
- /**
- * Handy debugging toString() method for token.
- *
- * @return The string value of the token.
- */
- public String toString() {
- if (type == NIL) {
- return "NIL";
- }
- else if (type == EOF) {
- return "EOF";
- }
-
- if (value == null) {
- return "";
- }
- return value;
- }
- }
-
- public static final Token EOF = new Token(Token.EOF, null);
- public static final Token NIL = new Token(Token.NIL, null);
-
- private static final String WHITE = " \t\n\r";
- // The list of delimiter characters we process when
- // handling parsing of ATOMs.
- private static final String atomDelimiters = "(){}%*\"\\" + WHITE;
- // this set of tokens is a slighly expanded set used for
- // specific response parsing. When dealing with Body
- // section names, there are sub pieces to the name delimited
- // by "[", "]", ".", "<", ">" and SPACE, so reading these using
- // a superset of the ATOM processing makes for easier parsing.
- private static final String tokenDelimiters = "<>[].(){}%*\"\\" + WHITE;
-
- // the response data read from the connection
- private byte[] response;
- // current parsing position
- private int pos;
-
- public IMAPResponseTokenizer(byte [] response) {
- this.response = response;
- }
-
- /**
- * Get the remainder of the response as a string.
- *
- * @return A string representing the remainder of the response.
- */
- public String getRemainder() {
- // make sure we're still in range
- if (pos >= response.length) {
- return "";
- }
-
- try {
- return new String(response, pos, response.length - pos, "ISO8859-1");
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
-
- public Token next() throws MessagingException {
- return next(false);
- }
-
- public Token next(boolean nilAllowed) throws MessagingException {
- return readToken(nilAllowed, false);
- }
-
- public Token next(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
- return readToken(nilAllowed, expandedDelimiters);
- }
-
- public Token peek() throws MessagingException {
- return peek(false, false);
- }
-
- public Token peek(boolean nilAllowed) throws MessagingException {
- return peek(nilAllowed, false);
- }
-
- public Token peek(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
- int start = pos;
- try {
- return readToken(nilAllowed, expandedDelimiters);
- } finally {
- pos = start;
- }
- }
-
- /**
- * Read an ATOM token from the parsed response.
- *
- * @return A token containing the value of the atom token.
- */
- private Token readAtomicToken(String delimiters) {
- // skip to next delimiter
- int start = pos;
- while (++pos < response.length) {
- // break on the first non-atom character.
- byte ch = response[pos];
- if (delimiters.indexOf(response[pos]) != -1 || ch < 32 || ch >= 127) {
- break;
- }
- }
-
- try {
- // Numeric tokens we store as a different type.
- String value = new String(response, start, pos - start, "ISO8859-1");
- try {
- int intValue = Integer.parseInt(value);
- return new Token(Token.NUMERIC, value);
- } catch (NumberFormatException e) {
- }
- return new Token(Token.ATOM, value);
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
- /**
- * Read the next token from the response.
- *
- * @return The next token from the response. White space is skipped, and comment
- * tokens are also skipped if indicated.
- * @exception ResponseFormatException
- */
- private Token readToken(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
- String delimiters = expandedDelimiters ? tokenDelimiters : atomDelimiters;
-
- if (pos >= response.length) {
- return EOF;
- } else {
- byte ch = response[pos];
- if (ch == '\"') {
- return readQuotedString();
- // beginning of a length-specified literal?
- } else if (ch == '{') {
- return readLiteral();
- // white space, eat this and find a real token.
- } else if (WHITE.indexOf(ch) != -1) {
- eatWhiteSpace();
- return readToken(nilAllowed, expandedDelimiters);
- // either a CTL or special. These characters have a self-defining token type.
- } else if (ch < 32 || ch >= 127 || delimiters.indexOf(ch) != -1) {
- pos++;
- return new Token((int)ch, String.valueOf((char)ch));
- } else {
- // start of an atom, parse it off.
- Token token = readAtomicToken(delimiters);
- // now, if we've been asked to look at NIL tokens, check to see if it is one,
- // and return that instead of the ATOM.
- if (nilAllowed) {
- if (token.getValue().equalsIgnoreCase("NIL")) {
- return NIL;
- }
- }
- return token;
- }
- }
- }
-
- /**
- * Read the next token from the response, returning it as a byte array value.
- *
- * @return The next token from the response. White space is skipped, and comment
- * tokens are also skipped if indicated.
- * @exception ResponseFormatException
- */
- private byte[] readData(boolean nilAllowed) throws MessagingException {
- if (pos >= response.length) {
- return null;
- } else {
- byte ch = response[pos];
- if (ch == '\"') {
- return readQuotedStringData();
- // beginning of a length-specified literal?
- } else if (ch == '{') {
- return readLiteralData();
- // white space, eat this and find a real token.
- } else if (WHITE.indexOf(ch) != -1) {
- eatWhiteSpace();
- return readData(nilAllowed);
- // either a CTL or special. These characters have a self-defining token type.
- } else if (ch < 32 || ch >= 127 || atomDelimiters.indexOf(ch) != -1) {
- throw new ResponseFormatException("Invalid string value: " + ch);
- } else {
- // only process this if we're allowing NIL as an option.
- if (nilAllowed) {
- // start of an atom, parse it off.
- Token token = next(true);
- if (token.isType(Token.NIL)) {
- return null;
- }
- // invalid token type.
- throw new ResponseFormatException("Invalid string value: " + token.getValue());
- }
- // invalid token type.
- throw new ResponseFormatException("Invalid string value: " + ch);
- }
- }
- }
-
- /**
- * Extract a substring from the response string and apply any
- * escaping/folding rules to the string.
- *
- * @param start The starting offset in the response.
- * @param end The response end offset + 1.
- *
- * @return The processed string value.
- * @exception ResponseFormatException
- */
- private byte[] getEscapedValue(int start, int end) throws MessagingException {
- ByteArrayOutputStream value = new ByteArrayOutputStream();
-
- for (int i = start; i < end; i++) {
- byte ch = response[i];
- // is this an escape character?
- if (ch == '\\') {
- i++;
- if (i == end) {
- throw new ResponseFormatException("Invalid escape character");
- }
- value.write(response[i]);
- }
- // line breaks are ignored, except for naked '\n' characters, which are consider
- // parts of linear whitespace.
- else if (ch == '\r') {
- // see if this is a CRLF sequence, and skip the second if it is.
- if (i < end - 1 && response[i + 1] == '\n') {
- i++;
- }
- }
- else {
- // just append the ch value.
- value.write(ch);
- }
- }
- return value.toByteArray();
- }
-
- /**
- * Parse out a quoted string from the response, applying escaping
- * rules to the value.
- *
- * @return The QUOTEDSTRING token with the value.
- * @exception ResponseFormatException
- */
- private Token readQuotedString() throws MessagingException {
- try {
- String value = new String(readQuotedStringData(), "ISO8859-1");
- return new Token(Token.QUOTEDSTRING, value);
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
- /**
- * Parse out a quoted string from the response, applying escaping
- * rules to the value.
- *
- * @return The byte array with the resulting string bytes.
- * @exception ResponseFormatException
- */
- private byte[] readQuotedStringData() throws MessagingException {
- int start = pos + 1;
- boolean requiresEscaping = false;
-
- // skip to end of comment/string
- while (++pos < response.length) {
- byte ch = response[pos];
- if (ch == '"') {
- byte[] value;
- if (requiresEscaping) {
- value = getEscapedValue(start, pos);
- }
- else {
- value = subarray(start, pos);
- }
- // step over the delimiter for all cases.
- pos++;
- return value;
- }
- else if (ch == '\\') {
- pos++;
- requiresEscaping = true;
- }
- // we need to process line breaks also
- else if (ch == '\r') {
- requiresEscaping = true;
- }
- }
-
- throw new ResponseFormatException("Missing '\"'");
- }
-
-
- /**
- * Parse out a literal string from the response, using the length
- * encoded before the listeral.
- *
- * @return The LITERAL token with the value.
- * @exception ResponseFormatException
- */
- protected Token readLiteral() throws MessagingException {
- try {
- String value = new String(readLiteralData(), "ISO8859-1");
- return new Token(Token.LITERAL, value);
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
-
- /**
- * Parse out a literal string from the response, using the length
- * encoded before the listeral.
- *
- * @return The byte[] array with the value.
- * @exception ResponseFormatException
- */
- protected byte[] readLiteralData() throws MessagingException {
- int lengthStart = pos + 1;
-
- // see if we have a close marker.
- int lengthEnd = indexOf("}\r\n", lengthStart);
- if (lengthEnd == -1) {
- throw new ResponseFormatException("Missing terminator on literal length");
- }
-
- int count = 0;
- try {
- count = Integer.parseInt(substring(lengthStart, lengthEnd));
- } catch (NumberFormatException e) {
- throw new ResponseFormatException("Invalid literal length " + substring(lengthStart, lengthEnd));
- }
-
- // step over the length
- pos = lengthEnd + 3;
-
- // too long?
- if (pos + count > response.length) {
- throw new ResponseFormatException("Invalid literal length: " + count);
- }
-
- byte[] value = subarray(pos, pos + count);
- pos += count;
-
- return value;
- }
-
-
- /**
- * Extract a substring from the response buffer.
- *
- * @param start The starting offset.
- * @param end The end offset (+ 1).
- *
- * @return A String extracted from the buffer.
- */
- protected String substring(int start, int end ) {
- try {
- return new String(response, start, end - start, "ISO8859-1");
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
-
- /**
- * Extract a subarray from the response buffer.
- *
- * @param start The starting offset.
- * @param end The end offset (+ 1).
- *
- * @return A byte array string extracted rom the buffer.
- */
- protected byte[] subarray(int start, int end ) {
- byte[] result = new byte[end - start];
- System.arraycopy(response, start, result, 0, end - start);
- return result;
- }
-
-
- /**
- * Test if the bytes in the response buffer match a given
- * string value.
- *
- * @param position The compare position.
- * @param needle The needle string we're testing for.
- *
- * @return True if the bytes match the needle value, false for any
- * mismatch.
- */
- public boolean match(int position, String needle) {
- int length = needle.length();
-
- if (response.length - position < length) {
- return false;
- }
-
- for (int i = 0; i < length; i++) {
- if (response[position + i ] != needle.charAt(i)) {
- return false;
- }
- }
- return true;
- }
-
-
- /**
- * Search for a given string starting from the current position
- * cursor.
- *
- * @param needle The search string.
- *
- * @return The index of a match (in absolute byte position in the
- * response buffer).
- */
- public int indexOf(String needle) {
- return indexOf(needle, pos);
- }
-
- /**
- * Search for a string in the response buffer starting from the
- * indicated position.
- *
- * @param needle The search string.
- * @param position The starting buffer position.
- *
- * @return The index of the match position. Returns -1 for no match.
- */
- public int indexOf(String needle, int position) {
- // get the last possible match position
- int last = response.length - needle.length();
- // no match possible
- if (last < position) {
- return -1;
- }
-
- for (int i = position; i <= last; i++) {
- if (match(i, needle)) {
- return i;
- }
- }
- return -1;
- }
-
-
-
- /**
- * Skip white space in the token string.
- */
- private void eatWhiteSpace() {
- // skip to end of whitespace
- while (++pos < response.length
- && WHITE.indexOf(response[pos]) != -1)
- ;
- }
-
-
- /**
- * Ensure that the next token in the parsed response is a
- * '(' character.
- *
- * @exception ResponseFormatException
- */
- public void checkLeftParen() throws MessagingException {
- Token token = next();
- if (token.getType() != '(') {
- throw new ResponseFormatException("Missing '(' in response");
- }
- }
-
-
- /**
- * Ensure that the next token in the parsed response is a
- * ')' character.
- *
- * @exception ResponseFormatException
- */
- public void checkRightParen() throws MessagingException {
- Token token = next();
- if (token.getType() != ')') {
- throw new ResponseFormatException("Missing ')' in response");
- }
- }
-
-
- /**
- * Read a string-valued token from the response. A string
- * valued token can be either a quoted string, a literal value,
- * or an atom. Any other token type is an error.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- public String readString() throws MessagingException {
- Token token = next(true);
- int type = token.getType();
- if (type == Token.NIL) {
- return null;
- }
- if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NUMERIC) {
- throw new ResponseFormatException("String token expected in response: " + token.getValue());
- }
- return token.getValue();
- }
-
-
- /**
- * Read an encoded string-valued token from the response. A string
- * valued token can be either a quoted string, a literal value,
- * or an atom. Any other token type is an error.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- public String readEncodedString() throws MessagingException {
- String value = readString();
- return decode(value);
- }
-
-
- /**
- * Decode a Base 64 encoded string value.
- *
- * @param original The original encoded string.
- *
- * @return The decoded string.
- * @exception MessagingException
- */
- public String decode(String original) throws MessagingException {
- StringBuffer result = new StringBuffer();
-
- for (int i = 0; i < original.length(); i++) {
- char ch = original.charAt(i);
-
- if (ch == '&') {
- i = decode(original, i, result);
- }
- else {
- result.append(ch);
- }
- }
-
- return result.toString();
- }
-
-
- /**
- * Decode a section of an encoded string value.
- *
- * @param original The original source string.
- * @param index The current working index.
- * @param result The StringBuffer used for the decoded result.
- *
- * @return The new index for the decoding operation.
- * @exception MessagingException
- */
- public static int decode(String original, int index, StringBuffer result) throws MessagingException {
- // look for the section terminator
- int terminator = original.indexOf('-', index);
-
- // unmatched?
- if (terminator == -1) {
- throw new MessagingException("Invalid UTF-7 encoded string");
- }
-
- // is this just an escaped "&"?
- if (terminator == index + 1) {
- // append and skip over this.
- result.append('&');
- return index + 2;
- }
-
- // step over the starting char
- index++;
-
- int chars = terminator - index;
- int quads = chars / 4;
- int residual = chars % 4;
-
- // buffer for decoded characters
- byte[] buffer = new byte[4];
- int bufferCount = 0;
-
- // process each of the full triplet pairs
- for (int i = 0; i < quads; i++) {
- byte b1 = decodingTable[original.charAt(index++) & 0xff];
- byte b2 = decodingTable[original.charAt(index++) & 0xff];
- byte b3 = decodingTable[original.charAt(index++) & 0xff];
- byte b4 = decodingTable[original.charAt(index++) & 0xff];
-
- buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
- buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
- buffer[bufferCount++] = (byte)((b3 << 6) | b4);
-
- // we've written 3 bytes to the buffer, but we might have a residual from a previous
- // iteration to deal with.
- if (bufferCount == 4) {
- // two complete chars here
- b1 = buffer[0];
- b2 = buffer[1];
- result.append((char)((b1 << 8) + (b2 & 0xff)));
- b1 = buffer[2];
- b2 = buffer[3];
- result.append((char)((b1 << 8) + (b2 & 0xff)));
- bufferCount = 0;
- }
- else {
- // we need to save the 3rd byte for the next go around
- b1 = buffer[0];
- b2 = buffer[1];
- result.append((char)((b1 << 8) + (b2 & 0xff)));
- buffer[0] = buffer[2];
- bufferCount = 1;
- }
- }
-
- // properly encoded, we should have an even number of bytes left.
-
- switch (residual) {
- // no residual...so we better not have an extra in the buffer
- case 0:
- // this is invalid...we have an odd number of bytes so far,
- if (bufferCount == 1) {
- throw new MessagingException("Invalid UTF-7 encoded string");
- }
- // one byte left. This shouldn't be valid. We need at least 2 bytes to
- // encode one unprintable char.
- case 1:
- throw new MessagingException("Invalid UTF-7 encoded string");
-
- // ok, we have two bytes left, which can only encode a single byte. We must have
- // a dangling unhandled char.
- case 2:
- {
- if (bufferCount != 1) {
- throw new MessagingException("Invalid UTF-7 encoded string");
- }
- byte b1 = decodingTable[original.charAt(index++) & 0xff];
- byte b2 = decodingTable[original.charAt(index++) & 0xff];
- buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
-
- b1 = buffer[0];
- b2 = buffer[1];
- result.append((char)((b1 << 8) + (b2 & 0xff)));
- break;
- }
-
- // we have 2 encoded chars. In this situation, we can't have a leftover.
- case 3:
- {
- // this is invalid...we have an odd number of bytes so far,
- if (bufferCount == 1) {
- throw new MessagingException("Invalid UTF-7 encoded string");
- }
- byte b1 = decodingTable[original.charAt(index++) & 0xff];
- byte b2 = decodingTable[original.charAt(index++) & 0xff];
- byte b3 = decodingTable[original.charAt(index++) & 0xff];
-
- buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
- buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
-
- b1 = buffer[0];
- b2 = buffer[1];
- result.append((char)((b1 << 8) + (b2 & 0xff)));
- break;
- }
- }
-
- // return the new scan location
- return terminator + 1;
- }
-
- /**
- * Read a string-valued token from the response, verifying this is an ATOM token.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- public String readAtom() throws MessagingException {
- return readAtom(false);
- }
-
-
- /**
- * Read a string-valued token from the response, verifying this is an ATOM token.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- public String readAtom(boolean expandedDelimiters) throws MessagingException {
- Token token = next(false, expandedDelimiters);
- int type = token.getType();
-
- if (type != Token.ATOM) {
- throw new ResponseFormatException("ATOM token expected in response: " + token.getValue());
- }
- return token.getValue();
- }
-
-
- /**
- * Read a number-valued token from the response. This must be an ATOM
- * token.
- *
- * @return The integer value of the source token.
- * @exception ResponseFormatException
- */
- public int readInteger() throws MessagingException {
- Token token = next();
- return token.getInteger();
- }
-
-
- /**
- * Read a number-valued token from the response. This must be an ATOM
- * token.
- *
- * @return The long value of the source token.
- * @exception ResponseFormatException
- */
- public int readLong() throws MessagingException {
- Token token = next();
- return token.getInteger();
- }
-
-
- /**
- * Read a string-valued token from the response. A string
- * valued token can be either a quoted string, a literal value,
- * or an atom. Any other token type is an error.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- public String readStringOrNil() throws MessagingException {
- // we need to recognize the NIL token.
- Token token = next(true);
- int type = token.getType();
-
- if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NIL) {
- throw new ResponseFormatException("String token or NIL expected in response: " + token.getValue());
- }
- // this returns null if the token is the NIL token.
- return token.getValue();
- }
-
-
- /**
- * Read a quoted string-valued token from the response.
- * Any other token type other than NIL is an error.
- *
- * @return The string value of the source token.
- * @exception ResponseFormatException
- */
- protected String readQuotedStringOrNil() throws MessagingException {
- // we need to recognize the NIL token.
- Token token = next(true);
- int type = token.getType();
-
- if (type != Token.QUOTEDSTRING && type != Token.NIL) {
- throw new ResponseFormatException("String token or NIL expected in response");
- }
- // this returns null if the token is the NIL token.
- return token.getValue();
- }
-
-
- /**
- * Read a date from a response string. This is expected to be in
- * Internet Date format, but there's a lot of variation implemented
- * out there. If we're unable to format this correctly, we'll
- * just return null.
- *
- * @return A Date object created from the source date.
- */
- public Date readDate() throws MessagingException {
- String value = readString();
-
- try {
- return dateParser.parse(value);
- } catch (Exception e) {
- // we're just skipping over this, so return null
- return null;
- }
- }
-
-
- /**
- * Read a date from a response string. This is expected to be in
- * Internet Date format, but there's a lot of variation implemented
- * out there. If we're unable to format this correctly, we'll
- * just return null.
- *
- * @return A Date object created from the source date.
- */
- public Date readDateOrNil() throws MessagingException {
- String value = readStringOrNil();
- // this might be optional
- if (value == null) {
- return null;
- }
-
- try {
- return dateParser.parse(value);
- } catch (Exception e) {
- // we're just skipping over this, so return null
- return null;
- }
- }
-
- /**
- * Read an internet address from a Fetch response. The
- * addresses are returned as a set of string tokens in the
- * order "personal list mailbox host". Any of these tokens
- * can be NIL.
- *
- * The address may also be the start of a group list, which
- * is indicated by the host being NIL. If we have found the
- * start of a group, then we need to parse multiple elements
- * until we find the group end marker (indicated by both the
- * mailbox and the host being NIL), and create a group
- * InternetAddress instance from this.
- *
- * @return An InternetAddress instance parsed from the
- * element.
- * @exception ResponseFormatException
- */
- public InternetAddress readAddress() throws MessagingException {
- // we recurse, expecting a null response back for sublists.
- if (peek().getType() != '(') {
- return null;
- }
-
- // must start with a paren
- checkLeftParen();
-
- // personal information
- String personal = readStringOrNil();
- // the domain routine information.
- String routing = readStringOrNil();
- // the target mailbox
- String mailbox = readStringOrNil();
- // and finally the host
- String host = readStringOrNil();
- // and validate the closing paren
- checkRightParen();
-
- // if this is a real address, we need to compose
- if (host != null) {
- StringBuffer address = new StringBuffer();
- if (routing != null) {
- address.append(routing);
- address.append(':');
- }
- address.append(mailbox);
- address.append('@');
- address.append(host);
-
- try {
- return new InternetAddress(address.toString(), personal);
- } catch (UnsupportedEncodingException e) {
- throw new ResponseFormatException("Invalid Internet address format");
- }
- }
- else {
- // we're going to recurse on this. If the mailbox is null (the group name), this is the group item
- // terminator.
- if (mailbox == null) {
- return null;
- }
-
- StringBuffer groupAddress = new StringBuffer();
-
- groupAddress.append(mailbox);
- groupAddress.append(':');
- int count = 0;
-
- while (true) {
- // now recurse until we hit the end of the list
- InternetAddress member = readAddress();
- if (member == null) {
- groupAddress.append(';');
-
- try {
- return new InternetAddress(groupAddress.toString(), personal);
- } catch (UnsupportedEncodingException e) {
- throw new ResponseFormatException("Invalid Internet address format");
- }
- }
- else {
- if (count != 0) {
- groupAddress.append(',');
- }
- groupAddress.append(member.toString());
- count++;
- }
- }
- }
- }
-
-
- /**
- * Parse out a list of addresses. This list of addresses is
- * surrounded by parentheses, and each address is also
- * parenthized (SP?).
- *
- * @return An array of the parsed addresses.
- * @exception ResponseFormatException
- */
- public InternetAddress[] readAddressList() throws MessagingException {
- // must start with a paren, but can be NIL also.
- Token token = next(true);
- int type = token.getType();
-
- // either of these results in a null address. The caller determines based on
- // context whether this was optional or not.
- if (type == Token.NIL) {
- return null;
- }
- // non-nil address and no paren. This is a syntax error.
- else if (type != '(') {
- throw new ResponseFormatException("Missing '(' in response");
- }
-
- List addresses = new ArrayList();
-
- // we have a list, now parse it.
- while (notListEnd()) {
- // go read the next address. If we had an address, add to the list.
- // an address ITEM cannot be NIL inside the parens.
- InternetAddress address = readAddress();
- addresses.add(address);
- }
- // we need to skip over the peeked token.
- checkRightParen();
- return (InternetAddress[])addresses.toArray(new InternetAddress[addresses.size()]);
- }
-
-
- /**
- * Check to see if we're at the end of a parenthized list
- * without advancing the parsing pointer. If we are at the
- * end, then this will step over the closing paren.
- *
- * @return True if the next token is a closing list paren, false otherwise.
- * @exception ResponseFormatException
- */
- public boolean checkListEnd() throws MessagingException {
- Token token = peek(true);
- if (token.getType() == ')') {
- // step over this token.
- next();
- return true;
- }
- return false;
- }
-
-
- /**
- * Reads a string item which can be encoded either as a single
- * string-valued token or a parenthized list of string tokens.
- *
- * @return A List containing all of the strings.
- * @exception ResponseFormatException
- */
- public List readStringList() throws MessagingException {
- Token token = peek(true);
-
- if (token.getType() == '(') {
- List list = new ArrayList();
-
- next();
-
- while (notListEnd()) {
- String value = readString();
- // this can be NIL, technically
- if (value != null) {
- list.add(value);
- }
- }
- // step over the closing paren
- next();
-
- return list;
- }
- else if (token != NIL) {
- List list = new ArrayList();
-
- // just a single string value.
- String value = readString();
- // this can be NIL, technically
- if (value != null) {
- list.add(value);
- }
-
- return list;
- } else {
- next();
- }
- return null;
- }
-
-
- /**
- * Reads all remaining tokens and returns them as a list of strings.
- * NIL values are not supported.
- *
- * @return A List containing all of the strings.
- * @exception ResponseFormatException
- */
- public List readStrings() throws MessagingException {
- List list = new ArrayList();
-
- while (hasMore()) {
- String value = readString();
- list.add(value);
- }
- return list;
- }
-
-
- /**
- * Skip over an extension item. This may be either a string
- * token or a parenthized item (with potential nesting).
- *
- * At the point where this is called, we're looking for a closing
- * ')', but we know it is not that. An EOF is an error, however,
- */
- public void skipExtensionItem() throws MessagingException {
- Token token = next();
- int type = token.getType();
-
- // list form? Scan to find the correct list closure.
- if (type == '(') {
- skipNestedValue();
- }
- // found an EOF? Big problem
- else if (type == Token.EOF) {
- throw new ResponseFormatException("Missing ')'");
- }
- }
-
- /**
- * Skip over a parenthized value that we're not interested in.
- * These lists may contain nested sublists, so we need to
- * handle the nesting properly.
- */
- public void skipNestedValue() throws MessagingException {
- Token token = next();
-
- while (true) {
- int type = token.getType();
- // list terminator?
- if (type == ')') {
- return;
- }
- // unexpected end of the tokens.
- else if (type == Token.EOF) {
- throw new ResponseFormatException("Missing ')'");
- }
- // encountered a nested list?
- else if (type == '(') {
- // recurse and finish this list.
- skipNestedValue();
- }
- // we're just skipping the token.
- token = next();
- }
- }
-
- /**
- * Get the next token and verify that it's of the expected type
- * for the context.
- *
- * @param type The type of token we're expecting.
- */
- public void checkToken(int type) throws MessagingException {
- Token token = next();
- if (token.getType() != type) {
- throw new ResponseFormatException("Unexpected token: " + token.getValue());
- }
- }
-
-
- /**
- * Read the next token as binary data. The next token can be a literal, a quoted string, or
- * the token NIL (which returns a null result). Any other token throws a ResponseFormatException.
- *
- * @return A byte array representing the rest of the response data.
- */
- public byte[] readByteArray() throws MessagingException {
- return readData(true);
- }
-
-
- /**
- * Determine what type of token encoding needs to be
- * used for a string value.
- *
- * @param value The string to test.
- *
- * @return Either Token.ATOM, Token.QUOTEDSTRING, or
- * Token.LITERAL, depending on the characters contained
- * in the value.
- */
- static public int getEncoding(byte[] value) {
-
- // a null string always needs to be represented as a quoted literal.
- if (value.length == 0) {
- return Token.QUOTEDSTRING;
- }
-
- for (int i = 0; i < value.length; i++) {
- int ch = value[i];
- // make sure the sign extension is eliminated
- ch = ch & 0xff;
- // check first for any characters that would
- // disqualify a quoted string
- // NULL
- if (ch == 0x00) {
- return Token.LITERAL;
- }
- // non-7bit ASCII
- if (ch > 0x7F) {
- return Token.LITERAL;
- }
- // carriage return
- if (ch == '\r') {
- return Token.LITERAL;
- }
- // linefeed
- if (ch == '\n') {
- return Token.LITERAL;
- }
- // now check for ATOM disqualifiers
- if (atomDelimiters.indexOf(ch) != -1) {
- return Token.QUOTEDSTRING;
- }
- // CTL character. We've already eliminated the high characters
- if (ch < 0x20) {
- return Token.QUOTEDSTRING;
- }
- }
- // this can be an ATOM token
- return Token.ATOM;
- }
-
-
- /**
- * Read a ContentType or ContentDisposition parameter
- * list from an IMAP command response.
- *
- * @return A ParameterList instance containing the parameters.
- * @exception MessagingException
- */
- public ParameterList readParameterList() throws MessagingException {
- ParameterList params = new ParameterList();
-
- // read the tokens, taking NIL into account.
- Token token = next(true, false);
-
- // just return an empty list if this is NIL
- if (token.isType(token.NIL)) {
- return params;
- }
-
- // these are pairs of strings for each parameter value
- while (notListEnd()) {
- String name = readString();
- String value = readString();
- params.set(name, value);
- }
- // we need to consume the list terminator
- checkRightParen();
- return params;
- }
-
-
- /**
- * Test if we have more data in the response buffer.
- *
- * @return true if there are more tokens to process. false if
- * we've reached the end of the stream.
- */
- public boolean hasMore() throws MessagingException {
- // we need to eat any white space that might be in the stream.
- eatWhiteSpace();
- return pos < response.length;
- }
-
-
- /**
- * Tests if we've reached the end of a parenthetical
- * list in our parsing stream.
- *
- * @return true if the next token will be a ')'. false if the
- * next token is anything else.
- * @exception MessagingException
- */
- public boolean notListEnd() throws MessagingException {
- return peek().getType() != ')';
- }
-
- /**
- * Read a list of Flag values from an IMAP response,
- * returning a Flags instance containing the appropriate
- * pieces.
- *
- * @return A Flags instance with the flag values.
- * @exception MessagingException
- */
- public Flags readFlagList() throws MessagingException {
- Flags flags = new Flags();
-
- // this should be a list here
- checkLeftParen();
-
- // run through the flag list
- while (notListEnd()) {
- // the flags are a bit of a pain. The flag names include "\" in the name, which
- // is not a character allowed in an atom. This requires a bit of customized parsing
- // to handle this.
- Token token = next();
- // flags can be specified as just atom tokens, so allow this as a user flag.
- if (token.isType(token.ATOM)) {
- // append the atom as a raw name
- flags.add(token.getValue());
- }
- // all of the system flags start with a '\' followed by
- // an atom. They also can be extension flags. IMAP has a special
- // case of "\*" that we need to check for.
- else if (token.isType('\\')) {
- token = next();
- // the next token is the real bit we need to process.
- if (token.isType('*')) {
- // this indicates USER flags are allowed.
- flags.add(Flags.Flag.USER);
- }
- // if this is an atom name, handle as a system flag
- else if (token.isType(Token.ATOM)) {
- String name = token.getValue();
- if (name.equalsIgnoreCase("Seen")) {
- flags.add(Flags.Flag.SEEN);
- }
- else if (name.equalsIgnoreCase("RECENT")) {
- flags.add(Flags.Flag.RECENT);
- }
- else if (name.equalsIgnoreCase("DELETED")) {
- flags.add(Flags.Flag.DELETED);
- }
- else if (name.equalsIgnoreCase("ANSWERED")) {
- flags.add(Flags.Flag.ANSWERED);
- }
- else if (name.equalsIgnoreCase("DRAFT")) {
- flags.add(Flags.Flag.DRAFT);
- }
- else if (name.equalsIgnoreCase("FLAGGED")) {
- flags.add(Flags.Flag.FLAGGED);
- }
- else {
- // this is a server defined flag....just add the name with the
- // flag thingy prepended.
- flags.add("\\" + name);
- }
- }
- else {
- throw new MessagingException("Invalid Flag: " + token.getValue());
- }
- }
- else {
- throw new MessagingException("Invalid Flag: " + token.getValue());
- }
- }
-
- // step over this for good practice.
- checkRightParen();
-
- return flags;
- }
-
-
- /**
- * Read a list of Flag values from an IMAP response,
- * returning a Flags instance containing the appropriate
- * pieces.
- *
- * @return A Flags instance with the flag values.
- * @exception MessagingException
- */
- public List readSystemNameList() throws MessagingException {
- List flags = new ArrayList();
-
- // this should be a list here
- checkLeftParen();
-
- // run through the flag list
- while (notListEnd()) {
- // the flags are a bit of a pain. The flag names include "\" in the name, which
- // is not a character allowed in an atom. This requires a bit of customized parsing
- // to handle this.
- Token token = next();
- // all of the system flags start with a '\' followed by
- // an atom. They also can be extension flags. IMAP has a special
- // case of "\*" that we need to check for.
- if (token.isType('\\')) {
- token = next();
- // if this is an atom name, handle as a system flag
- if (token.isType(Token.ATOM)) {
- // add the token value to the list WITH the
- // flag indicator included. The attributes method returns
- // these flag indicators, so we need to include it.
- flags.add("\\" + token.getValue());
- }
- else {
- throw new MessagingException("Invalid Flag: " + token.getValue());
- }
- }
- else {
- throw new MessagingException("Invalid Flag: " + token.getValue());
- }
- }
-
- // step over this for good practice.
- checkRightParen();
-
- return flags;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
deleted file mode 100644
index abeaf9c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 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();
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
deleted file mode 100644
index 1afeb84..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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();
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
deleted file mode 100644
index 60a3141..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
deleted file mode 100644
index e2d3a41..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
deleted file mode 100644
index 053a2db..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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;
- }
- }
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
deleted file mode 100644
index a31eb89..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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;
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
deleted file mode 100644
index 45137ee..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * 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();
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
deleted file mode 100644
index 8674f3a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
deleted file mode 100644
index 1a6812a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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);
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
deleted file mode 100644
index a38d0a1..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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");
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
deleted file mode 100644
index bb24800..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * 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);
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
deleted file mode 100644
index 1e346cc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
deleted file mode 100644
index cea8790..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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;
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
deleted file mode 100644
index 767b78c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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);
- }
-}
-
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
deleted file mode 100644
index ec86f6e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
- */
-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 javax.mail.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 javax.mail.Store#getFolder(java.lang.String)
- */
- public Folder getFolder(String name) throws MessagingException {
- return getDefaultFolder().getFolder(name);
- }
-
- /**
- *
- * @see javax.mail.Store#getFolder(javax.mail.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);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
deleted file mode 100644
index def485c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
deleted file mode 100644
index 8a8a97c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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");
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
deleted file mode 100644
index b628361..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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");
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
deleted file mode 100644
index 90e4707..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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);
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
deleted file mode 100644
index 845f54a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
deleted file mode 100644
index 33179f9..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-
-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
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
deleted file mode 100644
index 3ef0275..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * 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 javax.mail.Folder
- *
- * @version $Rev: 1610855 $ $Date: 2014-07-15 17:27:30 -0400 (Tue, 15 Jul 2014) $
- */
-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 javax.mail.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 javax.mail.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 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 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 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 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);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
deleted file mode 100644
index 1d5deb1..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * 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: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-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);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
deleted file mode 100644
index 99cde3b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * 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;
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
deleted file mode 100644
index c92b922..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-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);
- }
-}
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
deleted file mode 100644
index 5be4af5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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.PrintStream;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.mail.AuthenticationFailedException;
-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.pop3.connection.POP3Connection;
-import org.apache.geronimo.javamail.store.pop3.connection.POP3ConnectionPool;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-/**
- * POP3 implementation of javax.mail.Store POP protocol spec is implemented in
- * org.apache.geronimo.javamail.store.pop3.POP3Connection
- *
- * @version $Rev: 693530 $ $Date: 2008-09-09 13:57:23 -0400 (Tue, 09 Sep 2008) $
- */
-
-public class POP3Store extends Store {
- protected static final int DEFAULT_POP3_PORT = 110;
- protected static final int DEFAULT_POP3_SSL_PORT = 995;
-
-
- // our accessor for protocol properties and the holder of
- // protocol-specific information
- protected ProtocolProperties props;
- // our connection object
- protected POP3ConnectionPool connectionPool;
- // our session provided debug output stream.
- protected PrintStream debugStream;
- // the debug flag
- protected boolean debug;
- // the root folder
- protected POP3RootFolder root;
- // until we're connected, we're closed
- boolean closedForBusiness = true;
- protected LinkedList openFolders = new LinkedList();
-
-
- public POP3Store(Session session, URLName name) {
- this(session, name, "pop3", DEFAULT_POP3_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 ("pop3"). 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 POP3Store(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);
-
- // get our debug settings
- debugStream = session.getDebugOut();
- debug = session.getDebug();
- // the connection pool manages connections for the stores, folder, and message usage.
- connectionPool = new POP3ConnectionPool(this, props);
- }
-
-
- /**
- * Return a Folder object that represents the root of the namespace for the current user.
- *
- * Note that in some store configurations (such as IMAP4) the root folder might
- * not be the INBOX folder.
- *
- * @return the root Folder
- * @throws MessagingException if there was a problem accessing the store
- */
- public Folder getDefaultFolder() throws MessagingException {
- checkConnectionStatus();
- // if no root yet, create a root folder instance.
- if (root == null) {
- return new POP3RootFolder(this);
- }
- return root;
- }
-
- /**
- * Return the Folder corresponding to the given name.
- * The folder might not physically exist; the {@link Folder#exists()} method can be used
- * to determine if it is real.
- *
- * @param name the name of the Folder to return
- *
- * @return the corresponding folder
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public Folder getFolder(String name) throws MessagingException {
- return getDefaultFolder().getFolder(name);
- }
-
-
- /**
- * Return the folder identified by the URLName; the URLName must refer to this Store.
- * Implementations may use the {@link URLName#getFile()} method to determined the folder name.
- *
- * @param url
- *
- * @return the corresponding folder
- * @throws MessagingException
- * if there was a problem accessing the store
- */
- public Folder getFolder(URLName url) throws MessagingException {
- return getDefaultFolder().getFolder(url.getFile());
- }
-
-
- /**
- * @see javax.mail.Service#protocolConnect(java.lang.String, int,
- * java.lang.String, java.lang.String)
- */
- protected synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
-
- if (debug) {
- debugOut("Connecting to server " + host + ":" + port + " for user " + username);
- }
-
- // the connection pool handles all of the details here.
- if (connectionPool.protocolConnect(host, port, username, password))
- {
- // the store is now open
- closedForBusiness = false;
- return true;
- }
- return false;
- }
-
-
- /**
- * Get a connection for the store.
- *
- * @return The request connection object.
- * @exception MessagingException
- */
- protected POP3Connection getConnection() throws MessagingException {
- return connectionPool.getConnection();
- }
-
- /**
- * Return a connection back to the connection pool after
- * it has been used for a request.
- *
- * @param connection The return connection.
- *
- * @exception MessagingException
- */
- protected void releaseConnection(POP3Connection connection) throws MessagingException {
- connectionPool.releaseConnection(connection);
- }
-
- /**
- * Get a connection object for a folder to use.
- *
- * @param folder The requesting folder (always the inbox for POP3).
- *
- * @return An active POP3Connection.
- * @exception MessagingException
- */
- synchronized POP3Connection getFolderConnection(POP3Folder folder) throws MessagingException {
- POP3Connection connection = connectionPool.getConnection();
- openFolders.add(folder);
- return connection;
- }
-
- /**
- * Release a connection object after a folder is
- * finished with a request.
- *
- * @param folder The requesting folder.
- * @param connection
- *
- * @exception MessagingException
- */
- synchronized void releaseFolderConnection(POP3Folder folder, POP3Connection connection) throws MessagingException {
- openFolders.remove(folder);
- // return this back to the pool
- connectionPool.releaseConnection(connection);
- }
-
- /**
- * Close all open folders. We have a small problem here with a race condition. There's no safe, single
- * synchronization point for us to block creation of new folders while we're closing. So we make a copy of
- * the folders list, close all of those folders, and keep repeating until we're done.
- */
- protected void closeOpenFolders() {
- // we're no longer accepting additional opens. Any folders that open after this point will get an
- // exception trying to get a connection.
- closedForBusiness = true;
-
- while (true) {
- List folders = null;
-
- // grab our lock, copy the open folders reference, and null this out. Once we see a null
- // open folders ref, we're done closing.
- synchronized(connectionPool) {
- folders = openFolders;
- openFolders = new LinkedList();
- }
-
- // null folder, we're done
- if (folders.isEmpty()) {
- return;
- }
- // now close each of the open folders.
- for (int i = 0; i < folders.size(); i++) {
- POP3Folder folder = (POP3Folder)folders.get(i);
- try {
- folder.close(false);
- } catch (MessagingException e) {
- }
- }
- }
- }
-
-
- /**
- * @see javax.mail.Service#isConnected()
- */
- public boolean isConnected() {
- // the connect() method of the super class checks here first. If the connected flag
- // is off, then it's too early for use to try to get a connection and verify we still
- // have a live one.
- if (!super.isConnected()) {
- return false;
- }
- try {
- POP3Connection connection = getConnection();
- // a null connection likely means we had a failure establishing a
- // new connection to the POP3 server.
- if (connection == null) {
- return false;
- }
- try {
- // make sure the server is really there
- connection.pingServer();
- return true;
- }
- finally {
- // return the connection to the pool when finished
- if (connection != null) {
- releaseConnection(connection);
- }
- }
- } catch (MessagingException e) {
- }
- return false;
- }
-
- /**
- * Close the store, and any open folders associated with the
- * store.
- *
- * @exception MessagingException
- */
- public synchronized void close() throws MessagingException{
- // if already closed, nothing to do.
- if (closedForBusiness) {
- return;
- }
-
- // close the folders first, then shut down the Store.
- closeOpenFolders();
-
- connectionPool.close();
- connectionPool = null;
-
- // make sure we do the superclass close operation first so
- // notification events get broadcast properly.
- super.close();
- }
-
- /**
- * Check the status of our connection.
- *
- * @exception MessagingException
- */
- private void checkConnectionStatus() throws MessagingException {
- if (!this.isConnected()) {
- throw new MessagingException("Not connected ");
- }
- }
-
- /**
- * Internal debug output routine.
- *
- * @param value The string value to output.
- */
- void debugOut(String message) {
- debugStream.println("POP3Store DEBUG: " + message);
- }
-
- /**
- * Internal debugging routine for reporting exceptions.
- *
- * @param message A message associated with the exception context.
- * @param e The received exception.
- */
- void debugOut(String message, Throwable e) {
- debugOut("Received exception -> " + message);
- debugOut("Exception message -> " + e.getMessage());
- e.printStackTrace(debugStream);
- }
-
- /**
- * Finalizer to perform IMAPStore() cleanup when
- * no longer in use.
- *
- * @exception Throwable
- */
- protected void finalize() throws Throwable {
- super.finalize();
- close();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
deleted file mode 100644
index 138834e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
+++ /dev/null
@@ -1,693 +0,0 @@
-/**
- * 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.connection;
-
-import java.io.*;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetHeaders;
-
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseStream;
-import org.apache.geronimo.javamail.store.pop3.POP3Constants;
-import org.apache.geronimo.javamail.util.CommandFailedException;
-import org.apache.geronimo.javamail.util.InvalidCommandException;
-import org.apache.geronimo.javamail.util.MIMEInputReader;
-import org.apache.geronimo.javamail.util.MailConnection;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.geronimo.mail.util.Hex;
-
-/**
- * Simple implementation of POP3 transport.
- *
- * @version $Rev: 1641706 $ $Date: 2014-11-25 16:39:49 -0500 (Tue, 25 Nov 2014) $
- */
-public class POP3Connection extends MailConnection implements POP3Constants {
-
- static final protected String MAIL_APOP_ENABLED = "apop.enable";
- static final protected String MAIL_AUTH_ENABLED = "auth.enable";
- static final protected String MAIL_RESET_QUIT = "rsetbeforequit";
- static final protected String MAIL_DISABLE_TOP = "disabletop";
- //static final protected String MAIL_FORGET_TOP = "forgettopheaders"; //TODO forgettopheaders
-
- // the initial greeting string, which might be required for APOP authentication.
- protected String greeting;
- // is use of the AUTH command enabled
- protected boolean authEnabled;
- // is use of APOP command enabled
- protected boolean apopEnabled;
- // input reader wrapped around the socket input stream
- protected BufferedReader reader;
- // output writer wrapped around the socket output stream.
- protected PrintWriter writer;
- // this connection was closed unexpectedly
- protected boolean closed;
- // indicates whether this connection is currently logged in. Once
- // we send a QUIT, we're finished.
- protected boolean loggedIn;
- // indicates whether we need to avoid using the TOP command
- // when retrieving headers
- protected boolean topDisabled = false;
- // is TLS enabled on our part?
- protected boolean useTLS = false;
- // is TLS required on our part?
- protected boolean requireTLS = false;
-
- /**
- * Normal constructor for an POP3Connection() object.
- *
- * @param props The protocol properties abstraction containing our
- * property modifiers.
- */
- public POP3Connection(ProtocolProperties props) {
- super(props);
-
- // get our login properties flags
- authEnabled = props.getBooleanProperty(MAIL_AUTH_ENABLED, false);
- apopEnabled = props.getBooleanProperty(MAIL_APOP_ENABLED, false);
- topDisabled = props.getBooleanProperty(MAIL_DISABLE_TOP, false);
- // and also check for TLS enablement.
- useTLS = props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false);
- // and also check if TLS is required.
- requireTLS = props.getBooleanProperty(MAIL_STARTTLS_REQUIRED, false);
-
- }
-
-
- /**
- * Connect to the server and do the initial handshaking.
- *
- * @exception MessagingException
- */
- public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
- this.serverHost = host;
- this.serverPort = port;
- this.realm = realm;
- this.authid = authid;
- this.username = username;
- this.password = password;
-
- try {
- // create socket and connect to server.
- getConnection();
- // consume the welcome line
- getWelcome();
-
- // if we're not already using an SSL connection, and we have permission to issue STARTTLS or its even required
- // try to setup a SSL connection
- if (!sslConnection && (useTLS || requireTLS)) {
-
- // tell the server of our intention to start a TLS session
- POP3Response starttlsResponse = null;
- try {
- starttlsResponse = sendCommand("STLS");
- } catch (CommandFailedException e) {
-
- }
-
- //if the server does not support TLS check if its required.
- //If true then throw an error, if not establish a non SSL connection
- if(requireTLS && (starttlsResponse == null || starttlsResponse.isError())) {
- throw new MessagingException("Server doesn't support required transport level security");
- } else if(starttlsResponse != null && starttlsResponse.getStatus() == POP3Response.OK) {
- // The connection is then handled by the superclass level.
- getConnectedTLSSocket();
- } else {
- if (debug) {
- debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
- }
- }
- }
-
- getConnection();
-
- // go login with the server
- if (login())
- {
- loggedIn = true;
- return true;
- }
- return false;
- } catch (IOException e) {
- if (debug) {
- debugOut("I/O exception establishing connection", e);
- }
- throw new MessagingException("Connection error", e);
- }
- }
-
-
- /**
- * Create a transport connection object and connect it to the
- * target server.
- *
- * @exception MessagingException
- */
- protected void getConnection() throws MessagingException
- {
- try {
- // do all of the non-protocol specific set up. This will get our socket established
- // and ready use.
- super.getConnection();
- } catch (IOException e) {
- throw new MessagingException("Unable to obtain a connection to the POP3 server", e);
- }
-
- // The POP3 protocol is inherently a string-based protocol, so we get
- // string readers/writers for the connection streams. Note that we explicitly
- // set the encoding to ensure that an inappropriate native encoding is not picked up.
- try {
- reader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859-1"));
- writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), "ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
- protected void getWelcome() throws IOException {
- // just read the line and consume it. If debug is
- // enabled, there I/O stream will be traced
- greeting = reader.readLine();
- }
-
- public String toString() {
- return "POP3Connection host: " + serverHost + " port: " + serverPort;
- }
-
-
- /**
- * Close the connection. On completion, we'll be disconnected from
- * the server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // if we're already closed, get outta here.
- if (socket == null) {
- return;
- }
- try {
- // say goodbye
- logout();
- } finally {
- // and close up the connection. We do this in a finally block to make sure the connection
- // is shut down even if quit gets an error.
- closeServerConnection();
- // get rid of our response processor too.
- reader = null;
- writer = null;
- }
- }
-
-
- /**
- * Tag this connection as having been closed by the
- * server. This will not be returned to the
- * connection pool.
- */
- public void setClosed() {
- closed = true;
- }
-
- /**
- * Test if the connection has been forcibly closed.
- *
- * @return True if the server disconnected the connection.
- */
- public boolean isClosed() {
- return closed;
- }
-
- protected POP3Response sendCommand(String cmd) throws MessagingException {
- return sendCommand(cmd, false);
- }
-
- protected POP3Response sendMultiLineCommand(String cmd) throws MessagingException {
- return sendCommand(cmd, true);
- }
-
- protected synchronized POP3Response sendCommand(String cmd, boolean multiLine) throws MessagingException {
- if (socket.isConnected()) {
- {
- // NOTE: We don't use println() because it uses the platform concept of a newline rather
- // than using CRLF, which is required by the POP3 protocol.
- writer.write(cmd);
- writer.write("\r\n");
- writer.flush();
-
- POP3Response response = buildResponse(multiLine);
- if (response.isError()) {
- throw new CommandFailedException("Error issuing POP3 command: " + cmd);
- }
- return response;
- }
- }
- throw new MessagingException("Connection to Mail Server is lost, connection " + this.toString());
- }
-
- /**
- * Build a POP3Response item from the response stream.
- *
- * @param isMultiLineResponse
- * If true, this command is expecting multiple lines back from the server.
- *
- * @return A POP3Response item with all of the command response data.
- * @exception MessagingException
- */
- protected POP3Response buildResponse(boolean isMultiLineResponse) throws MessagingException {
- int status = ERR;
- byte[] data = null;
-
- String line;
- //MIMEInputReader source = new MIMEInputReader(reader); //TODO unused
-
- try {
- line = reader.readLine();
- } catch (IOException e) {
- throw new MessagingException("Error in receving response");
- }
-
- if (line == null || line.trim().equals("")) {
- throw new MessagingException("Empty Response");
- }
-
- if (line.startsWith("+OK")) {
- status = OK;
- line = removeStatusField(line);
- if (isMultiLineResponse) {
- data = getMultiLineResponse();
- }
- } else if (line.startsWith("-ERR")) {
- status = ERR;
- line = removeStatusField(line);
- }else if (line.startsWith("+")) {
- status = CHALLENGE;
- line = removeStatusField(line);
- if (isMultiLineResponse) {
- data = getMultiLineResponse();
- }
- } else {
- throw new MessagingException("Unexpected response: " + line);
- }
- return new POP3Response(status, line, data);
- }
-
- private static String removeStatusField(String line) {
- return line.substring(line.indexOf(SPACE) + 1);
- }
-
- /**
- * This could be a multiline response
- */
- private byte[] getMultiLineResponse() throws MessagingException {
-
- MIMEInputReader source = new MIMEInputReader(reader);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- // it's more efficient to do this a buffer at a time.
- // the MIMEInputReader takes care of the byte-stuffing and
- // ".\r\n" input terminator for us.
- try {
- OutputStreamWriter outWriter = new OutputStreamWriter(out, "ISO8859-1");
- char buffer[] = new char[500];
- try {
- int charsRead = -1;
- while ((charsRead = source.read(buffer)) >= 0) {
- outWriter.write(buffer, 0, charsRead);
- }
- outWriter.flush();
- } catch (IOException e) {
- throw new MessagingException("Error processing a multi-line response", e);
- }
- } catch (UnsupportedEncodingException e) {
- }
- return out.toByteArray();
- }
-
-
- /**
- * Retrieve the raw message content from the POP3
- * server. This is all of the message data, including
- * the header.
- *
- * @param sequenceNumber
- * The message sequence number.
- *
- * @return A byte array containing all of the message data.
- * @exception MessagingException
- */
- public byte[] retrieveMessageData(int sequenceNumber) throws MessagingException {
- POP3Response msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
- // we want the data directly in this case.
- return msgResponse.getData();
- }
-
- /**
- * Retrieve the message header information for a given
- * message, returned as an input stream suitable
- * for loading the message data.
- *
- * @param sequenceNumber
- * The server sequence number for the message.
- *
- * @return An inputstream that can be used to read the message
- * data.
- * @exception MessagingException
- */
- public ByteArrayInputStream retrieveMessageHeaders(int sequenceNumber) throws MessagingException {
- POP3Response msgResponse;
-
- // some POP3 servers don't correctly implement TOP, so this can be disabled. If
- // we can't use TOP, then use RETR and retrieve everything. We can just hand back
- // the stream, as the header loading routine will stop at the first
- // null line.
- if (topDisabled) {
- msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
- }
- else {
- msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0");
- }
-
- // just load the returned message data as a set of headers
- return msgResponse.getContentStream();
- }
-
- /**
- * Retrieve the total message size from the mail
- * server. This is the size of the headers plus
- * the size of the message content.
- *
- * @param sequenceNumber
- * The message sequence number.
- *
- * @return The full size of the message.
- * @exception MessagingException
- */
- public int retrieveMessageSize(int sequenceNumber) throws MessagingException {
- POP3Response msgResponse = sendCommand("LIST " + sequenceNumber);
- // Convert this into the parsed response type we need.
- POP3ListResponse list = new POP3ListResponse(msgResponse);
- // this returns the total message size
- return list.getSize();
- }
-
- /**
- * Retrieve the mail drop status information.
- *
- * @return An object representing the returned mail drop status.
- * @exception MessagingException
- */
- public POP3StatusResponse retrieveMailboxStatus() throws MessagingException {
- // issue the STAT command and return this into a status response
- return new POP3StatusResponse(sendCommand("STAT"));
- }
-
-
- /**
- * Retrieve the UID for an individual message.
- *
- * @param sequenceNumber
- * The target message sequence number.
- *
- * @return The string UID maintained by the server.
- * @exception MessagingException
- */
- public String retrieveMessageUid(int sequenceNumber) throws MessagingException {
- POP3Response msgResponse = sendCommand("UIDL " + sequenceNumber);
-
- String message = msgResponse.getFirstLine();
- // the UID is everything after the blank separating the message number and the UID.
- // there's not supposed to be anything else on the message, but trim it of whitespace
- // just to be on the safe side.
- return message.substring(message.indexOf(' ') + 1).trim();
- }
-
-
- /**
- * Delete a single message from the mail server.
- *
- * @param sequenceNumber
- * The sequence number of the message to delete.
- *
- * @exception MessagingException
- */
- public void deleteMessage(int sequenceNumber) throws MessagingException {
- // just issue the command...we ignore the command response
- sendCommand("DELE " + sequenceNumber);
- }
-
- /**
- * Logout from the mail server. This sends a QUIT
- * command, which will likely sever the mail connection.
- *
- * @exception MessagingException
- */
- public void logout() throws MessagingException {
- // we may have already sent the QUIT command
- if (!loggedIn) {
- return;
- }
- // just issue the command...we ignore the command response
- sendCommand("QUIT");
- loggedIn = false;
- }
-
- /**
- * Perform a reset on the mail server.
- *
- * @exception MessagingException
- */
- public void reset() throws MessagingException {
- // some mail servers mark retrieved messages for deletion
- // automatically. This will reset the read flags before
- // we go through normal cleanup.
- if (props.getBooleanProperty(MAIL_RESET_QUIT, false)) {
- // just send an RSET command first
- sendCommand("RSET");
- }
- }
-
- /**
- * Ping the mail server to see if we still have an active connection.
- *
- * @exception MessagingException thrown if we do not have an active connection.
- */
- public void pingServer() throws MessagingException {
- // just issue the command...we ignore the command response
- sendCommand("NOOP");
- }
-
- /**
- * Login to the mail server, using whichever method is
- * configured. This will try multiple methods, if allowed,
- * in decreasing levels of security.
- *
- * @return true if the login was successful.
- * @exception MessagingException
- */
- public synchronized boolean login() throws MessagingException {
- // permitted to use the AUTH command?
- if (authEnabled) {
- try {
- // go do the SASL thing
- return processSaslAuthentication();
- } catch (MessagingException e) {
- // Any error here means fall back to the next mechanism
- }
- }
-
- if (apopEnabled) {
- try {
- // go do the SASL thing
- return processAPOPAuthentication();
- } catch (MessagingException e) {
- // Any error here means fall back to the next mechanism
- }
- }
-
- try {
- // do the tried and true login processing.
- return processLogin();
- } catch (MessagingException e) {
- }
- // everything failed...can't get in
- return false;
- }
-
-
- /**
- * Process a basic LOGIN operation, using the
- * plain test USER/PASS command combo.
- *
- * @return true if we logged successfully.
- * @exception MessagingException
- */
- public boolean processLogin() throws MessagingException {
- // start by sending the USER command, followed by
- // the PASS command
- sendCommand("USER " + username);
- sendCommand("PASS " + password);
- return true; // we're in
- }
-
- /**
- * Process logging in using the APOP command. Only
- * works on servers that give a timestamp value
- * in the welcome response.
- *
- * @return true if the login was accepted.
- * @exception MessagingException
- */
- public boolean processAPOPAuthentication() throws MessagingException {
- int timeStart = greeting.indexOf('<');
- // if we didn't get an APOP challenge on the greeting, throw an exception
- // the main login processor will swallow that and fall back to the next
- // mechanism
- if (timeStart == -1) {
- throw new MessagingException("POP3 Server does not support APOP");
- }
- int timeEnd = greeting.indexOf('>');
- String timeStamp = greeting.substring(timeStart, timeEnd + 1);
-
- // we create the digest password using the timestamp value sent to use
- // concatenated with the password.
- String digestPassword = timeStamp + password;
-
- byte[] digest;
-
- try {
- // create a digest value from the password.
- MessageDigest md = MessageDigest.getInstance("MD5");
- digest = md.digest(digestPassword.getBytes("iso-8859-1"));
- } catch (NoSuchAlgorithmException e) {
- // this shouldn't happen, but if it does, we'll just try a plain
- // login.
- throw new MessagingException("Unable to create MD5 digest", e);
- } catch (UnsupportedEncodingException e) {
- // this shouldn't happen, but if it does, we'll just try a plain
- // login.
- throw new MessagingException("Unable to create MD5 digest", e);
- }
- // this will throw an exception if it gives an error failure
- sendCommand("APOP " + username + " " + new String(Hex.encode(digest)));
- // no exception, we must have passed
- return true;
- }
-
-
- /**
- * Process SASL-type authentication.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected boolean processSaslAuthentication() throws MessagingException {
- // if unable to get an appropriate authenticator, just fail it.
- ClientAuthenticator authenticator = getSaslAuthenticator();
- if (authenticator == null) {
- throw new MessagingException("Unable to obtain SASL authenticator");
- }
-
- // go process the login.
- return processLogin(authenticator);
- }
-
- /**
- * Attempt to retrieve a SASL authenticator for this
- * protocol.
- *
- * @return A SASL authenticator, or null if a suitable one
- * was not located.
- */
- protected ClientAuthenticator getSaslAuthenticator() {
- return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
- }
-
-
- /**
- * Process a login using the provided authenticator object.
- *
- * NB: This method is synchronized because we have a multi-step process going on
- * here. No other commands should be sent to the server until we complete.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
- if (debug) {
- debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
- }
-
- POP3Response response = sendCommand("AUTH " + authenticator.getMechanismName());
-
- // now process the challenge sequence. We get a continuation response back for each stage of the
- // authentication, and finally an OK when everything passes muster.
- while (true) {
- // this should be a continuation reply, if things are still good.
- if (response.isChallenge()) {
- // we're passed back a challenge value, Base64 encoded.
- byte[] challenge = response.decodeChallengeResponse();
-
- try {
- String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII");
-
- // have the authenticator evaluate and send back the encoded response.
- response = sendCommand(responseString);
- } catch (UnsupportedEncodingException ex) {
- }
- }
- else {
- // there are only two choices here, OK or a continuation. OK means
- // we've passed muster and are in.
- return true;
- }
- }
- }
-
-
- /**
- * Merge the configured SASL mechanisms with the capabilities that the
- * server has indicated it supports, returning a merged list that can
- * be used for selecting a mechanism.
- *
- * @return A List representing the intersection of the configured list and the
- * capabilities list.
- */
- protected List selectSaslMechanisms() {
- // just return the set that have been explicity permitted
- return getSaslMechanisms();
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java
deleted file mode 100644
index 8aa9c4b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * 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.connection;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Store;
-
-import javax.mail.StoreClosedException;
-
-import org.apache.geronimo.javamail.store.pop3.POP3Store;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-public class POP3ConnectionPool {
-
- protected static final String MAIL_PORT = "port";
-
- protected static final String MAIL_SASL_REALM = "sasl.realm";
- protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid";
-
- protected static final String DEFAULT_MAIL_HOST = "localhost";
-
- // Our hosting Store instance
- protected POP3Store store;
- // our Protocol abstraction
- protected ProtocolProperties props;
- // POP3 is not nearly as multi-threaded as IMAP. We really just have a single folder,
- // plus the Store, but the Store doesn't really talk to the server very much. We only
- // hold one connection available, and on the off chance there is a situation where
- // we need to create a new one, we'll authenticate on demand. The one case where
- // I know this might be an issue is a folder checking back with the Store to see it if
- // it is still connected.
- protected POP3Connection availableConnection;
-
- // our debug flag
- protected boolean debug;
-
- // the target host
- protected String host;
- // the target server port.
- protected int port;
- // the username we connect with
- protected String username;
- // the authentication password.
- protected String password;
- // the SASL realm name
- protected String realm;
- // the authorization id.
- protected String authid;
- // Turned on when the store is closed for business.
- protected boolean closed = false;
-
- /**
- * Create a connection pool associated with a give POP3Store instance. The
- * connection pool manages handing out connections for both the Store and
- * Folder and Message usage.
- *
- * @param store The Store we're creating the pool for.
- * @param props The protocol properties abstraction we use.
- */
- public POP3ConnectionPool(POP3Store store, ProtocolProperties props) {
- this.store = store;
- this.props = props;
- }
-
-
- /**
- * Manage the initial connection to the POP3 server. This is the first
- * point where we obtain the information needed to make an actual server
- * connection. Like the Store protocolConnect method, we return false
- * if there's any sort of authentication difficulties.
- *
- * @param host The host of the mail server.
- * @param port The mail server connection port.
- * @param user The connection user name.
- * @param password The connection password.
- *
- * @return True if we were able to connect and authenticate correctly.
- * @exception MessagingException
- */
- public synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
- // NOTE: We don't check for the username/password being null at this point. It's possible that
- // the server will send back a PREAUTH response, which means we don't need to go through login
- // processing. We'll need to check the capabilities response after we make the connection to decide
- // if logging in is necesssary.
-
- // save this for subsequent connections. All pool connections will use this info.
- // if the port is defaulted, then see if we have something configured in the session.
- // if not configured, we just use the default default.
- if (port == -1) {
- // check for a property and fall back on the default if it's not set.
- port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
- // it's possible that -1 might have been explicitly set, so one last check.
- if (port == -1) {
- port = props.getDefaultPort();
- }
- }
-
- // Before we do anything, let's make sure that we succesfully received a host
- if ( host == null ) {
- host = DEFAULT_MAIL_HOST;
- }
-
- this.host = host;
- this.port = port;
- this.username = username;
- this.password = password;
-
- // make sure we have the realm information
- realm = props.getProperty(MAIL_SASL_REALM);
- // get an authzid value, if we have one. The default is to use the username.
- authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
-
- // go create a connection and just add it to the pool. If there is an authenticaton error,
- // return the connect failure, and we may end up trying again.
- availableConnection = createPoolConnection();
- if (availableConnection == null) {
- return false;
- }
- // we're connected, authenticated, and ready to go.
- return true;
- }
-
- /**
- * Creates an authenticated pool connection and adds it to
- * the connection pool. If there is an existing connection
- * already in the pool, this returns without creating a new
- * connection.
- *
- * @exception MessagingException
- */
- protected POP3Connection createPoolConnection() throws MessagingException {
- POP3Connection connection = new POP3Connection(props);
- if (!connection.protocolConnect(host, port, authid, realm, username, password)) {
- // we only add live connections to the pool. Sever the connections and
- // allow it to go free.
- connection.closeServerConnection();
- return null;
- }
- // just return this connection
- return connection;
- }
-
-
- /**
- * Get a connection from the pool. We try to retrieve a live
- * connection, but we test the connection's liveness before
- * returning one. If we don't have a viable connection in
- * the pool, we'll create a new one. The returned connection
- * will be in the authenticated state already.
- *
- * @return A POP3Connection object that is connected to the server.
- */
- public synchronized POP3Connection getConnection() throws MessagingException {
- // if we have an available one (common when opening the INBOX), just return it
- POP3Connection connection = availableConnection;
-
- if (connection != null) {
- availableConnection = null;
- return connection;
- }
- // we need an additional connection...rare, but it can happen if we've closed the INBOX folder.
- return createPoolConnection();
- }
-
-
- /**
- * Return a connection to the connection pool.
- *
- * @param connection The connection getting returned.
- *
- * @exception MessagingException
- */
- public synchronized void releaseConnection(POP3Connection connection) throws MessagingException
- {
- // we're generally only called if the store needed to talk to the server and
- // then returned the connection to the pool. So it's pretty likely that we'll just cache this
- if (availableConnection == null) {
- availableConnection = connection;
- }
- else {
- // got too many connections created...not sure how, but get rid of this one.
- connection.close();
- }
- }
-
-
- /**
- * Close the entire connection pool.
- *
- * @exception MessagingException
- */
- public synchronized void close() throws MessagingException {
- // we'll on have the single connection in reserver
- if (availableConnection != null) {
- availableConnection.close();
- availableConnection = null;
- }
- // turn out the lights, hang the closed sign on the wall.
- closed = true;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java
deleted file mode 100644
index 5eeb7ba..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.connection;
-
-import java.io.ByteArrayInputStream;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.mail.MessagingException;
-
-/**
- * This class adds functionality to the basic response by parsing the reply for
- * LIST command and obtaining specific information about the msgnum and the
- * size. It could be for one or more msgs depending on wether a msg number was
- * passed or not into the LIST command
- *
- * @see org.apache.geronimo.javamail.store.pop3.POP3Response
- * @see org.apache.geronimo.javamail.store.pop3.response.DefaultPOP3Response
- *
- * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-
-public class POP3ListResponse extends POP3Response {
-
- private int msgnum = 0;
-
- private int size = 0;
-
- private List multipleMsgs = null;
-
- POP3ListResponse(POP3Response baseRes) throws MessagingException {
- super(baseRes.getStatus(), baseRes.getFirstLine(), baseRes.getData());
-
- // if ERR not worth proceeding any further
- if (OK == getStatus()) {
-
- // if data == null, then it mean it's a single line response
- if (baseRes.getData() == null) {
- String[] args = getFirstLine().split(SPACE);
- try {
- msgnum = Integer.parseInt(args[0]);
- } catch (NumberFormatException e) {
- throw new MessagingException("Invalid response for LIST command", e);
- }
- try {
- size = Integer.parseInt(args[1]);
- } catch (NumberFormatException e) {
- throw new MessagingException("Invalid response for LIST command", e);
- }
- } else {
- int totalMsgs = 0;
- String[] args = getFirstLine().split(SPACE);
- try {
- totalMsgs = Integer.parseInt(args[0]);
- } catch (NumberFormatException e) {
- throw new MessagingException("Invalid response for LIST command", e);
- }
- multipleMsgs = new ArrayList(totalMsgs);
- // Todo : multi-line response parsing
- }
-
- }
- }
-
- public int getMessageNumber() {
- return msgnum;
- }
-
- public int getSize() {
- return size;
- }
-
- /**
- * Messages can be accessed by multipleMsgs.getElementAt(msgnum)
- *
- */
- public List getMultipleMessageDetails() {
- return multipleMsgs;
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java
deleted file mode 100644
index e4fc2aa..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.connection;
-
-import java.io.ByteArrayInputStream;
-
-import org.apache.geronimo.javamail.store.pop3.POP3Constants;
-
-import org.apache.geronimo.mail.util.Base64;
-
-/**
- * This class provides the basic implementation for the POP3Response.
- *
- * @see org.apache.geronimo.javamail.store.pop3.POP3Response
- * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-
-public class POP3Response implements POP3Constants {
-
- private int status = ERR;
-
- private String firstLine;
-
- private byte[] data;
-
- POP3Response(int status, String firstLine, byte []data) {
- this.status = status;
- this.firstLine = firstLine;
- this.data = data;
- }
-
- public int getStatus() {
- return status;
- }
-
- public byte[] getData() {
- return data;
- }
-
- public ByteArrayInputStream getContentStream() {
- return new ByteArrayInputStream(data);
- }
-
- public String getFirstLine() {
- return firstLine;
- }
-
- public boolean isError() {
- return status == ERR;
- }
-
- public boolean isChallenge() {
- return status == CHALLENGE;
- }
-
- /**
- * Decode the message portion of a continuation challenge response.
- *
- * @return The byte array containing the decoded data.
- */
- public byte[] decodeChallengeResponse()
- {
- // the challenge response is a base64 encoded string...
- return Base64.decode(firstLine.trim());
- }
-
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java
deleted file mode 100644
index 7472cfc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.connection;
-
-import javax.mail.MessagingException;
-
-/**
- * This class adds functionality to the basic response by parsing the status
- * line and obtaining specific information about num of msgs and the size
- *
- * @see org.apache.geronimo.javamail.store.pop3.POP3Response
- * @see org.apache.geronimo.javamail.store.pop3.response.DefaultPOP3Response
- *
- * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-
-public class POP3StatusResponse extends POP3Response {
-
- private int numMessages = 0;
-
- private int size = 0;
-
- POP3StatusResponse(POP3Response baseRes) throws MessagingException {
- super(baseRes.getStatus(), baseRes.getFirstLine(), baseRes.getData());
-
- // if ERR not worth proceeding any further
- if (OK == getStatus()) {
- String[] args = getFirstLine().split(SPACE);
- try {
- numMessages = Integer.parseInt(args[0]);
- } catch (NumberFormatException e) {
- throw new MessagingException("Invalid response for STAT command", e);
- }
- try {
- size = Integer.parseInt(args[1]);
- } catch (NumberFormatException e) {
- throw new MessagingException("Invalid response for STAT command", e);
- }
- }
- }
-
- public int getNumMessages() {
- return numMessages;
- }
-
- public int getSize() {
- return size;
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
deleted file mode 100644
index 8ab1e2f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * 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.transport.nntp;
-
-import java.io.BufferedReader;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
-import org.apache.geronimo.javamail.util.MailConnection;
-import org.apache.geronimo.javamail.util.MIMEOutputStream;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.geronimo.mail.util.SessionUtil;
-
-/**
- * Simple implementation of NNTP transport. Just does plain RFC977-ish delivery.
- *
- * @version $Rev: 953638 $ $Date: 2010-06-11 06:09:00 -0400 (Fri, 11 Jun 2010) $
- */
-public class NNTPConnection extends MailConnection {
-
- /**
- * constants for EOL termination
- */
- protected static final char CR = '\r';
-
- protected static final char LF = '\n';
-
- /**
- * property keys for protocol properties.
- */
- protected static final int DEFAULT_NNTP_PORT = 119;
- // does the server support posting?
- protected boolean postingAllowed = true;
-
- // different authentication mechanisms
- protected boolean authInfoUserAllowed = false;
- protected boolean authInfoSaslAllowed = false;
-
- // the last response line received from the server.
- protected NNTPReply lastServerResponse = null;
-
- // the welcome string from the server.
- protected String welcomeString = null;
-
- // input reader wrapped around the socket input stream
- protected BufferedReader reader;
- // output writer wrapped around the socket output stream.
- protected PrintWriter writer;
-
- /**
- * Normal constructor for an NNTPConnection() object.
- *
- * @param props The property bundle for this protocol instance.
- */
- public NNTPConnection(ProtocolProperties props) {
- super(props);
- }
-
-
- /**
- * Connect to the server and do the initial handshaking.
- *
- * @param host The target host name.
- * @param port The target port
- * @param username The connection username (can be null)
- * @param password The authentication password (can be null).
- *
- * @return true if we were able to obtain a connection and
- * authenticate.
- * @exception MessagingException
- */
- public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
- super.protocolConnect(host, port, username, password);
- // create socket and connect to server.
- getConnection();
-
- // receive welcoming message
- getWelcome();
-
- return true;
- }
-
-
- /**
- * Create a transport connection object and connect it to the
- * target server.
- *
- * @exception MessagingException
- */
- protected void getConnection() throws MessagingException
- {
- try {
- // do all of the non-protocol specific set up. This will get our socket established
- // and ready use.
- super.getConnection();
- } catch (IOException e) {
- throw new MessagingException("Unable to obtain a connection to the NNTP server", e);
- }
-
- // The NNTP protocol is inherently a string-based protocol, so we get
- // string readers/writers for the connection streams. Note that we explicitly
- // set the encoding to ensure that an inappropriate native encoding is not picked up.
- try {
- reader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859-1"));
- writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), "ISO8859-1"));
- } catch (UnsupportedEncodingException e) {
- }
- }
-
-
- /**
- * Close the connection. On completion, we'll be disconnected from the
- * server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // if we're already closed, get outta here.
- if (socket == null) {
- return;
- }
- try {
- // say goodbye
- sendQuit();
- } finally {
- // and close up the connection. We do this in a finally block to
- // make sure the connection
- // is shut down even if quit gets an error.
- closeServerConnection();
- // get rid of our response processor too.
- reader = null;
- writer = null;
- }
- }
-
- public String toString() {
- return "NNTPConnection host: " + serverHost + " port: " + serverPort;
- }
-
-
- /**
- * Get the servers welcome blob from the wire....
- */
- public void getWelcome() throws MessagingException {
- NNTPReply line = getReply();
-
- //
- if (line.isError()) {
- throw new MessagingException("Error connecting to news server: " + line.getMessage());
- }
-
- // remember we can post.
- if (line.getCode() == NNTPReply.POSTING_ALLOWED) {
- postingAllowed = true;
- } else {
- postingAllowed = false;
- }
-
- // the NNTP store will want to use the welcome string, so save it.
- welcomeString = line.getMessage();
-
- // find out what extensions this server supports.
- getExtensions();
- }
-
-
- /**
- * Sends the QUIT message and receieves the response
- */
- public void sendQuit() throws MessagingException {
- sendLine("QUIT");
- }
-
-
- /**
- * Tell the server to switch to a named group.
- *
- * @param name
- * The name of the target group.
- *
- * @return The server response to the GROUP command.
- */
- public NNTPReply selectGroup(String name) throws MessagingException {
- // send the GROUP command
- return sendCommand("GROUP " + name);
- }
-
-
- /**
- * Ask the server what extensions it supports.
- *
- * @return True if the command was accepted ok, false for any errors.
- * @exception MessagingException
- */
- protected void getExtensions() throws MessagingException {
- NNTPReply reply = sendCommand("LIST EXTENSIONS", NNTPReply.EXTENSIONS_SUPPORTED);
-
- // we get a 202 code back. The first line is just a greeting, and
- // extensions are delivered as data
- // lines terminated with a "." line.
- if (reply.getCode() != NNTPReply.EXTENSIONS_SUPPORTED) {
- return;
- }
-
- // get a fresh extension mapping table.
- capabilities = new HashMap();
- authentications = new ArrayList();
-
- // get the extension data lines.
- List extensions = reply.getData();
-
- // process all of the continuation lines
- for (int i = 0; i < extensions.size(); i++) {
- // go process the extention
- processExtension((String) extensions.get(i));
- }
- }
-
-
- /**
- * Process an extension string passed back as the LIST EXTENSIONS response.
- *
- * @param extension
- * The string value of the extension (which will be of the form
- * "NAME arguments").
- */
- protected void processExtension(String extension) {
- String extensionName = extension.toUpperCase();
- String argument = "";
-
- int delimiter = extension.indexOf(' ');
- // if we have a keyword with arguments, parse them out and add to the
- // argument map.
- if (delimiter != -1) {
- extensionName = extension.substring(0, delimiter).toUpperCase();
- argument = extension.substring(delimiter + 1);
- }
-
- // add this to the map so it can be tested later.
- capabilities.put(extensionName, argument);
-
- // we need to determine which authentication mechanisms are supported here
- if (extensionName.equals("AUTHINFO")) {
- StringTokenizer tokenizer = new StringTokenizer(argument);
-
- while (tokenizer.hasMoreTokens()) {
- // we only know how to do USER or SASL
- String mechanism = tokenizer.nextToken().toUpperCase();
- if (mechanism.equals("SASL")) {
- authInfoSaslAllowed = true;
- }
- else if (mechanism.equals("USER")) {
- authInfoUserAllowed = true;
- }
- }
- }
- // special case for some older servers.
- else if (extensionName.equals("SASL")) {
- // The security mechanisms are blank delimited tokens.
- StringTokenizer tokenizer = new StringTokenizer(argument);
-
- while (tokenizer.hasMoreTokens()) {
- String mechanism = tokenizer.nextToken().toUpperCase();
- authentications.add(mechanism);
- }
- }
- }
-
-
- /**
- * Retrieve any argument information associated with a extension reported
- * back by the server on the EHLO command.
- *
- * @param name
- * The name of the target server extension.
- *
- * @return Any argument passed on a server extension. Returns null if the
- * extension did not include an argument or the extension was not
- * supported.
- */
- public String extensionParameter(String name) {
- if (capabilities != null) {
- return (String) capabilities.get(name);
- }
- return null;
- }
-
- /**
- * Tests whether the target server supports a named extension.
- *
- * @param name
- * The target extension name.
- *
- * @return true if the target server reported on the EHLO command that is
- * supports the targer server, false if the extension was not
- * supported.
- */
- public boolean supportsExtension(String name) {
- // this only returns null if we don't have this extension
- return extensionParameter(name) != null;
- }
-
-
- /**
- * Sends the data in the message down the socket. This presumes the server
- * is in the right place and ready for getting the DATA message and the data
- * right place in the sequence
- */
- public synchronized void sendPost(Message msg) throws MessagingException {
-
- // send the POST command
- NNTPReply line = sendCommand("POST");
-
- if (line.getCode() != NNTPReply.SEND_ARTICLE) {
- throw new MessagingException("Server rejected POST command: " + line);
- }
-
- // we've received permission to send the data, so ask the message to
- // write itself out.
- try {
- // the data content has two requirements we need to meet by
- // filtering the
- // output stream. Requirement 1 is to conicalize any line breaks.
- // All line
- // breaks will be transformed into properly formed CRLF sequences.
- //
- // Requirement 2 is to perform byte-stuff for any line that begins
- // with a "."
- // so that data is not confused with the end-of-data marker (a
- // "\r\n.\r\n" sequence.
- //
- // The MIME output stream performs those two functions on behalf of
- // the content
- // writer.
- MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
-
- msg.writeTo(mimeOut);
-
- // now to finish, we send a CRLF sequence, followed by a ".".
- mimeOut.writeSMTPTerminator();
- // and flush the data to send it along
- mimeOut.flush();
- } catch (IOException e) {
- throw new MessagingException("I/O error posting message", e);
- } catch (MessagingException e) {
- throw new MessagingException("Exception posting message", e);
- }
-
- // use a longer time out here to give the server time to process the
- // data.
- line = new NNTPReply(receiveLine());
-
- if (line.getCode() != NNTPReply.POSTED_OK) {
- throw new MessagingException("Server rejected POST command: " + line);
- }
- }
-
- /**
- * Issue a command and retrieve the response. If the given success indicator
- * is received, the command is returning a longer response, terminated by a
- * "crlf.crlf" sequence. These lines are attached to the reply.
- *
- * @param command
- * The command to issue.
- * @param success
- * The command reply that indicates additional data should be
- * retrieved.
- *
- * @return The command reply.
- */
- public synchronized NNTPReply sendCommand(String command, int success) throws MessagingException {
- NNTPReply reply = sendCommand(command);
- if (reply.getCode() == success) {
- reply.retrieveData(reader);
- }
- return reply;
- }
-
- /**
- * Send a command to the server, returning the first response line back as a
- * reply.
- *
- * @param data
- * The data to send.
- *
- * @return A reply object with the reply line.
- * @exception MessagingException
- */
- public NNTPReply sendCommand(String data) throws MessagingException {
- sendLine(data);
- NNTPReply reply = getReply();
- // did the server just inform us we need to authenticate? The spec
- // allows this
- // response to be sent at any time, so we need to try to authenticate
- // and then retry the command.
- if (reply.getCode() == NNTPReply.AUTHINFO_REQUIRED || reply.getCode() == NNTPReply.AUTHINFO_SIMPLE_REQUIRED) {
- debugOut("Authentication required received from server.");
- // authenticate with the server, if necessary
- processAuthentication(reply.getCode());
- // if we've safely authenticated, we can reissue the command and
- // process the response.
- sendLine(data);
- reply = getReply();
- }
- return reply;
- }
-
- /**
- * Send a command to the server, returning the first response line back as a
- * reply.
- *
- * @param data
- * The data to send.
- *
- * @return A reply object with the reply line.
- * @exception MessagingException
- */
- public NNTPReply sendAuthCommand(String data) throws MessagingException {
- sendLine(data);
- return getReply();
- }
-
- /**
- * Sends a message down the socket and terminates with the appropriate CRLF
- */
- public void sendLine(String data) throws MessagingException {
- if (socket == null || !socket.isConnected()) {
- throw new MessagingException("no connection");
- }
- try {
- outputStream.write(data.getBytes("ISO8859-1"));
- outputStream.write(CR);
- outputStream.write(LF);
- outputStream.flush();
- } catch (IOException e) {
- throw new MessagingException(e.toString());
- }
- }
-
- /**
- * Get a reply line for an NNTP command.
- *
- * @return An NNTP reply object from the stream.
- */
- public NNTPReply getReply() throws MessagingException {
- lastServerResponse = new NNTPReply(receiveLine());
- return lastServerResponse;
- }
-
- /**
- * Retrieve the last response received from the NNTP server.
- *
- * @return The raw response string (including the error code) returned from
- * the NNTP server.
- */
- public String getLastServerResponse() {
- if (lastServerResponse == null) {
- return "";
- }
- return lastServerResponse.getReply();
- }
-
- /**
- * Receives one line from the server. A line is a sequence of bytes
- * terminated by a CRLF
- *
- * @return the line from the server as String
- */
- public String receiveLine() throws MessagingException {
- if (socket == null || !socket.isConnected()) {
- throw new MessagingException("no connection");
- }
-
- try {
- String line = reader.readLine();
- if (line == null) {
- throw new MessagingException("Unexpected end of stream");
- }
- return line;
- } catch (IOException e) {
- throw new MessagingException("Error reading from server", e);
- }
- }
-
-
- /**
- * Authenticate with the server, if necessary (or possible).
- */
- protected void processAuthentication(int request) throws MessagingException {
- // we need to authenticate, but we don't have userid/password
- // information...fail this
- // immediately.
- if (username == null || password == null) {
- throw new MessagingException("Server requires user authentication");
- }
-
- if (request == NNTPReply.AUTHINFO_SIMPLE_REQUIRED) {
- processAuthinfoSimple();
- } else {
- if (!processSaslAuthentication()) {
- processAuthinfoUser();
- }
- }
- }
-
- /**
- * Process an AUTHINFO SIMPLE command. Not widely used, but if the server
- * asks for it, we can respond.
- *
- * @exception MessagingException
- */
- protected void processAuthinfoSimple() throws MessagingException {
- NNTPReply reply = sendAuthCommand("AUTHINFO SIMPLE");
- if (reply.getCode() != NNTPReply.AUTHINFO_CONTINUE) {
- throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
- }
- reply = sendAuthCommand(username + " " + password);
- if (reply.getCode() != NNTPReply.AUTHINFO_ACCEPTED) {
- throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
- }
- }
-
-
- /**
- * Process SASL-type authentication.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected boolean processSaslAuthentication() throws MessagingException {
- // only do this if permitted
- if (!authInfoSaslAllowed) {
- return false;
- }
- // if unable to get an appropriate authenticator, just fail it.
- ClientAuthenticator authenticator = getSaslAuthenticator();
- if (authenticator == null) {
- throw new MessagingException("Unable to obtain SASL authenticator");
- }
-
- // go process the login.
- return processLogin(authenticator);
- }
-
- /**
- * Attempt to retrieve a SASL authenticator for this
- * protocol.
- *
- * @return A SASL authenticator, or null if a suitable one
- * was not located.
- */
- protected ClientAuthenticator getSaslAuthenticator() {
- return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
- }
-
-
- /**
- * Process a login using the provided authenticator object.
- *
- * NB: This method is synchronized because we have a multi-step process going on
- * here. No other commands should be sent to the server until we complete.
- *
- * @return Returns true if the server support a SASL authentication mechanism and
- * accepted reponse challenges.
- * @exception MessagingException
- */
- protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
- debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
-
- // if the authenticator has some initial data, we compose a command
- // containing the initial data.
- if (authenticator.hasInitialResponse()) {
- StringBuffer command = new StringBuffer();
- // the auth command initiates the handshaking.
- command.append("AUTHINFO SASL ");
- // and tell the server which mechanism we're using.
- command.append(authenticator.getMechanismName());
- command.append(" ");
- // and append the response data
- try {
- command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
- } catch (UnsupportedEncodingException e) {
- }
- // send the command now
- sendLine(command.toString());
- }
- // we just send an auth command with the command type.
- else {
- StringBuffer command = new StringBuffer();
- // the auth command initiates the handshaking.
- command.append("AUTHINFO SASL");
- // and tell the server which mechanism we're using.
- command.append(authenticator.getMechanismName());
- // send the command now
- sendLine(command.toString());
- }
-
- // now process the challenge sequence. We get a 235 response back when
- // the server accepts the
- // authentication, and a 334 indicates we have an additional challenge.
- while (true) {
- // get the next line, and if it is an error response, return now.
- NNTPReply line = getReply();
-
- // if we get a completion return, we've passed muster, so give an
- // authentication response.
- if (line.getCode() == NNTPReply.AUTHINFO_ACCEPTED || line.getCode() == NNTPReply.AUTHINFO_ACCEPTED_FINAL) {
- debugOut("Successful SMTP authentication");
- return true;
- }
- // we have an additional challenge to process.
- else if (line.getCode() == NNTPReply.AUTHINFO_CHALLENGE) {
- // Does the authenticator think it is finished? We can't answer
- // an additional challenge,
- // so fail this.
- if (authenticator.isComplete()) {
- debugOut("Extra authentication challenge " + line);
- return false;
- }
-
- // we're passed back a challenge value, Base64 encoded.
- try {
- byte[] challenge = Base64.decode(line.getMessage().getBytes("ISO8859-1"));
-
- // have the authenticator evaluate and send back the encoded
- // response.
- sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII"));
- } catch (UnsupportedEncodingException e) {
- }
- }
- // completion or challenge are the only responses we know how to
- // handle. Anything else must
- // be a failure.
- else {
- debugOut("Authentication failure " + line);
- return false;
- }
- }
- }
-
-
- /**
- * Process an AUTHINFO USER command. Most common form of NNTP
- * authentication.
- *
- * @exception MessagingException
- */
- protected void processAuthinfoUser() throws MessagingException {
- // only do this if allowed by the server
- if (!authInfoUserAllowed) {
- return;
- }
- NNTPReply reply = sendAuthCommand("AUTHINFO USER " + username);
- // accepted without a password (uncommon, but allowed), we're done
- if (reply.getCode() == NNTPReply.AUTHINFO_ACCEPTED) {
- return;
- }
- // the only other non-error response is continue.
- if (reply.getCode() != NNTPReply.AUTHINFO_CONTINUE) {
- throw new MessagingException("Error authenticating with server using AUTHINFO USER: " + reply);
- }
- // now send the password. We expect an accepted response.
- reply = sendAuthCommand("AUTHINFO PASS " + password);
- if (reply.getCode() != NNTPReply.AUTHINFO_ACCEPTED) {
- throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
- }
- }
-
-
- /**
- * Indicate whether posting is allowed for a given server.
- *
- * @return True if the server allows posting, false if the server is
- * read-only.
- */
- public boolean isPostingAllowed() {
- return postingAllowed;
- }
-
- /**
- * Retrieve the welcome string sent back from the server.
- *
- * @return The server provided welcome string.
- */
- public String getWelcomeString() {
- return welcomeString;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java
deleted file mode 100644
index d631d72..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.transport.nntp;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.mail.MessagingException;
-
-/**
- * Util class to represent a reply from a NNTP server
- *
- * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
- */
-public class NNTPReply {
- // general server responses
- public static final int CAPABILITY_LIST = 101;
-
- public static final int POSTING_ALLOWED = 200;
-
- public static final int NO_POSTING_ALLOWED = 201;
-
- public static final int EXTENSIONS_SUPPORTED = 202;
-
- public static final int SERVICE_DISCONTINUED = 400;
-
- public static final int COMMAND_NOT_RECOGNIZED = 500;
-
- public static final int COMMAND_SYNTAX_ERROR = 501;
-
- public static final int PERMISSION_DENIED = 502;
-
- public static final int PROGRAM_FAULT = 503;
-
- // article responses
- public static final int ARTICLE_FOLLOWS = 220;
-
- public static final int HEAD_FOLLOWS = 221;
-
- public static final int BODY_FOLLOWS = 222;
-
- public static final int REQUEST_TEXT_SEPARATELY = 223;
-
- public static final int OVERVIEW_FOLLOWS = 224;
-
- public static final int NEW_ARTICLES_FOLLOWS = 230;
-
- public static final int NEW_GROUPS_FOLLOWS = 231;
-
- public static final int ARTICLE_TRANSFERRED = 235;
-
- public static final int NO_NEWSGROUP_SELECTED = 412;
-
- public static final int NO_ARTICLE_SELECTED = 420;
-
- public static final int NO_ARTICLE_NUMBER = 423;
-
- public static final int NO_ARTICLE_FOUND = 430;
-
- // group responses
- public static final int GROUP_SELECTED = 211;
-
- public static final int NO_SUCH_NEWSGROUP = 411;
-
- // post responses
- public static final int POSTED_OK = 240;
-
- public static final int SEND_ARTICLE = 340;
-
- public static final int POSTING_NOT_ALLOWED = 440;
-
- public static final int POSTING_FAILED = 441;
-
- // quit responses
- public static final int CLOSING_CONNECTION = 205;
-
- // authentication responses
- public static final int AUTHINFO_ACCEPTED = 250;
-
- public static final int AUTHINFO_ACCEPTED_FINAL = 251;
-
- public static final int AUTHINFO_CONTINUE = 350;
-
- public static final int AUTHINFO_CHALLENGE = 350;
-
- public static final int AUTHINFO_SIMPLE_REJECTED = 402;
-
- public static final int AUTHENTICATION_ACCEPTED = 281;
-
- public static final int MORE_AUTHENTICATION_REQUIRED = 381;
-
- public static final int AUTHINFO_REQUIRED = 480;
-
- public static final int AUTHINFO_SIMPLE_REQUIRED = 450;
-
- public static final int AUTHENTICATION_REJECTED = 482;
-
- // list active reponses
- public static final int LIST_FOLLOWS = 215;
-
- // The original reply string
- private final String reply;
-
- // returned message code
- private final int code;
-
- // the returned message text
- private final String message;
-
- // data associated with a long response command.
- private ArrayList data;
-
- NNTPReply(String s) throws MessagingException {
- // save the reply
- reply = s;
-
- // In a normal response, the first 3 must be the return code. However,
- // the response back from a QUIT command is frequently a null string.
- // Therefore, if the result is
- // too short, just default the code to -1 and use the entire text for
- // the message.
- if (s == null || s.length() < 3) {
- code = -1;
- message = s;
- return;
- }
-
- try {
- code = Integer.parseInt(s.substring(0, 3));
-
- // message should be separated by a space OR a continuation
- // character if this is a
- // multi-line response.
- if (s.length() > 4) {
- message = s.substring(4);
- } else {
- message = "";
- }
- } catch (NumberFormatException e) {
- throw new MessagingException("error in parsing reply code", e);
- }
- }
-
- /**
- * Retrieve data associated with a multi-line reponse from a server stream.
- *
- * @param in
- * The reader that's the source of the additional lines.
- *
- * @exception IOException
- */
- public void retrieveData(BufferedReader in) throws MessagingException {
- try {
- data = new ArrayList();
-
- String line = in.readLine();
- // read until the end of file or until we see the end of data
- // marker.
- while (line != null && !line.equals(".")) {
- // this line is not the terminator, but it may have been byte
- // stuffed. If it starts with
- // '.', throw away the leading one.
- if (line.startsWith(".")) {
- line = line.substring(1);
- }
-
- // just add the line to the list
- data.add(line);
- line = in.readLine();
- }
- } catch (IOException e) {
- throw new MessagingException("Error reading message reply", e);
- }
- }
-
- /**
- * Retrieve the long-command data from this response.
- *
- * @return The data list. Returns null if there is no associated data.
- */
- public List getData() {
- return data;
- }
-
- /**
- * Return the code value associated with the reply.
- *
- * @return The integer code associated with the reply.
- */
- public int getCode() {
- return this.code;
- }
-
- /**
- * Get the message text associated with the reply.
- *
- * @return The string value of the message from the reply.
- */
- public String getMessage() {
- return this.message;
- }
-
- /**
- * Retrieve the raw reply string for the reponse.
- *
- * @return The original reply string from the server.
- */
- public String getReply() {
- return reply;
- }
-
- /**
- * Indicates if reply is an error condition
- */
- boolean isError() {
- // error codes are all above 400
- return code >= 400;
- }
-
- public String toString() {
- return "CODE = " + getCode() + " : MSG = " + getMessage();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java
deleted file mode 100644
index e27a064..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.transport.nntp;
-
-import javax.mail.Session;
-import javax.mail.URLName;
-
-public class NNTPSSLTransport extends NNTPTransport {
- /**
- * @param session
- * @param name
- */
- public NNTPSSLTransport(Session session, URLName name) {
- super(session, name, "nntp-posts", DEFAULT_NNTP_SSL_PORT, true);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java
deleted file mode 100644
index 78d5408..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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.transport.nntp;
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-
-import javax.mail.Address;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.URLName;
-import javax.mail.event.TransportEvent;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.NewsAddress;
-
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-
-/**
- * Simple implementation of NNTP transport. Just does plain RFC977-ish delivery.
- * <p/> There is no way to indicate failure for a given recipient (it's possible
- * to have a recipient address rejected). The sun impl throws exceptions even if
- * others successful), but maybe we do a different way... <p/>
- *
- * @version $Rev: 673649 $ $Date: 2008-07-03 06:37:56 -0400 (Thu, 03 Jul 2008) $
- */
-public class NNTPTransport extends Transport {
- /**
- * property keys for protocol properties.
- */
- protected static final String NNTP_FROM = "from";
-
- 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;
-
- /**
- * Normal constructor for an NNTPTransport() object. This constructor is
- * used to build a transport instance for the "smtp" protocol.
- *
- * @param session
- * The attached session.
- * @param name
- * An optional URLName object containing target information.
- */
- public NNTPTransport(Session session, URLName name) {
- this(session, name, "nntp-post", 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 ("pop3"). 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 NNTPTransport(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);
- }
-
- /**
- * 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.
- return connection.protocolConnect(host, port, username, password);
- }
-
-
- /**
- * Send a message to multiple addressees.
- *
- * @param message
- * The message we're sending.
- * @param addresses
- * An array of addresses to send to.
- *
- * @exception MessagingException
- */
- public void sendMessage(Message message, Address[] addresses) throws MessagingException {
- if (!isConnected()) {
- throw new IllegalStateException("Not connected");
- }
-
- if (!connection.isPostingAllowed()) {
- throw new MessagingException("Posting disabled for host server");
- }
- // don't bother me w/ null messages or no addreses
- if (message == null) {
- throw new MessagingException("Null message");
- }
-
- // NNTP only handles instances of MimeMessage, not the more general
- // message case.
- if (!(message instanceof MimeMessage)) {
- throw new MessagingException("NNTP can only send MimeMessages");
- }
-
- // need to sort the from value out from a variety of sources.
- InternetAddress from = null;
-
- Address[] fromAddresses = message.getFrom();
-
- // If the message has a From address set, we just use that. Otherwise,
- // we set a From using
- // the property version, if available.
- if (fromAddresses == null || fromAddresses.length == 0) {
- // the from value can be set explicitly as a property
- String defaultFrom = props.getProperty(NNTP_FROM);
- if (defaultFrom == null) {
- message.setFrom(new InternetAddress(defaultFrom));
- }
- }
-
- // we must have a message list.
- if (addresses == null || addresses.length == 0) {
- throw new MessagingException("Null or empty address array");
- }
-
- boolean haveGroup = false;
-
- // enforce the requirement that all of the targets are NewsAddress
- // instances.
- for (int i = 0; i < addresses.length; i++) {
- if (!(addresses[i] instanceof NewsAddress)) {
- throw new MessagingException("Illegal NewsAddress " + addresses[i]);
- }
- }
-
- // event notifcation requires we send lists of successes and failures
- // broken down by category.
- // The categories are:
- //
- // 1) addresses successfully processed.
- // 2) addresses deemed valid, but had a processing failure that
- // prevented sending.
- // 3) addressed deemed invalid (basically all other processing
- // failures).
- ArrayList sentAddresses = new ArrayList();
- ArrayList unsentAddresses = new ArrayList();
- ArrayList invalidAddresses = new ArrayList();
-
- boolean sendFailure = false;
-
- // now try to post this message to the different news groups.
- for (int i = 0; i < addresses.length; i++) {
- try {
- // select the target news group
- NNTPReply reply = connection.selectGroup(((NewsAddress) addresses[i]).getNewsgroup());
-
- if (reply.getCode() != NNTPReply.GROUP_SELECTED) {
- invalidAddresses.add(addresses[i]);
- sendFailure = true;
- } else {
- // send data
- connection.sendPost(message);
- sentAddresses.add(addresses[i]);
- }
- } catch (MessagingException e) {
- unsentAddresses.add(addresses[i]);
- sendFailure = true;
- }
- }
-
- // create our lists for notification and exception reporting from this
- // point on.
- Address[] sent = (Address[]) sentAddresses.toArray(new Address[0]);
- Address[] unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
- Address[] invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
-
- if (sendFailure) {
- // did we deliver anything at all?
- if (sent.length == 0) {
- // notify of the error.
- notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
- } else {
- // notify that we delivered at least part of this
- notifyTransportListeners(TransportEvent.MESSAGE_PARTIALLY_DELIVERED, sent, unsent, invalid, message);
- }
-
- throw new MessagingException("Error posting NNTP message");
- }
-
- // notify our listeners of successful delivery.
- notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, sent, unsent, invalid, message);
- }
-
- /**
- * Close the connection. On completion, we'll be disconnected from the
- * server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // This is done to ensure proper event notification.
- super.close();
- // NB: We reuse the connection if asked to reconnect
- connection.close();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java
deleted file mode 100644
index 5de6e5a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.transport.nntp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-
-/**
- * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
- */
-public class StringListInputStream extends InputStream {
- // the list of lines we're reading from
- protected List lines;
-
- // the next line to process.
- protected int nextLine = 0;
-
- // current buffer of bytes to read from
- byte[] buffer;
-
- // current offset within the buffer;
- int offset;
-
- // indicator that we've left off at a split between the CR and LF of a line
- // break.
- boolean atLineBreak = false;
-
- public StringListInputStream(List lines) throws IOException {
- this.lines = lines;
- nextLine = 0;
- buffer = null;
- offset = 0;
- atLineBreak = false;
-
- // if we have at least one line in the list, get the bytes now.
- if (lines.size() > 0) {
- nextBuffer();
- }
- }
-
- /**
- * Just override the single byte read version, which handles all of the
- * lineend markers correctly.
- *
- * @return The next byte from the stream or -1 if we've hit the EOF.
- */
- public int read() throws IOException {
- // leave off at the split between a line?
- if (atLineBreak) {
- // flip this off and return the second line end character. Also step
- // to the next line.
- atLineBreak = false;
- nextBuffer();
- return '\n';
- }
- // gone past the end? Got an EOF
- if (buffer == null) {
- return -1;
- }
-
- // reach the end of the line?
- if (offset >= buffer.length) {
- // we're now working on a virtual linebreak
- atLineBreak = true;
- return '\r';
- }
- // just return the next byte
- return buffer[offset++];
-
- }
-
- /**
- * Step to the next buffer of string data.
- *
- * @exception IOException
- */
- protected void nextBuffer() throws IOException {
- // give an eof check.
- if (nextLine >= lines.size()) {
- buffer = null;
- } else {
- try {
- String next = (String) lines.get(nextLine++);
- buffer = next.getBytes("US-ASCII");
-
- } catch (UnsupportedEncodingException e) {
- throw new IOException("Invalid string encoding");
- }
- }
-
- offset = 0;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java
deleted file mode 100644
index 86652b2..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.transport.smtp;
-
-/**
- * Exception for when a SMTP reply string has a problem
- *
- * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
- */
-class MalformedSMTPReplyException extends Exception {
- MalformedSMTPReplyException() {
- super();
- }
-
- MalformedSMTPReplyException(String msg) {
- super(msg);
- }
-
- MalformedSMTPReplyException(String msg, Exception t) {
- super(msg, t);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java
deleted file mode 100644
index bfd2699..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-
-public class SMTPAddressFailedException extends MessagingException {
- // the failing address
- InternetAddress addr;
-
- // the failing command
- protected String cmd;
-
- // the error code for the failure
- protected int rc;
-
- /**
- * Constructor for an SMTPAddressFailingException.
- *
- * @param addr
- * The failing address.
- * @param cmd
- * The failing command string.
- * @param rc
- * The error code for the command.
- * @param err
- * An error message for the exception.
- */
- SMTPAddressFailedException(InternetAddress addr, java.lang.String cmd, int rc, java.lang.String err) {
- super(err);
- this.cmd = cmd;
- this.rc = rc;
- this.addr = addr;
- }
-
- /**
- * Get the failing command string for the exception.
- *
- * @return The string value of the failing command.
- */
- public String getCommand() {
- return cmd;
- }
-
- /**
- * The failing command return code.
- *
- * @return The failure return code.
- */
- public int getReturnCode() {
- return rc;
- }
-
- /**
- * Retrieve the internet address associated with this exception.
- *
- * @return The provided InternetAddress object.
- */
- public InternetAddress getAddress() {
- return addr;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java
deleted file mode 100644
index 990d656..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-
-public class SMTPAddressSucceededException extends MessagingException {
- // the succeeding address
- InternetAddress addr;
-
- // the failing command
- protected String cmd;
-
- // the error code for the failure
- protected int rc;
-
- /**
- * Constructor for an SMTPAddressSucceededException.
- *
- * @param addr
- * The succeeding address.
- * @param cmd
- * The succeeding command string.
- * @param rc
- * The error code for the command.
- * @param err
- * An error message for the exception.
- */
- SMTPAddressSucceededException(InternetAddress addr, java.lang.String cmd, int rc, java.lang.String err) {
- super(err);
- this.cmd = cmd;
- this.rc = rc;
- this.addr = addr;
- }
-
- /**
- * Get the failing command string for the exception.
- *
- * @return The string value of the failing command.
- */
- public String getCommand() {
- return cmd;
- }
-
- /**
- * The failing command return code.
- *
- * @return The failure return code.
- */
- public int getReturnCode() {
- return rc;
- }
-
- /**
- * Retrieve the internet address associated with this exception.
- *
- * @return The provided InternetAddress object.
- */
- public InternetAddress getAddress() {
- return addr;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
deleted file mode 100644
index ea84556..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.mail.Address;
-import javax.mail.AuthenticationFailedException;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import javax.mail.internet.MimePart;
-import javax.mail.Session;
-
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
-import org.apache.geronimo.javamail.util.CountingOutputStream;
-import org.apache.geronimo.javamail.util.MailConnection;
-import org.apache.geronimo.javamail.util.MIMEOutputStream;
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.geronimo.mail.util.XText;
-
-/**
- * Simple implementation of SMTP transport. Just does plain RFC977-ish delivery.
- *
- * @version $Rev: 1741822 $ $Date: 2016-04-30 18:04:39 -0400 (Sat, 30 Apr 2016) $
- */
-public class SMTPConnection extends MailConnection {
- protected static final String MAIL_SMTP_QUITWAIT = "quitwait";
- protected static final String MAIL_SMTP_EXTENSION = "mailextension";
- protected static final String MAIL_SMTP_EHLO = "ehlo";
- protected static final String MAIL_SMTP_ALLOW8BITMIME = "allow8bitmime";
- protected static final String MAIL_SMTP_REPORT_SUCCESS = "reportsuccess";
- protected static final String MAIL_SMTP_STARTTLS_ENABLE = "starttls.enable";
- protected static final String MAIL_SMTP_STARTTLS_REQUIRED = "starttls.required";
- protected static final String MAIL_SMTP_AUTH = "auth";
- protected static final String MAIL_SMTP_FROM = "from";
- protected static final String MAIL_SMTP_DSN_RET = "dsn.ret";
- protected static final String MAIL_SMTP_SUBMITTER = "submitter";
-
- /**
- * property keys for protocol properties.
- */
- protected static final int DEFAULT_NNTP_PORT = 119;
-
- // the last response line received from the server.
- protected SMTPReply lastServerResponse = null;
-
- // do we report success after completion of each mail send.
- protected boolean reportSuccess;
- // does the server support transport level security?
- protected boolean serverTLS = false;
- // is TLS enabled on our part?
- protected boolean useTLS = false;
- // is TLS required on our part?
- protected boolean requireTLS = false;
- // should we use 8BITMIME encoding if supported by the server?
- protected boolean use8bit = false;
-
- /**
- * Normal constructor for an SMTPConnection() object.
- *
- * @param props The property bundle for this protocol instance.
- */
- public SMTPConnection(ProtocolProperties props) {
- super(props);
-
- // check to see if we need to throw an exception after a send operation.
- reportSuccess = props.getBooleanProperty(MAIL_SMTP_REPORT_SUCCESS, false);
- // and also check for TLS enablement.
- useTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_ENABLE, false);
- // and also check if TLS is required.
- requireTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_REQUIRED, false);
- // and also check for 8bitmime support
- use8bit = props.getBooleanProperty(MAIL_SMTP_ALLOW8BITMIME, false);
- }
-
-
- /**
- * Connect to the server and do the initial handshaking.
- *
- * @param host The target host name.
- * @param port The target port
- * @param username The connection username (can be null)
- * @param password The authentication password (can be null).
- *
- * @return true if we were able to obtain a connection and
- * authenticate.
- * @exception MessagingException
- */
- public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
-
- // now check to see if we need to authenticate. If we need this, then
- // we must have a username and
- // password specified. Failing this may result in a user prompt to
- // collect the information.
- boolean mustAuthenticate = props.getBooleanProperty(MAIL_SMTP_AUTH, false);
-
- // if we need to authenticate, and we don't have both a userid and
- // password, then we fail this
- // immediately. The Service.connect() method will try to obtain the user
- // information and retry the
- // connection one time.
- if (mustAuthenticate && (username == null || password == null)) {
- debugOut("Failing connection for missing authentication information");
- return false;
- }
-
- super.protocolConnect(host, port, username, password);
-
- try {
- // create socket and connect to server.
- getConnection();
-
- // receive welcoming message
- if (!getWelcome()) {
- debugOut("Error getting welcome message");
- throw new MessagingException("Error in getting welcome msg");
- }
-
- // say hello
- if (!sendHandshake()) {
- debugOut("Error getting processing handshake message");
- throw new MessagingException("Error in saying EHLO to server");
- }
-
- // authenticate with the server, if necessary
- if (!processAuthentication()) {
- debugOut("User authentication failure");
- throw new AuthenticationFailedException("Error authenticating with server");
- }
- } catch (IOException e) {
- debugOut("I/O exception establishing connection", e);
- throw new MessagingException("Connection error", e);
- }
- debugOut("Successful connection");
- return true;
- }
-
-
- /**
- * Close the connection. On completion, we'll be disconnected from the
- * server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // if we're already closed, get outta here.
- if (socket == null) {
- return;
- }
- try {
- // say goodbye
- sendQuit();
- } finally {
- // and close up the connection. We do this in a finally block to
- // make sure the connection
- // is shut down even if quit gets an error.
- closeServerConnection();
- }
- }
-
- public String toString() {
- return "SMTPConnection host: " + serverHost + " port: " + serverPort;
- }
-
-
- /**
- * Set the sender for this mail.
- *
- * @param message
- * The message we're sending.
- *
- * @return True if the command was accepted, false otherwise.
- * @exception MessagingException
- */
- protected boolean sendMailFrom(Message message) throws MessagingException {
-
- // need to sort the from value out from a variety of sources.
- String from = null;
-
- // first potential source is from the message itself, if it's an
- // instance of SMTPMessage.
- if (message instanceof SMTPMessage) {
- from = ((SMTPMessage) message).getEnvelopeFrom();
- }
-
- // if not available from the message, check the protocol property next
- if (from == null || from.length() == 0) {
- // the from value can be set explicitly as a property
- from = props.getProperty(MAIL_SMTP_FROM);
- }
-
- // if not there, see if we have something in the message header.
- if (from == null || from.length() == 0) {
- Address[] fromAddresses = message.getFrom();
-
- // if we have some addresses in the header, then take the first one
- // as our From: address
- if (fromAddresses != null && fromAddresses.length > 0) {
- from = ((InternetAddress) fromAddresses[0]).getAddress();
- }
- // get what the InternetAddress class believes to be the local
- // address.
- else {
- InternetAddress local = InternetAddress.getLocalAddress(session);
- if (local != null) {
- from = local.getAddress();
- }
- }
- }
-
- if (from == null || from.length() == 0) {
- throw new MessagingException("no FROM address");
- }
-
- StringBuffer command = new StringBuffer();
-
- // start building up the command
- command.append("MAIL FROM: ");
- command.append(fixEmailAddress(from));
-
- // If the server supports the 8BITMIME extension, we might need to change the
- // transfer encoding for the content to allow for direct transmission of the
- // 8-bit codes.
- if (supportsExtension("8BITMIME")) {
- // we only do this if the capability was enabled via a property option or
- // by explicitly setting the property on the message object.
- if (use8bit || (message instanceof SMTPMessage && ((SMTPMessage)message).getAllow8bitMIME())) {
- // make sure we add the BODY= option to the FROM message.
- command.append(" BODY=8BITMIME");
-
- // go check the content and see if the can convert the transfer encoding to
- // allow direct 8-bit transmission.
- if (convertTransferEncoding((MimeMessage)message)) {
- // if we changed the encoding on any of the parts, then we
- // need to save the message again
- message.saveChanges();
- }
- }
- }
-
- // some servers ask for a size estimate on the initial send
- if (supportsExtension("SIZE")) {
- int estimate = getSizeEstimate(message);
- if (estimate > 0) {
- command.append(" SIZE=" + estimate);
- }
- }
-
- // does this server support Delivery Status Notification? Then we may
- // need to add some extra to the command.
- if (supportsExtension("DSN")) {
- String returnNotification = null;
-
- // the return notification stuff might be set as value on the
- // message object itself.
- if (message instanceof SMTPMessage) {
- // we need to convert the option into a string value.
- switch (((SMTPMessage) message).getReturnOption()) {
- case SMTPMessage.RETURN_FULL:
- returnNotification = "FULL";
- break;
-
- case SMTPMessage.RETURN_HDRS:
- returnNotification = "HDRS";
- break;
- }
- }
-
- // if not obtained from the message object, it can also be set as a
- // property.
- if (returnNotification == null) {
- // the DSN value is set by yet another property.
- returnNotification = props.getProperty(MAIL_SMTP_DSN_RET);
- }
-
- // if we have a target, add the notification stuff to our FROM
- // command.
- if (returnNotification != null) {
- command.append(" RET=");
- command.append(returnNotification);
- }
- }
-
- // if this server supports AUTH and we have submitter information, then
- // we also add the
- // "AUTH=" keyword to the MAIL FROM command (see RFC 2554).
-
- if (supportsExtension("AUTH")) {
- String submitter = null;
-
- // another option that can be specified on the message object.
- if (message instanceof SMTPMessage) {
- submitter = ((SMTPMessage) message).getSubmitter();
- }
- // if not part of the object, try for a propery version.
- if (submitter == null) {
- // we only send the extra keyword is a submitter is specified.
- submitter = props.getProperty(MAIL_SMTP_SUBMITTER);
- }
- // we have one...add the keyword, plus the submitter info in xtext
- // format (defined by RFC 1891).
- if (submitter != null) {
- command.append(" AUTH=");
- try {
- // add this encoded
- command.append(new String(XText.encode(submitter.getBytes("US-ASCII")), "US-ASCII"));
- } catch (UnsupportedEncodingException e) {
- throw new MessagingException("Invalid submitter value " + submitter);
- }
- }
- }
-
- String extension = null;
-
- // now see if we need to add any additional extension info to this
- // command. The extension is not
- // checked for validity. That's the reponsibility of the caller.
- if (message instanceof SMTPMessage) {
- extension = ((SMTPMessage) message).getMailExtension();
- }
- // this can come either from the object or from a set property.
- if (extension == null) {
- extension = props.getProperty(MAIL_SMTP_EXTENSION);
- }
-
- // have something real to add?
- if (extension != null && extension.length() != 0) {
- // tack this on the end with a blank delimiter.
- command.append(' ');
- command.append(extension);
- }
-
- // and finally send the command
- SMTPReply line = sendCommand(command.toString());
-
- // 250 response indicates success.
- return line.getCode() == SMTPReply.COMMAND_ACCEPTED;
- }
-
-
- /**
- * Check to see if a MIME body part can have its
- * encoding changed from quoted-printable or base64
- * encoding to 8bit encoding. In order for this
- * to work, it must follow the rules laid out in
- * RFC 2045. To qualify for conversion, the text
- * must be:
- *
- * 1) No more than 998 bytes long
- * 2) All lines are terminated with CRLF sequences
- * 3) CR and LF characters only occur in properly
- * formed line separators
- * 4) No null characters are allowed.
- *
- * The conversion will only be applied to text
- * elements, and this will recurse through the
- * different elements of MultiPart content.
- *
- * @param bodyPart The bodyPart to convert. Initially, this will be
- * the message itself.
- *
- * @return true if any conversion was performed, false if
- * nothing was converted.
- */
- protected boolean convertTransferEncoding(MimePart bodyPart)
- {
- boolean converted = false;
- try {
- // if this is a multipart element, apply the conversion rules
- // to each of the parts.
- if (bodyPart.isMimeType("multipart/")) {
- MimeMultipart parts = (MimeMultipart)bodyPart.getContent();
- for (int i = 0; i < parts.getCount(); i++) {
- // convert each body part, and accumulate the conversion result
- converted = converted && convertTransferEncoding((MimePart)parts.getBodyPart(i));
- }
- }
- else {
- // we only do this if the encoding is quoted-printable or base64
- String encoding = bodyPart.getEncoding();
- if (encoding != null) {
- encoding = encoding.toLowerCase();
- if (encoding.equals("quoted-printable") || encoding.equals("base64")) {
- // this requires encoding. Read the actual content to see if
- // it conforms to the 8bit encoding rules.
- if (isValid8bit(bodyPart.getInputStream())) {
- // There's a huge hidden gotcha lurking under the covers here.
- // If the content just exists as an encoded byte array, then just
- // switching the transfer encoding will mess things up because the
- // already encoded data gets transmitted in encoded form, but with
- // and 8bit encoding style. As a result, it doesn't get unencoded on
- // the receiving end. This is a nasty problem to debug.
- //
- // The solution is to get the content as it's object type, set it back
- // on the the message in raw form. Requesting the content will apply the
- // current transfer encoding value to the data. Once we have set the
- // content value back, we can reset the transfer encoding.
- bodyPart.setContent(bodyPart.getContent(), bodyPart.getContentType());
-
- // it's valid, so change the transfer encoding to just
- // pass the data through.
- bodyPart.setHeader("Content-Transfer-Encoding", "8bit");
- converted = true; // we've changed something
- }
- }
- }
- }
- } catch (MessagingException e) {
- } catch (IOException e) {
- }
- return converted;
- }
-
-
- /**
- * Get the server's welcome blob from the wire....
- */
- protected boolean getWelcome() throws MessagingException {
- SMTPReply line = getReply();
- // just return the error status...we don't care about any of the
- // response information
- return !line.isError();
- }
-
-
- /**
- * Get an estimate of the transmission size for this
- * message. This size is the complete message as it is
- * encoded and transmitted on the DATA command, not counting
- * the terminating ".CRLF".
- *
- * @param msg The message we're sending.
- *
- * @return The count of bytes, if it can be calculated.
- */
- protected int getSizeEstimate(Message msg) {
- // now the data... I could look at the type, but
- try {
- CountingOutputStream outputStream = new CountingOutputStream();
-
- // the data content has two requirements we need to meet by
- // filtering the
- // output stream. Requirement 1 is to conicalize any line breaks.
- // All line
- // breaks will be transformed into properly formed CRLF sequences.
- //
- // Requirement 2 is to perform byte-stuff for any line that begins
- // with a "."
- // so that data is not confused with the end-of-data marker (a
- // "\r\n.\r\n" sequence.
- //
- // The MIME output stream performs those two functions on behalf of
- // the content
- // writer.
- MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
-
- msg.writeTo(mimeOut);
-
- // now to finish, we make sure there's a line break at the end.
- mimeOut.forceTerminatingLineBreak();
- // and flush the data to send it along
- mimeOut.flush();
-
- return outputStream.getCount();
- } catch (IOException e) {
- return 0; // can't get an estimate
- } catch (MessagingException e) {
- return 0; // can't get an estimate
- }
- }
-
-
- /**
- * Sends the data in the message down the socket. This presumes the server
- * is in the right place and ready for getting the DATA message and the data
- * right place in the sequence
- */
- protected void sendData(MimeMessage msg) throws MessagingException {
-
- // send the DATA command
- SMTPReply line = sendCommand("DATA");
-
- if (line.isError()) {
- throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
- }
-
- // now the data... I could look at the type, but
- try {
- // the data content has two requirements we need to meet by
- // filtering the
- // output stream. Requirement 1 is to conicalize any line breaks.
- // All line
- // breaks will be transformed into properly formed CRLF sequences.
- //
- // Requirement 2 is to perform byte-stuff for any line that begins
- // with a "."
- // so that data is not confused with the end-of-data marker (a
- // "\r\n.\r\n" sequence.
- //
- // The MIME output stream performs those two functions on behalf of
- // the content
- // writer.
- MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
-
- msg.writeTo(mimeOut, new String[] {"Bcc", "Content-Length"});
-
- // now to finish, we send a CRLF sequence, followed by a ".".
- mimeOut.writeSMTPTerminator();
- // and flush the data to send it along
- mimeOut.flush();
- this.outputStream.flush(); // most of the time MIMEOutputStream#flush does nothing so ensure we actually flush the data
- } catch (IOException e) {
- throw new MessagingException(e.toString());
- } catch (MessagingException e) {
- throw new MessagingException(e.toString());
- }
-
- // use a longer time out here to give the server time to process the
- // data.
- line = getReply(TIMEOUT * 2);
-
- if (line.isError()) {
- throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
- }
- }
-
- /**
- * Sends the QUIT message and receieves the response
- */
- protected void sendQuit() throws MessagingException {
- // there's yet another property that controls whether we should wait for
- // a reply for a QUIT command. If true, we're suppposed to wait for a response
- // from the QUIT command. Otherwise we just send the QUIT and bail. The default
- // is "false"
- if (props.getBooleanProperty(MAIL_SMTP_QUITWAIT, true)) {
- // handle as a real command...we're going to ignore the response.
- sendCommand("QUIT");
- } else {
- // just send the command without waiting for a response.
- sendLine("QUIT");
- }
- }
-
- /**
- * Sets a receiver address for the current message
- *
- * @param addr
- * The target address.
- * @param dsn
- * An optional DSN option appended to the RCPT TO command.
- *
- * @return The status for this particular send operation.
- * @exception MessagingException
- */
- public SendStatus sendRcptTo(InternetAddress addr, String dsn) throws MessagingException {
- // compose the command using the fixed up email address. Normally, this
- // involves adding
- // "<" and ">" around the address.
-
- StringBuffer command = new StringBuffer();
-
- // compose the first part of the command
- command.append("RCPT TO: ");
- command.append(fixEmailAddress(addr.getAddress()));
-
- // if we have DSN information, append it to the command.
- if (dsn != null) {
- command.append(" NOTIFY=");
- command.append(dsn);
- }
-
- // get a string version of this command.
- String commandString = command.toString();
-
- SMTPReply line = sendCommand(commandString);
-
- switch (line.getCode()) {
- // these two are both successful transmissions
- case SMTPReply.COMMAND_ACCEPTED:
- case SMTPReply.ADDRESS_NOT_LOCAL:
- // we get out of here with the status information.
- return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);
-
- // these are considered invalid address errors
- case SMTPReply.PARAMETER_SYNTAX_ERROR:
- case SMTPReply.INVALID_COMMAND_SEQUENCE:
- case SMTPReply.MAILBOX_NOT_FOUND:
- case SMTPReply.INVALID_MAILBOX:
- case SMTPReply.USER_NOT_LOCAL:
- // we get out of here with the status information.
- return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);
-
- // the command was valid, but something went wrong in the server.
- case SMTPReply.SERVICE_NOT_AVAILABLE:
- case SMTPReply.MAILBOX_BUSY:
- case SMTPReply.PROCESSING_ERROR:
- case SMTPReply.INSUFFICIENT_STORAGE:
- case SMTPReply.MAILBOX_FULL:
- // we get out of here with the status information.
- return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);
-
- // everything else is considered really bad...
- default:
- // we get out of here with the status information.
- return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
- }
- }
-
- /**
- * Send a command to the server, returning the first response line back as a
- * reply.
- *
- * @param data
- * The data to send.
- *
- * @return A reply object with the reply line.
- * @exception MessagingException
- */
- protected SMTPReply sendCommand(String data) throws MessagingException {
- sendLine(data);
- return getReply();
- }
-
- /**
- * Sends a message down the socket and terminates with the appropriate CRLF
- */
- protected void sendLine(String data) throws MessagingException {
- if (socket == null || !socket.isConnected()) {
- throw new MessagingException("no connection");
- }
- try { // don't write it in multiple times, ie build the data + "\r\n" string in memory to not get surprises on servers read() side
- outputStream.write((data + "\r\n").getBytes("ISO8859-1"));
- outputStream.flush();
- } catch (IOException e) {
- throw new MessagingException(e.toString());
- }
- }
-
- /**
- * Receives one line from the server. A line is a sequence of bytes
- * terminated by a CRLF
- *
- * @return the line from the server as String
- */
- protected String receiveLine() throws MessagingException {
- return receiveLine(TIMEOUT);
- }
-
- protected SMTPReply getReply() throws MessagingException {
- return getReply(TIMEOUT);
- }
-
- /**
- * Get a reply line for an SMTP command.
- *
- * @return An SMTP reply object from the stream.
- */
- protected SMTPReply getReply(int timeout) throws MessagingException {
- try {
- lastServerResponse = new SMTPReply(receiveLine(timeout));
- // if the first line we receive is a continuation, continue
- // reading lines until we reach the non-continued one.
- while (lastServerResponse.isContinued()) {
- lastServerResponse.addLine(receiveLine(timeout));
- }
- } catch (MalformedSMTPReplyException e) {
- throw new MessagingException(e.toString());
- }
- return lastServerResponse;
- }
-
- /**
- * Retrieve the last response received from the SMTP server.
- *
- * @return The raw response string (including the error code) returned from
- * the SMTP server.
- */
- public SMTPReply getLastServerResponse() {
- return lastServerResponse;
- }
-
-
- /**
- * Receives one line from the server. A line is a sequence of bytes
- * terminated by a CRLF
- *
- * @return the line from the server as String
- */
- protected String receiveLine(int delayMillis) throws MessagingException {
- if (socket == null || !socket.isConnected()) {
- throw new MessagingException("no connection");
- }
-
- int timeout = 0;
-
- try {
- // for now, read byte for byte, looking for a CRLF
- timeout = socket.getSoTimeout();
-
- socket.setSoTimeout(delayMillis);
-
- StringBuffer buff = new StringBuffer();
-
- int c;
- boolean crFound = false, lfFound = false;
-
- while ((c = inputStream.read()) != -1 && crFound == false && lfFound == false) {
- // we're looking for a CRLF sequence, so mark each one as seen.
- // Any other
- // character gets appended to the end of the buffer.
- if (c == CR) {
- crFound = true;
- } else if (c == LF) {
- lfFound = true;
- } else {
- buff.append((char) c);
- }
- }
-
- String line = buff.toString();
- return line;
-
- } catch (SocketException e) {
- throw new MessagingException(e.toString());
- } catch (IOException e) {
- throw new MessagingException(e.toString());
- } finally {
- try {
- socket.setSoTimeout(timeout);
- } catch (SocketException e) {
- // ignore - was just trying to do the decent thing...
- }
- }
- }
-
- /**
- * Convert an InternetAddress into a form sendable on an SMTP mail command.
- * InternetAddress.getAddress() generally returns just the address portion
- * of the full address, minus route address markers. We need to ensure we
- * have an address with '<' and '>' delimiters.
- *
- * @param mail
- * The mail address returned from InternetAddress.getAddress().
- *
- * @return A string formatted for sending.
- */
- protected String fixEmailAddress(String mail) {
- if (mail.charAt(0) == '<') {
- return mail;
- }
- return "<" + mail + ">";
- }
-
- /**
- * Start the handshake process with the server, including setting up and
- * TLS-level work. At the completion of this task, we should be ready to
- * authenticate with the server, if needed.
- */
- protected boolean sendHandshake() throws MessagingException {
- // check to see what sort of initial handshake we need to make.
- boolean useEhlo = props.getBooleanProperty(MAIL_SMTP_EHLO, true);
- // if we're to use Ehlo, send it and then fall back to just a HELO
- // message if it fails.
- if (useEhlo) {
- if (!sendEhlo()) {
- sendHelo();
- }
- } else {
- // send the initial hello response.
- sendHelo();
- }
-
- if (useTLS || requireTLS) {
- // if we've been told to use TLS
- // if its not required and server does not support it we establish an unsecure connection
- //see GERONIMO-5873 and GERONIMO-5430
- if (requireTLS && !serverTLS) {
- // if we've been told to use TLS, and this server doesn't support
- // it, then this is a failure
- throw new MessagingException("Server doesn't support required transport level security");
- } else if (serverTLS){
- // if the server supports TLS, then use it for the connection.
- // on our connection.
- getConnectedTLSSocket();
-
- // some servers (gmail is one that I know of) only send a STARTTLS
- // extension message on the
- // first EHLO command. Now that we have the TLS handshaking
- // established, we need to send a
- // second EHLO message to retrieve the AUTH records from the server.
- if (!sendEhlo()) {
- throw new MessagingException("Failure sending EHLO command to SMTP server");
- }
- } else {
- if (debug) {
- debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
- }
- }
- }
-
- // this worked.
- return true;
- }
-
-
- /**
- * Switch the connection to using TLS level security, switching to an SSL
- * socket.
- */
- protected void getConnectedTLSSocket() throws MessagingException {
- debugOut("Attempting to negotiate STARTTLS with server " + serverHost);
- // tell the server of our intention to start a TLS session
- SMTPReply line = sendCommand("STARTTLS");
-
- if (line.getCode() != SMTPReply.SERVICE_READY) {
- debugOut("STARTTLS command rejected by SMTP server " + serverHost);
- throw new MessagingException("Unable to make TLS server connection");
- }
-
- debugOut("STARTTLS command accepted");
-
- // the base class handles the socket switch details
- super.getConnectedTLSSocket();
- }
-
-
- /**
- * Send the EHLO command to the SMTP server.
- *
- * @return True if the command was accepted ok, false for any errors.
- * @exception SMTPTransportException
- * @exception MalformedSMTPReplyException
- * @exception MessagingException
- */
- protected boolean sendEhlo() throws MessagingException {
- sendLine("EHLO " + getLocalHost());
-
- SMTPReply reply = getReply();
-
- // we get a 250 code back. The first line is just a greeting, and
- // extensions are identifed on
- // continuations. If this fails, then we'll try once more with HELO to
- // establish bona fides.
- if (reply.getCode() != SMTPReply.COMMAND_ACCEPTED) {
- return false;
- }
-
- // create a fresh mapping and authentications table
- capabilities = new HashMap();
- authentications = new ArrayList();
-
- List lines = reply.getLines();
- // process all of the continuation lines
- for (int i = 1; i < lines.size(); i++) {
- // go process the extention
- processExtension((String)lines.get(i));
- }
- return true;
- }
-
- /**
- * Send the HELO command to the SMTP server.
- *
- * @exception MessagingException
- */
- protected void sendHelo() throws MessagingException {
- // create a fresh mapping and authentications table
- // these will be empty, but it will prevent NPEs
- capabilities = new HashMap();
- authentications = new ArrayList();
-
- sendLine("HELO " + getLocalHost());
-
- SMTPReply line = getReply();
-
- // we get a 250 code back. The first line is just a greeting, and
- // extensions are identifed on
- // continuations. If this fails, then we'll try once more with HELO to
- // establish bona fides.
- if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
- throw new MessagingException("Failure sending HELO command to SMTP server");
- }
- }
-
- /**
- * Return the current startTLS property.
- *
- * @return The current startTLS property.
- */
- public boolean getStartTLS() {
- return useTLS;
- }
-
-
- /**
- * Set a new value for the startTLS property.
- *
- * @param start
- * The new setting.
- */
- public void setStartTLS(boolean start) {
- useTLS = start;
- }
-
-
- /**
- * Return the current requireTLS property.
- *
- * @return The current requireTLS property.
- */
- public boolean getRequireTLS() {
- return requireTLS;
- }
-
-
- /**
- * Set a new value for the requireTLS property.
- *
- * @param require
- * The new setting.
- */
- public void setRequireTLS(boolean require) {
- requireTLS = require;
- }
-
-
- /**
- * Process an extension string passed back as the EHLP response.
- *
- * @param extension
- * The string value of the extension (which will be of the form
- * "NAME arguments").
- */
- protected void processExtension(String extension) {
- debugOut("Processing extension " + extension);
- String extensionName = extension.toUpperCase();
- String argument = "";
-
- int delimiter = extension.indexOf(' ');
- // if we have a keyword with arguments, parse them out and add to the
- // argument map.
- if (delimiter != -1) {
- extensionName = extension.substring(0, delimiter).toUpperCase();
- argument = extension.substring(delimiter + 1);
- }
-
- // add this to the map so it can be tested later.
- capabilities.put(extensionName, argument);
-
- // process a few special ones that don't require extra parsing.
- // AUTH and AUTH=LOGIN are handled the same
- if (extensionName.equals("AUTH")) {
- // if we don't have an argument on AUTH, this means LOGIN.
- if (argument == null) {
- authentications.add("LOGIN");
- } else {
- // The security mechanisms are blank delimited tokens.
- StringTokenizer tokenizer = new StringTokenizer(argument);
-
- while (tokenizer.hasMoreTokens()) {
- String mechanism = tokenizer.nextToken().toUpperCase();
- authentications.add(mechanism);
- }
- }
- }
- // special case for some older servers.
- else if (extensionName.equals("AUTH=LOGIN")) {
- authentications.add("LOGIN");
- }
- // does this support transport level security?
- else if (extensionName.equals("STARTTLS")) {
- // flag this for later
- serverTLS = true;
- }
- }
-
-
- /**
- * Retrieve any argument information associated with a extension reported
- * back by the server on the EHLO command.
- *
- * @param name
- * The name of the target server extension.
- *
- * @return Any argument passed on a server extension. Returns null if the
- * extension did not include an argument or the extension was not
- * supported.
- */
- public String extensionParameter(String name) {
- if (capabilities != null) {
- return (String)capabilities.get(name);
- }
- return null;
- }
-
-
- /**
- * Tests whether the target server supports a named extension.
- *
- * @param name
- * The target extension name.
- *
- * @return true if the target server reported on the EHLO command that is
- * supports the targer server, false if the extension was not
- * supported.
- */
- public boolean supportsExtension(String name) {
- // this only returns null if we don't have this extension
- return extensionParameter(name) != null;
- }
-
-
- /**
- * Authenticate with the server, if necessary (or possible).
- *
- * @return true if we are ok to proceed, false for an authentication
- * failures.
- */
- protected boolean processAuthentication() throws MessagingException {
- // no authentication defined?
- if (!props.getBooleanProperty(MAIL_SMTP_AUTH, false)) {
- return true;
- }
-
- // we need to authenticate, but we don't have userid/password
- // information...fail this
- // immediately.
- if (username == null || password == null) {
- return false;
- }
-
- // if unable to get an appropriate authenticator, just fail it.
- ClientAuthenticator authenticator = getSaslAuthenticator();
- if (authenticator == null) {
- throw new MessagingException("Unable to obtain SASL authenticator");
- }
-
-
- if (debug) {
- debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
- }
-
- // if the authenticator has some initial data, we compose a command
- // containing the initial data.
- if (authenticator.hasInitialResponse()) {
- StringBuffer command = new StringBuffer();
- // the auth command initiates the handshaking.
- command.append("AUTH ");
- // and tell the server which mechanism we're using.
- command.append(authenticator.getMechanismName());
- command.append(" ");
- // and append the response data
- try {
- command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
- } catch (UnsupportedEncodingException e) {
- }
- // send the command now
- sendLine(command.toString());
- }
- // we just send an auth command with the command type.
- else {
- StringBuffer command = new StringBuffer();
- // the auth command initiates the handshaking.
- command.append("AUTH ");
- // and tell the server which mechanism we're using.
- command.append(authenticator.getMechanismName());
- // send the command now
- sendLine(command.toString());
- }
-
- // now process the challenge sequence. We get a 235 response back when
- // the server accepts the
- // authentication, and a 334 indicates we have an additional challenge.
- while (true) {
- // get the next line, and if it is an error response, return now.
- SMTPReply line;
- try {
- line = new SMTPReply(receiveLine());
- } catch (MalformedSMTPReplyException e) {
- throw new MessagingException(e.toString());
- } catch (MessagingException e) {
- throw e;
- }
-
- // if we get a completion return, we've passed muster, so give an
- // authentication response.
- if (line.getCode() == SMTPReply.AUTHENTICATION_COMPLETE) {
- debugOut("Successful SMTP authentication");
- return true;
- }
- // we have an additional challenge to process.
- else if (line.getCode() == SMTPReply.AUTHENTICATION_CHALLENGE) {
- // Does the authenticator think it is finished? We can't answer
- // an additional challenge,
- // so fail this.
- if (authenticator.isComplete()) {
- return false;
- }
-
- try {
- // we're passed back a challenge value, Base64 encoded.
- byte[] challenge = Base64.decode(line.getMessage().getBytes("ISO8859-1"));
-
- // have the authenticator evaluate and send back the encoded
- // response.
- sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII"));
- } catch (UnsupportedEncodingException e) {
- }
- }
- // completion or challenge are the only responses we know how to
- // handle. Anything else must
- // be a failure.
- else {
- if (debug) {
- debugOut("Authentication failure " + line);
- }
- return false;
- }
- }
- }
-
-
- /**
- * Attempt to retrieve a SASL authenticator for this
- * protocol.
- *
- * @return A SASL authenticator, or null if a suitable one
- * was not located.
- */
- protected ClientAuthenticator getSaslAuthenticator() {
- return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
- }
-
-
- /**
- * Read the bytes in a stream a test to see if this
- * conforms to the RFC 2045 rules for 8bit encoding.
- *
- * 1) No more than 998 bytes long
- * 2) All lines are terminated with CRLF sequences
- * 3) CR and LF characters only occur in properly
- * formed line separators
- * 4) No null characters are allowed.
- *
- * @param inStream The source input stream.
- *
- * @return true if this can be transmitted successfully
- * using 8bit encoding, false if an alternate encoding
- * will be required.
- */
- protected boolean isValid8bit(InputStream inStream) {
- try {
- int ch;
- int lineLength = 0;
- while ((ch = inStream.read()) >= 0) {
- // nulls are decidedly not allowed
- if (ch == 0) {
- return false;
- }
- // start of a CRLF sequence (potentially)
- else if (ch == '\r') {
- // check the next character. There must be one,
- // and it must be a LF for this to be value
- ch = inStream.read();
- if (ch != '\n') {
- return false;
- }
- // reset the line length
- lineLength = 0;
- }
- else {
- // a normal character
- lineLength++;
- // make sure the line is not too long
- if (lineLength > 998) {
- return false;
- }
- }
-
- }
- } catch (IOException e) {
- return false; // can't read this, don't try passing it
- }
- // this converted ok
- return true;
- }
-
-
- /**
- * Simple holder class for the address/send status duple, as we can have
- * mixed success for a set of addresses and a message
- */
- static public class SendStatus {
- public final static int SUCCESS = 0;
-
- public final static int INVALID_ADDRESS = 1;
-
- public final static int SEND_FAILURE = 2;
-
- public final static int GENERAL_ERROR = 3;
-
- // the status type of the send operation.
- int status;
-
- // the address associated with this status
- InternetAddress address;
-
- // the command string send to the server.
- String cmd;
-
- // the reply from the server.
- SMTPReply reply;
-
- /**
- * Constructor for a SendStatus item.
- *
- * @param s
- * The status type.
- * @param a
- * The address this is the status for.
- * @param c
- * The command string associated with this status.
- * @param r
- * The reply information from the server.
- */
- public SendStatus(int s, InternetAddress a, String c, SMTPReply r) {
- this.cmd = c;
- this.status = s;
- this.address = a;
- this.reply = r;
- }
-
- /**
- * Get the status information for this item.
- *
- * @return The current status code.
- */
- public int getStatus() {
- return this.status;
- }
-
- /**
- * Retrieve the InternetAddress object associated with this send
- * operation.
- *
- * @return The associated address object.
- */
- public InternetAddress getAddress() {
- return this.address;
- }
-
- /**
- * Retrieve the reply information associated with this send operati
- *
- * @return The SMTPReply object received for the operation.
- */
- public SMTPReply getReply() {
- return reply;
- }
-
- /**
- * Get the command string sent for this send operation.
- *
- * @return The command string for the MAIL TO command sent to the
- * server.
- */
- public String getCommand() {
- return cmd;
- }
-
- /**
- * Get an exception object associated with this send operation. There is
- * a mechanism for reporting send success via a send operation, so this
- * will be either a success or failure exception.
- *
- * @param reportSuccess
- * Indicates if we want success operations too.
- *
- * @return A newly constructed exception object.
- */
- public MessagingException getException(boolean reportSuccess) {
- if (status != SUCCESS) {
- return new SMTPAddressFailedException(address, cmd, reply.getCode(), reply.getMessage());
- } else {
- if (reportSuccess) {
- return new SMTPAddressSucceededException(address, cmd, reply.getCode(), reply.getMessage());
- }
- }
- return null;
- }
- }
-
-
- /**
- * Reset the server connection after an error.
- *
- * @exception MessagingException
- */
- public void resetConnection() throws MessagingException {
- // we want the caller to retrieve the last response responsbile for
- // requiring the reset, so save and
- // restore that info around the reset.
- SMTPReply last = lastServerResponse;
-
- // send a reset command.
- SMTPReply line = sendCommand("RSET");
-
- // if this did not reset ok, just close the connection
- if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
- close();
- }
- // restore this.
- lastServerResponse = last;
- }
-
-
- /**
- * Return the current reportSuccess property.
- *
- * @return The current reportSuccess property.
- */
- public boolean getReportSuccess() {
- return reportSuccess;
- }
-
- /**
- * Set a new value for the reportSuccess property.
- *
- * @param report
- * The new setting.
- */
- public void setReportSuccess(boolean report) {
- reportSuccess = report;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java
deleted file mode 100644
index 91d8c95..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import java.io.InputStream;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.MimeMessage;
-
-public class SMTPMessage extends MimeMessage {
-
- // never notify
- public static final int NOTIFY_NEVER = -1;
-
- // notify of successful deliveries.
- public static final int NOTIFY_SUCCESS = 1;
-
- // notify of delivery failures.
- public static final int NOTIFY_FAILURE = 2;
-
- // notify of delivery delays
- public static final int NOTIFY_DELAY = 4;
-
- // return full message with status notifications
- public static final int RETURN_FULL = 1;
-
- // return only message headers with status notifications
- public static final int RETURN_HDRS = 2;
-
- // support 8BitMime encodings
- protected boolean allow8bitMIME = false;
-
- // a from address specified in the message envelope. Overrides other from
- // sources.
- protected String envelopeFrom = null;
-
- // an option string to append to the MAIL command on sending.
- protected String mailExtension = null;
-
- // SMTP mail notification options if DSN is supported.
- protected int notifyOptions = 0;
-
- // DSN return option notification values.
- protected int returnOption = 0;
-
- // allow sending if some addresses give errors.
- protected boolean sendPartial = false;
-
- // an RFC 2554 AUTH= value.
- protected String submitter = null;
-
- /**
- * Default (and normal) constructor for an SMTPMessage.
- *
- * @param session
- * The hosting Javamail Session.
- */
- public SMTPMessage(Session session) {
- // this is a simple one.
- super(session);
- }
-
- /**
- * Construct an SMTPMessage instance by reading and parsing the data from
- * the provided InputStream. The InputStream will be left positioned at the
- * end of the message data on constructor completion.
- *
- * @param session
- * The hosting Javamail Session.
- */
- public SMTPMessage(Session session, InputStream source) throws MessagingException {
- // this is a simple one.
- super(session, source);
- }
-
- /**
- * Construct an SMTPMimeMessage from another source MimeMessage object. The
- * new object and the old object are independent of each other.
- *
- * @param source
- * The source MimeMessage object.
- */
- public SMTPMessage(MimeMessage source) throws MessagingException {
- super(source);
- }
-
- /**
- * Change the allow8BitMime attribute for the message.
- *
- * @param a
- * The new setting.
- */
- public void setAllow8bitMIME(boolean a) {
- allow8bitMIME = a;
- }
-
- /**
- * Retrieve the current 8bitMIME attribute.
- *
- * @return The current attribute value.
- */
- public boolean getAllow8bitMIME() {
- return allow8bitMIME;
- }
-
- /**
- * Change the envelopeFrom attribute for the message.
- *
- * @param from
- * The new setting.
- */
- public void setEnvelopeFrom(String from) {
- envelopeFrom = from;
- }
-
- /**
- * Retrieve the current evelopeFrom attribute.
- *
- * @return The current attribute value.
- */
- public String getEnvelopeFrom() {
- return envelopeFrom;
- }
-
- /**
- * Change the mailExtension attribute for the message.
- *
- * @param e
- * The new setting.
- */
- public void setMailExtension(String e) {
- mailExtension = e;
- }
-
- /**
- * Retrieve the current mailExtension attribute.
- *
- * @return The current attribute value.
- */
- public String getMailExtension() {
- return mailExtension;
- }
-
- /**
- * Change the notifyOptions attribute for the message.
- *
- * @param options
- * The new setting.
- */
- public void setNotifyOptions(int options) {
- notifyOptions = options;
- }
-
- /**
- * Retrieve the current notifyOptions attribute.
- *
- * @return The current attribute value.
- */
- public int getNotifyOptions() {
- return notifyOptions;
- }
-
- /**
- * Change the returnOptions attribute for the message.
- *
- * @param option
- * The new setting.
- */
- public void setReturnOption(int option) {
- returnOption = option;
- }
-
- /**
- * Retrieve the current returnOption attribute.
- *
- * @return The current attribute value.
- */
- public int getReturnOption() {
- return returnOption;
- }
-
- /**
- * Change the sendPartial attribute for the message.
- *
- * @param a
- * The new setting.
- */
- public void setSendPartial(boolean a) {
- sendPartial = a;
- }
-
- /**
- * Retrieve the current sendPartial attribute.
- *
- * @return The current attribute value.
- */
- public boolean getSendPartial() {
- return sendPartial;
- }
-
- /**
- * Change the submitter attribute for the message.
- *
- * @param s
- * The new setting.
- */
- public void setSubmitter(String s) {
- submitter = s;
- }
-
- /**
- * Retrieve the current submitter attribute.
- *
- * @return The current attribute value.
- */
- public String getSubmitter() {
- return submitter;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java
deleted file mode 100644
index 092bd02..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Util class to represent a reply from a SMTP server
- *
- * @version $Rev: 673649 $ $Date: 2008-07-03 06:37:56 -0400 (Thu, 03 Jul 2008) $
- */
-class SMTPReply {
- // SMTP reply codes
- public static final int SERVICE_READY = 220;
-
- public static final int SERVICE_CLOSING = 221;
-
- public static final int AUTHENTICATION_COMPLETE = 235;
-
- public static final int COMMAND_ACCEPTED = 250;
-
- public static final int ADDRESS_NOT_LOCAL = 251;
-
- public static final int AUTHENTICATION_CHALLENGE = 334;
-
- public static final int START_MAIL_INPUT = 354;
-
- public static final int SERVICE_NOT_AVAILABLE = 421;
-
- public static final int MAILBOX_BUSY = 450;
-
- public static final int PROCESSING_ERROR = 451;
-
- public static final int INSUFFICIENT_STORAGE = 452;
-
- public static final int COMMAND_SYNTAX_ERROR = 500;
-
- public static final int PARAMETER_SYNTAX_ERROR = 501;
-
- public static final int COMMAND_NOT_IMPLEMENTED = 502;
-
- public static final int INVALID_COMMAND_SEQUENCE = 503;
-
- public static final int COMMAND_PARAMETER_NOT_IMPLEMENTED = 504;
-
- public static final int MAILBOX_NOT_FOUND = 550;
-
- public static final int USER_NOT_LOCAL = 551;
-
- public static final int MAILBOX_FULL = 552;
-
- public static final int INVALID_MAILBOX = 553;
-
- public static final int TRANSACTION_FAILED = 553;
-
- // The original reply string
- private final String reply;
-
- // returned message code
- private final int code;
-
- // the returned message text
- private final String message;
-
- // additional returned lines from a continued response
- private List lines;
-
- // indicates that this is a continuation response
- private boolean continued;
-
- SMTPReply(String s) throws MalformedSMTPReplyException {
- // save the reply
- reply = s;
-
- // In a normal response, the first 3 must be the return code. However,
- // the response back from a QUIT command is frequently a null string.
- // Therefore, if the result is
- // too short, just default the code to -1 and use the entire text for
- // the message.
- if (s == null || s.length() < 3) {
- code = -1;
- message = s;
- return;
- }
-
- try {
- continued = false;
- code = Integer.parseInt(s.substring(0, 3));
-
- // message should be separated by a space OR a continuation
- // character if this is a
- // multi-line response.
- if (s.length() > 4) {
- //
- if (s.charAt(3) == '-') {
- continued = true;
- }
- message = s.substring(4);
- } else {
- message = "";
- }
- } catch (NumberFormatException e) {
- throw new MalformedSMTPReplyException("error in parsing code", e);
- }
- }
-
- /**
- * Add a line to a continued response. This will
- * update the continued status if the end of the
- * response is reached.
- *
- * @param line The line to add.
- */
- public void addLine(String line) {
- if (lines == null) {
- lines = new ArrayList();
- lines.add(message);
- }
- // mark if we're still continued
- continued = line.charAt(3) == '-';
- // add the line to the list
- lines.add(line.substring(4));
- }
-
- /**
- * Get the list of all of the lines associated with
- * this reply.
- *
- * @return A List containing all lines associated with this
- * reply.
- */
- public List getLines() {
- if (lines == null) {
- lines = new ArrayList();
- lines.add(message);
- }
- return lines;
- }
-
-
- /**
- * Return the code value associated with the reply.
- *
- * @return The integer code associated with the reply.
- */
- public int getCode() {
- return this.code;
- }
-
- /**
- * Get the message text associated with the reply.
- *
- * @return The string value of the message from the reply.
- */
- public String getMessage() {
- return this.message;
- }
-
- /**
- * Retrieve the raw reply string for the reponse.
- *
- * @return The original reply string from the server.
- */
- public String getReply() {
- return reply;
- }
-
- /**
- * Indicates if reply is an error condition
- */
- boolean isError() {
- // error codes are all above 400
- return code >= 400;
- }
-
- /**
- * Indicates whether this response is flagged as part of a multiple line
- * response.
- *
- * @return true if the response has multiple lines, false if this is the
- * last line of the response.
- */
- public boolean isContinued() {
- return continued;
- }
-
- public String toString() {
- return "CODE = " + getCode() + " : MSG = " + getMessage();
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java
deleted file mode 100644
index 0794065..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import javax.mail.Session;
-import javax.mail.URLName;
-
-public class SMTPSTransport extends SMTPTransport {
- /**
- * @param session
- * @param name
- */
- public SMTPSTransport(Session session, URLName name) {
- super(session, name, "smtps", 465, true);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java
deleted file mode 100644
index 20ff08a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import javax.mail.Address;
-import javax.mail.SendFailedException;
-
-public class SMTPSendFailedException extends SendFailedException {
- // the failing command
- protected String cmd;
-
- // the error code for the failure
- protected int rc;
-
- /**
- * Constructor for an SMTPSendFaileException.
- *
- * @param cmd
- * The failing command string.
- * @param rc
- * The error code for the failing command.
- * @param err
- * An error message for the exception.
- * @param ex
- * Any associated nested exception.
- * @param vs
- * An array of valid, sent addresses.
- * @param vus
- * An array of addresses that were valid, but were unsent.
- * @param inv
- * An array of addresses deemed invalid.
- */
- SMTPSendFailedException(java.lang.String cmd, int rc, java.lang.String err, java.lang.Exception ex, Address[] vs,
- Address[] vus, Address[] inv) {
- super(err, ex, vs, vus, inv);
- this.cmd = cmd;
- this.rc = rc;
- }
-
- /**
- * Get the failing command string for the exception.
- *
- * @return The string value of the failing command.
- */
- public String getCommand() {
- return cmd;
- }
-
- /**
- * The failing command return code.
- *
- * @return The failure return code.
- */
- public int getReturnCode() {
- return rc;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
deleted file mode 100644
index b89988f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * 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.transport.smtp;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.Socket;
-import java.util.ArrayList;
-
-import javax.mail.Address;
-import javax.mail.AuthenticationFailedException;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.URLName;
-import javax.mail.event.TransportEvent;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import javax.mail.internet.MimePart;
-
-import org.apache.geronimo.javamail.util.ProtocolProperties;
-import org.apache.geronimo.javamail.transport.smtp.SMTPConnection.SendStatus;
-
-/**
- * Simple implementation of SMTP transport. Just does plain RFC821-ish delivery.
- * <p/> Supported properties : <p/>
- * <ul>
- * <li> mail.host : to set the server to deliver to. Default = localhost</li>
- * <li> mail.smtp.port : to set the port. Default = 25</li>
- * <li> mail.smtp.locahost : name to use for HELO/EHLO - default getHostName()</li>
- * </ul>
- * <p/> There is no way to indicate failure for a given recipient (it's possible
- * to have a recipient address rejected). The sun impl throws exceptions even if
- * others successful), but maybe we do a different way... <p/> TODO : lots.
- * ESMTP, user/pass, indicate failure, etc...
- *
- * @version $Rev: 995094 $ $Date: 2010-09-08 11:29:50 -0400 (Wed, 08 Sep 2010) $
- */
-public class SMTPTransport extends Transport {
- /**
- * property keys for protocol properties. The actual property name will be
- * appended with "mail." + protocol + ".", where the protocol is either
- * "smtp" or "smtps".
- */
- protected static final String MAIL_SMTP_DSN_NOTIFY = "dsn.notify";
- protected static final String MAIL_SMTP_SENDPARTIAL = "sendpartial";
- protected static final String MAIL_SMTP_EXTENSION = "mailextension";
- protected static final String DEFAULT_MAIL_HOST = "localhost";
-
- protected static final int DEFAULT_MAIL_SMTP_PORT = 25;
- protected static final int DEFAULT_MAIL_SMTPS_PORT = 465;
-
-
- // do we use SSL for our initial connection?
- protected boolean sslConnection = false;
-
- // our accessor for protocol properties and the holder of
- // protocol-specific information
- protected ProtocolProperties props;
- // our active connection object
- protected SMTPConnection connection;
-
- // the last response line received from the server.
- protected SMTPReply lastServerResponse = null;
-
- /**
- * Normal constructor for an SMTPTransport() object. This constructor is
- * used to build a transport instance for the "smtp" protocol.
- *
- * @param session
- * The attached session.
- * @param name
- * An optional URLName object containing target information.
- */
- public SMTPTransport(Session session, URLName name) {
- this(session, name, "smtp", DEFAULT_MAIL_SMTP_PORT, false);
- }
-
-
- /**
- * Common constructor used by the SMTPTransport and SMTPSTransport 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 (either "smtp" or "smtps". This helps us in
- * retrieving protocol-specific session properties.
- * @param defaultPort
- * The default port used by this protocol. For "smtp", this will
- * be 25. The default for "smtps" is 465.
- * @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 SMTPTransport(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 SMTPConnection(props);
- }
-
-
- /**
- * Connect to a server using an already created socket. This connection is
- * just like any other connection, except we will not create a new socket.
- *
- * @param socket
- * The socket connection to use.
- */
- public void connect(Socket socket) throws MessagingException {
- connection.connect(socket);
- super.connect();
- }
-
-
- /**
- * Do the protocol connection for an SMTP 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.
- return connection.protocolConnect(host, port, username, password);
- }
-
- /**
- * Send a message to multiple addressees.
- *
- * @param message
- * The message we're sending.
- * @param addresses
- * An array of addresses to send to.
- *
- * @exception MessagingException
- */
- public void sendMessage(Message message, Address[] addresses) throws MessagingException {
- if (!isConnected()) {
- throw new IllegalStateException("Not connected");
- }
- // don't bother me w/ null messages or no addreses
- if (message == null) {
- throw new MessagingException("Null message");
- }
-
- // SMTP only handles instances of MimeMessage, not the more general
- // message case.
- if (!(message instanceof MimeMessage)) {
- throw new MessagingException("SMTP can only send MimeMessages");
- }
-
- // we must have a message list.
- if (addresses == null || addresses.length == 0) {
- throw new MessagingException("Null or empty address array");
- }
-
- boolean reportSuccess = getReportSuccess();
-
- // now see how we're configured for this send operation.
- boolean partialSends = false;
-
- // this can be attached directly to the message.
- if (message instanceof SMTPMessage) {
- partialSends = ((SMTPMessage) message).getSendPartial();
- }
-
- // if still false on the message object, check for a property
- // version also
- if (!partialSends) {
- partialSends = props.getBooleanProperty(MAIL_SMTP_SENDPARTIAL, false);
- }
-
- boolean haveGroup = false;
-
- // enforce the requirement that all of the targets are InternetAddress
- // instances.
- for (int i = 0; i < addresses.length; i++) {
- if (addresses[i] instanceof InternetAddress) {
- // and while we're here, see if we have a groups in the address
- // list. If we do, then
- // we're going to need to expand these before sending.
- if (((InternetAddress) addresses[i]).isGroup()) {
- haveGroup = true;
- }
- } else {
- throw new MessagingException("Illegal InternetAddress " + addresses[i]);
- }
- }
-
- // did we find a group? Time to expand this into our full target list.
- if (haveGroup) {
- addresses = expandGroups(addresses);
- }
-
- SendStatus[] stats = new SendStatus[addresses.length];
-
- // create our lists for notification and exception reporting.
- Address[] sent = null;
- Address[] unsent = null;
- Address[] invalid = null;
-
- try {
- // send sender first. If this failed, send a failure notice of the
- // event, using the full list of
- // addresses as the unsent, and nothing for the rest.
- if (!connection.sendMailFrom(message)) {
- unsent = addresses;
- sent = new Address[0];
- invalid = new Address[0];
- // notify of the error.
- notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
-
- // include the reponse information here.
- SMTPReply last = connection.getLastServerResponse();
- // now send an "uber-exception" to indicate the failure.
- throw new SMTPSendFailedException("MAIL FROM", last.getCode(), last.getMessage(), null, sent, unsent,
- invalid);
- }
-
- // get the additional notification status, if available
- String dsn = getDeliveryStatusNotification(message);
-
- // we need to know about any failures once we've gone through the
- // complete list, so keep a
- // failure flag.
- boolean sendFailure = false;
-
- // event notifcation requires we send lists of successes and
- // failures broken down by category.
- // The categories are:
- //
- // 1) addresses successfully processed.
- // 2) addresses deemed valid, but had a processing failure that
- // prevented sending.
- // 3) addressed deemed invalid (basically all other processing
- // failures).
- ArrayList sentAddresses = new ArrayList();
- ArrayList unsentAddresses = new ArrayList();
- ArrayList invalidAddresses = new ArrayList();
-
- // Now we add a MAIL TO record for each recipient. At this point, we
- // just collect
- for (int i = 0; i < addresses.length; i++) {
- InternetAddress target = (InternetAddress) addresses[i];
-
- // write out the record now.
- SendStatus status = connection.sendRcptTo(target, dsn);
- stats[i] = status;
-
- switch (status.getStatus()) {
- // successfully sent
- case SendStatus.SUCCESS:
- sentAddresses.add(target);
- break;
-
- // we have an invalid address of some sort, or a general sending
- // error (which we'll
- // interpret as due to an invalid address.
- case SendStatus.INVALID_ADDRESS:
- case SendStatus.GENERAL_ERROR:
- sendFailure = true;
- invalidAddresses.add(target);
- break;
-
- // good address, but this was a send failure.
- case SendStatus.SEND_FAILURE:
- sendFailure = true;
- unsentAddresses.add(target);
- break;
- }
- }
-
- // if we had a send failure, then we need to check if we allow
- // partial sends. If not allowed,
- // we abort the send operation now.
- if (sendFailure) {
- // if we're not allowing partial successes or we've failed on
- // all of the addresses, it's
- // time to abort.
- if (!partialSends || sentAddresses.isEmpty()) {
- // we send along the valid and invalid address lists on the
- // notifications and
- // exceptions.
- // however, since we're aborting the entire send, the
- // successes need to become
- // members of the failure list.
- unsentAddresses.addAll(sentAddresses);
-
- // this one is empty.
- sent = new Address[0];
- unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
- invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
-
- // go reset our connection so we can process additional
- // sends.
- connection.resetConnection();
-
- // get a list of chained exceptions for all of the failures.
- MessagingException failures = generateExceptionChain(stats, false);
-
- // now send an "uber-exception" to indicate the failure.
- throw new SMTPSendFailedException("MAIL TO", 0, "Invalid Address", failures, sent, unsent, invalid);
- }
- }
-
- try {
- // try to send the data
- connection.sendData((MimeMessage)message);
- } catch (MessagingException e) {
- // If there's an error at this point, this is a complete
- // delivery failure.
- // we send along the valid and invalid address lists on the
- // notifications and
- // exceptions.
- // however, since we're aborting the entire send, the successes
- // need to become
- // members of the failure list.
- unsentAddresses.addAll(sentAddresses);
-
- // this one is empty.
- sent = new Address[0];
- unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
- invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
- // notify of the error.
- notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
- // send a send failure exception.
- throw new SMTPSendFailedException("DATA", 0, "Send failure", e, sent, unsent, invalid);
- }
-
- // create our lists for notification and exception reporting from
- // this point on.
- sent = (Address[]) sentAddresses.toArray(new Address[0]);
- unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
- invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
-
- // if sendFailure is true, we had an error during the address phase,
- // but we had permission to
- // process this as a partial send operation. Now that the data has
- // been sent ok, it's time to
- // report the partial failure.
- if (sendFailure) {
- // notify our listeners of the partial delivery.
- notifyTransportListeners(TransportEvent.MESSAGE_PARTIALLY_DELIVERED, sent, unsent, invalid, message);
-
- // get a list of chained exceptions for all of the failures (and
- // the successes, if reportSuccess has been
- // turned on).
- MessagingException failures = generateExceptionChain(stats, reportSuccess);
-
- // now send an "uber-exception" to indicate the failure.
- throw new SMTPSendFailedException("MAIL TO", 0, "Invalid Address", failures, sent, unsent, invalid);
- }
-
- // notify our listeners of successful delivery.
- notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, sent, unsent, invalid, message);
-
- // we've not had any failures, but we've been asked to report
- // success as an exception. Do
- // this now.
- if (reportSuccess) {
- // generate the chain of success exceptions (we already know
- // there are no failure ones to report).
- MessagingException successes = generateExceptionChain(stats, reportSuccess);
- if (successes != null) {
- throw successes;
- }
- }
- } catch (SMTPSendFailedException e) {
- // if this is a send failure, we've already handled
- // notifications....just rethrow it.
- throw e;
- } catch (MessagingException e) {
- // notify of the error.
- notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
- throw e;
- }
- }
-
-
- /**
- * Determine what delivery status notification should
- * be added to the RCPT TO: command.
- *
- * @param message The message we're sending.
- *
- * @return The string NOTIFY= value to add to the command.
- */
- protected String getDeliveryStatusNotification(Message message) {
- String dsn = null;
-
- // there's an optional notification argument that can be added to
- // MAIL TO. See if we've been
- // provided with one.
-
- // an SMTPMessage object is the first source
- if (message instanceof SMTPMessage) {
- // get the notification options
- int options = ((SMTPMessage) message).getNotifyOptions();
-
- switch (options) {
- // a zero value indicates nothing is set.
- case 0:
- break;
-
- case SMTPMessage.NOTIFY_NEVER:
- dsn = "NEVER";
- break;
-
- case SMTPMessage.NOTIFY_SUCCESS:
- dsn = "SUCCESS";
- break;
-
- case SMTPMessage.NOTIFY_FAILURE:
- dsn = "FAILURE";
- break;
-
- case SMTPMessage.NOTIFY_DELAY:
- dsn = "DELAY";
- break;
-
- // now for combinations...there are few enough combinations here
- // that we can just handle this in the switch statement rather
- // than have to
- // concatentate everything together.
- case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE):
- dsn = "SUCCESS,FAILURE";
- break;
-
- case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_DELAY):
- dsn = "SUCCESS,DELAY";
- break;
-
- case (SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
- dsn = "FAILURE,DELAY";
- break;
-
- case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
- dsn = "SUCCESS,FAILURE,DELAY";
- break;
- }
- }
-
- // if still null, grab a property value (yada, yada, yada...)
- if (dsn == null) {
- dsn = props.getProperty(MAIL_SMTP_DSN_NOTIFY);
- }
- return dsn;
- }
-
-
-
- /**
- * Close the connection. On completion, we'll be disconnected from the
- * server and unable to send more data.
- *
- * @exception MessagingException
- */
- public void close() throws MessagingException {
- // This is done to ensure proper event notification.
- super.close();
- // NB: We reuse the connection if asked to reconnect
- connection.close();
- }
-
-
- /**
- * Turn a series of send status items into a chain of exceptions indicating
- * the state of each send operation.
- *
- * @param stats
- * The list of SendStatus items.
- * @param reportSuccess
- * Indicates whether we should include the report success items.
- *
- * @return The head of a chained list of MessagingExceptions.
- */
- protected MessagingException generateExceptionChain(SendStatus[] stats, boolean reportSuccess) {
- MessagingException current = null;
-
- for (int i = 0; i < stats.length; i++) {
- SendStatus status = stats[i];
-
- if (status != null) {
- MessagingException nextException = stats[i].getException(reportSuccess);
- // if there's an exception associated with this status, chain it
- // up with the rest.
- if (nextException != null) {
- if (current == null) {
- current = nextException;
- } else {
- current.setNextException(nextException);
- current = nextException;
- }
- }
- }
- }
- return current;
- }
-
- /**
- * Expand the address list by converting any group addresses into single
- * address targets.
- *
- * @param addresses
- * The input array of addresses.
- *
- * @return The expanded array of addresses.
- * @exception MessagingException
- */
- protected Address[] expandGroups(Address[] addresses) throws MessagingException {
- ArrayList expandedAddresses = new ArrayList();
-
- // run the list looking for group addresses, and add the full group list
- // to our targets.
- for (int i = 0; i < addresses.length; i++) {
- InternetAddress address = (InternetAddress) addresses[i];
- // not a group? Just copy over to the other list.
- if (!address.isGroup()) {
- expandedAddresses.add(address);
- } else {
- // get the group address and copy each member of the group into
- // the expanded list.
- InternetAddress[] groupAddresses = address.getGroup(true);
- for (int j = 1; j < groupAddresses.length; j++) {
- expandedAddresses.add(groupAddresses[j]);
- }
- }
- }
-
- // convert back into an array.
- return (Address[]) expandedAddresses.toArray(new Address[0]);
- }
-
-
- /**
- * Retrieve the local client host name.
- *
- * @return The string version of the local host name.
- * @exception SMTPTransportException
- */
- public String getLocalHost() throws MessagingException {
- return connection.getLocalHost();
- }
-
-
- /**
- * Explicitly set the local host information.
- *
- * @param localHost
- * The new localHost name.
- */
- public void setLocalHost(String localHost) {
- connection.setLocalHost(localHost);
- }
-
-
- /**
- * Return the current reportSuccess property.
- *
- * @return The current reportSuccess property.
- */
- public boolean getReportSuccess() {
- return connection.getReportSuccess();
- }
-
- /**
- * Set a new value for the reportSuccess property.
- *
- * @param report
- * The new setting.
- */
- public void setReportSuccess(boolean report) {
- connection.setReportSuccess(report);
- }
-
- /**
- * Return the current startTLS property.
- *
- * @return The current startTLS property.
- */
- public boolean getStartTLS() {
- return connection.getStartTLS();
- }
-
- /**
- * Set a new value for the startTLS property.
- *
- * @param start
- * The new setting.
- */
- public void setStartTLS(boolean start) {
- connection.setStartTLS(start);
- }
-
- /**
- * Retrieve the SASL realm used for DIGEST-MD5 authentication. This will
- * either be explicitly set, or retrieved using the mail.smtp.sasl.realm
- * session property.
- *
- * @return The current realm information (which can be null).
- */
- public String getSASLRealm() {
- return connection.getSASLRealm();
- }
-
- /**
- * Explicitly set the SASL realm used for DIGEST-MD5 authenticaiton.
- *
- * @param name
- * The new realm name.
- */
- public void setSASLRealm(String name) {
- connection.setSASLRealm(name);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java
deleted file mode 100644
index d6851e3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.transport.smtp;
-
-/**
- * General purpose Exception
- *
- * @version $Id: SMTPTransportException.java 437941 2006-08-29 03:56:02Z jdillon $
- */
-class SMTPTransportException extends Exception {
-
- SMTPTransportException() {
- super();
- }
-
- SMTPTransportException(String s) {
- super(s);
- }
-
- SMTPTransportException(String s, Exception t) {
- super(s, t);
- }
-
- SMTPTransportException(Exception t) {
- super("SMTP Transport error", t);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java
deleted file mode 100644
index 2c12b70..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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.util;
-
-import javax.mail.MessagingException;
-
-public class CommandFailedException extends MessagingException {
- public CommandFailedException() {
- super();
- }
-
- public CommandFailedException(String message) {
- super(message);
- }
-
- public CommandFailedException(String message, Exception cause) {
- super(message, cause);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java
deleted file mode 100644
index ece163d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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.util;
-
-import javax.mail.MessagingException;
-
-public class ConnectionException extends MessagingException {
- public ConnectionException() {
- super();
- }
-
- public ConnectionException(String message) {
- super(message);
- }
-
- public ConnectionException(String message, Exception cause) {
- super(message, cause);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java
deleted file mode 100644
index 3dc5e1c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An implementation of an OutputStream just counts
- * the number of bytes written to the stream.
- * @version $Rev: 671217 $ $Date: 2008-06-24 11:39:52 -0400 (Tue, 24 Jun 2008) $
- */
-public class CountingOutputStream extends OutputStream {
- // the counting accumulator
- int count = 0;
-
- // in order for this to work, we only need override the single character
- // form, as the others
- // funnel through this one by default.
- public void write(int ch) throws IOException {
- // just increment the count
- count++;
- }
-
-
- /**
- * Get the current accumulator total for this stream.
- *
- * @return The current count.
- */
- public int getCount() {
- return count;
- }
-
-
- /**
- * Reset the counter to zero.
- */
- public void reset() {
- count = 0;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java
deleted file mode 100644
index 4273cbb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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.util;
-
-import javax.mail.MessagingException;
-
-public class InvalidCommandException extends MessagingException {
- public InvalidCommandException() {
- super();
- }
-
- public InvalidCommandException(String message) {
- super(message);
- }
-
- public InvalidCommandException(String message, Exception cause) {
- super(message, cause);
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java
deleted file mode 100644
index 70c3727..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * An implementation of an OutputStream that performs MIME linebreak
- * canonicalization and "byte-stuff" so that data content does not get mistaken
- * for a message data-end marker (CRLF.CRLF)l
- *
- * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
- */
-public class MIMEInputReader extends Reader {
-
- // the wrappered output stream.
- protected Reader source;
-
- // a flag to indicate we've just processed a line break. This is used for
- // byte stuffing purposes. This
- // is initially true, because if the first character of the content is a
- // period, we need to byte-stuff
- // immediately.
- protected boolean atLineBreak = true;
- // we've hit the terminating marker on the data
- protected boolean endOfData = false;
-
-
- /**
- * Create an input reader that reads from the source input reader
- *
- * @param out
- * The wrapped Reader
- */
- public MIMEInputReader(Reader source) {
- this.source = source;
- }
-
- /**
- * Concrete implementation of the Reader read()
- * abstract method. This appears to be the only
- * abstract method, so all of the other reads must
- * funnel through this method.
- *
- * @param buffer The buffer to fill.
- * @param off The offset to start adding characters.
- * @param len The number of requested characters.
- *
- * @return The actual count of characters read. Returns -1
- * if we hit an EOF without reading any characters.
- * @exception IOException
- */
- public int read(char buffer[], int off, int len) throws IOException {
- // we've been asked for nothing, we'll return nothing.
- if (len == 0) {
- return 0;
- }
-
- // have we hit the end of data? Return a -1 indicator
- if (endOfData) {
- return -1;
- }
-
- // number of bytes read
- int bytesRead = 0;
-
- int lastRead;
-
- while (bytesRead < len && (lastRead = source.read()) >= 0) {
- // We are checking for the end of a multiline response
- // the format is .CRLF
-
- // we also have to check for byte-stuffing situation
- // where we remove a leading period.
- if (atLineBreak && lastRead == '.') {
- // step to the next character
- lastRead = source.read();
- // we have ".CR"...this is our end of stream
- // marker. Consume the LF from the reader and return
- if (lastRead == '\r') {
- source.read();
- // no more reads from this point.
- endOfData = true;
- break;
- }
- // the next character SHOULD be a ".". We swallow the first
- // dot and just write the next character to the buffer
- atLineBreak = false;
- }
- else if (lastRead == '\n') {
- // hit an end-of-line marker?
- // remember we just had a line break
- atLineBreak = true;
- }
- else
- {
- // something other than a line break character
- atLineBreak = false;
- }
- // add the character to the buffer
- buffer[off++] = (char)lastRead;
- bytesRead++;
- }
-
- // we must have had an EOF condition of some sort
- if (bytesRead == 0) {
- return -1;
- }
- // return the actual length read in
- return bytesRead;
- }
-
- /**
- * Close the stream. This is a NOP for this stream.
- *
- * @exception IOException
- */
- public void close() throws IOException {
- // does nothing
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java
deleted file mode 100644
index ac7b2bc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An implementation of an OutputStream that performs MIME linebreak
- * canonicalization and "byte-stuff" so that data content does not get mistaken
- * for a message data-end marker (CRLF.CRLF)l
- *
- * @version $Rev: 670717 $ $Date: 2008-06-23 15:41:19 -0400 (Mon, 23 Jun 2008) $
- */
-public class MIMEOutputStream extends OutputStream {
-
- // the wrappered output stream.
- protected OutputStream out;
-
- // last character we handled...used to recongnize line breaks.
- protected int lastWrite = -1;
-
- // a flag to indicate we've just processed a line break. This is used for
- // byte stuffing purposes. This
- // is initially true, because if the first character of the content is a
- // period, we need to byte-stuff
- // immediately.
- protected boolean atLineBreak = true;
-
- /**
- * Create an output stream that writes to the target output stream.
- *
- * @param out
- * The wrapped output stream.
- */
- public MIMEOutputStream(OutputStream out) {
- this.out = out;
- }
-
- // in order for this to work, we only need override the single character
- // form, as the others
- // funnel through this one by default.
- public void write(int ch) throws IOException {
- // if this is a CR character, always write out a full sequence, and
- // remember that we just did this.
- if (ch == '\r') {
- out.write((byte) '\r');
- out.write((byte) '\n');
- // we've just taken a break;
- atLineBreak = true;
- }
- // if this is a new line, then we need to determine if this is a loner
- // or part of a CRLF sequence.
- else if (ch == '\n') {
- // is this a lone ranger?
- if (lastWrite != '\r') {
- // write the full CRLF sequence.
- out.write((byte) '\r');
- out.write((byte) '\n');
- }
- // regardless of whether we wrote something or not, we're still at a
- // line break.
- atLineBreak = true;
- }
- // potential byte-stuffing situation?
- else if (ch == '.') {
- // ok, this is a potential stuff situation. Did we just have a line
- // break? Double up the character.
- if (atLineBreak) {
- out.write('.');
- }
- out.write('.');
- atLineBreak = false;
- } else {
- // just write this out and flip the linebreak flag.
- out.write(ch);
- atLineBreak = false;
- }
- // remember this last one for CRLF tracking purposes.
- lastWrite = ch;
- }
-
-
- /**
- * Force the stream to be terminated at a line break.
- * This is generally in preparation for the transport to
- * write out an end-of-data marker, which generally
- * needs to be preceded by a CRLF sequence.
- *
- * @exception IOException
- */
- public void forceTerminatingLineBreak() throws IOException {
- if (!atLineBreak) {
- out.write((byte) '\r');
- out.write((byte) '\n');
- // we've just taken a break;
- atLineBreak = true;
- }
- }
-
-
- /**
- * Write out the SMTP terminator to the output stream.
- * This ensures that we don't write out an extra
- * CRLF if the data terminates with that value.
- *
- * @exception IOException
- */
- public void writeSMTPTerminator() throws IOException {
- forceTerminatingLineBreak();
- out.write('.');
- out.write('\r');
- out.write('\n');
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java
deleted file mode 100644
index af079ae..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java
+++ /dev/null
@@ -1,960 +0,0 @@
-/**
- * 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.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.authentication.CramMD5Authenticator;
-import org.apache.geronimo.javamail.authentication.DigestMD5Authenticator;
-import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
-import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
-import org.apache.geronimo.javamail.authentication.SASLAuthenticator;
-
-/**
- * Base class for all mail Store/Transport connection. Centralizes management
- * of a lot of common connection handling. Actual protcol-specific
- * functions are handled at the subclass level.
- */
-public class MailConnection {
- /**
- * constants for EOL termination
- */
- protected static final char CR = '\r';
- protected static final char LF = '\n';
-
- /**
- * property keys for protocol properties.
- */
- protected static final String MAIL_PORT = "port";
- protected static final String MAIL_LOCALHOST = "localhost";
- protected static final String MAIL_STARTTLS_ENABLE = "starttls.enable";
- protected static final String MAIL_STARTTLS_REQUIRED = "starttls.required";
- protected static final String MAIL_SSL_ENABLE = "ssl.enable";
- protected static final String MAIL_TIMEOUT = "timeout";
- protected static final String MAIL_SASL_ENABLE = "sasl.enable";
- protected static final String MAIL_SASL_REALM = "sasl.realm";
- protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid";
- protected static final String MAIL_SASL_MECHANISMS = "sasl.mechanisms";
- protected static final String MAIL_PLAIN_DISABLE = "auth.plain.disable";
- protected static final String MAIL_LOGIN_DISABLE = "auth.login.disable";
-
- protected static final String MAIL_FACTORY = "socketFactory"; //GERONIMO-5429
- protected static final String MAIL_FACTORY_CLASS = "socketFactory.class";
- protected static final String MAIL_FACTORY_FALLBACK = "socketFactory.fallback";
- protected static final String MAIL_FACTORY_PORT = "socketFactory.port";
-
- protected static final String MAIL_SSL_FACTORY = "ssl.socketFactory"; //GERONIMO-5429
- protected static final String MAIL_SSL_FACTORY_CLASS = "ssl.socketFactory.class";
- protected static final String MAIL_SSL_FACTORY_PORT = "ssl.socketFactory.port";
- protected static final String MAIL_SSL_PROTOCOLS = "ssl.protocols";
- protected static final String MAIL_SSL_CIPHERSUITES = "ssl.ciphersuites";
- protected static final String MAIL_SSL_TRUST = "ssl.trust";
-
- protected static final String MAIL_LOCALADDRESS = "localaddress";
- protected static final String MAIL_LOCALPORT = "localport";
- protected static final String MAIL_ENCODE_TRACE = "encodetrace";
-
- protected static final int MIN_MILLIS = 1000 * 60;
- protected static final int TIMEOUT = MIN_MILLIS * 5;
- protected static final String DEFAULT_MAIL_HOST = "localhost";
-
- protected static final String CAPABILITY_STARTTLS = "STARTTLS";
-
- protected static final String AUTHENTICATION_PLAIN = "PLAIN";
- protected static final String AUTHENTICATION_LOGIN = "LOGIN";
- protected static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
- protected static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
-
- // The mail Session we're associated with
- protected Session session;
- // The protocol we're implementing
- protected String protocol;
- // There are usually SSL and non-SSL versions of these protocols. This
- // indicates which version we're using.
- protected boolean sslConnection;
- // This is the default port we should be using for making a connection. Each
- // protocol (and each ssl version of the protocol) normally has a different default that
- // should be used.
- protected int defaultPort;
-
- // a wrapper around our session to provide easier lookup of protocol
- // specific property values
- protected ProtocolProperties props;
-
- // The target server host
- protected String serverHost;
- // The target server port
- protected int serverPort;
-
- // the connection socket...can be a plain socket or SSLSocket, if TLS is being used.
- protected Socket socket;
-
- // our local host name
- protected InetAddress localAddress;
- // our local port value
- protected int localPort;
- // our local host name
- protected String localHost;
-
- // our timeout value
- protected int timeout;
-
- // our login username
- protected String username;
- // our login password
- protected String password;
- // our SASL security realm
- protected String realm;
- // our authorization id
- protected String authid;
-
- // input stream used to read data. If Sasl is in use, this might be other than the
- // direct access to the socket input stream.
- protected InputStream inputStream;
- // the other end of the connection pipeline.
- protected OutputStream outputStream;
-
- // our session provided debug output stream.
- protected PrintStream debugStream;
- // our debug flag (passed from the hosting transport)
- protected boolean debug;
-
- // list of authentication mechanisms supported by the server
- protected List authentications;
- // map of server extension arguments
- protected Map capabilities;
- // property list of authentication mechanisms
- protected List mechanisms;
-
- protected MailConnection(ProtocolProperties props)
- {
- // this is our properties retriever utility, which will look up
- // properties based on the appropriate "mail.protocol." prefix.
- // this also holds other information we might need for access, such as
- // the protocol name and the Session;
- this.props = props;
- this.protocol = props.getProtocol();
- this.session = props.getSession();
- this.sslConnection = props.getSSLConnection();
- this.defaultPort = props.getDefaultPort();
-
- // initialize our debug settings from the session
- debug = session.getDebug();
- debugStream = session.getDebugOut();
-
- String mailSSLEnable = props.getProperty(MAIL_SSL_ENABLE);
- if(mailSSLEnable != null) {
- this.sslConnection = Boolean.valueOf(mailSSLEnable);
- }
- }
-
-
- /**
- * Connect to the server and do the initial handshaking.
- *
- * @param host The target host name.
- * @param port The target port
- * @param username The connection username (can be null)
- * @param password The authentication password (can be null).
- *
- * @return true if we were able to obtain a connection and
- * authenticate.
- * @exception MessagingException
- */
- public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
- // NOTE: We don't check for the username/password being null at this point. It's possible that
- // the server will send back a PREAUTH response, which means we don't need to go through login
- // processing. We'll need to check the capabilities response after we make the connection to decide
- // if logging in is necesssary.
-
- // save this for subsequent connections. All pool connections will use this info.
- // if the port is defaulted, then see if we have something configured in the session.
- // if not configured, we just use the default default.
- if (port == -1) {
- // check for a property and fall back on the default if it's not set.
- port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
- // it's possible that -1 might have been explicitly set, so one last check.
- if (port == -1) {
- port = props.getDefaultPort();
- }
- }
-
- // Before we do anything, let's make sure that we successfully received a host
- if ( host == null ) {
- host = DEFAULT_MAIL_HOST;
- }
-
- this.serverHost = host;
- this.serverPort = port;
- this.username = username;
- this.password = password;
-
- // make sure we have the realm information
- realm = props.getProperty(MAIL_SASL_REALM);
- // get an authzid value, if we have one. The default is to use the username.
- authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
- return true;
- }
-
-
- /**
- * Establish a connection using an existing socket.
- *
- * @param s The socket to use.
- */
- public void connect(Socket s) {
- // just save the socket connection
- this.socket = s;
- }
-
-
- /**
- * Create a transport connection object and connect it to the
- * target server.
- *
- * @exception MessagingException
- */
- protected void getConnection() throws IOException, MessagingException
- {
- // We might have been passed a socket to connect with...if not, we need to create one of the correct type.
- if (socket == null) {
- // get the connection properties that control how we set this up.
- getConnectionProperties();
- // if this is the SSL version of the protocol, we start with an SSLSocket
- if (sslConnection) {
- getConnectedSSLSocket();
- }
- else
- {
- getConnectedSocket();
- }
- }
- // if we already have a socket, get some information from it and override what we've been passed.
- else {
- localPort = socket.getPort();
- localAddress = socket.getInetAddress();
- }
-
- // now set up the input/output streams.
- getConnectionStreams();
- }
-
- /**
- * Get common connection properties before creating a connection socket.
- */
- protected void getConnectionProperties() {
-
- // there are several protocol properties that can be set to tune the created socket. We need to
- // retrieve those bits before creating the socket.
- timeout = props.getIntProperty(MAIL_TIMEOUT, -1);
- localAddress = null;
- // see if we have a local address override.
- String localAddrProp = props.getProperty(MAIL_LOCALADDRESS);
- if (localAddrProp != null) {
- try {
- localAddress = InetAddress.getByName(localAddrProp);
- } catch (UnknownHostException e) {
- // not much we can do if this fails.
- }
- }
-
- // check for a local port...default is to allow socket to choose.
- localPort = props.getIntProperty(MAIL_LOCALPORT, 0);
- }
-
-
- /**
- * Creates a connected socket
- *
- * @exception MessagingException
- */
- protected void getConnectedSocket() throws IOException {
- debugOut("Attempting plain socket connection to server " + serverHost + ":" + serverPort);
-
- // make sure this is null
- socket = null;
-
- createSocket(false);
-
- // if we have a timeout value, set that before returning
- if (timeout >= 0) {
- socket.setSoTimeout(timeout);
- }
- }
-
- private boolean createSocketFromFactory(boolean ssl, boolean layer) throws IOException {
-
- String socketFactoryClass = props.getProperty(ssl?MAIL_SSL_FACTORY_CLASS:MAIL_FACTORY_CLASS);
-
- if(socketFactoryClass == null) {
- return false;
- }
-
- // we'll try this with potentially two different factories if we're allowed to fall back.
- boolean fallback = props.getBooleanProperty(MAIL_FACTORY_FALLBACK, false);
- int socketFactoryPort = props.getIntProperty(ssl?MAIL_SSL_FACTORY_PORT:MAIL_FACTORY_PORT, -1);
- Integer portArg = new Integer(socketFactoryPort == -1 ? serverPort : socketFactoryPort);
-
- debugOut("Creating "+(ssl?"":"non-")+"SSL socket using factory " + socketFactoryClass+ " listening on port "+portArg);
-
- while (true) {
- try {
-
- // use the current context loader to resolve this.
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- Class factoryClass = loader.loadClass(socketFactoryClass);
-
- // done indirectly, we need to invoke the method using reflection.
- // This retrieves a factory instance.
- //Method getDefault = factoryClass.getMethod("getDefault", new Class[0]); //TODO check instantiation of socket factory
- Object defFactory = factoryClass.newInstance();// getDefault.invoke(new Object(), new Object[0]);
- // now that we have the factory, there are two different createSocket() calls we use,
- // depending on whether we have a localAddress override.
-
- if (localAddress != null && !layer) {
- // retrieve the createSocket(String, int, InetAddress, int) method.
- Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
- Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
-
- Object[] createSocketArgs = new Object[] { serverHost, portArg, localAddress, new Integer(localPort) };
- socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
- break;
- }
- else {
- if(layer) {
- // retrieve the createSocket(String, int) method.
- Class[] createSocketSig = new Class[] { Socket.class, String.class, Integer.TYPE, Boolean.TYPE };
- Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
-
- Object[] createSocketArgs = new Object[] { socket, serverHost, new Integer(serverPort), Boolean.TRUE };
- socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
- break;
- } else {
- // retrieve the createSocket(String, int) method.
- Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
- Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
-
- Object[] createSocketArgs = new Object[] { serverHost, portArg };
- socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
- break;
- }
-
-
- }
- } catch (Throwable e) {
- // if we're allowed to fallback, then use the default factory and try this again. We only
- // allow this to happen once.
- if (fallback) {
- debugOut("First attempt at creating "+(ssl?"":"non-")+"SSL socket failed, falling back to default factory");
- socketFactoryClass = ssl?"javax.net.ssl.SSLSocketFactory":"javax.net.SocketFactory";
- fallback = false;
- continue;
- }
- // we have an exception. We're going to throw an IOException, which may require unwrapping
- // or rewrapping the exception.
- else {
- // we have an exception from the reflection, so unwrap the base exception
- if (e instanceof InvocationTargetException) {
- e = ((InvocationTargetException)e).getTargetException();
- }
-
- debugOut("Failure creating "+(ssl?"":"non-")+"SSL socket", e);
- // throw this as an IOException, with the original exception attached.
- IOException ioe = new IOException("Error connecting to " + serverHost + ", " + serverPort);
- ioe.initCause(e);
- throw ioe;
- }
- }
- }
-
- return true;
- }
-
- private void createSocketFromFactory(SocketFactory sf, boolean layer) throws IOException {
-
- if(sf instanceof SSLSocketFactory && layer) {
- socket = ((SSLSocketFactory) sf).createSocket(socket, serverHost, serverPort, true);
- return;
- }
-
- if (localAddress != null) {
- socket = sf.createSocket(serverHost, serverPort, localAddress, localPort);
- } else
- {
- socket = sf.createSocket(serverHost, serverPort);
- }
- }
-
- private boolean createSocketFromConfiguredFactoryInstance(boolean ssl, boolean layer) throws IOException {
-
-
-
- if (ssl) {
- Object sfProp = props.getPropertyAsObject(MAIL_SSL_FACTORY);
- if (sfProp != null && sfProp instanceof SSLSocketFactory) {
- createSocketFromFactory((SSLSocketFactory) sfProp, layer);
- debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
- return true;
- }
- } else {
- Object sfProp = props.getPropertyAsObject(MAIL_FACTORY);
- if (sfProp != null && sfProp instanceof SocketFactory) {
- createSocketFromFactory((SocketFactory) sfProp, layer);
- debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
- return true;
- }
- }
-
- return false;
- }
-
- private void createSSLSocketFromSSLContext(boolean layer) throws IOException{
-
- debugOut("Creating "+(layer?"layered ":"non-layered ")+"SSL socket using SSL Context");
-
-
- try {
- SSLContext sslcontext = SSLContext.getInstance("TLS");
-
- String sslTrust = props.getProperty(MAIL_SSL_TRUST);
-
- TrustManager trustManager = null;
-
- if(sslTrust != null) {
- if(sslTrust.equals("*")) {
- trustManager = new SSLTrustManager(null, true); //trust all
- } else
- {
- String[] trustedHosts = sslTrust.split("\\s+");
- trustManager = new SSLTrustManager(trustedHosts, false); //trust some
-
- if(serverHost == null || serverHost.isEmpty() || !Arrays.asList(trustedHosts).contains(serverHost)) {
- throw new IOException("Server is not trusted: " + serverHost);
- }
-
- }
- } else {
- trustManager = new SSLTrustManager(null, false); //default
-
- }
-
- sslcontext.init(null, new TrustManager[]{trustManager}, null);
-
- createSocketFromFactory(sslcontext.getSocketFactory(), layer);
- } catch (KeyManagementException e) {
- //cannot happen
- throw new IOException(e);
- } catch (NoSuchAlgorithmException e) {
- //cannot happen
- throw new IOException(e);
- }
- }
-
- private void createSocket(boolean ssl) throws IOException {
-
- if(createSocketFromConfiguredFactoryInstance(ssl, false)) {
- return;
- }
-
- if(createSocketFromFactory(ssl, false)) {
- return;
- }
-
- if(!ssl) {
- createSocketFromFactory(SocketFactory.getDefault(), false);
- return;
- }
-
-
- createSSLSocketFromSSLContext(false);
- }
-
-
- /**
- * Creates a connected SSL socket for an initial SSL connection.
- *
- * @exception MessagingException
- */
- protected void getConnectedSSLSocket() throws IOException {
- debugOut("Attempting SSL socket connection to server " + serverHost + ":" + serverPort);
- // the socket factory can be specified via a protocol property, a session property, and if all else
- // fails (which it usually does), we fall back to the standard factory class.
-
- // make sure this is null
- socket = null;
-
- createSocket(true);
-
- // and set the timeout value
- if (timeout >= 0) {
- socket.setSoTimeout(timeout);
- }
-
- // if there is a list of protocols specified, we need to break this down into
- // the individual names
- String protocols = props.getProperty(MAIL_SSL_PROTOCOLS);
- if (protocols != null) {
- ArrayList list = new ArrayList();
- StringTokenizer t = new StringTokenizer(protocols);
-
- while (t.hasMoreTokens()) {
- list.add(t.nextToken());
- }
-
- ((SSLSocket)socket).setEnabledProtocols((String[])list.toArray(new String[list.size()]));
- }
-
- // and do the same for any cipher suites
- String suites = props.getProperty(MAIL_SSL_CIPHERSUITES);
- if (suites != null) {
- ArrayList list = new ArrayList();
- StringTokenizer t = new StringTokenizer(suites);
-
- while (t.hasMoreTokens()) {
- list.add(t.nextToken());
- }
-
- ((SSLSocket)socket).setEnabledCipherSuites((String[])list.toArray(new String[list.size()]));
- }
- }
-
-
- /**
- * Switch the connection to using TLS level security,
- * switching to an SSL socket.
- */
- protected void getConnectedTLSSocket() throws MessagingException {
- // it worked, now switch the socket into TLS mode
- try {
-
- // we use the same target and port as the current connection.
- serverHost = socket.getInetAddress().getHostName();
- serverPort = socket.getPort();
-
- // the socket factory can be specified via a session property. By default, we use
- // the native SSL factory.
- if(createSocketFromConfiguredFactoryInstance(true, true)) {
- debugOut("TLS socket factory configured as instance");
- } else if(createSocketFromFactory(true, true)) {
- debugOut("TLS socket factory configured as class");
- } else {
- debugOut("TLS socket factory from SSLContext");
- createSSLSocketFromSSLContext(true);
- }
-
- // if this is an instance of SSLSocket (very common), try setting the protocol to be
- // "TLSv1". If this is some other class because of a factory override, we'll just have to
- // accept that things will work.
- if (socket instanceof SSLSocket) {
- String[] suites = ((SSLSocket)socket).getSupportedCipherSuites();
- ((SSLSocket)socket).setEnabledCipherSuites(suites);
- ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1"} );
- ((SSLSocket)socket).setUseClientMode(true);
- debugOut("Initiating STARTTLS handshake");
- ((SSLSocket)socket).startHandshake();
- } else {
- throw new IOException("Socket is not an instance of SSLSocket, maybe wrong configured ssl factory?");
- }
-
- getConnectionStreams();
- debugOut("TLS connection established");
- }
- catch (Exception e) {
- debugOut("Failure attempting to convert connection to TLS", e);
- throw new MessagingException("Unable to convert connection to SSL", e);
- }
- }
-
-
- /**
- * Set up the input and output streams for server communications once the
- * socket connection has been made.
- *
- * @exception MessagingException
- */
- protected void getConnectionStreams() throws MessagingException, IOException {
- // and finally, as a last step, replace our input streams with the secure ones.
- // now set up the input/output streams.
- inputStream = new TraceInputStream(socket.getInputStream(), debugStream, debug, props.getBooleanProperty(
- MAIL_ENCODE_TRACE, false));
- outputStream = new TraceOutputStream(socket.getOutputStream(), debugStream, debug, props.getBooleanProperty(
- MAIL_ENCODE_TRACE, false));
- }
-
-
- /**
- * Close the server connection at termination.
- */
- public void closeServerConnection()
- {
- try {
- socket.close();
- } catch (IOException ignored) {
- }
-
- socket = null;
- inputStream = null;
- outputStream = null;
- }
-
-
- /**
- * Verify that we have a good connection before
- * attempting to send a command.
- *
- * @exception MessagingException
- */
- protected void checkConnected() throws MessagingException {
- if (socket == null || !socket.isConnected()) {
- throw new MessagingException("no connection");
- }
- }
-
-
- /**
- * Retrieve the SASL realm used for DIGEST-MD5 authentication.
- * This will either be explicitly set, or retrieved using the
- * mail.imap.sasl.realm session property.
- *
- * @return The current realm information (which can be null).
- */
- public String getSASLRealm() {
- // if the realm is null, retrieve it using the realm session property.
- if (realm == null) {
- realm = props.getProperty(MAIL_SASL_REALM);
- }
- return realm;
- }
-
-
- /**
- * Explicitly set the SASL realm used for DIGEST-MD5 authenticaiton.
- *
- * @param name The new realm name.
- */
- public void setSASLRealm(String name) {
- realm = name;
- }
-
-
- /**
- * Get a list of the SASL mechanisms we're configured to accept.
- *
- * @return A list of mechanisms we're allowed to use.
- */
- protected List getSaslMechanisms() {
- if (mechanisms == null) {
- mechanisms = new ArrayList();
- String mechList = props.getProperty(MAIL_SASL_MECHANISMS);
- if (mechList != null) {
- // the mechanisms are a blank or comma-separated list
- StringTokenizer tokenizer = new StringTokenizer(mechList, " ,");
-
- while (tokenizer.hasMoreTokens()) {
- String mech = tokenizer.nextToken().toUpperCase();
- mechanisms.add(mech);
- }
- }
- }
- return mechanisms;
- }
-
-
- /**
- * Get the list of authentication mechanisms the server
- * is supposed to support.
- *
- * @return A list of the server supported authentication
- * mechanisms.
- */
- protected List getServerMechanisms() {
- return authentications;
- }
-
-
- /**
- * Merge the configured SASL mechanisms with the capabilities that the
- * server has indicated it supports, returning a merged list that can
- * be used for selecting a mechanism.
- *
- * @return A List representing the intersection of the configured list and the
- * capabilities list.
- */
- protected List selectSaslMechanisms() {
- List configured = getSaslMechanisms();
- List supported = getServerMechanisms();
-
- // if not restricted, then we'll select from anything supported.
- if (configured.isEmpty()) {
- return supported;
- }
-
- List merged = new ArrayList();
-
- // we might need a subset of the supported ones
- for (int i = 0; i < configured.size(); i++) {
- // if this is in both lists, add to the merged one.
- String mech = (String)configured.get(i);
- if (supported.contains(mech)) {
- merged.add(mech);
- }
- }
- return merged;
- }
-
-
- /**
- * Process SASL-type authentication.
- *
- * @return An authenticator to process the login challenge/response handling.
- * @exception MessagingException
- */
- protected ClientAuthenticator getLoginAuthenticator() throws MessagingException {
-
- // get the list of mechanisms we're allowed to use.
- List mechs = selectSaslMechanisms();
-
- try {
- String[] mechArray = (String[])mechs.toArray(new String[0]);
- // create a SASLAuthenticator, if we can. A failure likely indicates we're not
- // running on a Java 5 VM, and the Sasl API isn't available.
- return new SASLAuthenticator(mechArray, session.getProperties(), protocol, serverHost, getSASLRealm(), authid, username, password);
- } catch (Throwable e) {
- }
-
-
- // now go through the progression of mechanisms we support, from the most secure to the
- // least secure.
-
- if (mechs.contains(AUTHENTICATION_DIGESTMD5)) {
- return new DigestMD5Authenticator(serverHost, username, password, getSASLRealm());
- }
- else if (mechs.contains(AUTHENTICATION_CRAMMD5)) {
- return new CramMD5Authenticator(username, password);
- }
- else if (mechs.contains(AUTHENTICATION_LOGIN)) {
- return new LoginAuthenticator(username, password);
- }
- else if (mechs.contains(AUTHENTICATION_PLAIN)) {
- return new PlainAuthenticator(authid, username, password);
- }
- else {
- // can't find a mechanism we support in common
- return null;
- }
- }
-
-
- /**
- * Internal debug output routine.
- *
- * @param value The string value to output.
- */
- protected void debugOut(String message) {
- if (debug) {
- debugStream.println(protocol + " DEBUG: " + message);
- }
- }
-
- /**
- * Internal debugging routine for reporting exceptions.
- *
- * @param message A message associated with the exception context.
- * @param e The received exception.
- */
- protected void debugOut(String message, Throwable e) {
- if (debug) {
- debugOut("Received exception -> " + message);
- debugOut("Exception message -> " + e.getMessage());
- e.printStackTrace(debugStream);
- }
- }
-
-
- /**
- * Test if this connection has a given capability.
- *
- * @param capability The capability name.
- *
- * @return true if this capability is in the list, false for a mismatch.
- */
- public boolean hasCapability(String capability) {
- return capabilities.containsKey(capability);
- }
-
- /**
- * Get the capabilities map.
- *
- * @return The capabilities map for the connection.
- */
- public Map getCapabilities() {
- return capabilities;
- }
-
-
- /**
- * Test if the server supports a given mechanism.
- *
- * @param mech The mechanism name.
- *
- * @return true if the server has asserted support for the named
- * mechanism.
- */
- public boolean supportsMechanism(String mech) {
- return authentications.contains(mech);
- }
-
-
- /**
- * Retrieve the connection host.
- *
- * @return The host name.
- */
- public String getHost() {
- return serverHost;
- }
-
-
- /**
- * Retrieve the local client host name.
- *
- * @return The string version of the local host name.
- * @exception SMTPTransportException
- */
- public String getLocalHost() throws MessagingException {
- if (localHost == null) {
-
- if (localHost == null) {
- localHost = props.getProperty(MAIL_LOCALHOST);
- }
-
- if (localHost == null) {
- localHost = props.getSessionProperty(MAIL_LOCALHOST);
- }
-
- if (localHost == null) {
- try {
- localHost = InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- // fine, we're misconfigured - ignore
- }
- }
-
- if (localHost == null) {
- throw new MessagingException("Can't get local hostname. "
- + " Please correctly configure JDK/DNS or set mail.smtp.localhost");
- }
- }
-
- return localHost;
- }
-
-
- /**
- * Explicitly set the local host information.
- *
- * @param localHost
- * The new localHost name.
- */
- public void setLocalHost(String localHost) {
- this.localHost = localHost;
- }
-
- private class SSLTrustManager implements X509TrustManager {
-
- private final X509TrustManager defaultTrustManager;
-
- private final boolean trustAll;
- private final String[] trustedHosts;
-
- SSLTrustManager(String[] trustedHosts, boolean trustAll) throws IOException{
- super();
- this.trustAll = trustAll;
- this.trustedHosts = trustedHosts;
-
- try {
- TrustManagerFactory defaultTrustManagerFactory = TrustManagerFactory.getInstance("X509");
- defaultTrustManagerFactory.init((KeyStore)null);
- defaultTrustManager = (X509TrustManager) defaultTrustManagerFactory.getTrustManagers()[0];
- } catch (NoSuchAlgorithmException e) {
- //cannot happen
- throw new IOException(e);
- } catch (KeyStoreException e) {
- //cannot happen
- throw new IOException(e);
- }
-
- }
-
- /* (non-Javadoc)
- * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
- */
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- defaultTrustManager.checkClientTrusted(chain, authType);
-
- }
-
- /* (non-Javadoc)
- * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
- */
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- if (!trustAll || trustedHosts != null) {
- defaultTrustManager.checkServerTrusted(chain, authType);
- }
-
- }
-
- /* (non-Javadoc)
- * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
- */
- public X509Certificate[] getAcceptedIssuers() {
- return defaultTrustManager.getAcceptedIssuers();
- }
-
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java
deleted file mode 100644
index 7ef1a6d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * 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.util;
-
-import java.util.Properties;
-
-import javax.mail.Session;
-
-/**
- * Interface for providing access to protocol specific properties to
- * utility classes.
- */
-public class ProtocolProperties {
- // the protocol we're working with.
- protected String protocol;
- // a preconstructed prefix string to reduce concatenation operations.
- protected String protocolPrefix;
- // the Session that's the source of all of the properties
- protected Session session;
- // the sslConnection property. This indicates this protocol is to use SSL for
- // all communications with the server.
- protected boolean sslConnection;
- // the default port property. The default port differs with the protocol
- // and the sslConnection property.
- protected int defaultPort;
-
-
- public ProtocolProperties(Session session, String protocol, boolean sslConnection, int defaultPort) {
- this.session = session;
- this.protocol = protocol;
- this.sslConnection = sslConnection;
- this.defaultPort = defaultPort;
- // this helps avoid a lot of concatenates when retrieving properties.
- protocolPrefix = "mail." + protocol + ".";
- }
-
-
- /**
- * Retrieve the Session associated with this property bundle instance.
- *
- * @return A Session object that's the source of the accessed properties.
- */
- public Session getSession() {
- return session;
- }
-
-
- /**
- * Retrieve the name of the protocol used to access properties.
- *
- * @return The protocol String name.
- */
- public String getProtocol() {
- return protocol;
- }
-
-
- /**
- * Retrieve the SSL Connection flag for this protocol;
- *
- * @return true if an SSL connection is required, false otherwise.
- */
- public boolean getSSLConnection() {
- return sslConnection;
- }
-
-
- /**
- * Return the default port to use with this connection.
- *
- * @return The default port value.
- */
- public int getDefaultPort() {
- return defaultPort;
- }
-
-
- /**
- * Get a property associated with this mail protocol.
- *
- * @param name The name of the property.
- *
- * @return The property value (returns null if the property has not been set).
- */
- public String getProperty(String name) {
- // the name we're given is the least qualified part of the name.
- // We construct the full property name
- // using the protocol
- String fullName = protocolPrefix + name;
- return session.getProperty(fullName);
- }
-
- /**
- * Get a property (as object) associated with this mail protocol.
- *
- * @param name The name of the property.
- *
- * @return The property value (returns null if the property has not been set).
- */
- public Object getPropertyAsObject(String name) {
- // the name we're given is the least qualified part of the name.
- // We construct the full property name
- // using the protocol
- String fullName = protocolPrefix + name;
- return session.getProperties().get(fullName);
- }
-
- /**
- * Get a property associated with this mail session. Returns
- * the provided default if it doesn't exist.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value (returns defaultValue if the property has not been set).
- */
- public String getProperty(String name, String defaultValue) {
- // the name we're given is the least qualified part of the name.
- // We construct the full property name
- // using the protocol
- String fullName = protocolPrefix + name;
- String value = session.getProperty(fullName);
- if (value == null) {
- value = defaultValue;
- }
- return value;
- }
-
-
- /**
- * Get a property associated with this mail session as an integer value. Returns
- * the default value if the property doesn't exist or it doesn't have a valid int value.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value converted to an int.
- */
- public int getIntProperty(String name, int defaultValue)
- {
- // retrieve the property
- String value = getProperty(name);
- // return the default value if not set.
- if (value == null) {
- return defaultValue;
- }
- return Integer.parseInt(value);
- }
-
-
- /**
- * Get a property associated with this mail session as an boolean value. Returns
- * the default value if the property doesn't exist or it doesn't have a valid int value.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value converted to a boolean
- */
- public boolean getBooleanProperty(String name, boolean defaultValue)
- {
- // retrieve the property
- String value = getProperty(name);
- // return the default value if not set.
- if (value == null) {
- return defaultValue;
- }
- // just do a single test for true.
- if ("true".equals(value)) {
- return true;
- }
- // return false for anything other than true
- return false;
- }
-
-
- /**
- * Get a property associated with this mail session. Session
- * properties all begin with "mail."
- *
- * @param name The name of the property.
- *
- * @return The property value (returns null if the property has not been set).
- */
- public String getSessionProperty(String name) {
- // the name we're given is the least qualified part of the name.
- // We construct the full property name
- // using the protocol
- String fullName = "mail." + name;
- return session.getProperty(fullName);
- }
-
- /**
- * Get a property associated with this mail session. Returns
- * the provided default if it doesn't exist.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value (returns defaultValue if the property has not been set).
- */
- public String getSessionProperty(String name, String defaultValue) {
- // the name we're given is the least qualified part of the name.
- // We construct the full property name
- // using the protocol
- String fullName = "mail." + name;
- String value = session.getProperty(fullName);
- if (value == null) {
- value = defaultValue;
- }
- return value;
- }
-
-
- /**
- * Get a property associated with this mail session as an integer value. Returns
- * the default value if the property doesn't exist or it doesn't have a valid int value.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value converted to an int.
- */
- public int getIntSessionProperty(String name, int defaultValue)
- {
- // retrieve the property
- String value = getSessionProperty(name);
- // return the default value if not set.
- if (value == null) {
- return defaultValue;
- }
- return Integer.parseInt(value);
- }
-
-
- /**
- * Get a property associated with this mail session as an boolean value. Returns
- * the default value if the property doesn't exist or it doesn't have a valid int value.
- *
- * @param name The name of the property.
- * @param defaultValue
- * The default value to return if the property doesn't exist.
- *
- * @return The property value converted to a boolean
- */
- public boolean getBooleanSessionProperty(String name, boolean defaultValue)
- {
- // retrieve the property
- String value = getSessionProperty(name);
- // return the default value if not set.
- if (value == null) {
- return defaultValue;
- }
- // just do a single test for true.
- if ("true".equals(value)) {
- return true;
- }
- // return false for anything other than true
- return false;
- }
-
- /**
- * Get the complete set of properties associated with this Session.
- *
- * @return The Session properties bundle.
- */
- public Properties getProperties() {
- return session.getProperties();
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java
deleted file mode 100644
index e533313..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.util;
-
-import javax.mail.MessagingException;
-
-public class ResponseFormatException extends MessagingException {
- public ResponseFormatException() {
- super();
- }
-
- public ResponseFormatException(String message) {
- super(message);
- }
-
- public ResponseFormatException(String message, Exception cause) {
- super(message, cause);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java
deleted file mode 100644
index 05763b6..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.util;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.geronimo.mail.james.mime4j.codec.QuotedPrintableOutputStream;
-
-/**
- * @version $Rev: 1704974 $ $Date: 2015-09-23 22:13:31 -0400 (Wed, 23 Sep 2015) $
- */
-public class TraceInputStream extends FilterInputStream {
- // the current debug setting
- protected boolean debug = false;
-
- // the target trace output stream.
- protected OutputStream traceStream;
-
- /**
- * Construct a debug trace stream.
- *
- * @param in
- * The source input stream.
- * @param traceStream
- * The side trace stream to which trace data gets written.
- * @param encode
- * Indicates whether we wish the Trace data to be Q-P encoded.
- */
- public TraceInputStream(InputStream in, OutputStream traceStream, boolean debug, boolean encode) {
- super(in);
- this.debug = debug;
- if (encode) {
- this.traceStream = new QuotedPrintableOutputStream(traceStream, false);
- } else {
- this.traceStream = traceStream;
- }
- }
-
- /**
- * Set the current setting of the debug trace stream debug flag.
- *
- * @param d
- * The new debug flag settings.
- */
- public void setDebug(boolean d) {
- debug = d;
- }
-
- /**
- * Reads up to len bytes of data from this input stream, placing them directly
- * into the provided byte array.
- *
- * @param b the provided data buffer.
- * @param off the starting offset within the buffer for placing the data.
- * @param len the maximum number of bytes to read.
- * @return that number of bytes that have been read and copied into the
- * buffer or -1 if an end of stream occurs.
- * @exception IOException for any I/O errors.
- */
- public int read(byte b[], int off, int len) throws IOException {
- int count = in.read(b, off, len);
- if (debug && count > 0) {
- traceStream.write(b, off, count);
- }
- return count;
- }
-
- /**
- * Read the next byte of data from the input stream, returning it as an
- * int value. Returns -1 if the end of stream is detected.
- *
- * @return The next byte of data or -1 to indicate end-of-stream.
- * @exception IOException for any I/O errors
- */
- public int read() throws IOException {
- int b = in.read();
- if (debug) {
- traceStream.write(b);
- }
- return b;
- }
-
- public int read(byte[] b) throws IOException {
- final int read = in.read(b);
- if (debug && read > 0) {
- traceStream.write(b, 0, read);
- }
- return read;
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java
deleted file mode 100644
index 2f545fa..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.util;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.geronimo.mail.james.mime4j.codec.QuotedPrintableOutputStream;
-
-/**
- * @version $Rev: 1704974 $ $Date: 2015-09-23 22:13:31 -0400 (Wed, 23 Sep 2015) $
- */
-public class TraceOutputStream extends FilterOutputStream {
- // the current debug setting
- protected boolean debug = false;
-
- // the target trace output stream.
- protected OutputStream traceStream;
-
- /**
- * Construct a debug trace stream.
- *
- * @param out
- * The target out put stream.
- * @param traceStream
- * The side trace stream to which trace data gets written.
- * @param encode
- * Indicates whether we wish the Trace data to be Q-P encoded.
- */
- public TraceOutputStream(OutputStream out, OutputStream traceStream, boolean debug, boolean encode) {
- super(out);
- this.debug = debug;
- if (encode) {
- this.traceStream = new QuotedPrintableOutputStream(traceStream, false);
- } else {
- this.traceStream = traceStream;
- }
- }
-
- /**
- * Set the current setting of the debug trace stream debug flag.
- *
- * @param d
- * The new debug flag settings.
- */
- public void setDebug(boolean d) {
- debug = d;
- }
-
-
- /**
- * Write a single byte to the output stream.
- *
- * @param b The byte to be written.
- *
- * @exception IOException
- * thrown for any I/O errors.
- */
- public void write(int b) throws IOException {
- if (debug) {
- traceStream.write(b);
- }
- super.write(b);
- }
-
- public void write(byte[] b, int off, int len) throws IOException {
- if (this.debug) {
- this.traceStream.write(b, off, len);
- }
- out.write(b, off, len);
- }
-
- public void write(byte[] b) throws IOException {
- if (this.debug) {
- this.traceStream.write(b);
- }
- out.write(b);
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map
deleted file mode 100644
index 3bba278..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map
+++ /dev/null
@@ -1,34 +0,0 @@
-##
-## 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.
-##
-
-##
-## $Rev: 437934 $ $Date: 2006-08-28 20:27:42 -0700 (Mon, 28 Aug 2006) $
-##
-
-#
-# This file configures the default behaviour of JavaMail. DO NOT EDIT.
-# Create a new file /META-INF/javamail.address.map and put
-# the same format lines in there.
-#
-# Note that you can't override these defaults, merely add to them.
-#
-# $Rev: 351866 $ $Date: 2005-12-02 20:12:14 -0500 (Fri, 02 Dec 2005) $
-#
-rfc822=smtp
-news=nntp
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers
deleted file mode 100644
index e4db1a3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers
+++ /dev/null
@@ -1,43 +0,0 @@
-##
-## 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.
-##
-
-##
-## $Rev: 437934 $ $Date: 2006-08-28 20:27:42 -0700 (Mon, 28 Aug 2006) $
-##
-
-#
-# This file configures the default behaviour of JavaMail. DO NOT EDIT.
-# Create a new file /META-INF/javamail.providers and put
-# the same format lines in there.
-#
-# Note that you can't override these defaults, merely add to them.
-#
-# $Rev: 398634 $ $Date: 2006-05-01 12:56:06 -0400 (Mon, 01 May 2006) $
-#
-protocol=smtp; type=transport; class=org.apache.geronimo.javamail.transport.smtp.SMTPTransport; vendor=Apache Software Foundation; version=1.0
-protocol=smtps; type=transport; class=org.apache.geronimo.javamail.transport.smtp.SMTPSTransport; vendor=Apache Software Foundation; version=1.0
-protocol=nntp-post; type=transport; class=org.apache.geronimo.javamail.transport.nntp.NNTPTransport; vendor=Apache Software Foundation; version=1.0
-protocol=nntp-posts; type=transport; class=org.apache.geronimo.javamail.transport.nntp.NNTPSSLTransport; vendor=Apache Software Foundation; version=1.0
-protocol=nntp; type=store; class=org.apache.geronimo.javamail.store.nntp.NNTPStore; vendor=Apache Software Foundation; version=1.0
-protocol=nntps; type=store; class=org.apache.geronimo.javamail.store.nntp.NNTPSSLStore; vendor=Apache Software Foundation; version=1.0
-protocol=pop3; type=store; class=org.apache.geronimo.javamail.store.pop3.POP3Store; vendor=Apache Software Foundation; version=1.0
-protocol=pop3s; type=store; class=org.apache.geronimo.javamail.store.pop3.POP3SSLStore; vendor=Apache Software Foundation; version=1.0
-protocol=imap; type=store; class=org.apache.geronimo.javamail.store.imap.IMAPStore; vendor=Apache Software Foundation; version=1.0
-protocol=imaps; type=store; class=org.apache.geronimo.javamail.store.imap.IMAPSSLStore; vendor=Apache Software Foundation; version=1.0
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap
deleted file mode 100644
index 2783191..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap
+++ /dev/null
@@ -1,31 +0,0 @@
-##
-## 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.
-##
-## $Rev$ $Date$
-##
-
-text/plain;; x-java-content-handler=org.apache.geronimo.javamail.handlers.TextPlainHandler
-text/html;; x-java-content-handler=org.apache.geronimo.javamail.handlers.TextHtmlHandler
-text/xml;; x-java-content-handler=org.apache.geronimo.javamail.handlers.TextXmlHandler
-
-## These are not implemented in the reference implementation because the required support
-## is not available on server JVMs.
-## image/gif;; x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageGifHandler
-## image/jpeg;; x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageJpegHandler
-## image/jpg;; x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageJpegHandler
-
-multipart/*;; x-java-content-handler=org.apache.geronimo.javamail.handlers.MultipartHandler
-message/rfc822;; x-java-content-handler=org.apache.geronimo.javamail.handlers.RFC822MessageHandler
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler
deleted file mode 100644
index c6e297b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.ImageGifHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler
deleted file mode 100644
index c8148bb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.ImageJpegHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler
deleted file mode 100644
index 39d2e16..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.MultipartHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler
deleted file mode 100644
index a091915..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.RFC822MessageHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler
deleted file mode 100644
index 0da58ec..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.TextHtmlHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler
deleted file mode 100644
index c3518a0..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.TextPlainHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler
deleted file mode 100644
index 04b32e3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.handlers.TextXmlHandler # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore
deleted file mode 100644
index 18127c3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.imap.IMAPSSLStore # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore
deleted file mode 100644
index 6c35475..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.imap.IMAPStore # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore
deleted file mode 100644
index c8df215..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.nntp.NNTPSSLStore # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore
deleted file mode 100644
index 83d3d3a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.nntp.NNTPStore # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore
deleted file mode 100644
index ace45de..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.pop3.POP3SSLStore # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store
deleted file mode 100644
index 28dd416..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.store.pop3.POP3Store # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport
deleted file mode 100644
index 5af212f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.transport.nntp.NNTPSSLTransport # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport
deleted file mode 100644
index 7db7ae2..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.transport.nntp.NNTPTransport # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport
deleted file mode 100644
index cc5bbb5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.transport.smtp.SMTPSTransport # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport
deleted file mode 100644
index a16aa75..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.javamail.transport.smtp.SMTPTransport # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml
deleted file mode 100644
index 251ed2b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<!-- $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $ -->
-
-<project name="${project.name}">
-
- <body>
-
- ${parentProject}
-
- ${modules}
-
- ${reports}
-
- </body>
-
-</project>
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java
deleted file mode 100644
index 36c7cbb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.handlers;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-import javax.activation.DataContentHandler;
-import javax.activation.DataSource;
-
-import junit.framework.TestCase;
-
-/**
- * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
- */
-public abstract class AbstractHandler extends TestCase {
- protected DataContentHandler dch;
- protected String mimeType;
-
- public void testGetContent() throws Exception {
- final byte[] bytes = "Hello World".getBytes();
- DataSource ds = new DataSource() {
- public InputStream getInputStream() {
- return new ByteArrayInputStream(bytes);
- }
-
- public OutputStream getOutputStream() {
- throw new UnsupportedOperationException();
- }
-
- public String getContentType() {
- return mimeType;
- }
-
- public String getName() {
- throw new UnsupportedOperationException();
- }
- };
- Object o = dch.getContent(ds);
- assertEquals("Hello World", o);
- }
-
- public void testWriteTo() throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- dch.writeTo("Hello World", mimeType, baos);
- assertEquals("Hello World", baos.toString());
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java
deleted file mode 100644
index 79da869..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-
-/**
- * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
- */
-public class TextHtmlTest extends AbstractHandler {
- public void testDataFlavor() {
- DataFlavor[] flavours = dch.getTransferDataFlavors();
- assertEquals(1, flavours.length);
- DataFlavor flavor = flavours[0];
- assertEquals(String.class, flavor.getRepresentationClass());
- assertEquals("text/html", flavor.getMimeType());
- assertEquals("HTML Text", flavor.getHumanPresentableName());
- }
-
- protected void setUp() throws Exception {
- super.setUp();
-
- dch = new TextHtmlHandler();
- mimeType = "text/html";
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java
deleted file mode 100644
index 95dead8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-
-/**
- * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
- */
-public class TextPlainTest extends AbstractHandler {
- public void testDataFlavor() {
- DataFlavor[] flavours = dch.getTransferDataFlavors();
- assertEquals(1, flavours.length);
- DataFlavor flavor = flavours[0];
- assertEquals(String.class, flavor.getRepresentationClass());
- assertEquals("text/plain", flavor.getMimeType());
- assertEquals("Plain Text", flavor.getHumanPresentableName());
- }
-
- protected void setUp() throws Exception {
- super.setUp();
-
- dch = new TextPlainHandler();
- mimeType = "text/plain";
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java
deleted file mode 100644
index 9122ec8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.handlers;
-
-import java.awt.datatransfer.DataFlavor;
-
-/**
- * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
- */
-public class TextXmlTest extends AbstractHandler {
- public void testDataFlavor() {
- DataFlavor[] flavours = dch.getTransferDataFlavors();
- assertEquals(1, flavours.length);
- DataFlavor flavor = flavours[0];
- assertEquals(String.class, flavor.getRepresentationClass());
- assertEquals("text/xml", flavor.getMimeType());
- assertEquals("XML Text", flavor.getHumanPresentableName());
- }
-
- protected void setUp() throws Exception {
- super.setUp();
-
- dch = new TextXmlHandler();
- mimeType = "text/xml";
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java
deleted file mode 100755
index e999475..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * 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.issues;
-
-import java.io.File;
-import java.util.Properties;
-
-import javax.activation.DataHandler;
-import javax.activation.FileDataSource;
-import javax.mail.BodyPart;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import junit.framework.Assert;
-
-import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
-
-public class GERONIMO6480Test extends AbstractProtocolTest {
-
- public void testGERONIMO6480_0() throws Exception {
- BodyPart attachmentPart = new MimeBodyPart();
- attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
- attachmentPart.setFileName("test.pdf");
- String contentType = getSendedAttachmentContentType(attachmentPart);
- Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
- // "text/plain; name=test.pdf" with Geronimo because setFileName force it to 'text/plain' when adding the 'name=' part instead of keeping it null
- }
-
- public void testGERONIMO6480_1() throws Exception {
- BodyPart attachmentPart = new MimeBodyPart();
- attachmentPart.addHeader("Content-Type", "aplication/pdf");
- // setDataHandler reset "Content-Type" so equivalent to previous test
- attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
- attachmentPart.setFileName("test.pdf");
- String contentType = getSendedAttachmentContentType(attachmentPart);
- Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
- // "text/plain; name=test.pdf" with Geronimo because setFileName force it to 'text/plain' when adding the 'name=' part instead of keeping it null
- }
-
- public void testGERONIMO6480_2() throws Exception {
- BodyPart attachmentPart = new MimeBodyPart();
- attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
- attachmentPart.addHeader("Content-Type", "aplication/pdf");
- attachmentPart.setFileName("test.pdf");
- String contentType = getSendedAttachmentContentType(attachmentPart);
- Assert.assertEquals("aplication/pdf; name=test.pdf".toLowerCase(), contentType.toLowerCase());
- }
-
- public void testGERONIMO6480_3() throws Exception {
- System.setProperty("mail.mime.setcontenttypefilename", Boolean.FALSE.toString());
- try {
- BodyPart attachmentPart = new MimeBodyPart();
- attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
- attachmentPart.setFileName("test.pdf");
- String contentType = getSendedAttachmentContentType(attachmentPart);
- Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
- } finally {
- System.setProperty("mail.mime.setcontenttypefilename", Boolean.TRUE.toString());
- }
- }
-
- public void testGERONIMO6480_4() throws Exception {
- BodyPart attachmentPart = new MimeBodyPart();
- attachmentPart.setFileName("test.pdf");
- attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
- String contentType = getSendedAttachmentContentType(attachmentPart);
- Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
- }
-
- private File getAbsoluteFilePathFromClassPath(String filename) throws Exception {
- return new File(GERONIMO6480Test.class.getClassLoader().getResource(filename).toURI());
- }
-
- private String getSendedAttachmentContentType(BodyPart attachmentPart) throws Exception {
-
- start();
- Properties props = new Properties();
- props.setProperty("mail.transport.protocol", "smtp");
- props.setProperty("mail.store.protocol", "imap");
- props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- //props.setProperty("mail.debug", "true");
- Session session = Session.getInstance(props);
-
- BodyPart messageBodyPart = new MimeBodyPart();
- messageBodyPart.setText("See attachment.");
-
- MimeMultipart multipart = new MimeMultipart();
- multipart.addBodyPart(messageBodyPart);
- multipart.addBodyPart(attachmentPart);
-
- Message message = new MimeMessage(session);
- message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("test@mockserver.com"));
- message.setSubject("Test attachment content-type");
- message.setContent(multipart);
-
- Transport.send(message);
-
- return getAttachmentContentType(session);
- }
-
- private String getAttachmentContentType(Session session) throws Exception {
- Store store = session.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
-
- Folder folder = store.getDefaultFolder();
- folder = folder.getFolder("inbox");
- folder.open(Folder.READ_ONLY);
-
- server.ensureMsgCount(1);
-
- Message message = folder.getMessage(1);
- MimeMultipart multipart = (MimeMultipart) message.getContent();
- BodyPart attachmentPart = multipart.getBodyPart(1);
- return attachmentPart.getContentType();
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java
deleted file mode 100644
index e10bf5a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * 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.issues;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.util.Properties;
-
-import javax.activation.DataHandler;
-import javax.activation.DataSource;
-import javax.activation.FileDataSource;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import junit.framework.Assert;
-
-import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
-import org.apache.geronimo.javamail.testserver.MailServer;
-
-public class IssuesTest extends AbstractProtocolTest {
-
- public void testGERONIMO6519() throws Exception {
-
- PrintStream original = System.out;
-
- try {
-
- start();
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- props.setProperty("mail.smtp.localhost", "some.full.qualified.name.com");
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- System.setOut(new PrintStream(baos, true));
-
- Session session = Session.getInstance(props);
- MimeMessage message = new MimeMessage(session);
- message.setFrom(new InternetAddress("test@localhost"));
- message.setRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress("test@localhost"));
- message.setText("test");
-
- Transport.send(message);
- Assert.assertTrue(baos.toString().contains("EHLO some.full.qualified.name.com"));
-
- } finally {
- System.setOut(original);
- }
-
- }
-
- public void testGERONIMO4594() throws Exception {
- Assert.assertTrue(doGERONIMO4594(true, true));
- }
-
- public void testGERONIMO4594Fail0() throws Exception {
- Assert.assertFalse(doGERONIMO4594(false, true));
- }
-
- public void testGERONIMO4594Fail1() throws Exception {
- Assert.assertFalse(doGERONIMO4594(false, false));
- }
-
- public void testGERONIMO4594Fail2() throws Exception {
- Assert.assertFalse(doGERONIMO4594(true, false));
- }
-
- private boolean doGERONIMO4594(boolean decode, boolean encode) throws Exception {
-
- final String specialFileName = "encoded_filename_\u00C4\u00DC\u00D6\u0226(test).pdf";
-
- System.setProperty("mail.mime.decodefilename", String.valueOf(decode));
- System.setProperty("mail.mime.encodefilename", String.valueOf(encode));
- try {
-
- start();
-
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.transport.protocol", "smtp");
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- props.setProperty("mail.store.protocol", "imap");
- props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
- //props.setProperty("mail.debug","true");
- Session session = Session.getInstance(props);
-
- MimeMessage msg = new MimeMessage(session);
- msg.setSubject("a file for you");
- msg.setRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress("serveruser@localhost"));
- msg.setFrom(new InternetAddress("serveruser@localhost"));
-
- MimeBodyPart messageBodyPart = new MimeBodyPart();
- Multipart multipart = new MimeMultipart();
- messageBodyPart.setText("This is message body");
- File file = MailServer.getAbsoluteFilePathFromClassPath("pdf-test.pdf");
- Assert.assertTrue(file.exists());
- DataSource source = new FileDataSource(file.getAbsoluteFile());
- messageBodyPart.setDataHandler(new DataHandler(source));
- messageBodyPart.setFileName(specialFileName);
- multipart.addBodyPart(messageBodyPart);
- msg.setContent(multipart);
- sendMessage(msg);
- server.ensureMsgCount(1);
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(1, f.getMessageCount());
- Message[] messages = new Message[2];
- messages[0] = f.getMessage(1);
- boolean match = specialFileName.equals(((Multipart) messages[0].getContent()).getBodyPart(0).getFileName());
- f.close(false);
- store.close();
- return match;
-
- } finally {
- System.setProperty("mail.mime.decodefilename", "false");
- System.setProperty("mail.mime.encodefilename", "false");
- }
-
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java
deleted file mode 100644
index ff09eb8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
- * 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;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Properties;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Store;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.james.protocols.lib.PortUtil;
-
-public class AuthenticationTest extends TestCase {
-
- public void testImplUsage() throws Exception {
-
- //check that we load our mail impl
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "imap");
- Session jmsession = Session.getInstance(props);
- Assert.assertEquals(org.apache.geronimo.javamail.store.imap.IMAPStore.class, jmsession.getStore().getClass());
-
- }
-
- public void testAuthenticatePlain() throws Exception {
-
- final int listenerPort = PortUtil.getNonPrivilegedPort();
- //greenmail does not have AUTHENTICATE "PLAIN" support
- FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer(null, "user", "pass");
- fs.startServer(listenerPort);
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.imap.port", String.valueOf(listenerPort));
- props.setProperty("mail.debug", String.valueOf(true));
- props.setProperty("mail.debug.auth", String.valueOf(true));
-
- Session session = Session.getInstance(props);
- Store store = session.getStore("imap");
- store.connect("localhost", "user", "pass");
- assertTrue(store.isConnected());
- fs.join();
- assertNull(fs.exception);
- }
-
- public void testAuthenticatePlainFail() throws Exception {
-
- final int listenerPort = PortUtil.getNonPrivilegedPort();
- //greenmail does not have AUTHENTICATE "PLAIN" support
- FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer(null, "user", "pass");
- fs.startServer(listenerPort);
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.imap.port", String.valueOf(listenerPort));
- props.setProperty("mail.debug", String.valueOf(true));
- props.setProperty("mail.debug.auth", String.valueOf(true));
- Session session = Session.getInstance(props);
- Store store = session.getStore("imap");
-
- try {
-
- store.connect("localhost", "userXXX", "passXXX");
- fail();
- } catch (MessagingException e) {
- //expected
- }
- }
-
- public void testAuthenticatePlainAuthzid() throws Exception {
-
- final int listenerPort = PortUtil.getNonPrivilegedPort();
- //greenmail does not have AUTHENTICATE "PLAIN" support
- FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer("authzid", "user", "pass");
- fs.startServer(listenerPort);
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.imap.port", String.valueOf(listenerPort));
- props.setProperty("mail.debug", String.valueOf(true));
- props.setProperty("mail.debug.auth", String.valueOf(true));
- props.setProperty("mail.imap.sasl.authorizationid", "authzid");
-
- Session session = Session.getInstance(props);
- Store store = session.getStore("imap");
- store.connect("localhost", "user", "pass");
- assertTrue(store.isConnected());
- fs.join();
- assertNull(fs.exception);
- }
-
-
- private class FakeImapAuthPlainServer extends Thread{
-
- private ServerSocket serverSocket;
- private Socket socket;
- private String authzid;
- private String username;
- private String password;
- Exception exception;
-
- private FakeImapAuthPlainServer(String authzid, String username, String password) {
- this.password = password;
- this.username = username;
- this.authzid = authzid==null?"":authzid;
- }
-
- void startServer(int port) throws IOException {
-
- serverSocket = new ServerSocket(port);
- this.setDaemon(false);
- this.start();
-
- }
-
-
- public void run() {
- try {
- socket = serverSocket.accept();
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
- pw.write("* OK ready\r\n");
- pw.flush();
- String tag = br.readLine().split(" ")[0];
- pw.write("* OK IMAP4rev1 Server ready\r\n");
- pw.write("* CAPABILITY IMAP4rev1 AUTH=PLAIN\r\n");
- pw.write(tag+" OK CAPABILITY completed.\r\n");
- pw.flush();
- tag = br.readLine().split(" ")[0];
- pw.write("+ \r\n");
- pw.flush();
- String authline = new String(Base64.decode(br.readLine()));
- System.out.println("authline : "+authline );
-
- if(!"".equals(authzid) && !(authzid+"\0"+username+"\0"+password).equals(authline)) {
- pw.write(tag+" BAD username password invalid.\r\n");
- pw.flush();
- return;
- }
-
- if("".equals(authzid) && !(username+"\0"+username+"\0"+password).equals(authline) && !("\0"+username+"\0"+password).equals(authline)) {
- pw.write(tag+" BAD username password invalid.\r\n");
- pw.flush();
- return;
- }
-
- pw.write(tag + " OK Authenticated.\r\n");
- pw.flush();
-
- String fin = br.readLine();
- tag = fin.split(" ")[0];
-
- if(fin.contains("CAPA")) {
- pw.write("* CAPABILITY IMAP4rev1 AUTH=PLAIN\r\n");
- pw.write(tag+" OK CAPABILITY completed.\r\n");
- pw.flush();
- tag = br.readLine().split(" ")[0];
- pw.write(tag+" OK NOOP.\r\n");
- }
- else {
- pw.write(tag+" OK NOOP.\r\n");
- }
-
- pw.flush();
-
- } catch (Exception e) {
- exception = e;
- }finally {
-
- try {
- socket.close();
- } catch (Exception e) {
- //ignore
- }
-
- try {
- serverSocket.close();
- } catch (Exception e) {
- //ignore
- }
-
- }
- }
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java
deleted file mode 100644
index 3dd7866..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * 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;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.Properties;
-
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
-
-
-public class IMAPStoreTest extends AbstractProtocolTest {
-
- public void testSimple() throws Exception {
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- Session session = Session.getInstance(props);
-
- // Load the message from IMAP
- Store store = session.getStore("imap");
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder folder = store.getFolder("INBOX");
- folder.open(Folder.READ_ONLY);
- Message[] messages = new Message[2];
- messages[0] = folder.getMessage(1);
- messages[1] = folder.getMessage(2);
- checkMessages(messages);
- folder.close(false);
- store.close();
- }
-
-
- private void checkMessages(Message[] messages) throws Exception {
- MimeMessage msg1 = (MimeMessage)messages[0];
- Object content = msg1.getContent();
- assertTrue(content instanceof MimeMultipart);
- MimeMultipart multipart = (MimeMultipart)content;
- assertEquals("First part", multipart.getBodyPart(0).getContent());
- assertEquals("Second part", multipart.getBodyPart(1).getContent());
- checkMessage(msg1);
-
- MimeMessage msg2 = (MimeMessage)messages[1];
- assertEquals("Foo Bar", msg2.getContent().toString().trim());
- checkMessage(msg2);
- }
-
- private void checkMessage(MimeMessage input) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- input.writeTo(out);
-
- Properties props = new Properties();
- Session s = Session.getInstance(props);
-
- byte [] inputData = out.toByteArray();
- System.out.println(new String(inputData, 0, inputData.length));
-
- MimeMessage output = new MimeMessage(s, new ByteArrayInputStream(inputData));
-
- assertEquals(input.getContentType().toLowerCase(), output.getContentType().toLowerCase());
- }
-
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
deleted file mode 100644
index 9ef05e7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.BufferedReader;
-
-import javax.mail.internet.MimeMessage;
-
-import junit.framework.TestCase;
-import org.apache.geronimo.javamail.store.imap.IMAPStoreTest;
-
-public class IMAPBodyStructureTest extends TestCase {
-
- public void testMultipart() throws Exception {
- InputStream in = IMAPStoreTest.class.getResourceAsStream("/imap/multipart.bodystructure");
- BufferedReader r = new BufferedReader(new InputStreamReader(in));
- try {
- IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(r.readLine().getBytes("ISO8859-1"));
- IMAPBodyStructure s = new IMAPBodyStructure(tokenizer);
- assertNull(s.disposition.getDisposition());
- assertNull(s.md5Hash);
- } finally {
- in.close();
- }
- }
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java
deleted file mode 100644
index a91133d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/**
- * 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.InputStream;
-import java.util.Properties;
-
-import javax.mail.Address;
-import javax.mail.FetchProfile;
-import javax.mail.Flags;
-import javax.mail.Flags.Flag;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.Transport;
-import javax.mail.UIDFolder;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import junit.framework.Assert;
-
-import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
-import org.apache.geronimo.javamail.testserver.MailServer.DummySocketFactory;
-
-public class POP3StoreTest extends AbstractProtocolTest {
-
-
-
-
- public void testSendRetrieve() throws Exception {
-
- start();
-
- // Setup JavaMail session
- Properties props = new Properties();
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- props.setProperty("mail.debug","true");
- Session session = Session.getInstance(props);
- // Send messages for the current test to James
- sendMessage(session, "/messages/multipart.msg");
- sendMessage(session, "/messages/simple.msg");
- server.ensureMsgCount(2);
-
- props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- Message[] messages = new Message[2];
- messages[0] = f.getMessage(1);
- messages[1] = f.getMessage(2);
- checkMessages(messages);
- f.close(false);
- store.close();
- }
-
-
-
-
- private void checkMessages(Message[] messages) throws Exception {
- MimeMessage msg1 = (MimeMessage)messages[0];
- Object content = msg1.getContent();
- assertTrue(content instanceof MimeMultipart);
- MimeMultipart multipart = (MimeMultipart)content;
- assertEquals("First part", multipart.getBodyPart(0).getContent());
- assertEquals("Second part", multipart.getBodyPart(1).getContent());
- checkMessage(msg1);
-
- MimeMessage msg2 = (MimeMessage)messages[1];
- assertEquals("Foo Bar", msg2.getContent().toString().trim());
- checkMessage(msg2);
- }
-
- private void checkMessage(MimeMessage input) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- input.writeTo(out);
-
- Properties props = new Properties();
- Session s = Session.getInstance(props);
-
- byte [] inputData = out.toByteArray();
- System.out.println(new String(inputData, 0, inputData.length));
-
- MimeMessage output = new MimeMessage(s, new ByteArrayInputStream(inputData));
-
- assertEquals(input.getContentType().toLowerCase(), output.getContentType().toLowerCase());
- }
-
-
- public void testStartTLS() throws Exception {
-
- pop3Conf.enableSSL(true, false);
-
- start();
-
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3.starttls.required", "true");
- props.setProperty("mail.pop3.ssl.trust", "*");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- f.close(false);
- store.close();
-
- }
-
- public void testAPOP() throws Exception {
-
- pop3Conf.enableSSL(true, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3.apop.enable", "true");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- f.close(false);
- store.close();
-
- }
-
- public void testFetch() throws Exception {
-
-
- pop3Conf.enableSSL(true, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- FetchProfile fp = new FetchProfile();
- fp.add(UIDFolder.FetchProfileItem.UID);
- fp.add(FetchProfile.Item.CONTENT_INFO);
-
- Message[] msgs = f.getMessages();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- Assert.assertEquals(2, msgs.length);
-
- f.fetch(msgs, fp);
- Assert.assertEquals(2, f.getMessageCount());
-
- for (int i = 0; i < msgs.length; i++) {
- Message message = msgs[i];
- message.writeTo(bout);
- String msg = bout.toString();
- Assert.assertNotNull(msg);
- int num = message.getMessageNumber();
- Assert.assertTrue(num > 0);
- String uid = ((POP3Folder) f).getUID(message);
- Assert.assertNotNull(uid);
- Assert.assertTrue(!uid.isEmpty());
- }
-
- f.close(false);
- store.close();
-
- }
-
-
-
- public void testDelete() throws Exception {
-
-
- pop3Conf.enableSSL(true, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_WRITE); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- Message[] msgs = f.getMessages();
- f.setFlags(msgs, new Flags(Flag.DELETED), true);
- Assert.assertEquals(2, f.getMessageCount());
- f.getMessage(1).getSubject(); //should fail
- //Assert.assertEquals(2, f.expunge());
- f.close(false);
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(0, f.getMessageCount());
- store.close();
-
- }
-
-
-
- public void testStartTLSFail() throws Exception {
-
-
- pop3Conf.enableSSL(false, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3.starttls.required", "true");
- props.setProperty("mail.pop3.ssl.trust", "*");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- try {
- store.connect("127.0.0.1", "serveruser", "serverpass");
- fail();
- } catch (MessagingException e) {
- //Expected
- }
- }
-
- public void testSSLEnable() throws Exception {
-
-
- pop3Conf.enableSSL(false, true);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3.ssl.enable", "true");
- props.setProperty("mail.pop3.ssl.trust", "*");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- f.close(false);
- store.close();
-
- }
-
- public void testSSLPop3s() throws Exception {
-
-
- pop3Conf.enableSSL(false, true);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3s");
- props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3s.ssl.trust", "*");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- f.close(false);
- store.close();
-
- }
-
- public void testSSLPop3sFactoryClass() throws Exception {
-
-
- pop3Conf.enableSSL(false, true);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3s");
- props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3s.ssl.trust", "*");
- props.setProperty("mail.pop3s.ssl.socketFactory.class", DummySocketFactory.class.getName());
-
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- try {
- store.connect("127.0.0.1", "serveruser", "serverpass");
- fail();
- } catch (MessagingException e) {
- Assert.assertEquals("dummy socket factory", e.getCause().getCause().getMessage());
-
- //Expected
- }
-
-
-
- }
-
- public void testSSLPop3sFactoryInstance() throws Exception {
-
-
- pop3Conf.enableSSL(false, true);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3s");
- props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3s.ssl.trust", "*");
- props.put("mail.pop3s.ssl.socketFactory", new DummySocketFactory());
-
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- try {
- store.connect("127.0.0.1", "serveruser", "serverpass");
- fail();
- } catch (MessagingException e) {
- Assert.assertEquals("dummy socket factory", e.getCause().getMessage());
-
- //Expected
- }
-
- }
-
- public void testSSLPop3sNotEnabled() throws Exception {
-
-
- pop3Conf.enableSSL(false, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3s");
- props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- props.setProperty("mail.pop3s.ssl.trust", "*");
- props.setProperty("mail.pop3s.ssl.enable", "false");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
- Assert.assertEquals(2, f.getMessageCount());
- f.close(false);
- store.close();
-
- }
-
- public void testPop3GetMsgs() throws Exception {
-
-
- pop3Conf.enableSSL(false, false);
-
- start();
- sendTestMsgs();
-
- Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
- props.setProperty("mail.debug", "true");
-
- Session jmsession = Session.getInstance(props);
- Store store = jmsession.getStore();
- store.connect("127.0.0.1", "serveruser", "serverpass");
- Folder f = store.getFolder("INBOX");
- f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
-
-
- Message[] msgs = f.getMessages();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- Assert.assertEquals(2, msgs.length);
-
- for (int i = 0; i < msgs.length; i++) {
- Message message = msgs[i];
- message.writeTo(bout);
- String msg = bout.toString();
- Assert.assertNotNull(msg);
- int num = message.getMessageNumber();
- Assert.assertTrue(num > 0);
- String uid = ((POP3Folder) f).getUID(message);
- Assert.assertNotNull(uid);
- Assert.assertTrue(!uid.isEmpty());
- }
-
- f.close(false);
- store.close();
-
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java
deleted file mode 100644
index 8648869..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * 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.testserver;
-
-import java.io.InputStream;
-import java.util.Properties;
-
-import javax.mail.Address;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.geronimo.javamail.store.pop3.POP3StoreTest;
-
-public abstract class AbstractProtocolTest extends TestCase {
-
- protected MailServer server = new MailServer();
- protected MailServer.Pop3TestConfiguration pop3Conf;
- protected MailServer.SmtpTestConfiguration smtpConf;
- protected MailServer.ImapTestConfiguration imapConf;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- pop3Conf = new MailServer.Pop3TestConfiguration();
- smtpConf = new MailServer.SmtpTestConfiguration();
- imapConf = new MailServer.ImapTestConfiguration();
-
- }
-
- protected void start() throws Exception {
-
- server.start(smtpConf, pop3Conf, imapConf);
-
- }
-
- public void testImplUsageImap() throws Exception {
-
- //check that we load our mail impl
- final Properties props = new Properties();
- props.setProperty("mail.store.protocol", "imap");
- final Session jmsession = Session.getInstance(props);
- Assert.assertEquals(org.apache.geronimo.javamail.store.imap.IMAPStore.class, jmsession.getStore().getClass());
-
- }
-
- public void testImplUsagePop3() throws Exception {
-
- //check that we load our mail impl
- final Properties props = new Properties();
- props.setProperty("mail.store.protocol", "pop3");
- final Session jmsession = Session.getInstance(props);
- Assert.assertEquals(org.apache.geronimo.javamail.store.pop3.POP3Store.class, jmsession.getStore().getClass());
-
- }
-
- public void testImplUsageSmtp() throws Exception {
-
- //check that we load our mail impl
- final Properties props = new Properties();
- props.setProperty("mail.transport.protocol", "smtp");
- final Session jmsession = Session.getInstance(props);
- Assert.assertEquals(org.apache.geronimo.javamail.transport.smtp.SMTPTransport.class, jmsession.getTransport().getClass());
-
- }
-
- protected void sendTestMsgs() throws Exception {
- final Properties props = new Properties();
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- props.setProperty("mail.debug", "true");
- final Session session = Session.getInstance(props);
- sendMessage(session, "/messages/multipart.msg");
- sendMessage(session, "/messages/simple.msg");
- server.ensureMsgCount(2);
- }
-
- protected void sendMessage(final Session session, final String msgFile) throws Exception {
- MimeMessage message;
- final InputStream in = POP3StoreTest.class.getResourceAsStream(msgFile);
- try {
- message = new MimeMessage(session, in);
- } finally {
- in.close();
- }
- Transport.send(message, new Address[] { new InternetAddress("serveruser@localhost") });
- }
-
- protected void sendMessage(final MimeMessage message) throws Exception {
- Transport.send(message, new Address[] { new InternetAddress("serveruser@localhost") });
- }
-
- @Override
- protected void tearDown() throws Exception {
- server.stop();
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java
deleted file mode 100644
index 4c0bead..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * 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.testserver;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import javax.annotation.Resource;
-
-import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.exception.BadCredentialsException;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.pop3server.mailbox.MailboxAdapter;
-import org.apache.james.protocols.api.Request;
-import org.apache.james.protocols.api.Response;
-import org.apache.james.protocols.lib.POP3BeforeSMTPHelper;
-import org.apache.james.protocols.lib.Slf4jLoggerAdapter;
-import org.apache.james.protocols.pop3.POP3Response;
-import org.apache.james.protocols.pop3.POP3Session;
-import org.apache.james.protocols.pop3.core.AbstractApopCmdHandler;
-import org.apache.james.protocols.pop3.mailbox.Mailbox;
-
-public class ApopCmdHandler extends AbstractApopCmdHandler {
-
- private MailboxManager manager;
-
-
- @Resource(name = "mailboxmanager")
- public void setMailboxManager(MailboxManager manager) {
- this.manager = manager;
- }
-
- @Override
- public Response onCommand(POP3Session session, Request request) {
- Response response = super.onCommand(session, request);
- if (POP3Response.OK_RESPONSE.equals(response.getRetCode())) {
- POP3BeforeSMTPHelper.addIPAddress(session.getRemoteAddress().getAddress().getHostAddress());
- }
- return response;
- }
-
- @Override
- protected Mailbox auth(POP3Session session, String apopTimestamp, String user, String digest) throws Exception {
- MailboxSession mSession = null;
-
- String plaintextpassword = "serverpass";
-
- try {
- final String toHash = apopTimestamp.trim()+plaintextpassword;
-
- if(!getMD5(toHash).equals(digest))
- {
- System.out.println("Digests does not match");
- return null;
- }
-
-
- session.setUser(user);
-
- mSession = manager.createSystemSession(session.getUser(), new Slf4jLoggerAdapter(session.getLogger()));
- manager.startProcessingRequest(mSession);
- MailboxPath inbox = MailboxPath.inbox(mSession);
-
- // check if the mailbox exists, if not create it
- if (!manager.mailboxExists(inbox, mSession)) {
- manager.createMailbox(inbox, mSession);
- }
- MessageManager mailbox = manager.getMailbox(MailboxPath.inbox(mSession), mSession);
- return new MailboxAdapter(manager, mailbox, mSession);
- } catch (BadCredentialsException e) {
- return null;
- } catch (MailboxException e) {
- throw new IOException("Unable to access mailbox for user " + session.getUser(), e);
- } finally {
- if (mSession != null) {
- manager.endProcessingRequest(mSession);
- }
- }
-
- }
-
- private static String getMD5(final String input) {
- try {
- final MessageDigest md = MessageDigest.getInstance("MD5");
- final byte[] messageDigest = md.digest(input.getBytes());
- final BigInteger number = new BigInteger(1, messageDigest);
- String hashtext = number.toString(16);
- // Now we need to zero pad it if you actually want the full 32 chars.
- while (hashtext.length() < 32) {
- hashtext = "0" + hashtext;
- }
- return hashtext;
- }
- catch (final NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java
deleted file mode 100644
index b73d6f4..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java
+++ /dev/null
@@ -1,590 +0,0 @@
-/**
- * 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.testserver;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-
-import javax.mail.Flags;
-import javax.mail.internet.MimeMessage;
-import javax.net.ssl.SSLSocketFactory;
-
-import org.apache.commons.configuration.DefaultConfigurationBuilder;
-import org.apache.james.dnsservice.api.DNSService;
-import org.apache.james.domainlist.api.DomainListException;
-import org.apache.james.domainlist.api.mock.SimpleDomainList;
-import org.apache.james.filesystem.api.mock.MockFileSystem;
-import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
-import org.apache.james.imap.encode.main.DefaultLocalizer;
-import org.apache.james.imap.main.DefaultImapDecoderFactory;
-import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
-import org.apache.james.imapserver.netty.IMAPServer;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.acl.GroupMembershipResolver;
-import org.apache.james.mailbox.acl.MailboxACLResolver;
-import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
-import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.store.Authenticator;
-import org.apache.james.mailbox.store.StoreMailboxManager;
-import org.apache.james.mailrepository.mock.MockMailRepositoryStore;
-import org.apache.james.pop3server.netty.POP3Server;
-import org.apache.james.protocols.lib.PortUtil;
-import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader;
-import org.apache.james.queue.api.MailQueue;
-import org.apache.james.queue.api.MailQueue.MailQueueItem;
-import org.apache.james.queue.api.MailQueueFactory;
-import org.apache.james.queue.file.FileMailQueueFactory;
-import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.smtpserver.netty.SMTPServer;
-import org.apache.james.user.api.UsersRepositoryException;
-import org.apache.james.user.lib.mock.MockUsersRepository;
-import org.apache.mailet.HostAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-//James based POP3 or IMAP or SMTP server (for unittesting only)
-public class MailServer {
-
- private POP3Server pop3Server;
- private IMAPServer imapServer;
- private SMTPServer smtpServer;
- private AlterableDNSServer dnsServer;
- private final MockUsersRepository usersRepository = new MockUsersRepository();
- private final MockFileSystem fileSystem = new MockFileSystem();
- private MockProtocolHandlerLoader protocolHandlerChain;
- private StoreMailboxManager<Long> mailboxManager;
-
- private MockMailRepositoryStore store;
- private DNSService dnsService;
- private MailQueueFactory queueFactory;
- private MailQueue queue;
- private final Semaphore sem = new Semaphore(0);
- private final Logger log = LoggerFactory.getLogger("Mock");
-
- public void ensureMsgCount(final int count) throws InterruptedException {
- sem.acquire(count);
- }
-
- private class Fetcher extends Thread {
-
- private final MailQueue queue;
- private final MessageManager mailbox;
- private final MailboxSession session;
-
- Fetcher(final MailQueue queue, final MessageManager mailbox, final MailboxSession session) {
- super();
- this.queue = queue;
- this.mailbox = mailbox;
- this.session = session;
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- System.out.println("Await new mail ...");
- final MailQueueItem item = queue.deQueue();
- System.out.println("got it");
- final MimeMessage msg = item.getMail().getMessage();
- final ByteArrayOutputStream bout = new ByteArrayOutputStream();
- msg.writeTo(bout);
- mailbox.appendMessage(new ByteArrayInputStream(bout.toByteArray()), new Date(), session, true, new Flags());
- item.done(true);
- sem.release();
- System.out.println("mail copied over");
- } catch (final Exception e) {
- e.printStackTrace();
- return;
- }
- }
- }
-
- }
-
- public MailServer() {
- super();
- try {
- usersRepository.addUser("serveruser", "serverpass");
- } catch (final UsersRepositoryException e) {
- throw new RuntimeException(e);
- }
-
- }
-
- public void start(final SmtpTestConfiguration smtpConfig, final Pop3TestConfiguration pop3Config, final ImapTestConfiguration imapConfig)
- throws Exception {
- setUpServiceManager();
-
- imapServer = new IMAPServer();
-
- imapServer.setImapEncoder(DefaultImapEncoderFactory.createDefaultEncoder(new DefaultLocalizer(), false));
- imapServer.setImapDecoder(DefaultImapDecoderFactory.createDecoder());
-
- pop3Server = new POP3Server();
- pop3Server.setProtocolHandlerLoader(protocolHandlerChain);
-
- smtpServer = new SMTPServer() {
- @Override
- protected java.lang.Class<? extends org.apache.james.protocols.lib.handler.HandlersPackage> getJMXHandlersPackage() {
- return RefinedJMXHandlersLoader.class;
- };
-
- };
- smtpServer.setProtocolHandlerLoader(protocolHandlerChain);
- smtpServer.setDNSService(dnsServer);
-
- imapServer.setFileSystem(fileSystem);
- pop3Server.setFileSystem(fileSystem);
- smtpServer.setFileSystem(fileSystem);
-
- imapServer.setLog(log);
- pop3Server.setLog(log);
- smtpServer.setLog(log);
-
- final MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, "serveruser", "INBOX");
- final MailboxSession session = mailboxManager.login("serveruser", "serverpass", LoggerFactory.getLogger("Test"));
-
- if (!mailboxManager.mailboxExists(mailboxPath, session)) {
- mailboxManager.createMailbox(mailboxPath, session);
- }
-
- imapServer.setImapProcessor(DefaultImapProcessorFactory.createXListSupportingProcessor(mailboxManager, null, null));//new StoreSubscriptionManager(new InMemoryMailboxSessionMapperFactory()), null));
-
- //setupTestMails(session, mailboxManager.getMailbox(mailboxPath, session));
-
- new Fetcher(queue, mailboxManager.getMailbox(mailboxPath, session), session).start();
-
- smtpConfig.init();
- pop3Config.init();
- imapConfig.init();
-
- smtpServer.configure(smtpConfig);
- pop3Server.configure(pop3Config);
- imapServer.configure(imapConfig);
-
- smtpServer.init();
- pop3Server.init();
- imapServer.init();
-
- }
-
- public void stop() throws Exception {
-
- if (protocolHandlerChain != null) {
- protocolHandlerChain.dispose();
- }
-
- if (imapServer != null) {
- imapServer.destroy();
- }
-
- if (pop3Server != null) {
- pop3Server.destroy();
- }
-
- if (smtpServer != null) {
- smtpServer.destroy();
- }
-
- }
-
- /* protected void setupTestMailsx(MailboxSession session, MessageManager mailbox) throws MailboxException {
- mailbox.appendMessage(new ByteArrayInputStream(content), new Date(), session, true, new Flags());
- byte[] content2 = ("EMPTY").getBytes();
- mailbox.appendMessage(new ByteArrayInputStream(content2), new Date(), session, true, new Flags());
- }*/
-
- protected void setUpServiceManager() throws Exception {
- protocolHandlerChain = new MockProtocolHandlerLoader();
- protocolHandlerChain.put("usersrepository", usersRepository);
-
- final InMemoryMailboxSessionMapperFactory factory = new InMemoryMailboxSessionMapperFactory();
- final MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
- final GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
- mailboxManager = new StoreMailboxManager<Long>(factory, new Authenticator() {
-
- public boolean isAuthentic(final String userid, final CharSequence passwd) {
- try {
- return usersRepository.test(userid, passwd.toString());
- } catch (final UsersRepositoryException e) {
- e.printStackTrace();
- return false;
- }
- }
- }, aclResolver, groupMembershipResolver);
- mailboxManager.init();
-
- protocolHandlerChain.put("mailboxmanager", mailboxManager);
-
- protocolHandlerChain.put("fileSystem", fileSystem);
-
- //smtp
- dnsServer = new AlterableDNSServer();
- store = new MockMailRepositoryStore();
- protocolHandlerChain.put("mailStore", store);
- protocolHandlerChain.put("dnsservice", dnsServer);
- protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);
-
- protocolHandlerChain.put("recipientrewritetable", new RecipientRewriteTable() {
-
- public void addRegexMapping(final String user, final String domain, final String regex) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void removeRegexMapping(final String user, final String domain, final String regex)
- throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void addAddressMapping(final String user, final String domain, final String address)
- throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void removeAddressMapping(final String user, final String domain, final String address)
- throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void addErrorMapping(final String user, final String domain, final String error) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void removeErrorMapping(final String user, final String domain, final String error)
- throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public Collection<String> getUserDomainMappings(final String user, final String domain) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void addMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void removeMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public Map<String, Collection<String>> getAllMappings() throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void addAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public void removeAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public Collection<String> getMappings(final String user, final String domain) throws ErrorMappingException,
- RecipientRewriteTableException {
- throw new UnsupportedOperationException("Not implemented");
- }
- });
-
- protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);
-
- final FileMailQueueFactory ff = new FileMailQueueFactory();// MockMailQueueFactory();
- ff.setLog(log);
- ff.setFileSystem(fileSystem);
- queueFactory = ff;
-
- queue = queueFactory.getQueue(MailQueueFactory.SPOOL);
- protocolHandlerChain.put("mailqueuefactory", queueFactory);
- protocolHandlerChain.put("domainlist", new SimpleDomainList() {
-
- @Override
- public String getDefaultDomain() {
- return "localhost";
- }
-
- @Override
- public String[] getDomains() throws DomainListException {
- return new String[] { "localhost" };
- }
-
- @Override
- public boolean containsDomain(final String serverName) {
- return "localhost".equals(serverName);
- }
- });
-
- }
-
- /**
- * @return the queue
- */
- public MailQueue getQueue() {
- return queue;
- }
-
- public static File getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) throws FileNotFoundException {
-
- File configFile = null;
- final URL configURL = MailServer.class.getClassLoader().getResource(fileNameFromClasspath);
- if (configURL != null) {
- try {
- configFile = new File(configURL.toURI());
- } catch (URISyntaxException e) {
- configFile = new File(configURL.getPath());
- }
-
- //Java 7 only
- /*if(!configFile.exists()) {
- try {
- configFile = Paths.get(configURL.toURI()).toFile();
- } catch (URISyntaxException e) {
- throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+ " due to "+e);
- }
- }*/
-
- if (configFile.exists()) {
- return configFile;
- } else {
- throw new FileNotFoundException("Cannot read from "+configFile.getAbsolutePath()+" (original resource was "+fileNameFromClasspath+", URL: "+configURL+"), because the file does not exist");
- }
-
- } else {
- throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+", because resource cannot be found within the classpath");
- }
-
- }
-
- public static abstract class AbstractTestConfiguration extends DefaultConfigurationBuilder {
-
- private final int listenerPort = PortUtil.getNonPrivilegedPort();
-
- /**
- * @return the listenerPort
- */
- public int getListenerPort() {
- return listenerPort;
- }
-
- public AbstractTestConfiguration enableSSL(final boolean enableStartTLS, final boolean enableSSL) throws FileNotFoundException {
- addProperty("tls.[@startTLS]", enableStartTLS);
- addProperty("tls.[@socketTLS]", enableSSL);
- addProperty("tls.keystore", "file://" + getAbsoluteFilePathFromClassPath("dummykeystore.jks").getAbsolutePath());
- addProperty("tls.secret", "123456");
- addProperty("tls.provider", "org.bouncycastle.jce.provider.BouncyCastleProvider");
- return this;
- }
-
- public void init() {
- addProperty("[@enabled]", true);
- addProperty("bind", "127.0.0.1:" + this.listenerPort);
- addProperty("connectiontimeout", "360000");
- //addProperty("jmxName", getServertype().name()+"on"+this.listenerPort);
- addProperty("helloName", "jamesserver");
- addProperty("helloName.[@autodetect]", false);
- }
-
- }
-
- public static class Pop3TestConfiguration extends AbstractTestConfiguration {
-
- @Override
- public void init() {
- super.init();
-
- addProperty("helloName", "pop3 on port " + getListenerPort());
-
- addProperty("handlerchain.[@coreHandlersPackage]", RefinedCoreCmdHandlerLoader.class.getName());
-
- }
-
- }
-
- public static class ImapTestConfiguration extends AbstractTestConfiguration {
-
- @Override
- public void init() {
- super.init();
-
- addProperty("helloName", "imap on port " + getListenerPort());
-
- }
-
- }
-
- public static class SmtpTestConfiguration extends AbstractTestConfiguration {
-
- @Override
- public void init() {
- super.init();
- addProperty("handlerchain.handler[@class]", RefinedSmtpCoreCmdHandlerLoader.class.getName());
-
- }
-
- public SmtpTestConfiguration setRequireAuth(final boolean requireAuth) {
-
- addProperty("authRequired", requireAuth);
- return this;
- }
-
- public SmtpTestConfiguration setHeloEhloEnforcement(final boolean heloEhloEnforcement) {
-
- addProperty("heloEhloEnforcement", heloEhloEnforcement);
- return this;
- }
-
- }
-
- public static class DummySocketFactory extends SSLSocketFactory {
-
- @Override
- public Socket createSocket(final String host, final int port) throws IOException, UnknownHostException {
- throw new IOException("dummy socket factory");
- }
-
- @Override
- public Socket createSocket(final InetAddress host, final int port) throws IOException {
- throw new IOException("dummy socket factory");
- }
-
- @Override
- public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException,
- UnknownHostException {
- throw new IOException("dummy socket factory");
- }
-
- @Override
- public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort)
- throws IOException {
- throw new IOException("dummy socket factory");
- }
-
- @Override
- public Socket createSocket(final Socket arg0, final String arg1, final int arg2, final boolean arg3) throws IOException {
- throw new IOException("dummy socket factory");
- }
-
- @Override
- public String[] getDefaultCipherSuites() {
- return new String[0];
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return new String[0];
- }
-
- }
-
- private final class AlterableDNSServer implements DNSService {
-
- private InetAddress localhostByName = null;
-
- public Collection<String> findMXRecords(final String hostname) {
- final List<String> res = new ArrayList<String>();
- if (hostname == null) {
- return res;
- }
- if ("james.apache.org".equals(hostname)) {
- res.add("nagoya.apache.org");
- }
- return res;
- }
-
- public Iterator<HostAddress> getSMTPHostAddresses(final String domainName) {
- throw new UnsupportedOperationException("Unimplemented mock service");
- }
-
- public InetAddress[] getAllByName(final String host) throws UnknownHostException {
- return new InetAddress[] { getByName(host) };
- }
-
- public InetAddress getByName(final String host) throws UnknownHostException {
- if (getLocalhostByName() != null) {
- if ("127.0.0.1".equals(host)) {
- return getLocalhostByName();
- }
- }
-
- if ("0.0.0.0".equals(host)) {
- return InetAddress.getByName("0.0.0.0");
- }
-
- if ("james.apache.org".equals(host)) {
- return InetAddress.getByName("james.apache.org");
- }
-
- if ("abgsfe3rsf.de".equals(host)) {
- throw new UnknownHostException();
- }
-
- if ("128.0.0.1".equals(host) || "192.168.0.1".equals(host) || "127.0.0.1".equals(host) || "127.0.0.0".equals(host)
- || "255.0.0.0".equals(host) || "255.255.255.255".equals(host)) {
- return InetAddress.getByName(host);
- }
-
- throw new UnsupportedOperationException("getByName not implemented in mock for host: " + host);
- }
-
- public Collection<String> findTXTRecords(final String hostname) {
- final List<String> res = new ArrayList<String>();
- if (hostname == null) {
- return res;
- }
-
- if ("2.0.0.127.bl.spamcop.net.".equals(hostname)) {
- res.add("Blocked - see http://www.spamcop.net/bl.shtml?127.0.0.2");
- }
- return res;
- }
-
- public InetAddress getLocalhostByName() {
- return localhostByName;
- }
-
- public void setLocalhostByName(final InetAddress localhostByName) {
- this.localhostByName = localhostByName;
- }
-
- public String getHostName(final InetAddress addr) {
- return addr.getHostName();
- }
-
- public InetAddress getLocalHost() throws UnknownHostException {
- return InetAddress.getLocalHost();
- }
- }
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java
deleted file mode 100644
index d2c0e9b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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.testserver;
-
-
-
-public class RefinedCoreCmdHandlerLoader extends org.apache.james.pop3server.core.CoreCmdHandlerLoader {
-
- public RefinedCoreCmdHandlerLoader() {
- super();
- getHandlers().add(ApopCmdHandler.class.getName());
-
- }
-
-
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java
deleted file mode 100644
index 32fd915..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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.testserver;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.james.protocols.lib.handler.HandlersPackage;
-import org.apache.james.smtpserver.jmx.CommandHandlerResultJMXMonitor;
-import org.apache.james.smtpserver.jmx.ConnectHandlerResultJMXMonitor;
-import org.apache.james.smtpserver.jmx.HookResultJMXMonitor;
-//import org.apache.james.smtpserver.jmx.LineHandlerResultJMXMonitor;
-
-public class RefinedJMXHandlersLoader implements HandlersPackage {
-
- private final List<String> handlers = new ArrayList<String>();
-
- public RefinedJMXHandlersLoader() {
- handlers.add(ConnectHandlerResultJMXMonitor.class.getName());
- handlers.add(CommandHandlerResultJMXMonitor.class.getName());
- //handlers.add(LineHandlerResultJMXMonitor.class.getName());
- handlers.add(HookResultJMXMonitor.class.getName());
- }
-
- /**
- * @see org.apache.james.protocols.api.handler.HandlersPackage#getHandlers()
- */
- public List<String> getHandlers() {
- return handlers;
- }
-
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java
deleted file mode 100644
index ba7f59d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * 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.testserver;
-
- /****************************************************************
- * 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. *
- ****************************************************************/
-
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.james.protocols.api.handler.CommandDispatcher;
-import org.apache.james.protocols.api.handler.CommandHandlerResultLogger;
-import org.apache.james.protocols.lib.handler.HandlersPackage;
-import org.apache.james.protocols.smtp.core.ExpnCmdHandler;
-import org.apache.james.protocols.smtp.core.HeloCmdHandler;
-import org.apache.james.protocols.smtp.core.HelpCmdHandler;
-import org.apache.james.protocols.smtp.core.NoopCmdHandler;
-import org.apache.james.protocols.smtp.core.PostmasterAbuseRcptHook;
-import org.apache.james.protocols.smtp.core.QuitCmdHandler;
-import org.apache.james.protocols.smtp.core.ReceivedDataLineFilter;
-import org.apache.james.protocols.smtp.core.RsetCmdHandler;
-import org.apache.james.protocols.smtp.core.VrfyCmdHandler;
-import org.apache.james.protocols.smtp.core.esmtp.AuthCmdHandler;
-import org.apache.james.protocols.smtp.core.esmtp.EhloCmdHandler;
-import org.apache.james.protocols.smtp.core.esmtp.MailSizeEsmtpExtension;
-import org.apache.james.protocols.smtp.core.esmtp.StartTlsCmdHandler;
-import org.apache.james.protocols.smtp.core.log.HookResultLogger;
-import org.apache.james.smtpserver.AddDefaultAttributesMessageHook;
-import org.apache.james.smtpserver.AuthRequiredToRelayRcptHook;
-import org.apache.james.smtpserver.DataLineJamesMessageHookHandler;
-import org.apache.james.smtpserver.JamesDataCmdHandler;
-import org.apache.james.smtpserver.JamesMailCmdHandler;
-import org.apache.james.smtpserver.JamesRcptCmdHandler;
-import org.apache.james.smtpserver.JamesWelcomeMessageHandler;
-import org.apache.james.smtpserver.SendMailHandler;
-import org.apache.james.smtpserver.SenderAuthIdentifyVerificationRcptHook;
-import org.apache.james.smtpserver.UsersRepositoryAuthHook;
-
-/**
- * This class represent the base command handlers which are shipped with james.
- */
-public class RefinedSmtpCoreCmdHandlerLoader implements HandlersPackage {
-
- private final String COMMANDDISPATCHER = CommandDispatcher.class.getName();
- private final String AUTHCMDHANDLER = AuthCmdHandler.class.getName();
- private final String DATACMDHANDLER = JamesDataCmdHandler.class.getName();
- private final String EHLOCMDHANDLER = EhloCmdHandler.class.getName();
- private final String EXPNCMDHANDLER = ExpnCmdHandler.class.getName();
- private final String HELOCMDHANDLER = HeloCmdHandler.class.getName();
- private final String HELPCMDHANDLER = HelpCmdHandler.class.getName();
- private final String MAILCMDHANDLER = JamesMailCmdHandler.class.getName();
- private final String NOOPCMDHANDLER = NoopCmdHandler.class.getName();
- private final String QUITCMDHANDLER = QuitCmdHandler.class.getName();
- private final String RCPTCMDHANDLER = JamesRcptCmdHandler.class.getName();
- private final String RSETCMDHANDLER = RsetCmdHandler.class.getName();
- private final String VRFYCMDHANDLER = VrfyCmdHandler.class.getName();
- private final String MAILSIZEHOOK = MailSizeEsmtpExtension.class.getName();
- private final String WELCOMEMESSAGEHANDLER = JamesWelcomeMessageHandler.class.getName();
- private final String USERSREPOSITORYAUTHHANDLER = UsersRepositoryAuthHook.class.getName();
- private final String POSTMASTERABUSEHOOK = PostmasterAbuseRcptHook.class.getName();
- private final String AUTHREQUIREDTORELAY = AuthRequiredToRelayRcptHook.class.getName();
- private final String SENDERAUTHIDENTITYVERIFICATION = SenderAuthIdentifyVerificationRcptHook.class.getName();
- private final String RECEIVEDDATALINEFILTER = ReceivedDataLineFilter.class.getName();
- private final String DATALINEMESSAGEHOOKHANDLER = DataLineJamesMessageHookHandler.class.getName();
- private final String STARTTLSHANDLER = StartTlsCmdHandler.class.getName();
-
- // MessageHooks
- private final String ADDDEFAULTATTRIBUTESHANDLER = AddDefaultAttributesMessageHook.class.getName();
- private final String SENDMAILHANDLER = SendMailHandler.class.getName();
-
- // logging stuff
- private final String COMMANDHANDLERRESULTLOGGER = CommandHandlerResultLogger.class.getName();
- private final String HOOKRESULTLOGGER = HookResultLogger.class.getName();
-
- private final List<String> commands = new LinkedList<String>();
-
- public RefinedSmtpCoreCmdHandlerLoader() {
- // Insert the base commands in the Map
- commands.add(WELCOMEMESSAGEHANDLER);
- commands.add(COMMANDDISPATCHER);
- commands.add(AUTHCMDHANDLER);
- commands.add(DATACMDHANDLER);
- commands.add(EHLOCMDHANDLER);
- commands.add(EXPNCMDHANDLER);
- commands.add(HELOCMDHANDLER);
- commands.add(HELPCMDHANDLER);
- commands.add(MAILCMDHANDLER);
- commands.add(NOOPCMDHANDLER);
- commands.add(QUITCMDHANDLER);
- commands.add(RCPTCMDHANDLER);
- commands.add(RSETCMDHANDLER);
- commands.add(VRFYCMDHANDLER);
- commands.add(MAILSIZEHOOK);
- commands.add(USERSREPOSITORYAUTHHANDLER);
- commands.add(AUTHREQUIREDTORELAY);
- commands.add(SENDERAUTHIDENTITYVERIFICATION);
- commands.add(POSTMASTERABUSEHOOK);
- commands.add(RECEIVEDDATALINEFILTER);
- commands.add(DATALINEMESSAGEHOOKHANDLER);
- commands.add(STARTTLSHANDLER);
- // Add the default messageHooks
- commands.add(ADDDEFAULTATTRIBUTESHANDLER);
- commands.add(SENDMAILHANDLER);
-
- // Add logging stuff
- commands.add(COMMANDHANDLERRESULTLOGGER);
- commands.add(HOOKRESULTLOGGER);
- }
-
- /**
- * @see org.apache.james.protocols.api.handler.HandlersPackage#getHandlers()
- */
- public List<String> getHandlers() {
- return commands;
- }
-}
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java
deleted file mode 100644
index d0f9ead..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.transport.smtp;
-
-import java.util.Properties;
-
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-
-import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
-
-public class SMTPTransportTest extends AbstractProtocolTest {
-
- public void testSSLEnable() throws Exception {
-
-
- smtpConf.enableSSL(false, false);
-
- start();
-
- Properties props = new Properties();
- props.setProperty("mail.transport.protocol", "smtp");
- props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
- props.setProperty("mail.debug", "true");
-
- Session jmsession = Session.getInstance(props);
- Transport t = jmsession.getTransport();
- t.connect();
-
- MimeMessage msg = new MimeMessage(jmsession);
- msg.setFrom(new InternetAddress("test@apache.org"));
- msg.setSubject("Hi!");
- msg.setText("All your base are belong to us");
-
-
- t.sendMessage(msg, new InternetAddress[]{new InternetAddress("testto@apache.org")});
-
- }
-
-
-}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks
deleted file mode 100644
index cb140cd..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks
+++ /dev/null
Binary files differ
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure
deleted file mode 100644
index e406923..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure
+++ /dev/null
@@ -1 +0,0 @@
-(("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 1281 28 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 1510 33 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "0016e6d976ed8989d30464e986d1") NIL NIL)
\ No newline at end of file
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg
deleted file mode 100644
index 8fbc2af..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg
+++ /dev/null
@@ -1,19 +0,0 @@
-Date: Sat, 11 Oct 2008 00:48:01 +0200 (CEST)
-From: from@localhost
-To: serveruser@localhost
-Message-ID: urn:uuid:219365EB848AD9CACB1223678880948
-Subject: Test
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="----=_Part_0_6727097.1223678881682"
-
-------=_Part_0_6727097.1223678881682
-Content-Type: text/plain; charset=us-ascii
-Content-Transfer-Encoding: 7bit
-
-First part
-------=_Part_0_6727097.1223678881682
-Content-Type: text/plain; charset=us-ascii
-Content-Transfer-Encoding: 7bit
-
-Second part
-------=_Part_0_6727097.1223678881682--
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg
deleted file mode 100644
index 9e429ed..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg
+++ /dev/null
@@ -1,11 +0,0 @@
-Date: Sat, 11 Oct 2008 00:48:01 +0200 (CEST)
-From: from@localhost
-To: serveruser@localhost
-Subject: Test Foo
-MIME-Version: 1.0
-Content-Type: text/plain; charset=us-ascii
-Content-Transfer-Encoding: 7bit
-
-Foo Bar
-
-
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf
deleted file mode 100644
index 8671636..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf
+++ /dev/null
Binary files differ
diff --git a/geronimo-javamail_1.5/pom.xml b/geronimo-javamail_1.5/pom.xml
deleted file mode 100644
index 6d18175..0000000
--- a/geronimo-javamail_1.5/pom.xml
+++ /dev/null
@@ -1,273 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-
-<!-- $Rev: 1704994 $ $Date: 2014-07-20 09:36:35 +0200 (So, 20. Jul 2014)
- $ -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.geronimo.genesis</groupId>
- <artifactId>genesis-java5-flava</artifactId>
- <version>2.2</version>
- </parent>
-
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5</artifactId>
- <name>Geronimo JavaMail 1.5</name>
- <packaging>pom</packaging>
-
- <version>0.0.1-SNAPSHOT</version>
-
- <description>
- Geronimmo JavaMail Bundle.
- </description>
-
- <scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/geronimo/javamail/trunk/geronimo-javamail_1.5</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/geronimo/javamail/trunk/geronimo-javamail_1.5</developerConnection>
- <url>http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5</url>
- </scm>
-
- <properties>
- <siteId>javamail/${project.artifactId}</siteId>
- <projectName>Apache Geronimo Javamail Bundle</projectName>
- </properties>
-
- <url>http://geronimo.apache.org/maven/${siteId}/${project.version}</url>
-
- <distributionManagement>
- <site>
- <id>apache-website</id>
- <url>${site.deploy.url}/maven/${siteId}/${project.version}</url>
- </site>
- </distributionManagement>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-activation_1.1_spec</artifactId>
- <version>1.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-javamail_1.5_spec</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
-
- <!-- INTERNAL -->
-
- <dependency>
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5_provider</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-osgi-locator</artifactId>
- <version>1.0</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.3</version>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.18</version>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>3.3</version>
- <configuration>
- <stagingDirectory>${staging.directory}</stagingDirectory>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.doxia</groupId>
- <artifactId>doxia-module-markdown</artifactId>
- <version>1.3</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
- </pluginManagement>
-
- <plugins>
-
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <includes>
- <include>src/**/*</include>
- <include>pom.xml</include>
- </includes>
- <excludes>
- <exclude>**/*/MANIFEST.MF</exclude>
- <exclude>.git</exclude>
- <exclude>.gitignore</exclude>
- <exclude>.idea</exclude>
- <exclude>*.iws</exclude>
- <exclude>*.iml</exclude>
- <exclude>*.ipr</exclude>
- <exclude>**/src/test/resources/**/*.bodystructure</exclude>
- <exclude>**/src/test/resources/**/*.msg</exclude>
- <exclude>**/resources/OSGI-INF/providers/**/*</exclude>
- </excludes>
- </configuration>
- <executions>
- <execution>
- <phase>verify</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-enforcer-plugin</artifactId>
- <executions>
- <execution>
- <phase>validate</phase>
- <goals>
- <goal>enforce</goal>
- </goals>
- <configuration>
- <rules>
- <!-- Allow any Java >= 1.5 -->
- <requireJavaVersion>
- <version>[1.5,)</version>
- </requireJavaVersion>
-
- <!-- Allow any Maven >= 2.0.7 -->
- <requireMavenVersion>
- <version>[2.0.7,)</version>
- </requireMavenVersion>
- </rules>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <modules>
- <module>geronimo-javamail_1.5_provider</module>
- <module>geronimo-javamail_1.5_mail</module>
- </modules>
-
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>3.0.0</version>
- <configuration>
- <xmlOutput>true</xmlOutput>
- <!-- Optional directory to put findbugs xdoc xml report -->
- <xmlOutputDirectory>target/site</xmlOutputDirectory>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- <version>3.2</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-project-info-reports-plugin</artifactId>
- <version>2.7</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.9.1</version>
- <configuration>
- <notimestamp>true</notimestamp>
- <show>private</show>
- </configuration>
- <reportSets>
- <reportSet>
- <reports>
- <report>javadoc</report>
- </reports>
- </reportSet>
- <reportSet>
- <inherited>false</inherited>
- <reports>
- <report>aggregate</report>
- </reports>
- </reportSet>
- </reportSets>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-report-plugin</artifactId>
- <version>2.18</version>
- <configuration>
- <aggregate>true</aggregate>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <version>2.6</version>
- <configuration>
- <formats>
- <format>html</format>
- </formats>
- <aggregate>true</aggregate>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>versions-maven-plugin</artifactId>
- <version>2.1</version>
- <reportSets>
- <reportSet>
- <reports>
- <report>dependency-updates-report</report>
- <report>plugin-updates-report</report>
- <report>property-updates-report</report>
- </reports>
- </reportSet>
- </reportSets>
- </plugin>
- </plugins>
- </reporting>
-
-</project>
diff --git a/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt b/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt
deleted file mode 100644
index b842f21..0000000
--- a/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt
+++ /dev/null
@@ -1,52 +0,0 @@
- ----
- Privacy Policy
- -----
- Olivier Lamy
- -----
- 2013-11-13
- -----
-
-~~ 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.
-
-Privacy Policy
-
- Information about your use of this website is collected using server access logs and a tracking cookie. The
- collected information consists of the following:
-
- [[1]] The IP address from which you access the website;
-
- [[2]] The type of browser and operating system you use to access our site;
-
- [[3]] The date and time you access our site;
-
- [[4]] The pages you visit; and
-
- [[5]] The addresses of pages from where you followed a link to our site.
-
- []
-
- Part of this information is gathered using a tracking cookie set by the
- {{{http://www.google.com/analytics/}Google Analytics}} service and handled by Google as described in their
- {{{http://www.google.com/privacy.html}privacy policy}}. See your browser documentation for instructions on how to
- disable the cookie if you prefer not to share this data with Google.
-
- We use the gathered information to help us make our site more useful to visitors and to better understand how and
- when our site is used. We do not track or collect personally identifiable information or associate gathered data
- with any personally identifying information from other sources.
-
- By using this website, you consent to the collection of this data in the manner and for the purpose described above.
diff --git a/geronimo-javamail_1.5/src/site/markdown/index.md b/geronimo-javamail_1.5/src/site/markdown/index.md
deleted file mode 100644
index 01cb1b9..0000000
--- a/geronimo-javamail_1.5/src/site/markdown/index.md
+++ /dev/null
@@ -1,35 +0,0 @@
-<!---
-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.
--->
-# Geronimo JavaMail 1.5
-
-Geronimo JavaMail 1.5
-
-## Get started
-
-Just get it from maven
-
-### Core
-
-<pre class="prettyprint linenums"><![CDATA[
-<dependency>
- <groupId>org.apache.geronimo.javamail</groupId>
- <artifactId>geronimo-javamail_1.5_provider</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-</dependency>
-]]></pre>
\ No newline at end of file
diff --git a/geronimo-javamail_1.5/src/site/site.xml b/geronimo-javamail_1.5/src/site/site.xml
deleted file mode 100644
index 272648e..0000000
--- a/geronimo-javamail_1.5/src/site/site.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- 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.
--->
-<project name="Apache Johnzon"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://maven.apache.org/DECORATION/1.0.1"
- xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.1
- http://maven.apache.org/xsd/decoration-1.0.1.xsd">
- <bannerLeft>
- <name>Geronimo JavaMail</name>
- <alt>Geronimo JavaMail</alt>
- <href>/index.html</href>
- </bannerLeft>
- <bannerRight>
- <src>http://geronimo.apache.org/images/topleft_logo_437x64.gif</src>
- <href>http://geronimo.apache.org/</href>
- </bannerRight>
-
- <custom>
- <fluidoSkin>
- <topBarEnabled>true</topBarEnabled>
- <sideBarEnabled>true</sideBarEnabled>
- <sourceLineNumbersEnabled>true</sourceLineNumbersEnabled>
- </fluidoSkin>
- </custom>
-
- <skin>
- <groupId>org.apache.maven.skins</groupId>
- <artifactId>maven-fluido-skin</artifactId>
- <version>1.3.0</version>
- </skin>
-
- <body>
-
- <head>
-
- <script type="text/javascript">
-
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
- })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
- ga('create', 'UA-3211522-15', 'apache.org');
- ga('send', 'pageview');
-
- </script>
-
- </head>
-
- <menu name="User Guide">
- <item name="Home" href="/index.html"/>
- </menu>
-
- <menu ref="reports" inherit="bottom"/>
-
- <menu name="ASF">
- <item name="How Apache Works" href="http://www.apache.org/foundation/how-it-works.html"/>
- <item name="Foundation" href="http://www.apache.org/foundation/"/>
- <item name="Sponsoring Apache" href="http://www.apache.org/foundation/sponsorship.html"/>
- <item name="Thanks" href="http://www.apache.org/foundation/thanks.html"/>
- </menu>
-
- <footer>
- <div class="row span16"><div>Apache Geronimo, Apache, the Apache feather logo, and the Apache Johnzon project logos are trademarks of The Apache Software Foundation.
- All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div>
- <a href="${project.url}/privacy-policy.html">Privacy Policy</a>
- </div>
- </footer>
-
- </body>
-</project>