You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by "Robin Bankhead (JIRA)" <ji...@apache.org> on 2013/09/24 15:53:03 UTC
[jira] [Updated] (MAILBOX-199) Maildir support for Windows
[ https://issues.apache.org/jira/browse/MAILBOX-199?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Robin Bankhead updated MAILBOX-199:
-----------------------------------
Description:
Propose that Maildir be supported under the Windows platform. To my knowledge, the only technical bar to this is that maildir uses the colon (":") character, which is an illegal character on the NTFS (and I believe also FAT*) filesystem.
The Maildir standard document[1] that this project refers to, specifies a colon (although quite obliquely). The "standard" clearly was never aimed at use on Windows, but its benefits as a format strike me as sufficiently great that a small deviation is justifiable in order to include it with James and thus increase platform-portability.
The below patch alters message-naming so that, instead of a literal colon, the local system's path separator character (java.io.File.pathSeparator) is used in each case, giving a colon on *NIX and a semicolon (";") on Windows. (Critique of this particular methodology is welcome.)
It also includes a quick fix for an issue encountered with file locking on Windows, which calls System.gc() on that platform. There may be other issues like this; I'm searching for them currently.
[1] http://cr.yp.to/proto/maildir.html
was:
Propose that Maildir be supported under the Windows platform. To my knowledge, the only technical bar to this is that maildir uses the colon (":") character, which is an illegal character on the NTFS (and I believe also FAT*) filesystem.
The Maildir standard document[1] that this project refers to, specifies a colon (although quite obliquely). The "standard" clearly was never aimed at use on Windows, but its benefits as a format strike me as sufficiently great that a small deviation is justifiable in order to include it with James and thus increase platform-portability.
The below patch alters message-naming so that, instead of a literal colon, the local system's path separator character (java.io.File.pathSeparator) is used in each case, giving a colon on *NIX and a semicolon (";") on Windows. (Critique of this particular methodology is welcome.)
It also includes a quick fix for an issue encountered with file locking on Windows, which calls System.gc() so should be made OS-specific. There may be other issues like this; I'm searching for them currently.
[1] http://cr.yp.to/proto/maildir.html
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: /home/robin/backups/app-dev/Java/apache-james-mailbox-api/maildir
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
--- src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java Base (BASE)
+++ src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java Locally Modified (Based On LOCAL)
@@ -729,7 +729,7 @@
public static String stripMetaFromName(String fileName) {
int end = fileName.indexOf(",S="); // the size
if (end == -1)
- end = fileName.indexOf(":2,"); // the flags
+ end = fileName.indexOf(MaildirMessageName.FLAG_PREFIX + "2,"); // the flags
if (end == -1)
return fileName; // there is no meta data to strip
return fileName.substring(0, end);
Index: src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
--- src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java Base (BASE)
+++ src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java Locally Modified (Based On LOCAL)
@@ -41,20 +41,25 @@
public static final String FLAG_SEEN = "S";
public static final String FLAG_DELETED = "T";
+ // Character used instead of ":" for Windows filesystems.
+ // Using java.io.File.pathSeparator which = ":" on *NIX
+ // and ";" on Windows.
+ public static final String FLAG_PREFIX = File.pathSeparator;//";";
+
// patterns
public static final String PATTERN_STRING_MESSAGE_NAME = "\\d+\\.\\w+\\..+?";
- public static final String PATTERN_STRING_FLAGS = ":2,[DFRST]*";
+ public static final String PATTERN_STRING_FLAGS = FLAG_PREFIX + "2,[DFRST]*";
public static final String PATTERN_STRING_SIZE = ",S=\\d+";
public static final Pattern PATTERN_MESSAGE =
Pattern.compile(PATTERN_STRING_MESSAGE_NAME + optional(PATTERN_STRING_SIZE) + optional(PATTERN_STRING_FLAGS));
public static final Pattern PATTERN_UNSEEN_MESSAGES =
- Pattern.compile(PATTERN_STRING_MESSAGE_NAME + PATTERN_STRING_SIZE + optional(":2,[^S]*"));
+ Pattern.compile(PATTERN_STRING_MESSAGE_NAME + PATTERN_STRING_SIZE + optional(FLAG_PREFIX + "2,[^S]*"));
public static final FilenameFilter FILTER_UNSEEN_MESSAGES = createRegexFilter(PATTERN_UNSEEN_MESSAGES);
public static final Pattern PATTERN_DELETED_MESSAGES =
- Pattern.compile(PATTERN_STRING_MESSAGE_NAME + PATTERN_STRING_SIZE + ":2,.*" + FLAG_DELETED);
+ Pattern.compile(PATTERN_STRING_MESSAGE_NAME + PATTERN_STRING_SIZE + FLAG_PREFIX + "2,.*" + FLAG_DELETED);
public static final FilenameFilter FILTER_DELETED_MESSAGES = createRegexFilter(PATTERN_DELETED_MESSAGES);
@@ -250,7 +255,7 @@
* into its components hostname, size and flags and fills the respective variables.
*/
private void splitHostNameAndMeta() {
- String[] hostnamemetaFlags = hostnameAndMeta.split(":", 2);
+ String[] hostnamemetaFlags = hostnameAndMeta.split(FLAG_PREFIX, 2);
if (hostnamemetaFlags.length >= 1) {
this.hostnameAndMeta = hostnamemetaFlags[0];
int firstEnd = hostnameAndMeta.indexOf(',');
@@ -272,7 +277,7 @@
}
if (hostnamemetaFlags.length >= 2) {
- this.flagsString = ":" + hostnamemetaFlags[1];
+ this.flagsString = FLAG_PREFIX + hostnamemetaFlags[1];
}
if (isMessageNameStrictParse()) {
if (sizeString == null) {
@@ -364,7 +369,7 @@
* @return A String valid for Maildir
*/
public String encodeFlags(Flags flags) {
- StringBuilder localFlagsString = new StringBuilder(":2,");
+ StringBuilder localFlagsString = new StringBuilder(FLAG_PREFIX + "2,");
if (flags.contains(Flags.Flag.DRAFT))
localFlagsString.append(FLAG_DRAFT);
if (flags.contains(Flags.Flag.FLAGGED))
Index: src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
--- src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java Base (BASE)
+++ src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java Locally Modified (Based On LOCAL)
@@ -216,7 +216,18 @@
// if the flags don't have change we should not try to move
// the file
if (newMessageFile.equals(messageFile) == false) {
+ byte tries = 0;
+ while (true) {
+ try {
FileUtils.moveFile(messageFile, newMessageFile);
+ break;
+ } catch(IOException e) {
+ if(File.pathSeparator.equals(":") || ++tries >= 5) {
+ throw e;
+ }
+ System.gc();
+ }
+ }
modSeq = newMessageFile.lastModified();
} else {
Index: src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
--- src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java Base (BASE)
+++ src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java Locally Modified (Based On LOCAL)
@@ -48,34 +48,34 @@
public static List<Object[]> testData() {
List<Object[]> args = new ArrayList<Object[]>();
// no size, two flags
- Parts parts = Parts.fullName("1328026049.19146_0.km1111:2,RS").timeSeconds(1328026049)
+ Parts parts = Parts.fullName("1328026049.19146_0.km1111;2,RS").timeSeconds(1328026049)
.baseName("1328026049.19146_0.km1111").flagAnswered().flagSeen();
args.add(valid(parts));
// size and flag
- parts = Parts.fullName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111,S=13103:2,S")
+ parts = Parts.fullName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111,S=13103;2,S")
.timeSeconds(1328613172).size(13103L)
.baseName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111").flagSeen();
args.add(valid(parts));
// size, no flags
- parts = Parts.fullName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111,S=1344:2,")
+ parts = Parts.fullName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111,S=1344;2,")
.baseName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111").timeSeconds(1340124194)
.size(1344L);
args.add(valid(parts));
// three flags, no size
- parts = Parts.fullName("1106685752.12132_0.km1111:2,FRS").baseName("1106685752.12132_0.km1111")
+ parts = Parts.fullName("1106685752.12132_0.km1111;2,FRS").baseName("1106685752.12132_0.km1111")
.timeSeconds(1106685752).flagFlagged().flagAnswered().flagSeen();
args.add(valid(parts));
// with dovecot attributes
- parts = Parts.fullName("1035478339.27041_118.foo.org,S=1000,W=1030:2,S")
+ parts = Parts.fullName("1035478339.27041_118.foo.org,S=1000,W=1030;2,S")
.baseName("1035478339.27041_118.foo.org").timeSeconds(1035478339).size(1000L).flagSeen();
args.add(valid(parts));
parts = parts.copy();
- parts.fullName = "1035478339.27041_118.foo.org,W=1030,S=1000:2,S";
+ parts.fullName = "1035478339.27041_118.foo.org,W=1030,S=1000;2,S";
args.add(valid(parts));
// new mail, no info part at all. found in courier maildirs
@@ -84,15 +84,15 @@
args.add(valid(parts));
// new mail, generated by james
- parts = Parts.fullName("1356001301.e563087e30181513.foohost,S=629:2,")
+ parts = Parts.fullName("1356001301.e563087e30181513.foohost,S=629;2,")
.baseName("1356001301.e563087e30181513.foohost").timeSeconds(1356001301).size(629L);
args.add(valid(parts));
- parts = Parts.fullName("1355675588.5c7e107958851103.foohost,S=654:2,S").timeSeconds(1355675588)
+ parts = Parts.fullName("1355675588.5c7e107958851103.foohost,S=654;2,S").timeSeconds(1355675588)
.baseName("1355675588.5c7e107958851103.foohost").size(654L).flagSeen();
args.add(valid(parts));
- parts = Parts.fullName("1355675651.f3dd564265174501.foohost,S=661:2,")
+ parts = Parts.fullName("1355675651.f3dd564265174501.foohost,S=661;2,")
.baseName("1355675651.f3dd564265174501.foohost").timeSeconds(1355675651).size(661L);
args.add(valid(parts));
> Maildir support for Windows
> ---------------------------
>
> Key: MAILBOX-199
> URL: https://issues.apache.org/jira/browse/MAILBOX-199
> Project: James Mailbox
> Issue Type: New Feature
> Components: maildir
> Environment: Windows 7 Professional
> Reporter: Robin Bankhead
>
> Propose that Maildir be supported under the Windows platform. To my knowledge, the only technical bar to this is that maildir uses the colon (":") character, which is an illegal character on the NTFS (and I believe also FAT*) filesystem.
> The Maildir standard document[1] that this project refers to, specifies a colon (although quite obliquely). The "standard" clearly was never aimed at use on Windows, but its benefits as a format strike me as sufficiently great that a small deviation is justifiable in order to include it with James and thus increase platform-portability.
> The below patch alters message-naming so that, instead of a literal colon, the local system's path separator character (java.io.File.pathSeparator) is used in each case, giving a colon on *NIX and a semicolon (";") on Windows. (Critique of this particular methodology is welcome.)
> It also includes a quick fix for an issue encountered with file locking on Windows, which calls System.gc() on that platform. There may be other issues like this; I'm searching for them currently.
> [1] http://cr.yp.to/proto/maildir.html
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org