adds the apache james mailbox, how sucky this is

This commit is contained in:
Timothy Prepscius 2013-09-01 23:13:22 -04:00
parent 1ae87ecb84
commit 30a7aca7ad
1460 changed files with 129739 additions and 0 deletions

View File

@ -0,0 +1 @@
apache-james-mailbox/memory

6
james/apache-james-mailbox/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.idea/
target
*.iml
derby.log
var
log

View File

@ -0,0 +1,35 @@
K 25
svn:wc:ra_dav:version-url
V 47
/repos/asf/!svn/ver/1509309/james/mailbox/trunk
END
NOTICE
K 25
svn:wc:ra_dav:version-url
V 54
/repos/asf/!svn/ver/1140981/james/mailbox/trunk/NOTICE
END
LICENSE
K 25
svn:wc:ra_dav:version-url
V 55
/repos/asf/!svn/ver/1140981/james/mailbox/trunk/LICENSE
END
.gitignore
K 25
svn:wc:ra_dav:version-url
V 58
/repos/asf/!svn/ver/1429793/james/mailbox/trunk/.gitignore
END
pom.xml
K 25
svn:wc:ra_dav:version-url
V 55
/repos/asf/!svn/ver/1476176/james/mailbox/trunk/pom.xml
END
README.md
K 25
svn:wc:ra_dav:version-url
V 57
/repos/asf/!svn/ver/1452487/james/mailbox/trunk/README.md
END

View File

@ -0,0 +1,9 @@
K 10
svn:ignore
V 18
.*
target
var
log
END

View File

@ -0,0 +1,237 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk
http://svn.apache.org/repos/asf
2013-08-01T15:50:28.815636Z
1509309
eric
has-props
13f79535-47bb-0310-9956-ffa450edef68
NOTICE
file
2013-09-02T02:54:40.000000Z
9fd1bc161f9ca2039bb1b4739710a0b6
2011-06-29T07:14:24.677999Z
1140981
rdonkin
418
maildir
dir
LICENSE
file
2013-09-02T02:54:40.000000Z
13ad9758cf5d8c437249d7a892c54852
2011-06-29T07:14:24.677999Z
1140981
rdonkin
10183
hbase
dir
zoo-seq-provider
dir
src
dir
pom.xml
file
2013-09-02T02:54:40.000000Z
8961b605d2e08836c2eb6075a50ef985
2013-04-26T13:01:43.322108Z
1476176
eric
22284
store
dir
caching
dir
README.md
file
2013-09-02T02:54:40.000000Z
ca07870fb4b8faa65e1e43b6f179924c
2013-03-04T20:31:08.236868Z
1452487
ieugen
3109
spring
dir
.gitignore
file
2013-09-02T02:54:40.000000Z
ec50350e18fc2c63fd4abf14e9c4c473
2013-01-07T13:21:20.783231Z
1429793
ieugen
38
memory
dir
api
dir
jpa
dir
lucene
dir
tool
dir
jcr
dir

View File

@ -0,0 +1,6 @@
.idea/
target
*.iml
derby.log
var
log

View File

@ -0,0 +1,179 @@
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

View File

@ -0,0 +1,9 @@
=========================================================================
== NOTICE file for use with the Apache License, Version 2.0, ==
=========================================================================
Apache JAMES Mailbox
Copyright 2009-2011 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

View File

@ -0,0 +1,86 @@
Apache James Mailbox project
============================
The James Mailbox project aims to provide an email (message) store. The main user of the Mailbox project is James Server
project. The implementations can be used standalone and do not depend on James Server.
The project defines the Mailbox API and has several implementations that you can use. More details bellow.
Overview
========
Apache James Mailbox has the following project (Maven) structure:
~~~
|-- api -- Mailbox API
|-- hbase -- Mailbox implementation over HBase
|-- jcr -- Mailbox implementation over Java Content Repository (JCR)
|-- jpa -- Database Mailbox implementation using Java Persistence API
|-- lucene -- Email indexing module with Apache Lucene
|-- maildir -- Email storage using Maildir format http://en.wikipedia.org/wiki/Maildir
|-- memory -- In memory Mailbox implementation - good for testing
|-- spring -- Spring module - starts a specific mailbox implementation
|-- store -- Common base/utility classes used in all mailbox implementations
|-- tool -- Database migration/mailbox export tool
|-- zoo-seq-provider -- Distributed unique ID generator using Zookeeper and Curator (Clustering James Mailbox)
~~~
Mailbox JPA
===========
Persist email messages inside any database that is supported by your Java Persistence Api provider. Currently James uses
OpenJPA (http://openjpa.apache.org/), but it's easy to implement your own.
Mailbox 'In memory' message store
=================================
In module **memory**, does not persist emails. It just keeps them in memory. Fast, and good for testing.
**Note:** Not to be used in production.
Mailbox JCR
===========
Uses Java Content Repository as a persistence layer. Uses Jackrabbit as a provider (http://jackrabbit.apache.org/),
but you could swap in any provider. Comes with all the nice features that Jackrabbit has.
Mailbox Maildir
===============
Implements the Maildir standard for email storage (http://en.wikipedia.org/wiki/Maildir). Works only on GNU/Linux and other
*Nix systems.
Mailbox HBase
=============
Uses Apache HBase (http://hbase.apache.org/) for storing email messages. Provides a scalable email storage. To have a fully
distributed email server you will also need, among others:
* distributed UID generation, look at Zookeeper Sequence Provider (**zoo-seq-provider**) for distributed locking and Mailbox manipulation
* distributed SMTP/IMAP access
* other
Zookeeper Sequence Provider
==========================
Uses Zookeeper and Curator Framework for generating distributed unique ID's, needed for mailbox management from multiple
instances of James (IMAP) servers.
Building
========
The primary build tool for Apache James Mailbox is maven 3.
On a new checkout start by running
~~~
$ mvn clean package
~~~
This will compiled all modules
For just building without running junit tests:
~~~
$ mvn clean package -DskiTests=true
~~~

View File

@ -0,0 +1,576 @@
<?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.
-->
<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>
<artifactId>james-project</artifactId>
<groupId>org.apache.james</groupId>
<version>1.8.2</version>
<relativePath />
</parent>
<artifactId>apache-james-mailbox</artifactId>
<version>0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<repositories>
<!-- apache.snapshot is needed for james-project SNAPSHOT, see JAMES-1470 -->
<repository>
<id>apache.snapshots</id>
<name>Apache Snapshot Repository</name>
<url>http://repository.apache.org/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<name>Apache James :: Mailbox</name>
<description>Apache James Mailbox</description>
<url>http://james.apache.org/mailbox</url>
<inceptionYear>2010</inceptionYear>
<modules>
<module>api</module>
<module>caching</module>
<module>hbase</module>
<module>jcr</module>
<module>jpa</module>
<module>lucene</module>
<module>maildir</module>
<module>memory</module>
<module>store</module>
<module>spring</module>
<module>tool</module>
<module>zoo-seq-provider</module>
</modules>
<scm>
<connection>scm:svn:http://svn.apache.org/repos/asf/james/mailbox/trunk</connection>
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/james/mailbox/trunk</developerConnection>
<url>http://svn.apache.org/viewcvs.cgi/james/mailbox/trunk?root=Apache-SVN</url>
</scm>
<issueManagement>
<system>JIRA</system>
<url>http://issues.apache.org/jira/browse/MAILBOX</url>
</issueManagement>
<distributionManagement>
<site>
<id>mailbox-website</id>
<url>scpexe://people.apache.org/www/james.apache.org/mailbox</url>
</site>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<javax.activation.groupId>javax.activation</javax.activation.groupId>
<javax.activation.artifactId>activation</javax.activation.artifactId>
<javax.mail.groupId>javax.mail</javax.mail.groupId>
<javax.mail.artifactId>mail</javax.mail.artifactId>
<openjpa.version>2.2.1</openjpa.version>
<javax.persistence.version>1.0.2</javax.persistence.version>
<javax.inject.version>1</javax.inject.version>
<apache-mime4j.version>0.7.2</apache-mime4j.version>
<javax.mail.version>1.4.1</javax.mail.version>
<activation.version>1.1.1</activation.version>
<jmock.version>2.5.1</jmock.version>
<hbase.version>0.92.0</hbase.version>
<hadoop.version>1.0.1</hadoop.version>
<spring.version>3.1.2.RELEASE</spring.version>
<commons-io.version>2.4</commons-io.version>
<commons-lang.version>2.6</commons-lang.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<commons-configuration.version>1.9</commons-configuration.version>
<commons-beanutils-core.version>1.8.3</commons-beanutils-core.version>
<h2.version>1.3.170</h2.version>
<derby.version>10.9.1.0</derby.version>
<geronimo-jpa-spec.version>1.1</geronimo-jpa-spec.version>
<jcr.version>2.0</jcr.version>
<jackrabbit.version>2.5.2</jackrabbit.version>
<lucene.version>3.6.0</lucene.version>
<xercesImpl.version>2.9.1</xercesImpl.version>
<xml-apis.version>1.3.04</xml-apis.version>
<geronimo-annotation-spec.version>1.1.1</geronimo-annotation-spec.version>
<geronimo-activation-spec.version>1.1</geronimo-activation-spec.version>
<geronimo-javamail-mail.version>1.8.3</geronimo-javamail-mail.version>
<apache-mailet.version>2.5.0</apache-mailet.version>
<slf4j.version>1.7.2</slf4j.version>
<junit.version>4.11</junit.version>
<jasypt.version>1.9.0</jasypt.version>
<guava.version>13.0</guava.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!--
START Modules
-->
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-api</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-store</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-lucene</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-lucene</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-store</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-jpa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-jcr</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-memory</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-maildir</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-hbase</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-james-mailbox-tool</artifactId>
<version>${project.version}</version>
</dependency>
<!--
END Modules
-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-smartcn</artifactId>
<version>${lucene.version}</version>
</dependency>
<!--
START Mail
-->
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-mime4j-core</artifactId>
<version>${apache-mime4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-mime4j-dom</artifactId>
<version>${apache-mime4j.version}</version>
</dependency>
<!-- Declare javamail as provided to be able to easily switch -->
<!-- to different implementations (Geronimo) -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>${javax.mail.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>${activation.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax.inject.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-activation_1.1_spec</artifactId>
<version>${geronimo-activation-spec.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.javamail</groupId>
<artifactId>geronimo-javamail_1.4_mail</artifactId>
<version>${geronimo-javamail-mail.version}</version>
</dependency>
<!--
END Mail
-->
<!--
Start James Mailet
-->
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-mailet-api</artifactId>
<version>${apache-mailet.version}</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--
START Logging
-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<!--
START Logging
-->
<!--
Start Commons
-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>${commons-pool.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<scope>test</scope>
<version>${commons-configuration.version}</version>
<exclusions>
<exclusion>
<artifactId>dom4j</artifactId>
<groupId>dom4j</groupId>
</exclusion>
<exclusion>
<artifactId>servletapi</artifactId>
<groupId>servletapi</groupId>
</exclusion>
<exclusion>
<artifactId>xerces</artifactId>
<groupId>xerces</groupId>
</exclusion>
<exclusion>
<artifactId>commons-digester</artifactId>
<groupId>commons-digester</groupId>
</exclusion>
<exclusion>
<artifactId>commons-beanutils-core</artifactId>
<groupId>commons-beanutils</groupId>
</exclusion>
<exclusion>
<artifactId>commons-beanutils-bean-collections</artifactId>
<groupId>commons-beanutils</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils-core</artifactId>
<version>${commons-beanutils-core.version}</version>
</dependency>
<!--
END Commons
-->
<!--
START Testing
-->
<!--
Use to build protocol tester.
Convert this to testing once MPT has been released.
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock</artifactId>
<version>${jmock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<version>${jmock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>${derby.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--
END Testing
-->
<!--
START OpenJPA
-->
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa</artifactId>
<version>${openjpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>${geronimo-jpa-spec.version}</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>${jasypt.version}</version>
</dependency>
<!--
END OpenJPA
-->
<!--
START JCR
-->
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>${jcr.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr-commons</artifactId>
<version>${jackrabbit.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
<version>${jackrabbit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xercesImpl.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>${xml-apis.version}</version>
<scope>test</scope>
</dependency>
<!--
END JCR
-->
<!--
START GERONIMO ANNOTATION
-->
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-annotation_1.0_spec</artifactId>
<version>${geronimo-annotation-spec.version}</version>
</dependency>
<!--
END GERONIMO ANNOTATION
-->
<!--
START SPRING
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--
END SPRING
-->
<!--
START HBASE/HADOOP
-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>${hbase.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>${hbase.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-test</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
<!--
END HBASE/HADOOP
-->
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>bin</descriptorRef>
<descriptorRef>src</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>geronimo</id>
<properties>
<javax.mail.groupId>org.apache.geronimo.javamail</javax.mail.groupId>
<javax.mail.artifactId>geronimo-javamail_1.4_mail</javax.mail.artifactId>
<javax.activation.groupId>org.apache.geronimo.specs</javax.activation.groupId>
<javax.activation.artifactId>geronimo-activation_1.1_spec</javax.activation.artifactId>
<version.javax.mail>1.6</version.javax.mail>
<version.activation>1.0.2</version.activation>
</properties>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,179 @@
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

View File

@ -0,0 +1,9 @@
=========================================================================
== NOTICE file for use with the Apache License, Version 2.0, ==
=========================================================================
Apache JAMES Mailbox
Copyright 2009-2011 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

View File

@ -0,0 +1,86 @@
Apache James Mailbox project
============================
The James Mailbox project aims to provide an email (message) store. The main user of the Mailbox project is James Server
project. The implementations can be used standalone and do not depend on James Server.
The project defines the Mailbox API and has several implementations that you can use. More details bellow.
Overview
========
Apache James Mailbox has the following project (Maven) structure:
~~~
|-- api -- Mailbox API
|-- hbase -- Mailbox implementation over HBase
|-- jcr -- Mailbox implementation over Java Content Repository (JCR)
|-- jpa -- Database Mailbox implementation using Java Persistence API
|-- lucene -- Email indexing module with Apache Lucene
|-- maildir -- Email storage using Maildir format http://en.wikipedia.org/wiki/Maildir
|-- memory -- In memory Mailbox implementation - good for testing
|-- spring -- Spring module - starts a specific mailbox implementation
|-- store -- Common base/utility classes used in all mailbox implementations
|-- tool -- Database migration/mailbox export tool
|-- zoo-seq-provider -- Distributed unique ID generator using Zookeeper and Curator (Clustering James Mailbox)
~~~
Mailbox JPA
===========
Persist email messages inside any database that is supported by your Java Persistence Api provider. Currently James uses
OpenJPA (http://openjpa.apache.org/), but it's easy to implement your own.
Mailbox 'In memory' message store
=================================
In module **memory**, does not persist emails. It just keeps them in memory. Fast, and good for testing.
**Note:** Not to be used in production.
Mailbox JCR
===========
Uses Java Content Repository as a persistence layer. Uses Jackrabbit as a provider (http://jackrabbit.apache.org/),
but you could swap in any provider. Comes with all the nice features that Jackrabbit has.
Mailbox Maildir
===============
Implements the Maildir standard for email storage (http://en.wikipedia.org/wiki/Maildir). Works only on GNU/Linux and other
*Nix systems.
Mailbox HBase
=============
Uses Apache HBase (http://hbase.apache.org/) for storing email messages. Provides a scalable email storage. To have a fully
distributed email server you will also need, among others:
* distributed UID generation, look at Zookeeper Sequence Provider (**zoo-seq-provider**) for distributed locking and Mailbox manipulation
* distributed SMTP/IMAP access
* other
Zookeeper Sequence Provider
==========================
Uses Zookeeper and Curator Framework for generating distributed unique ID's, needed for mailbox management from multiple
instances of James (IMAP) servers.
Building
========
The primary build tool for Apache James Mailbox is maven 3.
On a new checkout start by running
~~~
$ mvn clean package
~~~
This will compiled all modules
For just building without running junit tests:
~~~
$ mvn clean package -DskiTests=true
~~~

View File

@ -0,0 +1,11 @@
K 25
svn:wc:ra_dav:version-url
V 51
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api
END
pom.xml
K 25
svn:wc:ra_dav:version-url
V 59
/repos/asf/!svn/ver/1452816/james/mailbox/trunk/api/pom.xml
END

View File

@ -0,0 +1,8 @@
K 10
svn:ignore
V 22
.*
target
coverage.ec
END

View File

@ -0,0 +1,65 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
has-props
13f79535-47bb-0310-9956-ffa450edef68
src
dir
pom.xml
file
2013-09-02T02:54:40.000000Z
44a7f4b20cd292f5dc9e54c022b5a28d
2013-03-05T14:39:26.245277Z
1452816
ieugen
has-props
2431

View File

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 13
svn:mime-type
V 10
text/plain
END

View File

@ -0,0 +1,64 @@
<?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.
-->
<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>
<artifactId>apache-james-mailbox</artifactId>
<groupId>org.apache.james</groupId>
<version>0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>apache-james-mailbox-api</artifactId>
<packaging>bundle</packaging>
<name>Apache James :: Mailbox :: API</name>
<dependencies>
<dependency>
<groupId>${javax.mail.groupId}</groupId>
<artifactId>${javax.mail.artifactId}</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,64 @@
<?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.
-->
<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>
<artifactId>apache-james-mailbox</artifactId>
<groupId>org.apache.james</groupId>
<version>0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>apache-james-mailbox-api</artifactId>
<packaging>bundle</packaging>
<name>Apache James :: Mailbox :: API</name>
<dependencies>
<dependency>
<groupId>${javax.mail.groupId}</groupId>
<artifactId>${javax.mail.artifactId}</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 55
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src
END

View File

@ -0,0 +1,37 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
test
dir
main
dir
reporting-site
dir

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 60
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main
END

View File

@ -0,0 +1,31 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
java
dir

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 65
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main/java
END

View File

@ -0,0 +1,31 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
org
dir

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 69
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main/java/org
END

View File

@ -0,0 +1,31 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
apache
dir

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 76
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main/java/org/apache
END

View File

@ -0,0 +1,31 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org/apache
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
james
dir

View File

@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 82
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main/java/org/apache/james
END

View File

@ -0,0 +1,31 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org/apache/james
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
mailbox
dir

View File

@ -0,0 +1,71 @@
K 25
svn:wc:ra_dav:version-url
V 90
/repos/asf/!svn/ver/1469272/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox
END
MailboxSession.java
K 25
svn:wc:ra_dav:version-url
V 110
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxSession.java
END
MessageManager.java
K 25
svn:wc:ra_dav:version-url
V 110
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
END
SubscriptionManager.java
K 25
svn:wc:ra_dav:version-url
V 115
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java
END
MailboxListener.java
K 25
svn:wc:ra_dav:version-url
V 111
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxListener.java
END
MailboxSessionIdGenerator.java
K 25
svn:wc:ra_dav:version-url
V 121
/repos/asf/!svn/ver/1179215/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxSessionIdGenerator.java
END
QuotaManager.java
K 25
svn:wc:ra_dav:version-url
V 108
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/QuotaManager.java
END
StandardMailboxMetaDataComparator.java
K 25
svn:wc:ra_dav:version-url
V 129
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/StandardMailboxMetaDataComparator.java
END
MailboxManager.java
K 25
svn:wc:ra_dav:version-url
V 110
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
END
MailboxPathLocker.java
K 25
svn:wc:ra_dav:version-url
V 113
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxPathLocker.java
END
RequestAware.java
K 25
svn:wc:ra_dav:version-url
V 108
/repos/asf/!svn/ver/1091296/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/RequestAware.java
END
MailboxListenerSupport.java
K 25
svn:wc:ra_dav:version-url
V 118
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MailboxListenerSupport.java
END

View File

@ -0,0 +1,414 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox
http://svn.apache.org/repos/asf
2013-04-18T10:45:04.570973Z
1469272
eric
13f79535-47bb-0310-9956-ffa450edef68
MailboxSession.java
file
2013-09-02T02:54:40.000000Z
cb7675a3ffc764d08452e46bf7f2a239
2013-03-05T14:22:04.421500Z
1452807
ieugen
4763
MailboxListener.java
file
2013-09-02T02:54:40.000000Z
54552467f028450060786f9e9399f549
2013-03-05T14:22:04.421500Z
1452807
ieugen
has-props
6155
StandardMailboxMetaDataComparator.java
file
2013-09-02T02:54:40.000000Z
078779e84e76f35c4f4b9cf71ac20252
2012-02-09T12:13:02.344953Z
1242288
eric
2647
RequestAware.java
file
2013-09-02T02:54:40.000000Z
38347644deb415697b0f25e980493be5
2011-04-12T05:10:18.798553Z
1091296
felixk
1858
MailboxPathLocker.java
file
2013-09-02T02:54:40.000000Z
b63742685323388dfec666a33828b762
2012-02-09T12:13:02.344953Z
1242288
eric
2905
quota
dir
exception
dir
SubscriptionManager.java
file
2013-09-02T02:54:40.000000Z
30408d6b85c925a7d672dc2c9a8554de
2012-02-09T12:13:02.344953Z
1242288
eric
2638
MessageManager.java
file
2013-09-02T02:54:40.000000Z
5f3e7cf0193f0e6a7b42f535367fd2ef
2013-03-05T14:22:04.421500Z
1452807
ieugen
has-props
13580
acl
dir
model
dir
MailboxSessionIdGenerator.java
file
2013-09-02T02:54:40.000000Z
fbc4d03d4b879667b984c9689cc597cc
2011-10-05T13:28:07.200119Z
1179215
norman
has-props
1721
QuotaManager.java
file
2013-09-02T02:54:40.000000Z
073b8ef2b5a330fb72bbae8c26dcffe0
2012-02-09T12:13:02.344953Z
1242288
eric
2083
MailboxManager.java
file
2013-09-02T02:54:40.000000Z
1a619fd6c1ac1ca15150816b987a714c
2013-03-05T14:22:04.421500Z
1452807
ieugen
has-props
10178
MailboxListenerSupport.java
file
2013-09-02T02:54:40.000000Z
2b563d6d12cab3ffd75e2005b98504c0
2012-02-09T12:13:02.344953Z
1242288
eric
2914

View File

@ -0,0 +1,5 @@
K 13
svn:eol-style
V 6
native
END

View File

@ -0,0 +1,5 @@
K 13
svn:eol-style
V 6
native
END

View File

@ -0,0 +1,5 @@
K 13
svn:eol-style
V 6
native
END

View File

@ -0,0 +1,227 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.io.Serializable;
import java.util.List;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MessageMetaData;
import org.apache.james.mailbox.model.UpdatedFlags;
/**
* Listens to <code>Mailbox</code> events.<br>
* Note that listeners may be removed asynchronously.
*/
public interface MailboxListener {
/**
* Informs this listener about the given event.
*
* @param event
* not null
*/
void event(final Event event);
/**
* A mailbox event.
*/
@SuppressWarnings("serial")
public abstract class Event implements Serializable {
private final MailboxSession session;
private final MailboxPath path;
public Event(final MailboxSession session, final MailboxPath path) {
this.session = session;
this.path = path;
}
/**
* Gets the {@link MailboxSession} in which's context the {@link Event}
* happened
*
* @return session
*/
public MailboxSession getSession() {
return session;
}
/**
* Return the path of the Mailbox this event belongs to.
*
* @return path
*/
public MailboxPath getMailboxPath() {
return path;
}
}
/**
* Indicates that mailbox has been deleted.
*/
public class MailboxDeletion extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxDeletion(final MailboxSession session, MailboxPath path) {
super(session, path);
}
}
/**
* Indicates that a mailbox has been Added.
*/
public class MailboxAdded extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxAdded(final MailboxSession session, MailboxPath path) {
super(session, path);
}
}
/**
* Indicates that a mailbox has been renamed.
*/
public abstract class MailboxRenamed extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxRenamed(final MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Gets the new name for this mailbox.
*
* @return name, not null
*/
public abstract MailboxPath getNewPath();
}
/**
* A mailbox event related to updated ACL
*/
public abstract class MailboxACLUpdated extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxACLUpdated(MailboxSession session, MailboxPath path) {
super(session, path);
}
public abstract MailboxACL getUpdatedACL();
}
/**
* A mailbox event related to a message.
*/
public abstract class MessageEvent extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MessageEvent(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Gets the message UIDs for the subject of this event.
*
* @return message uids
*/
public abstract List<Long> getUids();
}
public abstract class Expunged extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public Expunged(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Return the flags which were set for the added message
*
* @return flags
*/
public abstract MessageMetaData getMetaData(long uid);
}
/**
* A mailbox event related to updated flags
*/
public abstract class FlagsUpdated extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public FlagsUpdated(MailboxSession session, MailboxPath path) {
super(session, path);
}
public abstract List<UpdatedFlags> getUpdatedFlags();
}
/**
* A mailbox event related to added message
*/
public abstract class Added extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public Added(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Return the flags which were set for the added message
*
* @return flags
*/
public abstract MessageMetaData getMetaData(long uid);
}
}

View File

@ -0,0 +1,81 @@
/****************************************************************
* 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.james.mailbox;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxPath;
/**
* Implementations of this interface supports {@link MailboxListener}. Its needed that the events get handled
* in the submitted order
*
*
*/
public interface MailboxListenerSupport {
/**
* <p>
* Implementations of Mailbox may interpret the fact that someone is
* listening and do some caching and even postpone persistence until
* everyone has removed itself.
* </p>
*
* @param mailboxPath
* not null
* @param listener
* not null
* @param session
* not null
* @throws MailboxException
*/
void addListener(MailboxPath mailboxPath, MailboxListener listener, MailboxSession session) throws MailboxException;
/**
* Remove the {@link MailboxListener}
*
* @param mailboxPath
* @param listner
* @param session
* @throws MailboxException
*/
void removeListener(MailboxPath mailboxPath, MailboxListener listner, MailboxSession session) throws MailboxException;
/**
* Add a {@link MailboxListener} which get fired for ever
* {@link MailboxPath}
*
* @param listener
* @param session
* @throws MailboxException
*/
void addGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException;
/**
* Remove the {@link MailboxListener}
*
* @param listner
* @param session
* @throws MailboxException
*/
void removeGlobalListener(MailboxListener listner, MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,260 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.util.List;
import org.apache.james.mailbox.exception.BadCredentialsException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxExistsException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.model.MailboxMetaData;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MailboxQuery;
import org.apache.james.mailbox.model.MessageRange;
import org.slf4j.Logger;
/**
* <p>
* Central MailboxManager which creates, lists, provides, renames and deletes
* Mailboxes
* </p>
* <p>
* An important goal is to be JavaMail feature compatible. That means JavaMail
* could be used in both directions: As a backend for e.g. accessing a Maildir
* JavaMail store or as a frontend to access a JDBC MailboxManager through
* JavaMail. This should be possible by not too complicated wrapper classes. Due
* to the complexity of JavaMail it might be impossible to avoid some
* limitations.
* </p>
* <p>
* Internally MailboxManager deals with named repositories that could have
* different implementations. E.g. JDBC connections to different hosts or
* Maildir / Mbox like stores. These repositories are identified by their names
* and maybe are configured in config.xml. The names of the mailboxes have to be
* mapped to the corresponding repository name. For user mailboxes this could be
* done by a "User.getRepositoryName()" property. It is imaginable that
* repositories lookup further properties from the user object like a path name
* for a file based storage method. Until Milestone 6 there is only one named
* repository: "default".
* </p>
* <p>
* The only operation that requires dealing with the named repositories directly
* is the quota management. It is probably really difficult to implement a quota
* system that spans multiple repository implementations. That is why quotas are
* created for a specific repository. To be able to administer, repositories and
* theier belonging mailboxes can be listet.
* </p>
*/
public interface MailboxManager extends RequestAware, MailboxListenerSupport {
/**
* Return the delimiter to use for folders
*
* @return delimiter
*/
char getDelimiter();
/**
* Gets an session suitable for IMAP.
*
* @param mailboxPath
* the Path of the mailbox, not null
* @param session
* the context for this call, not null
* @return <code>ImapMailboxSession</code>, not null
* @throws MailboxException
* when the mailbox cannot be opened
* @throws MailboxNotFoundException
* when the given mailbox does not exist
*/
MessageManager getMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Creates a new mailbox. Any intermediary mailboxes missing from the
* hierarchy should be created.
*
* @param mailboxPath
* @param mailboxSession
* the context for this call, not null
* @throws MailboxException
* when creation fails
*/
void createMailbox(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException;
/**
* Delete the mailbox with the name
*
* @param mailboxPath
* @param session
* @throws MailboxException
*/
void deleteMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Renames a mailbox.
*
* @param from
* original mailbox
* @param to
* new mailbox
* @param session
* the context for this call, not nul
* @throws MailboxException
* otherwise
* @throws MailboxExistsException
* when the <code>to</code> mailbox exists
* @throws MailboxNotFound
* when the <code>from</code> mailbox does not exist
*/
void renameMailbox(MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Copy the given {@link MessageRange} from one Mailbox to the other.
*
* Be aware that the copied Messages MUST get the \RECENT flag set!
*
* @param set
* messages to copy
* @param from
* name of the source mailbox
* @param to
* name of the destination mailbox
* @param session
* <code>MailboxSession</code>, not null
* @return a list of MessageRange - uids assigned to copied messages
*/
List<MessageRange> copyMessages(MessageRange set, MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Move the given {@link MessageRange} from one Mailbox to the other.
*
* Be aware that the moved Messages MUST get the \RECENT flag set!
*
* @param set
* messages to move
* @param from
* name of the source mailbox
* @param to
* name of the destination mailbox
* @param session
* <code>MailboxSession</code>, not null
* @return a list of MessageRange - uids assigned to moved messages
*/
List<MessageRange> moveMessages(MessageRange set, MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Searches for mailboxes matching the given query.
*
* @param expression
* not null
* @param session
* the context for this call, not null
* @throws MailboxException
*/
List<MailboxMetaData> search(MailboxQuery expression, MailboxSession session) throws MailboxException;
/**
* Does the given mailbox exist?
*
* @param mailboxPath
* not null
* @param session
* the context for this call, not null
* @return true when the mailbox exists and is accessible for the given
* user, false otherwise
* @throws MailboxException
*/
boolean mailboxExists(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Creates a new system session.<br>
* A system session is intended to be used for programmatic access.<br>
* Use {@link #login(String, String, Logger)} when accessing this API from a
* protocol.
*
* @param userName
* the name of the user whose session is being created
* @param log
* context sensitive log
* @return <code>MailboxSession</code>, not null
* @throws BadCredentialsException
* when system access is not allowed for the given user
* @throws MailboxException
* when the creation fails for other reasons
*/
MailboxSession createSystemSession(String userName, Logger log) throws BadCredentialsException, MailboxException;
/**
* Autenticates the given user against the given password.<br>
* When authentic and authorized, a session will be supplied
*
* @param userid
* user name
* @param passwd
* password supplied
* @param log
* context sensitive log
* @return a <code>MailboxSession</code> when the user is authentic and
* authorized to access
* @throws BadCredentialsException
* when system access is denighed for the given user
* @throws MailboxException
* when the creation fails for other reasons
*/
MailboxSession login(String userid, String passwd, Logger log) throws BadCredentialsException, MailboxException;
/**
* <p>
* Logs the session out, freeing any resources. Clients who open session
* should make best efforts to call this when the session is closed.
* </p>
* <p>
* Note that clients may not always be able to call logout (whether forced
* or not). Mailboxes that create sessions which are expensive to maintain
* <code>MUST</code> retain a reference and periodically check
* {@link MailboxSession#isOpen()}.
* </p>
* <p>
* Note that implementations much be aware that it is possible that this
* method may be called more than once with the same session.
* </p>
*
* @param session
* not null
* @param force
* true when the session logout is forced by premature connection
* termination
* @throws MailboxException
* when logout fails
*/
void logout(MailboxSession session, boolean force) throws MailboxException;
/**
* Return a unmodifiable {@link List} of {@link MailboxPath} objects
*
* @param session
* @return pathList
* @throws MailboxException
*/
List<MailboxPath> list(MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,69 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxPath;
/**
* The {@link MailboxPathLocker} is responsible to help to synchronize the
* access to a {@link MailboxPath} and execute an given {@link LockAwareExecution}
*
* Implementations that are not able to handle read / write locks in a different way are needed to handle all locks as write lock.
*/
public interface MailboxPathLocker {
/**
* @deprecated use {@link #executeWithLock(MailboxSession, MailboxPath, LockAwareExecution, boolean)} with argument <code>true</code>
*/
@Deprecated
public <T> T executeWithLock(MailboxSession session, MailboxPath path, LockAwareExecution<T> execution) throws MailboxException;
/**
* Execute the {@link LockAwareExecution} while holding a lock on the
* {@link MailboxPath}. If writeLock is true the implementation need to make sure that no other threads can read and write while the lock
* is hold. The contract is the same as documented in {@link ReadWriteLock}.
*
* @param session
* @param path
* @param execution
* @param writeLock
*
* @throws MailboxException
*/
public <T> T executeWithLock(MailboxSession session, MailboxPath path, LockAwareExecution<T> execution, boolean writeLock) throws MailboxException;
/**
* Execute code while holding a lock
*/
public interface LockAwareExecution<T> {
/**
* Execute code block
*
* @throws MailboxException
*/
public T execute() throws MailboxException;
}
}

View File

@ -0,0 +1,164 @@
/****************************************************************
* 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.james.mailbox;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
/**
* Mailbox session.
*/
public interface MailboxSession {
/**
* Id which will be used for a System session
*/
public final static long SYSTEM_SESSION_ID = 0L;
public static enum SessionType {
/**
* Session was created via the System
*/
System,
/**
* Session belongs to a specific user which was authenticated somehow
*/
User
}
/**
* Return if the {@link MailboxSession} is of type {@link SessionType#User} or {@link SessionType#System}
*
* @return type
*/
SessionType getType();
/**
* Gets the session ID.
*
* @return session id
*/
long getSessionId();
/**
* Is this session open?
*
* @return true if the session is open, false otherwise
*/
boolean isOpen();
/**
* Closes this session.
*/
void close();
/**
* Gets the logger for this session context.
*
* @return not null
*/
Logger getLog();
/**
* Gets the user executing this session.
*
* @return not null
*/
User getUser();
/**
* A mailbox user. Useful for specialist mailbox implementation.
*/
public interface User {
/**
* Gets the name of the user.
*
* @return not null
*/
String getUserName();
/**
* Return the Password for the logged in user
*
* @return password
*/
String getPassword();
/**
* Gets acceptable localisation for this user in preference order.<br>
* When localising a phrase, each <code>Locale</code> should be tried in
* order until an appropriate translation is obtained.
*
* @return not null, when empty the default local should be used
*/
List<Locale> getLocalePreferences();
}
/**
* Gets the <a href='http://www.isi.edu/in-notes/rfc2342.txt' rel='tag'>RFC
* 2342</a> personal namespace for the current session.<br>
* Note that though servers may offer multiple personal namespaces, support
* is not offered through this API. This decision may be revised if
* reasonable use cases emerge.
*
* @return Personal Namespace, not null
*/
String getPersonalSpace();
/**
* Gets the <a href='http://www.isi.edu/in-notes/rfc2342.txt' rel='tag'>RFC
* 2342</a> other users namespace for the current session.<br>
* Note that though servers may offer multiple other users namespaces,
* support is not offered through this API. This decision may be revised if
* reasonable use cases emerge.
*
* @return Other Users Namespace or null when there is non available
*/
String getOtherUsersSpace();
/**
* Iterates the <a href='http://www.isi.edu/in-notes/rfc2342.txt'
* rel='tag'>RFC 2342</a> Shared Namespaces available for the current
* session.
*
* @return not null though possibly empty
*/
Collection<String> getSharedSpaces();
/**
* Return the stored attributes for this {@link MailboxSession}.
*
* @return attributes
*/
Map<Object, Object> getAttributes();
/**
* Return server side, folder path separator
*
* @return path separator
*/
char getPathDelimiter();
}

View File

@ -0,0 +1,39 @@
/****************************************************************
* 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.james.mailbox;
/**
* Generator for id's which should used for new {@link MailboxSession} instances
*
*
*/
public interface MailboxSessionIdGenerator {
/**
* Return the next id to use for a {@link MailboxSession}. The id must be unique
* while the server is running and can be any long except {@link MailboxSession#SYSTEM_SESSION_ID}.
*
* The returned ids can be in any specific order.
*
* @return id
*/
long nextId();
}

View File

@ -0,0 +1,382 @@
/****************************************************************
* 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.james.mailbox;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.mail.Flags;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.UnsupportedCriteriaException;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.EditMode;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MessageResult;
import org.apache.james.mailbox.model.MessageResultIterator;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.model.SimpleMailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MessageResult.FetchGroup;
/**
* Interface which represent a Mailbox
*
* A {@link MessageManager} should be valid for the whole {@link MailboxSession}
*/
public interface MessageManager {
/**
* Return the count
*
* @param mailboxSession
* @return count
* @throws MailboxException
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
@Deprecated
long getMessageCount(MailboxSession mailboxSession) throws MailboxException;
/**
* Return if the Mailbox is writable
*
* @param session
* @return writable
* @throws MailboxException
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
@Deprecated
boolean isWriteable(MailboxSession session) throws MailboxException;
/**
* Return true if {@link MessageResult#getModSeq()} is stored in a permanent
* way.
*
* @param session
* @return modSeqPermanent
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
boolean isModSeqPermanent(MailboxSession session);
/**
* Searches for messages matching the given query. The result must be
* ordered
*
* @param mailboxSession
* not null
* @return uid iterator
* @throws UnsupportedCriteriaException
* when any of the search parameters are not supported by this
* mailbox
* @throws MailboxException
* when search fails for other reasons
*/
Iterator<Long> search(SearchQuery searchQuery, MailboxSession mailboxSession) throws MailboxException;
/**
* Expunges messages in the given range from this mailbox.
*
* @param set
* not null
* @param mailboxSession
* not null
* @return uid iterator
* @throws MailboxException
* if anything went wrong
*/
Iterator<Long> expunge(MessageRange set, MailboxSession mailboxSession) throws MailboxException;
/**
* Sets flags on messages within the given range. The new flags are returned
* for each message altered.
*
* @param flags
* Flags to be set
* @param value
* true = set, false = unset
* @param replace
* replace all Flags with this flags, value has to be true
* @param set
* the range of messages
* @param mailboxSession
* not null
* @return new flags indexed by UID
* @throws MailboxException
*/
Map<Long, Flags> setFlags(Flags flags, boolean value, boolean replace, MessageRange set, MailboxSession mailboxSession) throws MailboxException;
/**
* Appends a message to this mailbox. This method must return a higher UID
* as the last call in every case which also needs to be unique for the
* lifetime of the mailbox.
*
*
* @param internalDate
* the time of addition to be set, not null
* @param mailboxSession
* not null
* @param isRecent
* true when the message should be marked recent, false otherwise
* @param flags
* optionally set these flags on created message, or null when no
* additional flags should be set
* @return uid for the newly added message
* @throws MailboxException
* when message cannot be appended
*/
long appendMessage(InputStream msgIn, Date internalDate, MailboxSession mailboxSession, boolean isRecent, Flags flags) throws MailboxException;
/**
* Gets messages in the given range. The messages may get fetched under
* the-hood in batches so the caller should check if
* {@link MessageResultIterator#getException()} returns <code>null</code>
* after {@link MessageResultIterator#hasNext()} returns <code>false</code>.
*
*
* @param set
* @param fetchGroup
* data to fetch
* @param mailboxSession
* not null
* @return MessageResult with the fields defined by FetchGroup
* @throws MailboxException
*/
MessageResultIterator getMessages(MessageRange set, FetchGroup fetchGroup, MailboxSession mailboxSession) throws MailboxException;
/**
* Tells whether the given {@link MailboxSession}'s user has the given
* {@link MailboxACLRight} for this {@link MessageManager}'s mailbox.
*
* @param right
* @param session
* @return true if the given {@link MailboxSession}'s user has the given
* {@link MailboxACLRight} for this {@link MessageManager}'s
* mailbox; false otherwise.
* @throws MailboxException
*/
public boolean hasRight(MailboxACLRight right, MailboxSession session) throws MailboxException;
/**
* Returns the rights applicable to the user who has sent the current
* request.
*
* @param session
* @return the rights applicable to the user who has sent the request,
* returns {@link SimpleMailboxACL#NO_RIGHTS} if
* {@code session.getUser()} is null.
* @throws UnsupportedRightException
*/
public abstract MailboxACLRights myRights(MailboxSession session) throws MailboxException;
/**
* Computes a result suitable for the LISTRIGHTS IMAP command. The result is
* computed for this mailbox and the given {@code identifier}.
*
* From RFC 4314 section 3.7:
* The first element of the resulting array contains the (possibly empty)
* set of rights the identifier will always be granted in the mailbox.
* Following this are zero or more right sets the identifier can be granted
* in the mailbox. Rights mentioned in the same set are tied together. The
* server MUST either grant all tied rights to the identifier in the mailbox
* or grant none.
*
* The same right MUST NOT be listed more than once in the LISTRIGHTS
* command.
*
* @param identifier
* the identifier from the LISTRIGHTS command.
* @param session
* @return
* @throws UnsupportedRightException
*/
public MailboxACLRights[] listRigths(MailboxACLEntryKey identifier, MailboxSession session) throws UnsupportedRightException;
/**
* TODO setRights.
*
* @param identifier
* @param editMode
* @param mailboxAclRights
* @throws UnsupportedRightException
*/
void setRights(MailboxACLEntryKey identifier, EditMode editMode, MailboxACLRights mailboxAclRights) throws UnsupportedRightException;
/**
* Gets current meta data for the mailbox.<br>
* Consolidates common calls together to allow improved performance.<br>
* The meta-data returned should be immutable and represent the current
* state of the mailbox.
*
* @param resetRecent
* true when recent flags should be reset, false otherwise
* @param mailboxSession
* context, not null
* @param fetchGroup
* describes which optional data should be returned
* @return meta data, not null
* @throws MailboxException
*/
MetaData getMetaData(boolean resetRecent, MailboxSession mailboxSession, MessageManager.MetaData.FetchGroup fetchGroup) throws MailboxException;
/**
* Meta data about the current state of the mailbox.
*/
public interface MetaData {
/**
* Describes the optional data types which will get set in the
* {@link MetaData}.
*
* These are always set: - HIGHESTMODSEQ - PERMANENTFLAGS - UIDNEXT -
* UIDVALIDITY - MODSEQPERMANET - WRITABLE
*/
public enum FetchGroup {
/**
* Only include the message and recent count
*/
NO_UNSEEN,
/**
* Only include the unseen message and recent count
*/
UNSEEN_COUNT,
/**
* Only include the first unseen and the recent count
*/
FIRST_UNSEEN,
/**
* Only return the "always set" metadata as documented above
*/
NO_COUNT
};
/**
* Gets the UIDs of recent messages if requested or an empty
* {@link List} otherwise.
*
* @return the uids flagged RECENT in this mailbox,
*/
List<Long> getRecent();
/**
* Gets the number of recent messages.
*
* @return the number of messages flagged RECENT in this mailbox
*/
long countRecent();
/**
* Gets the flags which can be stored by this mailbox.
*
* @return Flags that can be stored
*/
Flags getPermanentFlags();
/**
* Gets the UIDVALIDITY.
*
* @return UIDVALIDITY
*/
long getUidValidity();
/**
* Gets the next UID predicted. The returned UID is not guaranteed to be
* the one that is assigned to the next message. Its only guaranteed
* that it will be at least equals or bigger then the value
*
* @return the uid that will be assigned to the next appended message
*/
long getUidNext();
/**
* Return the highest mod-sequence for the mailbox. If this value has
* changed till the last check you can be sure that some changes where
* happen on the mailbox
*
* @return higestModSeq
*/
long getHighestModSeq();
/**
* Gets the number of messages that this mailbox contains. This is an
* optional property.<br>
*
* @return number of messages contained or -1 when this optional data
* has not be requested
*
*/
long getMessageCount();
/**
* Gets the number of unseen messages contained in this mailbox. This is
* an optional property.<br>
*
* @return number of unseen messages contained or zero when this
* optional data has not been requested
* @see FetchGroup#UNSEEN_COUNT
*/
long getUnseenCount();
/**
* Gets the UID of the first unseen message. This is an optional
* property.<br>
*
* @return uid of the first unseen message, or null when there are no
* unseen messages
* @see FetchGroup#FIRST_UNSEEN
*/
Long getFirstUnseen();
/**
* Is this mailbox writable?
*
* @return true if read-write, false if read only
*/
boolean isWriteable();
/**
* Return true if the mailbox does store the mod-sequences in a
* permanent way
*
* @return permanent
*/
boolean isModSeqPermanent();
/**
* Returns the ACL concerning this mailbox.
*
* @return acl
*/
MailboxACL getACL();
}
}

View File

@ -0,0 +1,52 @@
/****************************************************************
* 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.james.mailbox;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.Quota;
/**
* Allows to get quotas for {@link MailboxSession} which are bound to a user.
*
*/
public interface QuotaManager {
/**
* Return the message count {@link Quota} for the given {@link MailboxSession} (which in fact is
* bound to a user)
*
* @param session
* @return quota
* @throws MailboxException
*/
public Quota getMessageQuota(MailboxSession session) throws MailboxException;
/**
* Return the message storage {@link Quota} for the given {@link MailboxSession} (which in fact is
* bound to a user)
*
* @param session
* @return quota
* @throws MailboxException
*/
public Quota getStorageQuota(MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,41 @@
/****************************************************************
* 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.james.mailbox;
/**
* Implementations of this interface are aware of processing requests
*/
public interface RequestAware {
/**
* Start the processing of a request for the given MailboxSession. If the
* user is not logged in already then the MailboxSession will be null
*
* @param session
*/
public void startProcessingRequest(MailboxSession session);
/**
* End the processing of a request for the given MailboxSession. If the user
* is not logged in already then the MailboxSession will be null
*
* @param session
*/
public void endProcessingRequest(MailboxSession session);
}

View File

@ -0,0 +1,68 @@
/****************************************************************
* 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.james.mailbox;
import java.io.Serializable;
import java.util.Comparator;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxMetaData;
/**
* Orders by name with INBOX first.
*/
public class StandardMailboxMetaDataComparator implements Comparator<MailboxMetaData>, Serializable {
private static final long serialVersionUID = 1L;
/**
* Static comparison.
*
* @param one
* possibly null
* @param two
* possibly null
* @return {@link Comparator#compare(Object, Object)}
*/
public static int order(MailboxMetaData one, MailboxMetaData two) {
final String nameTwo = two.getPath().getName();
final int result;
final String nameOne = one.getPath().getName();
if (MailboxConstants.INBOX.equals(nameOne)) {
result = MailboxConstants.INBOX.equals(nameTwo) ? 0 : -1;
} else if (MailboxConstants.INBOX.equals(nameTwo)) {
result = 1;
} else if (nameOne == null) {
result = nameTwo == null ? 0 : 1;
} else if (nameTwo == null) {
result = -1;
} else {
result = nameOne.compareTo(nameTwo);
}
return result;
}
/**
* @see Comparator#compare(Object, Object)
*/
public int compare(MailboxMetaData one, MailboxMetaData two) {
return order(one, two);
}
}

View File

@ -0,0 +1,68 @@
/****************************************************************
* 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.james.mailbox;
import java.util.Collection;
import org.apache.james.mailbox.exception.SubscriptionException;
/**
* Subscribes mailboxes to users. This is only needed to implement if the Mailbox should be usable via
* IMAP. For POP3 only you don't need this at all.
*
*/
public interface SubscriptionManager extends RequestAware {
/**
* Subscribes the user in the session to the given mailbox.
*
* @param session
* not null
* @param mailbox
* not null
* @throws SubscriptionException
* when subscription fails
*/
public void subscribe(MailboxSession session, String mailbox) throws SubscriptionException;
/**
* Finds all subscriptions for the user in the session.
*
* @param session
* not null
* @return not null
* @throws SubscriptionException
* when subscriptions cannot be read
*/
public Collection<String> subscriptions(MailboxSession session) throws SubscriptionException;
/**
* Unsubscribes the user in the session from the given mailbox.
*
* @param session
* not null
* @param mailbox
* not null
* @throws SubscriptionException
* when subscriptions cannot be read
*/
public void unsubscribe(MailboxSession session, String mailbox) throws SubscriptionException;
}

View File

@ -0,0 +1,227 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.io.Serializable;
import java.util.List;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MessageMetaData;
import org.apache.james.mailbox.model.UpdatedFlags;
/**
* Listens to <code>Mailbox</code> events.<br>
* Note that listeners may be removed asynchronously.
*/
public interface MailboxListener {
/**
* Informs this listener about the given event.
*
* @param event
* not null
*/
void event(final Event event);
/**
* A mailbox event.
*/
@SuppressWarnings("serial")
public abstract class Event implements Serializable {
private final MailboxSession session;
private final MailboxPath path;
public Event(final MailboxSession session, final MailboxPath path) {
this.session = session;
this.path = path;
}
/**
* Gets the {@link MailboxSession} in which's context the {@link Event}
* happened
*
* @return session
*/
public MailboxSession getSession() {
return session;
}
/**
* Return the path of the Mailbox this event belongs to.
*
* @return path
*/
public MailboxPath getMailboxPath() {
return path;
}
}
/**
* Indicates that mailbox has been deleted.
*/
public class MailboxDeletion extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxDeletion(final MailboxSession session, MailboxPath path) {
super(session, path);
}
}
/**
* Indicates that a mailbox has been Added.
*/
public class MailboxAdded extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxAdded(final MailboxSession session, MailboxPath path) {
super(session, path);
}
}
/**
* Indicates that a mailbox has been renamed.
*/
public abstract class MailboxRenamed extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxRenamed(final MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Gets the new name for this mailbox.
*
* @return name, not null
*/
public abstract MailboxPath getNewPath();
}
/**
* A mailbox event related to updated ACL
*/
public abstract class MailboxACLUpdated extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public MailboxACLUpdated(MailboxSession session, MailboxPath path) {
super(session, path);
}
public abstract MailboxACL getUpdatedACL();
}
/**
* A mailbox event related to a message.
*/
public abstract class MessageEvent extends Event {
/**
*
*/
private static final long serialVersionUID = 1L;
public MessageEvent(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Gets the message UIDs for the subject of this event.
*
* @return message uids
*/
public abstract List<Long> getUids();
}
public abstract class Expunged extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public Expunged(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Return the flags which were set for the added message
*
* @return flags
*/
public abstract MessageMetaData getMetaData(long uid);
}
/**
* A mailbox event related to updated flags
*/
public abstract class FlagsUpdated extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public FlagsUpdated(MailboxSession session, MailboxPath path) {
super(session, path);
}
public abstract List<UpdatedFlags> getUpdatedFlags();
}
/**
* A mailbox event related to added message
*/
public abstract class Added extends MessageEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public Added(MailboxSession session, MailboxPath path) {
super(session, path);
}
/**
* Return the flags which were set for the added message
*
* @return flags
*/
public abstract MessageMetaData getMetaData(long uid);
}
}

View File

@ -0,0 +1,81 @@
/****************************************************************
* 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.james.mailbox;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxPath;
/**
* Implementations of this interface supports {@link MailboxListener}. Its needed that the events get handled
* in the submitted order
*
*
*/
public interface MailboxListenerSupport {
/**
* <p>
* Implementations of Mailbox may interpret the fact that someone is
* listening and do some caching and even postpone persistence until
* everyone has removed itself.
* </p>
*
* @param mailboxPath
* not null
* @param listener
* not null
* @param session
* not null
* @throws MailboxException
*/
void addListener(MailboxPath mailboxPath, MailboxListener listener, MailboxSession session) throws MailboxException;
/**
* Remove the {@link MailboxListener}
*
* @param mailboxPath
* @param listner
* @param session
* @throws MailboxException
*/
void removeListener(MailboxPath mailboxPath, MailboxListener listner, MailboxSession session) throws MailboxException;
/**
* Add a {@link MailboxListener} which get fired for ever
* {@link MailboxPath}
*
* @param listener
* @param session
* @throws MailboxException
*/
void addGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException;
/**
* Remove the {@link MailboxListener}
*
* @param listner
* @param session
* @throws MailboxException
*/
void removeGlobalListener(MailboxListener listner, MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,260 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.util.List;
import org.apache.james.mailbox.exception.BadCredentialsException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxExistsException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.model.MailboxMetaData;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MailboxQuery;
import org.apache.james.mailbox.model.MessageRange;
import org.slf4j.Logger;
/**
* <p>
* Central MailboxManager which creates, lists, provides, renames and deletes
* Mailboxes
* </p>
* <p>
* An important goal is to be JavaMail feature compatible. That means JavaMail
* could be used in both directions: As a backend for e.g. accessing a Maildir
* JavaMail store or as a frontend to access a JDBC MailboxManager through
* JavaMail. This should be possible by not too complicated wrapper classes. Due
* to the complexity of JavaMail it might be impossible to avoid some
* limitations.
* </p>
* <p>
* Internally MailboxManager deals with named repositories that could have
* different implementations. E.g. JDBC connections to different hosts or
* Maildir / Mbox like stores. These repositories are identified by their names
* and maybe are configured in config.xml. The names of the mailboxes have to be
* mapped to the corresponding repository name. For user mailboxes this could be
* done by a "User.getRepositoryName()" property. It is imaginable that
* repositories lookup further properties from the user object like a path name
* for a file based storage method. Until Milestone 6 there is only one named
* repository: "default".
* </p>
* <p>
* The only operation that requires dealing with the named repositories directly
* is the quota management. It is probably really difficult to implement a quota
* system that spans multiple repository implementations. That is why quotas are
* created for a specific repository. To be able to administer, repositories and
* theier belonging mailboxes can be listet.
* </p>
*/
public interface MailboxManager extends RequestAware, MailboxListenerSupport {
/**
* Return the delimiter to use for folders
*
* @return delimiter
*/
char getDelimiter();
/**
* Gets an session suitable for IMAP.
*
* @param mailboxPath
* the Path of the mailbox, not null
* @param session
* the context for this call, not null
* @return <code>ImapMailboxSession</code>, not null
* @throws MailboxException
* when the mailbox cannot be opened
* @throws MailboxNotFoundException
* when the given mailbox does not exist
*/
MessageManager getMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Creates a new mailbox. Any intermediary mailboxes missing from the
* hierarchy should be created.
*
* @param mailboxPath
* @param mailboxSession
* the context for this call, not null
* @throws MailboxException
* when creation fails
*/
void createMailbox(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException;
/**
* Delete the mailbox with the name
*
* @param mailboxPath
* @param session
* @throws MailboxException
*/
void deleteMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Renames a mailbox.
*
* @param from
* original mailbox
* @param to
* new mailbox
* @param session
* the context for this call, not nul
* @throws MailboxException
* otherwise
* @throws MailboxExistsException
* when the <code>to</code> mailbox exists
* @throws MailboxNotFound
* when the <code>from</code> mailbox does not exist
*/
void renameMailbox(MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Copy the given {@link MessageRange} from one Mailbox to the other.
*
* Be aware that the copied Messages MUST get the \RECENT flag set!
*
* @param set
* messages to copy
* @param from
* name of the source mailbox
* @param to
* name of the destination mailbox
* @param session
* <code>MailboxSession</code>, not null
* @return a list of MessageRange - uids assigned to copied messages
*/
List<MessageRange> copyMessages(MessageRange set, MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Move the given {@link MessageRange} from one Mailbox to the other.
*
* Be aware that the moved Messages MUST get the \RECENT flag set!
*
* @param set
* messages to move
* @param from
* name of the source mailbox
* @param to
* name of the destination mailbox
* @param session
* <code>MailboxSession</code>, not null
* @return a list of MessageRange - uids assigned to moved messages
*/
List<MessageRange> moveMessages(MessageRange set, MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
/**
* Searches for mailboxes matching the given query.
*
* @param expression
* not null
* @param session
* the context for this call, not null
* @throws MailboxException
*/
List<MailboxMetaData> search(MailboxQuery expression, MailboxSession session) throws MailboxException;
/**
* Does the given mailbox exist?
*
* @param mailboxPath
* not null
* @param session
* the context for this call, not null
* @return true when the mailbox exists and is accessible for the given
* user, false otherwise
* @throws MailboxException
*/
boolean mailboxExists(MailboxPath mailboxPath, MailboxSession session) throws MailboxException;
/**
* Creates a new system session.<br>
* A system session is intended to be used for programmatic access.<br>
* Use {@link #login(String, String, Logger)} when accessing this API from a
* protocol.
*
* @param userName
* the name of the user whose session is being created
* @param log
* context sensitive log
* @return <code>MailboxSession</code>, not null
* @throws BadCredentialsException
* when system access is not allowed for the given user
* @throws MailboxException
* when the creation fails for other reasons
*/
MailboxSession createSystemSession(String userName, Logger log) throws BadCredentialsException, MailboxException;
/**
* Autenticates the given user against the given password.<br>
* When authentic and authorized, a session will be supplied
*
* @param userid
* user name
* @param passwd
* password supplied
* @param log
* context sensitive log
* @return a <code>MailboxSession</code> when the user is authentic and
* authorized to access
* @throws BadCredentialsException
* when system access is denighed for the given user
* @throws MailboxException
* when the creation fails for other reasons
*/
MailboxSession login(String userid, String passwd, Logger log) throws BadCredentialsException, MailboxException;
/**
* <p>
* Logs the session out, freeing any resources. Clients who open session
* should make best efforts to call this when the session is closed.
* </p>
* <p>
* Note that clients may not always be able to call logout (whether forced
* or not). Mailboxes that create sessions which are expensive to maintain
* <code>MUST</code> retain a reference and periodically check
* {@link MailboxSession#isOpen()}.
* </p>
* <p>
* Note that implementations much be aware that it is possible that this
* method may be called more than once with the same session.
* </p>
*
* @param session
* not null
* @param force
* true when the session logout is forced by premature connection
* termination
* @throws MailboxException
* when logout fails
*/
void logout(MailboxSession session, boolean force) throws MailboxException;
/**
* Return a unmodifiable {@link List} of {@link MailboxPath} objects
*
* @param session
* @return pathList
* @throws MailboxException
*/
List<MailboxPath> list(MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,69 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxPath;
/**
* The {@link MailboxPathLocker} is responsible to help to synchronize the
* access to a {@link MailboxPath} and execute an given {@link LockAwareExecution}
*
* Implementations that are not able to handle read / write locks in a different way are needed to handle all locks as write lock.
*/
public interface MailboxPathLocker {
/**
* @deprecated use {@link #executeWithLock(MailboxSession, MailboxPath, LockAwareExecution, boolean)} with argument <code>true</code>
*/
@Deprecated
public <T> T executeWithLock(MailboxSession session, MailboxPath path, LockAwareExecution<T> execution) throws MailboxException;
/**
* Execute the {@link LockAwareExecution} while holding a lock on the
* {@link MailboxPath}. If writeLock is true the implementation need to make sure that no other threads can read and write while the lock
* is hold. The contract is the same as documented in {@link ReadWriteLock}.
*
* @param session
* @param path
* @param execution
* @param writeLock
*
* @throws MailboxException
*/
public <T> T executeWithLock(MailboxSession session, MailboxPath path, LockAwareExecution<T> execution, boolean writeLock) throws MailboxException;
/**
* Execute code while holding a lock
*/
public interface LockAwareExecution<T> {
/**
* Execute code block
*
* @throws MailboxException
*/
public T execute() throws MailboxException;
}
}

View File

@ -0,0 +1,164 @@
/****************************************************************
* 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.james.mailbox;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
/**
* Mailbox session.
*/
public interface MailboxSession {
/**
* Id which will be used for a System session
*/
public final static long SYSTEM_SESSION_ID = 0L;
public static enum SessionType {
/**
* Session was created via the System
*/
System,
/**
* Session belongs to a specific user which was authenticated somehow
*/
User
}
/**
* Return if the {@link MailboxSession} is of type {@link SessionType#User} or {@link SessionType#System}
*
* @return type
*/
SessionType getType();
/**
* Gets the session ID.
*
* @return session id
*/
long getSessionId();
/**
* Is this session open?
*
* @return true if the session is open, false otherwise
*/
boolean isOpen();
/**
* Closes this session.
*/
void close();
/**
* Gets the logger for this session context.
*
* @return not null
*/
Logger getLog();
/**
* Gets the user executing this session.
*
* @return not null
*/
User getUser();
/**
* A mailbox user. Useful for specialist mailbox implementation.
*/
public interface User {
/**
* Gets the name of the user.
*
* @return not null
*/
String getUserName();
/**
* Return the Password for the logged in user
*
* @return password
*/
String getPassword();
/**
* Gets acceptable localisation for this user in preference order.<br>
* When localising a phrase, each <code>Locale</code> should be tried in
* order until an appropriate translation is obtained.
*
* @return not null, when empty the default local should be used
*/
List<Locale> getLocalePreferences();
}
/**
* Gets the <a href='http://www.isi.edu/in-notes/rfc2342.txt' rel='tag'>RFC
* 2342</a> personal namespace for the current session.<br>
* Note that though servers may offer multiple personal namespaces, support
* is not offered through this API. This decision may be revised if
* reasonable use cases emerge.
*
* @return Personal Namespace, not null
*/
String getPersonalSpace();
/**
* Gets the <a href='http://www.isi.edu/in-notes/rfc2342.txt' rel='tag'>RFC
* 2342</a> other users namespace for the current session.<br>
* Note that though servers may offer multiple other users namespaces,
* support is not offered through this API. This decision may be revised if
* reasonable use cases emerge.
*
* @return Other Users Namespace or null when there is non available
*/
String getOtherUsersSpace();
/**
* Iterates the <a href='http://www.isi.edu/in-notes/rfc2342.txt'
* rel='tag'>RFC 2342</a> Shared Namespaces available for the current
* session.
*
* @return not null though possibly empty
*/
Collection<String> getSharedSpaces();
/**
* Return the stored attributes for this {@link MailboxSession}.
*
* @return attributes
*/
Map<Object, Object> getAttributes();
/**
* Return server side, folder path separator
*
* @return path separator
*/
char getPathDelimiter();
}

View File

@ -0,0 +1,39 @@
/****************************************************************
* 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.james.mailbox;
/**
* Generator for id's which should used for new {@link MailboxSession} instances
*
*
*/
public interface MailboxSessionIdGenerator {
/**
* Return the next id to use for a {@link MailboxSession}. The id must be unique
* while the server is running and can be any long except {@link MailboxSession#SYSTEM_SESSION_ID}.
*
* The returned ids can be in any specific order.
*
* @return id
*/
long nextId();
}

View File

@ -0,0 +1,382 @@
/****************************************************************
* 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.james.mailbox;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.mail.Flags;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.UnsupportedCriteriaException;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.EditMode;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MessageResult;
import org.apache.james.mailbox.model.MessageResultIterator;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.model.SimpleMailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MessageResult.FetchGroup;
/**
* Interface which represent a Mailbox
*
* A {@link MessageManager} should be valid for the whole {@link MailboxSession}
*/
public interface MessageManager {
/**
* Return the count
*
* @param mailboxSession
* @return count
* @throws MailboxException
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
@Deprecated
long getMessageCount(MailboxSession mailboxSession) throws MailboxException;
/**
* Return if the Mailbox is writable
*
* @param session
* @return writable
* @throws MailboxException
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
@Deprecated
boolean isWriteable(MailboxSession session) throws MailboxException;
/**
* Return true if {@link MessageResult#getModSeq()} is stored in a permanent
* way.
*
* @param session
* @return modSeqPermanent
* @deprecated use
* {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
*/
boolean isModSeqPermanent(MailboxSession session);
/**
* Searches for messages matching the given query. The result must be
* ordered
*
* @param mailboxSession
* not null
* @return uid iterator
* @throws UnsupportedCriteriaException
* when any of the search parameters are not supported by this
* mailbox
* @throws MailboxException
* when search fails for other reasons
*/
Iterator<Long> search(SearchQuery searchQuery, MailboxSession mailboxSession) throws MailboxException;
/**
* Expunges messages in the given range from this mailbox.
*
* @param set
* not null
* @param mailboxSession
* not null
* @return uid iterator
* @throws MailboxException
* if anything went wrong
*/
Iterator<Long> expunge(MessageRange set, MailboxSession mailboxSession) throws MailboxException;
/**
* Sets flags on messages within the given range. The new flags are returned
* for each message altered.
*
* @param flags
* Flags to be set
* @param value
* true = set, false = unset
* @param replace
* replace all Flags with this flags, value has to be true
* @param set
* the range of messages
* @param mailboxSession
* not null
* @return new flags indexed by UID
* @throws MailboxException
*/
Map<Long, Flags> setFlags(Flags flags, boolean value, boolean replace, MessageRange set, MailboxSession mailboxSession) throws MailboxException;
/**
* Appends a message to this mailbox. This method must return a higher UID
* as the last call in every case which also needs to be unique for the
* lifetime of the mailbox.
*
*
* @param internalDate
* the time of addition to be set, not null
* @param mailboxSession
* not null
* @param isRecent
* true when the message should be marked recent, false otherwise
* @param flags
* optionally set these flags on created message, or null when no
* additional flags should be set
* @return uid for the newly added message
* @throws MailboxException
* when message cannot be appended
*/
long appendMessage(InputStream msgIn, Date internalDate, MailboxSession mailboxSession, boolean isRecent, Flags flags) throws MailboxException;
/**
* Gets messages in the given range. The messages may get fetched under
* the-hood in batches so the caller should check if
* {@link MessageResultIterator#getException()} returns <code>null</code>
* after {@link MessageResultIterator#hasNext()} returns <code>false</code>.
*
*
* @param set
* @param fetchGroup
* data to fetch
* @param mailboxSession
* not null
* @return MessageResult with the fields defined by FetchGroup
* @throws MailboxException
*/
MessageResultIterator getMessages(MessageRange set, FetchGroup fetchGroup, MailboxSession mailboxSession) throws MailboxException;
/**
* Tells whether the given {@link MailboxSession}'s user has the given
* {@link MailboxACLRight} for this {@link MessageManager}'s mailbox.
*
* @param right
* @param session
* @return true if the given {@link MailboxSession}'s user has the given
* {@link MailboxACLRight} for this {@link MessageManager}'s
* mailbox; false otherwise.
* @throws MailboxException
*/
public boolean hasRight(MailboxACLRight right, MailboxSession session) throws MailboxException;
/**
* Returns the rights applicable to the user who has sent the current
* request.
*
* @param session
* @return the rights applicable to the user who has sent the request,
* returns {@link SimpleMailboxACL#NO_RIGHTS} if
* {@code session.getUser()} is null.
* @throws UnsupportedRightException
*/
public abstract MailboxACLRights myRights(MailboxSession session) throws MailboxException;
/**
* Computes a result suitable for the LISTRIGHTS IMAP command. The result is
* computed for this mailbox and the given {@code identifier}.
*
* From RFC 4314 section 3.7:
* The first element of the resulting array contains the (possibly empty)
* set of rights the identifier will always be granted in the mailbox.
* Following this are zero or more right sets the identifier can be granted
* in the mailbox. Rights mentioned in the same set are tied together. The
* server MUST either grant all tied rights to the identifier in the mailbox
* or grant none.
*
* The same right MUST NOT be listed more than once in the LISTRIGHTS
* command.
*
* @param identifier
* the identifier from the LISTRIGHTS command.
* @param session
* @return
* @throws UnsupportedRightException
*/
public MailboxACLRights[] listRigths(MailboxACLEntryKey identifier, MailboxSession session) throws UnsupportedRightException;
/**
* TODO setRights.
*
* @param identifier
* @param editMode
* @param mailboxAclRights
* @throws UnsupportedRightException
*/
void setRights(MailboxACLEntryKey identifier, EditMode editMode, MailboxACLRights mailboxAclRights) throws UnsupportedRightException;
/**
* Gets current meta data for the mailbox.<br>
* Consolidates common calls together to allow improved performance.<br>
* The meta-data returned should be immutable and represent the current
* state of the mailbox.
*
* @param resetRecent
* true when recent flags should be reset, false otherwise
* @param mailboxSession
* context, not null
* @param fetchGroup
* describes which optional data should be returned
* @return meta data, not null
* @throws MailboxException
*/
MetaData getMetaData(boolean resetRecent, MailboxSession mailboxSession, MessageManager.MetaData.FetchGroup fetchGroup) throws MailboxException;
/**
* Meta data about the current state of the mailbox.
*/
public interface MetaData {
/**
* Describes the optional data types which will get set in the
* {@link MetaData}.
*
* These are always set: - HIGHESTMODSEQ - PERMANENTFLAGS - UIDNEXT -
* UIDVALIDITY - MODSEQPERMANET - WRITABLE
*/
public enum FetchGroup {
/**
* Only include the message and recent count
*/
NO_UNSEEN,
/**
* Only include the unseen message and recent count
*/
UNSEEN_COUNT,
/**
* Only include the first unseen and the recent count
*/
FIRST_UNSEEN,
/**
* Only return the "always set" metadata as documented above
*/
NO_COUNT
};
/**
* Gets the UIDs of recent messages if requested or an empty
* {@link List} otherwise.
*
* @return the uids flagged RECENT in this mailbox,
*/
List<Long> getRecent();
/**
* Gets the number of recent messages.
*
* @return the number of messages flagged RECENT in this mailbox
*/
long countRecent();
/**
* Gets the flags which can be stored by this mailbox.
*
* @return Flags that can be stored
*/
Flags getPermanentFlags();
/**
* Gets the UIDVALIDITY.
*
* @return UIDVALIDITY
*/
long getUidValidity();
/**
* Gets the next UID predicted. The returned UID is not guaranteed to be
* the one that is assigned to the next message. Its only guaranteed
* that it will be at least equals or bigger then the value
*
* @return the uid that will be assigned to the next appended message
*/
long getUidNext();
/**
* Return the highest mod-sequence for the mailbox. If this value has
* changed till the last check you can be sure that some changes where
* happen on the mailbox
*
* @return higestModSeq
*/
long getHighestModSeq();
/**
* Gets the number of messages that this mailbox contains. This is an
* optional property.<br>
*
* @return number of messages contained or -1 when this optional data
* has not be requested
*
*/
long getMessageCount();
/**
* Gets the number of unseen messages contained in this mailbox. This is
* an optional property.<br>
*
* @return number of unseen messages contained or zero when this
* optional data has not been requested
* @see FetchGroup#UNSEEN_COUNT
*/
long getUnseenCount();
/**
* Gets the UID of the first unseen message. This is an optional
* property.<br>
*
* @return uid of the first unseen message, or null when there are no
* unseen messages
* @see FetchGroup#FIRST_UNSEEN
*/
Long getFirstUnseen();
/**
* Is this mailbox writable?
*
* @return true if read-write, false if read only
*/
boolean isWriteable();
/**
* Return true if the mailbox does store the mod-sequences in a
* permanent way
*
* @return permanent
*/
boolean isModSeqPermanent();
/**
* Returns the ACL concerning this mailbox.
*
* @return acl
*/
MailboxACL getACL();
}
}

View File

@ -0,0 +1,52 @@
/****************************************************************
* 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.james.mailbox;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.Quota;
/**
* Allows to get quotas for {@link MailboxSession} which are bound to a user.
*
*/
public interface QuotaManager {
/**
* Return the message count {@link Quota} for the given {@link MailboxSession} (which in fact is
* bound to a user)
*
* @param session
* @return quota
* @throws MailboxException
*/
public Quota getMessageQuota(MailboxSession session) throws MailboxException;
/**
* Return the message storage {@link Quota} for the given {@link MailboxSession} (which in fact is
* bound to a user)
*
* @param session
* @return quota
* @throws MailboxException
*/
public Quota getStorageQuota(MailboxSession session) throws MailboxException;
}

View File

@ -0,0 +1,41 @@
/****************************************************************
* 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.james.mailbox;
/**
* Implementations of this interface are aware of processing requests
*/
public interface RequestAware {
/**
* Start the processing of a request for the given MailboxSession. If the
* user is not logged in already then the MailboxSession will be null
*
* @param session
*/
public void startProcessingRequest(MailboxSession session);
/**
* End the processing of a request for the given MailboxSession. If the user
* is not logged in already then the MailboxSession will be null
*
* @param session
*/
public void endProcessingRequest(MailboxSession session);
}

View File

@ -0,0 +1,68 @@
/****************************************************************
* 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.james.mailbox;
import java.io.Serializable;
import java.util.Comparator;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxMetaData;
/**
* Orders by name with INBOX first.
*/
public class StandardMailboxMetaDataComparator implements Comparator<MailboxMetaData>, Serializable {
private static final long serialVersionUID = 1L;
/**
* Static comparison.
*
* @param one
* possibly null
* @param two
* possibly null
* @return {@link Comparator#compare(Object, Object)}
*/
public static int order(MailboxMetaData one, MailboxMetaData two) {
final String nameTwo = two.getPath().getName();
final int result;
final String nameOne = one.getPath().getName();
if (MailboxConstants.INBOX.equals(nameOne)) {
result = MailboxConstants.INBOX.equals(nameTwo) ? 0 : -1;
} else if (MailboxConstants.INBOX.equals(nameTwo)) {
result = 1;
} else if (nameOne == null) {
result = nameTwo == null ? 0 : 1;
} else if (nameTwo == null) {
result = -1;
} else {
result = nameOne.compareTo(nameTwo);
}
return result;
}
/**
* @see Comparator#compare(Object, Object)
*/
public int compare(MailboxMetaData one, MailboxMetaData two) {
return order(one, two);
}
}

View File

@ -0,0 +1,68 @@
/****************************************************************
* 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.james.mailbox;
import java.util.Collection;
import org.apache.james.mailbox.exception.SubscriptionException;
/**
* Subscribes mailboxes to users. This is only needed to implement if the Mailbox should be usable via
* IMAP. For POP3 only you don't need this at all.
*
*/
public interface SubscriptionManager extends RequestAware {
/**
* Subscribes the user in the session to the given mailbox.
*
* @param session
* not null
* @param mailbox
* not null
* @throws SubscriptionException
* when subscription fails
*/
public void subscribe(MailboxSession session, String mailbox) throws SubscriptionException;
/**
* Finds all subscriptions for the user in the session.
*
* @param session
* not null
* @return not null
* @throws SubscriptionException
* when subscriptions cannot be read
*/
public Collection<String> subscriptions(MailboxSession session) throws SubscriptionException;
/**
* Unsubscribes the user in the session from the given mailbox.
*
* @param session
* not null
* @param mailbox
* not null
* @throws SubscriptionException
* when subscriptions cannot be read
*/
public void unsubscribe(MailboxSession session, String mailbox) throws SubscriptionException;
}

View File

@ -0,0 +1,29 @@
K 25
svn:wc:ra_dav:version-url
V 94
/repos/asf/!svn/ver/1292019/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl
END
SimpleGroupMembershipResolver.java
K 25
svn:wc:ra_dav:version-url
V 129
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/SimpleGroupMembershipResolver.java
END
UnionMailboxACLResolver.java
K 25
svn:wc:ra_dav:version-url
V 123
/repos/asf/!svn/ver/1292019/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/UnionMailboxACLResolver.java
END
GroupMembershipResolver.java
K 25
svn:wc:ra_dav:version-url
V 123
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/GroupMembershipResolver.java
END
MailboxACLResolver.java
K 25
svn:wc:ra_dav:version-url
V 118
/repos/asf/!svn/ver/1292019/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/MailboxACLResolver.java
END

View File

@ -0,0 +1,164 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl
http://svn.apache.org/repos/asf
2012-02-21T21:05:02.067525Z
1292019
ppalaga
13f79535-47bb-0310-9956-ffa450edef68
SimpleGroupMembershipResolver.java
file
2013-09-02T02:54:40.000000Z
b44ac189eb5c41157ee5385e2f95924e
2012-02-09T12:13:02.344953Z
1242288
eric
has-props
2508
UnionMailboxACLResolver.java
file
2013-09-02T02:54:40.000000Z
ed6f457a1bf983e54befa85758cc0e15
2012-02-21T21:05:02.067525Z
1292019
ppalaga
has-props
21192
GroupMembershipResolver.java
file
2013-09-02T02:54:40.000000Z
263bd0d4db90f8f7cf062652c4cf8add
2012-02-09T12:13:02.344953Z
1242288
eric
1523
MailboxACLResolver.java
file
2013-09-02T02:54:40.000000Z
6480d0b6110328544dea8916b5606fbe
2012-02-21T21:05:02.067525Z
1292019
ppalaga
has-props
8685

View File

@ -0,0 +1,5 @@
K 13
svn:mime-type
V 10
text/plain
END

View File

@ -0,0 +1,35 @@
/****************************************************************
* 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.james.mailbox.acl;
/**
* An interface for querying group memberships.
*/
public interface GroupMembershipResolver {
/**
* Tests if the given user is a member of the given group.
*
* @param user
* @param group
* @return
*/
boolean isMember(String user, String group);
}

View File

@ -0,0 +1,178 @@
/*
* 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.james.mailbox.acl;
import javax.mail.Flags;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
/**
* Implements the interpretation of ACLs.
*
* From RFC4314: <cite>It is possible for multiple identifiers in an access
* control list to apply to a given user. For example, an ACL may include rights
* to be granted to the identifier matching the user, one or more
* implementation-defined identifiers matching groups that include the user,
* and/or the identifier "anyone". How these rights are combined to determine
* the users access is implementation defined. An implementation may choose, for
* example, to use the union of the rights granted to the applicable
* identifiers. An implementation may instead choose, for example, to use only
* those rights granted to the most specific identifier present in the ACL. A
* client can determine the set of rights granted to the logged-in user for a
* given mailbox name by using the MYRIGHTS command. </cite>
*
*/
public interface MailboxACLResolver {
/**
* Applies global ACL to the given <code>resourceACL</code>. From RFC 4314:
* An implementation [...] MAY force rights to always or never be granted to
* particular identifiers.
*
* @param resourceACL
* @param resourceOwnerIsGroup
* @return
* @throws UnsupportedRightException
*/
public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Tells whether the given user has the given right granted on the basis of
* the given resourceACL. Global ACL (if there is any) should be applied
* within this method.
*
* @param requestUser
* the user for whom the given right is tested, possibly
* <code>null</code> when there is no authenticated user in the
* given context.
* @param groupMembershipResolver
* this resolver is used when checking whether any group rights
* contained in resourceACL are applicable for the requestUser.
* @param right
* the right which will be proven to apply for the given
* requestUser.
* @param resourceACL
* the ACL defining the access right for the resource in
* question.
* @param resourceOwner
* this user name is used as a replacement for the "owner" place
* holder in the resourceACL.
* @param resourceOwnerIsGroup
* true if the resourceOwner is a group of users, false
* otherwise.
* @return true if the given user has the given right for the given
* resource; false otherwise.
* @throws UnsupportedRightException
*/
boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Maps the given {@code mailboxACLRights} to READ-WRITE and READ-ONLY
* response codes.
*
* From RFC 4314 section 5.2:
*
* The server SHOULD include a READ-WRITE response code in the tagged OK
* response if at least one of the "i", "e", or "shared flag rights"(***) is
* granted to the current user.
*
* The server MUST include a READ-ONLY response code in the tagged OK
* response to a SELECT command if none of the following rights is granted
* to the current user: "i", "e", and "shared flag rights"(***).
*
* @param mailboxACLRights
* the rights applicable to the user and resource in question.
* This method supposes that any global ACLs were already applied
* to the {@code mailboxACLRights} parameter before this method
* is called.
* @param sharedFlags
* From RFC 4314 section 5.2: If the ACL server implements some
* flags as shared for a mailbox (i.e., the ACL for the mailbox
* MAY be set up so that changes to those flags are visible to
* another user), lets call the set of rights associated with
* these flags (as described in Section 4) for that mailbox
* collectively as "shared flag rights". Note that the
* "shared flag rights" set MAY be different for different
* mailboxes.
*
* If the server doesnt support "shared multiuser write access"
* to a mailbox or doesnt implement shared flags on the mailbox,
* "shared flag rights" for the mailbox is defined to be the
* empty set.
*
* @return
* @throws UnsupportedRightException
*/
public abstract boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException;
/**
* Computes a result suitable for the LISTRIGHTS IMAP command. The result is
* computed regardless of mailbox. Therefore it should be viewed as a
* general default which may be further customised depending on the given
* mailbox.
*
* @param key
* the identifier from the LISTRIGHTS command
* @param groupMembershipResolver
* @param resourceOwner
* the owner of the mailbox named in the LISTRIGHTS command. User
* name or group name.
* @param resourceOwnerIsGroup
* true if the {@code resourceOwner} is a group of users, false
* otherwise.
* @return an array of {@link MailboxACLRights}. The first element is the
* set of implicit (global) rights which does not need to be set
* explicitly for the given identifier. Further elements are groups
* of rights which can be set for the given identifier and resource.
* @throws UnsupportedRightException
*/
public MailboxACLRights[] listRights(final MailboxACLEntryKey key, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Computes the rights which apply to the given user and resource. Global
* ACL (if there is any) should be applied within this method.
*
* @param requestUser
* the user for whom the rights are computed, possibly
* <code>null</code> when there is no authenticated user in the
* given context.
* @param groupMembershipResolver
* this resolver is used when checking whether any group rights
* contained in resourceACL are applicable for the requestUser.
* @param resourceACL
* the ACL defining the access right for the resource in
* question.
* @param resourceOwner
* this user name is used as a replacement for the "owner" place
* holder in the resourceACL.
* @param resourceOwnerIsGroup
* true if the resourceOwner is a group of users, false
* otherwise.
* @return the rights applicable for the given user and resource.
* @throws UnsupportedRightException
*/
public abstract MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
}

View File

@ -0,0 +1,81 @@
/*
* 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.james.mailbox.acl;
import java.util.HashSet;
import java.util.Set;
/**
* In memory {@link GroupMembershipResolver} implementation. There is no
* persistence. You will get only what you add.
*
*/
public class SimpleGroupMembershipResolver implements GroupMembershipResolver {
private static class Membership {
private final String group;
private final int hash;
private final String user;
public Membership(String user, String group) {
super();
this.group = group;
this.user = user;
final int PRIME = 31;
this.hash = PRIME * this.group.hashCode() + this.user.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof Membership) {
Membership other = (Membership) o;
return this.group == other.group || (this.group != null && this.group.equals(other.group)) && this.user == other.user || (this.user != null && this.user.equals(other.user));
}
return false;
}
@Override
public int hashCode() {
return hash;
}
@Override
public String toString() {
return group + ": " + user;
}
}
private Set<Membership> memberships = new HashSet<SimpleGroupMembershipResolver.Membership>(32);
public void addMembership(String group, String user) {
memberships.add(new Membership(user, group));
}
@Override
public boolean isMember(String user, String group) {
return memberships.contains(new Membership(user, group));
}
}

View File

@ -0,0 +1,442 @@
/*
* 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.james.mailbox.acl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
import org.apache.james.mailbox.model.MailboxACL.NameType;
import org.apache.james.mailbox.model.SimpleMailboxACL;
import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
import com.sun.mail.mbox.Mailbox;
/**
* An implementation which works with the union of the rights granted to the
* applicable identifiers. Inspired by RFC 4314 Section 2.
*
* In
* {@link UnionMailboxACLResolver#resolveRights(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, MailboxACL, String, boolean)}
* all applicable negative and non-negative rights are union-ed separately and
* the result is computed afterwards with
* <code>nonNegativeUnion.except(negativeUnion)</code>.
*
* Allows for setting distinct global ACL for users' mailboxes on one hand and
* group (a.k.a shared) mailboxes on the other hand. E.g. the zero parameter
* constructor uses full rights for user mailboxes and
* full-except-administration rights for group mailboxes.
*
*/
public class UnionMailboxACLResolver implements MailboxACLResolver {
public static final MailboxACL DEFAULT_GLOBAL_GROUP_ACL = SimpleMailboxACL.OWNER_FULL_EXCEPT_ADMINISTRATION_ACL;
/**
* Nothing else than full rights for the owner.
*/
public static final MailboxACL DEFAULT_GLOBAL_USER_ACL = SimpleMailboxACL.OWNER_FULL_ACL;
private static final int POSITIVE_INDEX = 0;
private static final int NEGATIVE_INDEX = 1;
private final MailboxACL groupGlobalACL;
/**
* Stores global ACL which is merged with ACL of every mailbox when
* computing
* {@link #rightsOf(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, Mailbox)}
* and
* {@link #hasRight(String, Mailbox, MailboxACLRight, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver)}
* .
*/
private final MailboxACL userGlobalACL;
/**
* Creates a new instance of UnionMailboxACLResolver with
* {@link #DEFAULT_GLOBAL_USER_ACL} as {@link #userGlobalACL} and
* {@link #DEFAULT_GLOBAL_USER_ACL} as {@link #groupGlobalACL}.
*/
public UnionMailboxACLResolver() {
super();
this.userGlobalACL = DEFAULT_GLOBAL_USER_ACL;
this.groupGlobalACL = DEFAULT_GLOBAL_GROUP_ACL;
}
/**
* Creates a new instance of UnionMailboxACLResolver with the given
* globalACL.
*
* @param groupGlobalACL
*
* @param globalACL
* see {@link #userGlobalACL}, cannot be null.
* @throws NullPointerException
* when globalACL is null.
*/
public UnionMailboxACLResolver(MailboxACL userGlobalACL, MailboxACL groupGlobalACL) {
super();
if (userGlobalACL == null) {
throw new NullPointerException("Missing userGlobalACL.");
}
if (groupGlobalACL == null) {
throw new NullPointerException("Missing groupGlobalACL.");
}
this.userGlobalACL = userGlobalACL;
this.groupGlobalACL = groupGlobalACL;
}
/**
* Tells whether the given {@code aclKey} {@link MailboxACLEntryKey} is
* applicable for the given {@code queryKey}.
*
* There are two use cases for which this method was designed and tested:
*
* (1) Calls from
* {@link #hasRight(String, GroupMembershipResolver, MailboxACLRight, MailboxACL, String, boolean)}
* and
* {@link #resolveRights(String, GroupMembershipResolver, MailboxACL, String, boolean)}
* in which the {@code queryKey} is a {@link NameType#user}.
*
* (2) Calls from
* {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
* where {@code queryKey} can be anything including {@link NameType#user},
* {@link NameType#group} and all {@link NameType#special} identifiers.
*
* Clearly the set of cases which this method has to handle in (1) is a
* proper subset of the cases handled in (2). See the javadoc on
* {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
* for more details.
*
* @param aclKey
* @param queryKey
* @param groupMembershipResolver
* @param resourceOwner
* @param resourceOwnerIsGroup
* @return
*/
protected static boolean applies(MailboxACLEntryKey aclKey, MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, String resourceOwner, boolean resourceOwnerIsGroup) {
final String aclKeyName = aclKey.getName();
final NameType aclKeyNameType = aclKey.getNameType();
if (MailboxACL.SpecialName.anybody.name().equals(aclKeyName)) {
/* this works also for unauthenticated users */
return true;
} else if (queryKey != null) {
String queryUserOrGroupName = queryKey.getName();
switch (queryKey.getNameType()) {
case user:
/* Authenticated users */
switch (aclKeyNameType) {
case special:
if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/* non null query user is viewed as authenticated */
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
return (!resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner)) || (resourceOwnerIsGroup && groupMembershipResolver.isMember(queryUserOrGroupName, resourceOwner));
} else {
/* should not happen unless the parent if is changed */
throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
}
case user:
return aclKeyName.equals(queryUserOrGroupName);
case group:
return groupMembershipResolver.isMember(queryUserOrGroupName, aclKeyName);
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
case group:
/* query is a group */
switch (aclKeyNameType) {
case special:
if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/*
* see the javadoc comment on listRights()
*/
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
return resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner);
} else {
/* should not happen unless the parent if is changed */
throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
}
case user:
/* query groups cannot match ACL users */
return false;
case group:
return aclKeyName.equals(queryUserOrGroupName);
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
case special:
/* query is a special name */
switch (aclKeyNameType) {
case special:
if (aclKeyName.equals(queryUserOrGroupName)) {
/*
* authenticated matches authenticated and owner matches
* owner
*/
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(queryUserOrGroupName) && MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/*
* query owner matches authenticated because owner will
* be resolved only if the user is authenticated
*/
return true;
} else {
return false;
}
case user:
case group:
/* query specials cannot match ACL users or groups */
return false;
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + queryKey.getNameType());
}
} else {
/* non-anybody ACL keys do not match non-authenticated queries */
return false;
}
}
/**
* @see org.apache.james.mailbox.MailboxACLResolver#applyGlobalACL(org.apache
* .james.mailbox.MailboxACL, boolean)
*/
@Override
public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
return resourceOwnerIsGroup ? resourceACL.union(groupGlobalACL) : resourceACL.union(userGlobalACL);
}
/**
* @see org.apache.james.mailbox.store.mail.MailboxACLResolver#hasRight(java.
* lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
* GroupMembershipResolver,
* org.apache.james.mailbox.MailboxACL.MailboxACLRight,
* org.apache.james.mailbox.MailboxACL, java.lang.String)
*/
@Override
public boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
boolean result = false;
Map<MailboxACLEntryKey, MailboxACLRights> entries = resourceOwnerIsGroup ? groupGlobalACL.getEntries() : userGlobalACL.getEntries();
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
if (key.isNegative()) {
return false;
} else {
result = true;
}
}
}
}
if (resourceACL != null) {
entries = resourceACL.getEntries();
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
if (key.isNegative()) {
return false;
} else {
result = true;
}
}
}
}
}
return result;
}
/**
* @see org.apache.james.mailbox.acl.MailboxACLResolver#isReadWrite(org.apache.james.mailbox.model.MailboxACL.MailboxACLRights,
* javax.mail.Flags)
*/
@Override
public boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException {
/* the two fast cases first */
if (mailboxACLRights.contains(Rfc4314Rights.i_Insert_RIGHT) || mailboxACLRights.contains(Rfc4314Rights.e_PerformExpunge_RIGHT)) {
return true;
}
/*
* then go through shared flags. RFC 4314 section 4:
*
* Changing flags: STORE
*
* - the server MUST check if the user has "t" right
*
* - when the user modifies \Deleted flag "s" right
*
* - when the user modifies \Seen flag "w" right - for all other message
* flags.
*/
else if (sharedFlags != null) {
if (sharedFlags.contains(Flag.DELETED) && mailboxACLRights.contains(Rfc4314Rights.t_DeleteMessages_RIGHT)) {
return true;
} else if (sharedFlags.contains(Flag.SEEN) && mailboxACLRights.contains(Rfc4314Rights.s_WriteSeenFlag_RIGHT)) {
return true;
} else {
boolean hasWriteRight = mailboxACLRights.contains(Rfc4314Rights.w_Write_RIGHT);
return hasWriteRight && (sharedFlags.contains(Flag.ANSWERED) || sharedFlags.contains(Flag.DRAFT) || sharedFlags.contains(Flag.FLAGGED) || sharedFlags.contains(Flag.RECENT) || sharedFlags.contains(Flag.USER));
}
}
return false;
}
/**
* The key point of this implementation is that it resolves everything what
* can be resolved. Let us explain what it means in particular for the
* implicit (global) rights included in the result:
*
* (1) if {@code queryKey} is a user key, the rights included come from the
* following ACL entries:
* <ul>
* <li>the entry literally matching the given user name</li>
* <li>the entries of the groups of which the given user is a member</li>
* <li>if the given user is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (2) if {@code queryKey} is a group key, the rights included come from the
* following ACL entries:
* <ul>
* <li>the entry literally matching the given group name</li>
* <li>if the given group is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry (*)</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (3) if {@code queryKey} is a special key, the rights included come from
* the following ACL entries:
* <ul>
* <li>the entry literally matching the given special name</li>
* <li>the "authenticated" entry if the {@code queryKey} is the "owner"
* query key (*)</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (*) This is the most questionable case: should "authenticated" ACL
* entries hold for group name queries? We say yes. Firstly, listing
* implicit rights for, say "group1", should inform which rights do not need
* to be set explicitly for the members of "group1". And secondly the group
* rights are actually queried and applied only for authenticated users. To
* put it in other words, the hasRight(user, right, ...) call can be
* performed only either with user == null (only "anybody" rights will
* apply) or with a user name which is there only after the user was
* authenticated.
*
* @see org.apache.james.mailbox.acl.MailboxACLResolver#listRightsDefault(boolean)
*/
@Override
public MailboxACLRights[] listRights(final MailboxACLEntryKey queryKey, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException {
MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
if (queryKey.isNegative()) {
return toListRightsArray(positiveNegativePair[NEGATIVE_INDEX]);
} else {
return toListRightsArray(positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]));
}
}
private static MailboxACLRights[] toListRightsArray(MailboxACLRights implicitRights) throws UnsupportedRightException {
List<MailboxACLRights> result = new ArrayList<MailboxACL.MailboxACLRights>(Rfc4314Rights.FIELD_COUNT);
result.add(implicitRights);
for (MailboxACLRight right : SimpleMailboxACL.FULL_RIGHTS) {
if (!implicitRights.contains(right)) {
result.add(new Rfc4314Rights(right));
}
}
return result.toArray(new MailboxACLRights[result.size()]);
}
/**
* @see org.apache.james.mailbox.store.mail.MailboxACLResolver#rightsOf(java.
* lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
* GroupMembershipResolver, org.apache.james.mailbox.MailboxACL,
* java.lang.String)
*/
@Override
public MailboxACL.MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
if (resourceACL != null) {
resolveRights(queryKey, groupMembershipResolver, resourceACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
}
return positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]);
}
/**
* What needs to be done for both global ACL and the given mailboxe's ACL.
*
* @param requestUser
* @param groupMembershipResolver
* @param entries
* @param resourceOwner
* @param resourceOwnerIsGroup
* @param positiveNegativePair
* @throws UnsupportedRightException
*/
private void resolveRights(MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, final Map<MailboxACLEntryKey, MailboxACLRights> entries, String resourceOwner, boolean resourceOwnerIsGroup, MailboxACL.MailboxACLRights[] positiveNegativePair)
throws UnsupportedRightException {
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup)) {
if (key.isNegative()) {
positiveNegativePair[NEGATIVE_INDEX] = positiveNegativePair[NEGATIVE_INDEX].union(entry.getValue());
} else {
positiveNegativePair[POSITIVE_INDEX] = positiveNegativePair[POSITIVE_INDEX].union(entry.getValue());
}
}
}
}
}
}

View File

@ -0,0 +1,35 @@
/****************************************************************
* 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.james.mailbox.acl;
/**
* An interface for querying group memberships.
*/
public interface GroupMembershipResolver {
/**
* Tests if the given user is a member of the given group.
*
* @param user
* @param group
* @return
*/
boolean isMember(String user, String group);
}

View File

@ -0,0 +1,178 @@
/*
* 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.james.mailbox.acl;
import javax.mail.Flags;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
/**
* Implements the interpretation of ACLs.
*
* From RFC4314: <cite>It is possible for multiple identifiers in an access
* control list to apply to a given user. For example, an ACL may include rights
* to be granted to the identifier matching the user, one or more
* implementation-defined identifiers matching groups that include the user,
* and/or the identifier "anyone". How these rights are combined to determine
* the users access is implementation defined. An implementation may choose, for
* example, to use the union of the rights granted to the applicable
* identifiers. An implementation may instead choose, for example, to use only
* those rights granted to the most specific identifier present in the ACL. A
* client can determine the set of rights granted to the logged-in user for a
* given mailbox name by using the MYRIGHTS command. </cite>
*
*/
public interface MailboxACLResolver {
/**
* Applies global ACL to the given <code>resourceACL</code>. From RFC 4314:
* An implementation [...] MAY force rights to always or never be granted to
* particular identifiers.
*
* @param resourceACL
* @param resourceOwnerIsGroup
* @return
* @throws UnsupportedRightException
*/
public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Tells whether the given user has the given right granted on the basis of
* the given resourceACL. Global ACL (if there is any) should be applied
* within this method.
*
* @param requestUser
* the user for whom the given right is tested, possibly
* <code>null</code> when there is no authenticated user in the
* given context.
* @param groupMembershipResolver
* this resolver is used when checking whether any group rights
* contained in resourceACL are applicable for the requestUser.
* @param right
* the right which will be proven to apply for the given
* requestUser.
* @param resourceACL
* the ACL defining the access right for the resource in
* question.
* @param resourceOwner
* this user name is used as a replacement for the "owner" place
* holder in the resourceACL.
* @param resourceOwnerIsGroup
* true if the resourceOwner is a group of users, false
* otherwise.
* @return true if the given user has the given right for the given
* resource; false otherwise.
* @throws UnsupportedRightException
*/
boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Maps the given {@code mailboxACLRights} to READ-WRITE and READ-ONLY
* response codes.
*
* From RFC 4314 section 5.2:
*
* The server SHOULD include a READ-WRITE response code in the tagged OK
* response if at least one of the "i", "e", or "shared flag rights"(***) is
* granted to the current user.
*
* The server MUST include a READ-ONLY response code in the tagged OK
* response to a SELECT command if none of the following rights is granted
* to the current user: "i", "e", and "shared flag rights"(***).
*
* @param mailboxACLRights
* the rights applicable to the user and resource in question.
* This method supposes that any global ACLs were already applied
* to the {@code mailboxACLRights} parameter before this method
* is called.
* @param sharedFlags
* From RFC 4314 section 5.2: If the ACL server implements some
* flags as shared for a mailbox (i.e., the ACL for the mailbox
* MAY be set up so that changes to those flags are visible to
* another user), lets call the set of rights associated with
* these flags (as described in Section 4) for that mailbox
* collectively as "shared flag rights". Note that the
* "shared flag rights" set MAY be different for different
* mailboxes.
*
* If the server doesnt support "shared multiuser write access"
* to a mailbox or doesnt implement shared flags on the mailbox,
* "shared flag rights" for the mailbox is defined to be the
* empty set.
*
* @return
* @throws UnsupportedRightException
*/
public abstract boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException;
/**
* Computes a result suitable for the LISTRIGHTS IMAP command. The result is
* computed regardless of mailbox. Therefore it should be viewed as a
* general default which may be further customised depending on the given
* mailbox.
*
* @param key
* the identifier from the LISTRIGHTS command
* @param groupMembershipResolver
* @param resourceOwner
* the owner of the mailbox named in the LISTRIGHTS command. User
* name or group name.
* @param resourceOwnerIsGroup
* true if the {@code resourceOwner} is a group of users, false
* otherwise.
* @return an array of {@link MailboxACLRights}. The first element is the
* set of implicit (global) rights which does not need to be set
* explicitly for the given identifier. Further elements are groups
* of rights which can be set for the given identifier and resource.
* @throws UnsupportedRightException
*/
public MailboxACLRights[] listRights(final MailboxACLEntryKey key, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException;
/**
* Computes the rights which apply to the given user and resource. Global
* ACL (if there is any) should be applied within this method.
*
* @param requestUser
* the user for whom the rights are computed, possibly
* <code>null</code> when there is no authenticated user in the
* given context.
* @param groupMembershipResolver
* this resolver is used when checking whether any group rights
* contained in resourceACL are applicable for the requestUser.
* @param resourceACL
* the ACL defining the access right for the resource in
* question.
* @param resourceOwner
* this user name is used as a replacement for the "owner" place
* holder in the resourceACL.
* @param resourceOwnerIsGroup
* true if the resourceOwner is a group of users, false
* otherwise.
* @return the rights applicable for the given user and resource.
* @throws UnsupportedRightException
*/
public abstract MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
}

View File

@ -0,0 +1,81 @@
/*
* 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.james.mailbox.acl;
import java.util.HashSet;
import java.util.Set;
/**
* In memory {@link GroupMembershipResolver} implementation. There is no
* persistence. You will get only what you add.
*
*/
public class SimpleGroupMembershipResolver implements GroupMembershipResolver {
private static class Membership {
private final String group;
private final int hash;
private final String user;
public Membership(String user, String group) {
super();
this.group = group;
this.user = user;
final int PRIME = 31;
this.hash = PRIME * this.group.hashCode() + this.user.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof Membership) {
Membership other = (Membership) o;
return this.group == other.group || (this.group != null && this.group.equals(other.group)) && this.user == other.user || (this.user != null && this.user.equals(other.user));
}
return false;
}
@Override
public int hashCode() {
return hash;
}
@Override
public String toString() {
return group + ": " + user;
}
}
private Set<Membership> memberships = new HashSet<SimpleGroupMembershipResolver.Membership>(32);
public void addMembership(String group, String user) {
memberships.add(new Membership(user, group));
}
@Override
public boolean isMember(String user, String group) {
return memberships.contains(new Membership(user, group));
}
}

View File

@ -0,0 +1,442 @@
/*
* 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.james.mailbox.acl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
import org.apache.james.mailbox.model.MailboxACL.NameType;
import org.apache.james.mailbox.model.SimpleMailboxACL;
import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
import com.sun.mail.mbox.Mailbox;
/**
* An implementation which works with the union of the rights granted to the
* applicable identifiers. Inspired by RFC 4314 Section 2.
*
* In
* {@link UnionMailboxACLResolver#resolveRights(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, MailboxACL, String, boolean)}
* all applicable negative and non-negative rights are union-ed separately and
* the result is computed afterwards with
* <code>nonNegativeUnion.except(negativeUnion)</code>.
*
* Allows for setting distinct global ACL for users' mailboxes on one hand and
* group (a.k.a shared) mailboxes on the other hand. E.g. the zero parameter
* constructor uses full rights for user mailboxes and
* full-except-administration rights for group mailboxes.
*
*/
public class UnionMailboxACLResolver implements MailboxACLResolver {
public static final MailboxACL DEFAULT_GLOBAL_GROUP_ACL = SimpleMailboxACL.OWNER_FULL_EXCEPT_ADMINISTRATION_ACL;
/**
* Nothing else than full rights for the owner.
*/
public static final MailboxACL DEFAULT_GLOBAL_USER_ACL = SimpleMailboxACL.OWNER_FULL_ACL;
private static final int POSITIVE_INDEX = 0;
private static final int NEGATIVE_INDEX = 1;
private final MailboxACL groupGlobalACL;
/**
* Stores global ACL which is merged with ACL of every mailbox when
* computing
* {@link #rightsOf(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, Mailbox)}
* and
* {@link #hasRight(String, Mailbox, MailboxACLRight, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver)}
* .
*/
private final MailboxACL userGlobalACL;
/**
* Creates a new instance of UnionMailboxACLResolver with
* {@link #DEFAULT_GLOBAL_USER_ACL} as {@link #userGlobalACL} and
* {@link #DEFAULT_GLOBAL_USER_ACL} as {@link #groupGlobalACL}.
*/
public UnionMailboxACLResolver() {
super();
this.userGlobalACL = DEFAULT_GLOBAL_USER_ACL;
this.groupGlobalACL = DEFAULT_GLOBAL_GROUP_ACL;
}
/**
* Creates a new instance of UnionMailboxACLResolver with the given
* globalACL.
*
* @param groupGlobalACL
*
* @param globalACL
* see {@link #userGlobalACL}, cannot be null.
* @throws NullPointerException
* when globalACL is null.
*/
public UnionMailboxACLResolver(MailboxACL userGlobalACL, MailboxACL groupGlobalACL) {
super();
if (userGlobalACL == null) {
throw new NullPointerException("Missing userGlobalACL.");
}
if (groupGlobalACL == null) {
throw new NullPointerException("Missing groupGlobalACL.");
}
this.userGlobalACL = userGlobalACL;
this.groupGlobalACL = groupGlobalACL;
}
/**
* Tells whether the given {@code aclKey} {@link MailboxACLEntryKey} is
* applicable for the given {@code queryKey}.
*
* There are two use cases for which this method was designed and tested:
*
* (1) Calls from
* {@link #hasRight(String, GroupMembershipResolver, MailboxACLRight, MailboxACL, String, boolean)}
* and
* {@link #resolveRights(String, GroupMembershipResolver, MailboxACL, String, boolean)}
* in which the {@code queryKey} is a {@link NameType#user}.
*
* (2) Calls from
* {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
* where {@code queryKey} can be anything including {@link NameType#user},
* {@link NameType#group} and all {@link NameType#special} identifiers.
*
* Clearly the set of cases which this method has to handle in (1) is a
* proper subset of the cases handled in (2). See the javadoc on
* {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
* for more details.
*
* @param aclKey
* @param queryKey
* @param groupMembershipResolver
* @param resourceOwner
* @param resourceOwnerIsGroup
* @return
*/
protected static boolean applies(MailboxACLEntryKey aclKey, MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, String resourceOwner, boolean resourceOwnerIsGroup) {
final String aclKeyName = aclKey.getName();
final NameType aclKeyNameType = aclKey.getNameType();
if (MailboxACL.SpecialName.anybody.name().equals(aclKeyName)) {
/* this works also for unauthenticated users */
return true;
} else if (queryKey != null) {
String queryUserOrGroupName = queryKey.getName();
switch (queryKey.getNameType()) {
case user:
/* Authenticated users */
switch (aclKeyNameType) {
case special:
if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/* non null query user is viewed as authenticated */
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
return (!resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner)) || (resourceOwnerIsGroup && groupMembershipResolver.isMember(queryUserOrGroupName, resourceOwner));
} else {
/* should not happen unless the parent if is changed */
throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
}
case user:
return aclKeyName.equals(queryUserOrGroupName);
case group:
return groupMembershipResolver.isMember(queryUserOrGroupName, aclKeyName);
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
case group:
/* query is a group */
switch (aclKeyNameType) {
case special:
if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/*
* see the javadoc comment on listRights()
*/
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
return resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner);
} else {
/* should not happen unless the parent if is changed */
throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
}
case user:
/* query groups cannot match ACL users */
return false;
case group:
return aclKeyName.equals(queryUserOrGroupName);
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
case special:
/* query is a special name */
switch (aclKeyNameType) {
case special:
if (aclKeyName.equals(queryUserOrGroupName)) {
/*
* authenticated matches authenticated and owner matches
* owner
*/
return true;
} else if (MailboxACL.SpecialName.owner.name().equals(queryUserOrGroupName) && MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
/*
* query owner matches authenticated because owner will
* be resolved only if the user is authenticated
*/
return true;
} else {
return false;
}
case user:
case group:
/* query specials cannot match ACL users or groups */
return false;
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
}
default:
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + queryKey.getNameType());
}
} else {
/* non-anybody ACL keys do not match non-authenticated queries */
return false;
}
}
/**
* @see org.apache.james.mailbox.MailboxACLResolver#applyGlobalACL(org.apache
* .james.mailbox.MailboxACL, boolean)
*/
@Override
public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
return resourceOwnerIsGroup ? resourceACL.union(groupGlobalACL) : resourceACL.union(userGlobalACL);
}
/**
* @see org.apache.james.mailbox.store.mail.MailboxACLResolver#hasRight(java.
* lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
* GroupMembershipResolver,
* org.apache.james.mailbox.MailboxACL.MailboxACLRight,
* org.apache.james.mailbox.MailboxACL, java.lang.String)
*/
@Override
public boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
boolean result = false;
Map<MailboxACLEntryKey, MailboxACLRights> entries = resourceOwnerIsGroup ? groupGlobalACL.getEntries() : userGlobalACL.getEntries();
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
if (key.isNegative()) {
return false;
} else {
result = true;
}
}
}
}
if (resourceACL != null) {
entries = resourceACL.getEntries();
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
if (key.isNegative()) {
return false;
} else {
result = true;
}
}
}
}
}
return result;
}
/**
* @see org.apache.james.mailbox.acl.MailboxACLResolver#isReadWrite(org.apache.james.mailbox.model.MailboxACL.MailboxACLRights,
* javax.mail.Flags)
*/
@Override
public boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException {
/* the two fast cases first */
if (mailboxACLRights.contains(Rfc4314Rights.i_Insert_RIGHT) || mailboxACLRights.contains(Rfc4314Rights.e_PerformExpunge_RIGHT)) {
return true;
}
/*
* then go through shared flags. RFC 4314 section 4:
*
* Changing flags: STORE
*
* - the server MUST check if the user has "t" right
*
* - when the user modifies \Deleted flag "s" right
*
* - when the user modifies \Seen flag "w" right - for all other message
* flags.
*/
else if (sharedFlags != null) {
if (sharedFlags.contains(Flag.DELETED) && mailboxACLRights.contains(Rfc4314Rights.t_DeleteMessages_RIGHT)) {
return true;
} else if (sharedFlags.contains(Flag.SEEN) && mailboxACLRights.contains(Rfc4314Rights.s_WriteSeenFlag_RIGHT)) {
return true;
} else {
boolean hasWriteRight = mailboxACLRights.contains(Rfc4314Rights.w_Write_RIGHT);
return hasWriteRight && (sharedFlags.contains(Flag.ANSWERED) || sharedFlags.contains(Flag.DRAFT) || sharedFlags.contains(Flag.FLAGGED) || sharedFlags.contains(Flag.RECENT) || sharedFlags.contains(Flag.USER));
}
}
return false;
}
/**
* The key point of this implementation is that it resolves everything what
* can be resolved. Let us explain what it means in particular for the
* implicit (global) rights included in the result:
*
* (1) if {@code queryKey} is a user key, the rights included come from the
* following ACL entries:
* <ul>
* <li>the entry literally matching the given user name</li>
* <li>the entries of the groups of which the given user is a member</li>
* <li>if the given user is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (2) if {@code queryKey} is a group key, the rights included come from the
* following ACL entries:
* <ul>
* <li>the entry literally matching the given group name</li>
* <li>if the given group is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry (*)</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (3) if {@code queryKey} is a special key, the rights included come from
* the following ACL entries:
* <ul>
* <li>the entry literally matching the given special name</li>
* <li>the "authenticated" entry if the {@code queryKey} is the "owner"
* query key (*)</li>
* <li>the "anybody" entry</li>
* </ul>
*
* (*) This is the most questionable case: should "authenticated" ACL
* entries hold for group name queries? We say yes. Firstly, listing
* implicit rights for, say "group1", should inform which rights do not need
* to be set explicitly for the members of "group1". And secondly the group
* rights are actually queried and applied only for authenticated users. To
* put it in other words, the hasRight(user, right, ...) call can be
* performed only either with user == null (only "anybody" rights will
* apply) or with a user name which is there only after the user was
* authenticated.
*
* @see org.apache.james.mailbox.acl.MailboxACLResolver#listRightsDefault(boolean)
*/
@Override
public MailboxACLRights[] listRights(final MailboxACLEntryKey queryKey, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException {
MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
if (queryKey.isNegative()) {
return toListRightsArray(positiveNegativePair[NEGATIVE_INDEX]);
} else {
return toListRightsArray(positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]));
}
}
private static MailboxACLRights[] toListRightsArray(MailboxACLRights implicitRights) throws UnsupportedRightException {
List<MailboxACLRights> result = new ArrayList<MailboxACL.MailboxACLRights>(Rfc4314Rights.FIELD_COUNT);
result.add(implicitRights);
for (MailboxACLRight right : SimpleMailboxACL.FULL_RIGHTS) {
if (!implicitRights.contains(right)) {
result.add(new Rfc4314Rights(right));
}
}
return result.toArray(new MailboxACLRights[result.size()]);
}
/**
* @see org.apache.james.mailbox.store.mail.MailboxACLResolver#rightsOf(java.
* lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
* GroupMembershipResolver, org.apache.james.mailbox.MailboxACL,
* java.lang.String)
*/
@Override
public MailboxACL.MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
if (resourceACL != null) {
resolveRights(queryKey, groupMembershipResolver, resourceACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
}
return positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]);
}
/**
* What needs to be done for both global ACL and the given mailboxe's ACL.
*
* @param requestUser
* @param groupMembershipResolver
* @param entries
* @param resourceOwner
* @param resourceOwnerIsGroup
* @param positiveNegativePair
* @throws UnsupportedRightException
*/
private void resolveRights(MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, final Map<MailboxACLEntryKey, MailboxACLRights> entries, String resourceOwner, boolean resourceOwnerIsGroup, MailboxACL.MailboxACLRights[] positiveNegativePair)
throws UnsupportedRightException {
if (entries != null) {
for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
final MailboxACLEntryKey key = entry.getKey();
if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup)) {
if (key.isNegative()) {
positiveNegativePair[NEGATIVE_INDEX] = positiveNegativePair[NEGATIVE_INDEX].union(entry.getValue());
} else {
positiveNegativePair[POSITIVE_INDEX] = positiveNegativePair[POSITIVE_INDEX].union(entry.getValue());
}
}
}
}
}
}

View File

@ -0,0 +1,89 @@
K 25
svn:wc:ra_dav:version-url
V 100
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception
END
MessageRangeException.java
K 25
svn:wc:ra_dav:version-url
V 127
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/MessageRangeException.java
END
MailboxSecurityException.java
K 25
svn:wc:ra_dav:version-url
V 130
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/MailboxSecurityException.java
END
BadCredentialsException.java
K 25
svn:wc:ra_dav:version-url
V 129
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/BadCredentialsException.java
END
SubscriptionException.java
K 25
svn:wc:ra_dav:version-url
V 127
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/SubscriptionException.java
END
OverQuotaException.java
K 25
svn:wc:ra_dav:version-url
V 124
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/OverQuotaException.java
END
UnsupportedRightException.java
K 25
svn:wc:ra_dav:version-url
V 131
/repos/asf/!svn/ver/1292019/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedRightException.java
END
InsufficientRightsException.java
K 25
svn:wc:ra_dav:version-url
V 133
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/InsufficientRightsException.java
END
MailboxNotFoundException.java
K 25
svn:wc:ra_dav:version-url
V 130
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/MailboxNotFoundException.java
END
UnsupportedOperationException.java
K 25
svn:wc:ra_dav:version-url
V 135
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedOperationException.java
END
MailboxException.java
K 25
svn:wc:ra_dav:version-url
V 122
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/MailboxException.java
END
MailboxExistsException.java
K 25
svn:wc:ra_dav:version-url
V 128
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/MailboxExistsException.java
END
UnsupportedCriteriaException.java
K 25
svn:wc:ra_dav:version-url
V 134
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedCriteriaException.java
END
ReadOnlyException.java
K 25
svn:wc:ra_dav:version-url
V 123
/repos/asf/!svn/ver/1242288/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/ReadOnlyException.java
END
UnsupportedSearchException.java
K 25
svn:wc:ra_dav:version-url
V 132
/repos/asf/!svn/ver/1452807/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedSearchException.java
END

View File

@ -0,0 +1,504 @@
10
dir
1519332
http://svn.apache.org/repos/asf/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception
http://svn.apache.org/repos/asf
2013-03-05T14:22:04.421500Z
1452807
ieugen
13f79535-47bb-0310-9956-ffa450edef68
MessageRangeException.java
file
2013-09-02T02:54:40.000000Z
f0c9ea5bb31bcb6db25f4dd419852c42
2012-02-09T12:13:02.344953Z
1242288
eric
1554
MailboxSecurityException.java
file
2013-09-02T02:54:40.000000Z
70321ac39e7e95afe3b11cc47780aa0e
2012-02-09T12:13:02.344953Z
1242288
eric
has-props
1355
BadCredentialsException.java
file
2013-09-02T02:54:40.000000Z
4b7e886773f91b38245101b6ec5c4ddf
2012-02-09T12:13:02.344953Z
1242288
eric
has-props
1521
SubscriptionException.java
file
2013-09-02T02:54:40.000000Z
517bf3db7a1cadd1a74f7e9930895ef0
2013-03-05T14:22:04.421500Z
1452807
ieugen
1584
OverQuotaException.java
file
2013-09-02T02:54:40.000000Z
2388eb21e2c5962805ecbad4a8d3f9d2
2012-02-09T12:13:02.344953Z
1242288
eric
1837
UnsupportedRightException.java
file
2013-09-02T02:54:40.000000Z
e885294bc958c67b8d081e0b0d6557ae
2012-02-21T21:05:02.067525Z
1292019
ppalaga
has-props
1711
InsufficientRightsException.java
file
2013-09-02T02:54:40.000000Z
117cb044bfaf25180cec1468545f62fd
2012-02-09T12:13:02.344953Z
1242288
eric
has-props
1438
MailboxNotFoundException.java
file
2013-09-02T02:54:40.000000Z
74d5a243fbf1f7d19f1bcaf74d9967d5
2013-03-05T14:22:04.421500Z
1452807
ieugen
2193
UnsupportedOperationException.java
file
2013-09-02T02:54:40.000000Z
e96da94593a7fe4c7cb8fe1eb1d5526c
2012-02-09T12:13:02.344953Z
1242288
eric
has-props
1553
MailboxException.java
file
2013-09-02T02:54:40.000000Z
2c12374bc0838c033084e4cd1bdf532b
2013-03-05T14:22:04.421500Z
1452807
ieugen
has-props
1686
MailboxExistsException.java
file
2013-09-02T02:54:40.000000Z
257c98299f6683e7c50d12e854fc95c4
2013-03-05T14:22:04.421500Z
1452807
ieugen
1937
UnsupportedCriteriaException.java
file
2013-09-02T02:54:40.000000Z
e73cb98d5eb377f3cf7d9d657900e6dd
2013-03-05T14:22:04.421500Z
1452807
ieugen
1510
ReadOnlyException.java
file
2013-09-02T02:54:40.000000Z
e3d78d70a8b997800af020a7501eb0fd
2012-02-09T12:13:02.344953Z
1242288
eric
1809
UnsupportedSearchException.java
file
2013-09-02T02:54:40.000000Z
4ccdb45a6d22e168e46f5ffe33ac82cd
2013-03-05T14:22:04.421500Z
1452807
ieugen
1532

View File

@ -0,0 +1,34 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that the credentials for this operation were not acceptable.
*/
public class BadCredentialsException extends MailboxException {
private static final long serialVersionUID = -8055692887730696513L;
public BadCredentialsException() {
super();
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.james.mailbox.exception;
/**
* Thrown when the rights granted to the given authenticated user do not suffice
* for the given action.
*
*/
public class InsufficientRightsException extends MailboxSecurityException {
/**
*
*/
private static final long serialVersionUID = 7310501567640913596L;
public InsufficientRightsException() {
super();
}
public InsufficientRightsException(String message) {
super(message);
}
public InsufficientRightsException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,41 @@
/****************************************************************
* 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.james.mailbox.exception;
/**
* Mailbox services should throw this exception in case of unsuccessfull
* operation.
*/
public class MailboxException extends Exception {
private static final long serialVersionUID = 4612761817238115904L;
public MailboxException() {
super();
}
public MailboxException(final String message) {
super(message);
}
public MailboxException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,50 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that the operation failed since the mailbox already exists.
*/
public class MailboxExistsException extends MailboxException {
private static final long serialVersionUID = -486951759505030166L;
private final String mailboxName;
public MailboxExistsException(String mailboxName) {
super("Mailbox with name=" + mailboxName + " already exists.");
this.mailboxName = mailboxName;
}
/**
* Gets the name of the mailbox which already exists.
*
* @return the mailboxName, not null
*/
public final String getMailboxName() {
return mailboxName;
}
public String toString() {
return getMessage();
}
}

View File

@ -0,0 +1,59 @@
/****************************************************************
* 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.james.mailbox.exception;
import org.apache.james.mailbox.model.MailboxPath;
/**
* Indicates that the failure is caused by a reference to a mailbox which does
* not exist.
*/
public class MailboxNotFoundException extends MailboxException {
private static final long serialVersionUID = -8493370806722264915L;
private final String mailboxName;
/**
* @param mailboxName
* name of the mailbox, not null
*/
public MailboxNotFoundException(String mailboxName) {
this.mailboxName = mailboxName;
}
/**
* @param mailboxPath
* name of the mailbox, not null
*/
public MailboxNotFoundException(MailboxPath mailboxPath) {
this.mailboxName = mailboxPath.toString();
}
/**
* Gets the name of the mailbox which cannot be found.
*
* @return name or null when only mailbox ID is known
*/
public final String getMailboxName() {
return mailboxName;
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.james.mailbox.exception;
/**
* Parent for security related exceptions.
*
*/
public class MailboxSecurityException extends MailboxException {
/**
*
*/
private static final long serialVersionUID = 4186633460326902649L;
public MailboxSecurityException() {
super();
}
public MailboxSecurityException(String message) {
super(message);
}
public MailboxSecurityException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,34 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Exception which should get thrown if an invalid message set was specified via
* an IMAP command
*/
public class MessageRangeException extends MailboxException {
private static final long serialVersionUID = 5016914557908202117L;
public MessageRangeException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,53 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* {@link MailboxException} which identicate that a user was over-quota
*
*
*/
public class OverQuotaException extends MailboxException{
/**
*
*/
private static final long serialVersionUID = 532673188582481689L;
private long used;
private long max;
public OverQuotaException(String msg, long max, long used) {
super(msg);
}
public OverQuotaException(long max, long used) {
this(null, max, used);
}
public long getUsed() {
return used;
}
public long getMax() {
return max;
}
}

View File

@ -0,0 +1,48 @@
/****************************************************************
* 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.james.mailbox.exception;
import org.apache.james.mailbox.model.MailboxPath;
/**
* {@link MailboxException} which should get thrown if someone tries to modify a READ-ONLY Mailbox
*
*
*/
public class ReadOnlyException extends MailboxException{
/**
*
*/
private static final long serialVersionUID = 5016914557908202113L;
public ReadOnlyException(MailboxPath path, char delimiter) {
super(path.getFullName(delimiter));
}
public ReadOnlyException(MailboxPath path, char delimiter, Exception e) {
super(path.getFullName(delimiter), e);
}
}

View File

@ -0,0 +1,37 @@
/****************************************************************
* 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.james.mailbox.exception;
/**
* Indicates exception during subscription processing.
*/
public class SubscriptionException extends MailboxException {
private static final long serialVersionUID = -4512372322774311468L;
public SubscriptionException() {
super();
}
public SubscriptionException(Exception cause) {
super(null, cause);
}
}

View File

@ -0,0 +1,34 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that a search criteria is not supported.
*/
public class UnsupportedCriteriaException extends MailboxException {
private static final long serialVersionUID = 3791907285083231285L;
public UnsupportedCriteriaException() {
super();
}
}

View File

@ -0,0 +1,34 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that an operation required is not supported by this mailbox.
*/
public class UnsupportedOperationException extends MailboxException {
private static final long serialVersionUID = 1943118588115772317L;
public UnsupportedOperationException(String message) {
super(message);
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.james.mailbox.exception;
import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
/**
* Thrown when the current system does not support the given right.
*
*/
public class UnsupportedRightException extends MailboxSecurityException {
private static final char INVALID_RIGHT = 0;
private static final long serialVersionUID = 2959248897018370078L;
private char unsupportedRight = INVALID_RIGHT;
public UnsupportedRightException() {
super();
}
public UnsupportedRightException(char right) {
super("Unsupported right flag '"+ right +"'.");
this.unsupportedRight = right;
}
public UnsupportedRightException(MailboxACLRight unsupportedRight) {
this(unsupportedRight.getValue());
}
public char getUnsupportedRight() {
return unsupportedRight;
}
}

View File

@ -0,0 +1,33 @@
/****************************************************************
* 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.james.mailbox.exception;
/**
* Indicates that the requested search is not supported by this implementation.
*/
public class UnsupportedSearchException extends MailboxException {
private static final long serialVersionUID = -7442949630563672557L;
public UnsupportedSearchException() {
super();
}
}

View File

@ -0,0 +1,34 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that the credentials for this operation were not acceptable.
*/
public class BadCredentialsException extends MailboxException {
private static final long serialVersionUID = -8055692887730696513L;
public BadCredentialsException() {
super();
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.james.mailbox.exception;
/**
* Thrown when the rights granted to the given authenticated user do not suffice
* for the given action.
*
*/
public class InsufficientRightsException extends MailboxSecurityException {
/**
*
*/
private static final long serialVersionUID = 7310501567640913596L;
public InsufficientRightsException() {
super();
}
public InsufficientRightsException(String message) {
super(message);
}
public InsufficientRightsException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,41 @@
/****************************************************************
* 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.james.mailbox.exception;
/**
* Mailbox services should throw this exception in case of unsuccessfull
* operation.
*/
public class MailboxException extends Exception {
private static final long serialVersionUID = 4612761817238115904L;
public MailboxException() {
super();
}
public MailboxException(final String message) {
super(message);
}
public MailboxException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,50 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mailbox.exception;
/**
* Indicates that the operation failed since the mailbox already exists.
*/
public class MailboxExistsException extends MailboxException {
private static final long serialVersionUID = -486951759505030166L;
private final String mailboxName;
public MailboxExistsException(String mailboxName) {
super("Mailbox with name=" + mailboxName + " already exists.");
this.mailboxName = mailboxName;
}
/**
* Gets the name of the mailbox which already exists.
*
* @return the mailboxName, not null
*/
public final String getMailboxName() {
return mailboxName;
}
public String toString() {
return getMessage();
}
}

View File

@ -0,0 +1,59 @@
/****************************************************************
* 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.james.mailbox.exception;
import org.apache.james.mailbox.model.MailboxPath;
/**
* Indicates that the failure is caused by a reference to a mailbox which does
* not exist.
*/
public class MailboxNotFoundException extends MailboxException {
private static final long serialVersionUID = -8493370806722264915L;
private final String mailboxName;
/**
* @param mailboxName
* name of the mailbox, not null
*/
public MailboxNotFoundException(String mailboxName) {
this.mailboxName = mailboxName;
}
/**
* @param mailboxPath
* name of the mailbox, not null
*/
public MailboxNotFoundException(MailboxPath mailboxPath) {
this.mailboxName = mailboxPath.toString();
}
/**
* Gets the name of the mailbox which cannot be found.
*
* @return name or null when only mailbox ID is known
*/
public final String getMailboxName() {
return mailboxName;
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.james.mailbox.exception;
/**
* Parent for security related exceptions.
*
*/
public class MailboxSecurityException extends MailboxException {
/**
*
*/
private static final long serialVersionUID = 4186633460326902649L;
public MailboxSecurityException() {
super();
}
public MailboxSecurityException(String message) {
super(message);
}
public MailboxSecurityException(String msg, Exception cause) {
super(msg, cause);
}
}

Some files were not shown because too many files have changed in this diff Show More