diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 8723c2d2a4a963aab5bb58d6a4c5935b52d94d03..d26789ddd0d5bcc53d7c53a58d7a8d151273c053 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -1,781 +1,781 @@
-
-
- * Represent a base 64 mapping. The 64 characters used in the encoding can be - * specified, since modified-UTF-7 uses other characters than UTF-7 (',' instead - * of '/'). - *
- *- * The exact type of the arguments and result values is adapted to the needs of - * the encoder and decoder, as opposed to following a strict interpretation of - * base 64. - *
- *- * Base 64, as specified in RFC 2045, is an encoding used to encode bytes as - * characters. In (modified-)UTF-7 however, it is used to encode characters as - * bytes, using some intermediate steps: - *
- *ch
, false otherwise
- */
- boolean contains(final char ch) {
- if (ch >= 128)
- return false;
- return inverseAlphabet[ch] >= 0;
- }
-
- /**
- * Encodes the six bit group as a character.
- *
- * @param sextet The six bit group to be encoded
- * @return The ASCII value of the character
- */
- byte getChar(final int sextet) {
- return (byte)alphabet[sextet];
- }
-}
+/* ====================================================================
+ * Copyright (c) 2006 J.T. Beetstra
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ====================================================================
+ */
+
+package com.beetstra.jutf7;
+
+import java.util.Arrays;
+
+/**
+ * + * Represent a base 64 mapping. The 64 characters used in the encoding can be + * specified, since modified-UTF-7 uses other characters than UTF-7 (',' instead + * of '/'). + *
+ *+ * The exact type of the arguments and result values is adapted to the needs of + * the encoder and decoder, as opposed to following a strict interpretation of + * base 64. + *
+ *+ * Base 64, as specified in RFC 2045, is an encoding used to encode bytes as + * characters. In (modified-)UTF-7 however, it is used to encode characters as + * bytes, using some intermediate steps: + *
+ *ch
, false otherwise
+ */
+ boolean contains(final char ch) {
+ if (ch >= 128)
+ return false;
+ return inverseAlphabet[ch] >= 0;
+ }
+
+ /**
+ * Encodes the six bit group as a character.
+ *
+ * @param sextet The six bit group to be encoded
+ * @return The ASCII value of the character
+ */
+ byte getChar(final int sextet) {
+ return (byte)alphabet[sextet];
+ }
+}
diff --git a/src/com/beetstra/jutf7/CharsetProvider.java b/src/com/beetstra/jutf7/CharsetProvider.java
index f0cabe56245d5f0075738d483ef8e5c2cbcb1f2f..5572736a32ebc0d49c6bf2f668993e1441917992 100644
--- a/src/com/beetstra/jutf7/CharsetProvider.java
+++ b/src/com/beetstra/jutf7/CharsetProvider.java
@@ -1,90 +1,90 @@
-/* ====================================================================
- * Copyright (c) 2006 J.T. Beetstra
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * ====================================================================
- */
-
-package com.beetstra.jutf7;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * - * Charset service-provider class used for both variants of the UTF-7 charset - * and the modified-UTF-7 charset. - *
- * - * @author Jaap Beetstra - */ -public class CharsetProvider extends java.nio.charset.spi.CharsetProvider { - private static final String UTF7_NAME = "UTF-7"; - private static final String UTF7_O_NAME = "X-UTF-7-OPTIONAL"; - private static final String UTF7_M_NAME = "X-MODIFIED-UTF-7"; - private static final String[] UTF7_ALIASES = new String[] { - "UNICODE-1-1-UTF-7", "CSUNICODE11UTF7", "X-RFC2152", "X-RFC-2152" - }; - private static final String[] UTF7_O_ALIASES = new String[] { - "X-RFC2152-OPTIONAL", "X-RFC-2152-OPTIONAL" - }; - private static final String[] UTF7_M_ALIASES = new String[] { - "X-IMAP-MODIFIED-UTF-7", "X-IMAP4-MODIFIED-UTF7", "X-IMAP4-MODIFIED-UTF-7", - "X-RFC3501", "X-RFC-3501" - }; - private Charset utf7charset = new UTF7Charset(UTF7_NAME, UTF7_ALIASES, false); - private Charset utf7oCharset = new UTF7Charset(UTF7_O_NAME, UTF7_O_ALIASES, true); - private Charset imap4charset = new ModifiedUTF7Charset(UTF7_M_NAME, UTF7_M_ALIASES); - private List charsets; - - public CharsetProvider() { - charsets = Arrays.asList(new Object[] { - utf7charset, imap4charset, utf7oCharset - }); - } - - /** - * {@inheritDoc} - */ - public Charset charsetForName(String charsetName) { - charsetName = charsetName.toUpperCase(); - for (Iterator iter = charsets.iterator(); iter.hasNext();) { - Charset charset = (Charset)iter.next(); - if (charset.name().equals(charsetName)) - return charset; - } - for (Iterator iter = charsets.iterator(); iter.hasNext();) { - Charset charset = (Charset)iter.next(); - if (charset.aliases().contains(charsetName)) - return charset; - } - return null; - } - - /** - * {@inheritDoc} - */ - public Iterator charsets() { - return charsets.iterator(); - } -} +/* ==================================================================== + * Copyright (c) 2006 J.T. Beetstra + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ==================================================================== + */ + +package com.beetstra.jutf7; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + *+ * Charset service-provider class used for both variants of the UTF-7 charset + * and the modified-UTF-7 charset. + *
+ * + * @author Jaap Beetstra + */ +public class CharsetProvider extends java.nio.charset.spi.CharsetProvider { + private static final String UTF7_NAME = "UTF-7"; + private static final String UTF7_O_NAME = "X-UTF-7-OPTIONAL"; + private static final String UTF7_M_NAME = "X-MODIFIED-UTF-7"; + private static final String[] UTF7_ALIASES = new String[] { + "UNICODE-1-1-UTF-7", "CSUNICODE11UTF7", "X-RFC2152", "X-RFC-2152" + }; + private static final String[] UTF7_O_ALIASES = new String[] { + "X-RFC2152-OPTIONAL", "X-RFC-2152-OPTIONAL" + }; + private static final String[] UTF7_M_ALIASES = new String[] { + "X-IMAP-MODIFIED-UTF-7", "X-IMAP4-MODIFIED-UTF7", "X-IMAP4-MODIFIED-UTF-7", + "X-RFC3501", "X-RFC-3501" + }; + private Charset utf7charset = new UTF7Charset(UTF7_NAME, UTF7_ALIASES, false); + private Charset utf7oCharset = new UTF7Charset(UTF7_O_NAME, UTF7_O_ALIASES, true); + private Charset imap4charset = new ModifiedUTF7Charset(UTF7_M_NAME, UTF7_M_ALIASES); + private List charsets; + + public CharsetProvider() { + charsets = Arrays.asList(new Object[] { + utf7charset, imap4charset, utf7oCharset + }); + } + + /** + * {@inheritDoc} + */ + public Charset charsetForName(String charsetName) { + charsetName = charsetName.toUpperCase(); + for (Iterator iter = charsets.iterator(); iter.hasNext();) { + Charset charset = (Charset)iter.next(); + if (charset.name().equals(charsetName)) + return charset; + } + for (Iterator iter = charsets.iterator(); iter.hasNext();) { + Charset charset = (Charset)iter.next(); + if (charset.aliases().contains(charsetName)) + return charset; + } + return null; + } + + /** + * {@inheritDoc} + */ + public Iterator charsets() { + return charsets.iterator(); + } +} diff --git a/src/com/beetstra/jutf7/ModifiedUTF7Charset.java b/src/com/beetstra/jutf7/ModifiedUTF7Charset.java index 603a19ee911949d8dc24230790fc61cd8277d8f8..26b0da44927388af2bde63085b573359b68065c7 100644 --- a/src/com/beetstra/jutf7/ModifiedUTF7Charset.java +++ b/src/com/beetstra/jutf7/ModifiedUTF7Charset.java @@ -1,57 +1,57 @@ -/* ==================================================================== - * Copyright (c) 2006 J.T. Beetstra - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ==================================================================== - */ - -package com.beetstra.jutf7; - -/** - *- * The character set specified in RFC 3501 to use for IMAP4rev1 mailbox name - * encoding. - *
- * - * @see RFC 3501< /a> - * @author Jaap Beetstra - */ -class ModifiedUTF7Charset extends UTF7StyleCharset { - private static final String MODIFIED_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - + "abcdefghijklmnopqrstuvwxyz" + "0123456789+,"; - - ModifiedUTF7Charset(String name, String[] aliases) { - super(name, aliases, MODIFIED_BASE64_ALPHABET, true); - } - - boolean canEncodeDirectly(char ch) { - if (ch == shift()) - return false; - return ch >= 0x20 && ch <= 0x7E; - } - - byte shift() { - return '&'; - } - - byte unshift() { - return '-'; - } -} +/* ==================================================================== + * Copyright (c) 2006 J.T. Beetstra + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ==================================================================== + */ + +package com.beetstra.jutf7; + +/** + *+ * The character set specified in RFC 3501 to use for IMAP4rev1 mailbox name + * encoding. + *
+ * + * @see RFC 3501< /a> + * @author Jaap Beetstra + */ +class ModifiedUTF7Charset extends UTF7StyleCharset { + private static final String MODIFIED_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + "0123456789+,"; + + ModifiedUTF7Charset(String name, String[] aliases) { + super(name, aliases, MODIFIED_BASE64_ALPHABET, true); + } + + boolean canEncodeDirectly(char ch) { + if (ch == shift()) + return false; + return ch >= 0x20 && ch <= 0x7E; + } + + byte shift() { + return '&'; + } + + byte unshift() { + return '-'; + } +} diff --git a/src/com/beetstra/jutf7/UTF7Charset.java b/src/com/beetstra/jutf7/UTF7Charset.java index 8c85472cf53d9376854fb7cde282ebb11ad7d177..04e256224f44400b85696aa002dd480e4bf94cb9 100644 --- a/src/com/beetstra/jutf7/UTF7Charset.java +++ b/src/com/beetstra/jutf7/UTF7Charset.java @@ -1,75 +1,75 @@ -/* ==================================================================== - * Copyright (c) 2006 J.T. Beetstra - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ==================================================================== - */ - -package com.beetstra.jutf7; - -/** - *- * The character set specified in RFC 2152. Two variants are supported using the - * encodeOptional constructor flag - *
- * - * @see RFC 2152< /a> - * @author Jaap Beetstra - */ -class UTF7Charset extends UTF7StyleCharset { - private static final String BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; - private static final String SET_D = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?"; - private static final String SET_O = "!\"#$%&*;<=>@[]^_`{|}"; - private static final String RULE_3 = " \t\r\n"; - final String directlyEncoded; - - UTF7Charset(String name, String[] aliases, boolean includeOptional) { - super(name, aliases, BASE64_ALPHABET, false); - if (includeOptional) - this.directlyEncoded = SET_D + SET_O + RULE_3; - else - this.directlyEncoded = SET_D + RULE_3; - } - - /* - * (non-Javadoc) - * @see com.beetstra.jutf7.UTF7StyleCharset#canEncodeDirectly(char) - */ - boolean canEncodeDirectly(char ch) { - return directlyEncoded.indexOf(ch) >= 0; - } - - /* - * (non-Javadoc) - * @see com.beetstra.jutf7.UTF7StyleCharset#shift() - */ - byte shift() { - return '+'; - } - - /* - * (non-Javadoc) - * @see com.beetstra.jutf7.UTF7StyleCharset#unshift() - */ - byte unshift() { - return '-'; - } -} +/* ==================================================================== + * Copyright (c) 2006 J.T. Beetstra + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ==================================================================== + */ + +package com.beetstra.jutf7; + +/** + *+ * The character set specified in RFC 2152. Two variants are supported using the + * encodeOptional constructor flag + *
+ * + * @see RFC 2152< /a> + * @author Jaap Beetstra + */ +class UTF7Charset extends UTF7StyleCharset { + private static final String BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + private static final String SET_D = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?"; + private static final String SET_O = "!\"#$%&*;<=>@[]^_`{|}"; + private static final String RULE_3 = " \t\r\n"; + final String directlyEncoded; + + UTF7Charset(String name, String[] aliases, boolean includeOptional) { + super(name, aliases, BASE64_ALPHABET, false); + if (includeOptional) + this.directlyEncoded = SET_D + SET_O + RULE_3; + else + this.directlyEncoded = SET_D + RULE_3; + } + + /* + * (non-Javadoc) + * @see com.beetstra.jutf7.UTF7StyleCharset#canEncodeDirectly(char) + */ + boolean canEncodeDirectly(char ch) { + return directlyEncoded.indexOf(ch) >= 0; + } + + /* + * (non-Javadoc) + * @see com.beetstra.jutf7.UTF7StyleCharset#shift() + */ + byte shift() { + return '+'; + } + + /* + * (non-Javadoc) + * @see com.beetstra.jutf7.UTF7StyleCharset#unshift() + */ + byte unshift() { + return '-'; + } +} diff --git a/src/com/beetstra/jutf7/UTF7StyleCharset.java b/src/com/beetstra/jutf7/UTF7StyleCharset.java index 0878af60317cb6b3daa9843f68dd918bfc3e30b4..53c9e0e10b5dd4061a6963328a8f7bdbb47c36e6 100644 --- a/src/com/beetstra/jutf7/UTF7StyleCharset.java +++ b/src/com/beetstra/jutf7/UTF7StyleCharset.java @@ -1,117 +1,117 @@ -/* ==================================================================== - * Copyright (c) 2006 J.T. Beetstra - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ==================================================================== - */ - -package com.beetstra.jutf7; - -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.util.Arrays; -import java.util.List; - -/** - *- * Abstract base class for UTF-7 style encoding and decoding. - *
- * - * @author Jaap Beetstra - */ -abstract class UTF7StyleCharset extends Charset { - private static final List CONTAINED = Arrays.asList(new String[] { - "US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE" - }); - final boolean strict; - Base64Util base64; - - /** - *- * Besides the name and aliases, two additional parameters are required. - * First the base 64 alphabet used; in modified UTF-7 a slightly different - * alphabet is used. Additionally, it should be specified if encoders and - * decoders should be strict about the interpretation of malformed encoded - * sequences. This is used since modified UTF-7 specifically disallows some - * constructs which are allowed (or not specifically disallowed) in UTF-7 - * (RFC 2152). - *
- * - * @param canonicalName The name as defined in java.nio.charset.Charset - * @param aliases The aliases as defined in java.nio.charset.Charset - * @param alphabet The base 64 alphabet used - * @param strict True if strict handling of sequences is requested - */ - protected UTF7StyleCharset(String canonicalName, String[] aliases, String alphabet, - boolean strict) { - super(canonicalName, aliases); - this.base64 = new Base64Util(alphabet); - this.strict = strict; - } - - /* - * (non-Javadoc) - * @see java.nio.charset.Charset#contains(java.nio.charset.Charset) - */ - public boolean contains(final Charset cs) { - return CONTAINED.contains(cs.name()); - } - - /* - * (non-Javadoc) - * @see java.nio.charset.Charset#newDecoder() - */ - public CharsetDecoder newDecoder() { - return new UTF7StyleCharsetDecoder(this, base64, strict); - } - - /* - * (non-Javadoc) - * @see java.nio.charset.Charset#newEncoder() - */ - public CharsetEncoder newEncoder() { - return new UTF7StyleCharsetEncoder(this, base64, strict); - } - - /** - * Tells if a character can be encoded using simple (US-ASCII) encoding or - * requires base 64 encoding. - * - * @param ch The character - * @return True if the character can be encoded directly, false otherwise - */ - abstract boolean canEncodeDirectly(char ch); - - /** - * Returns character used to switch to base 64 encoding. - * - * @return The shift character - */ - abstract byte shift(); - - /** - * Returns character used to switch from base 64 encoding to simple - * encoding. - * - * @return The unshift character - */ - abstract byte unshift(); -} +/* ==================================================================== + * Copyright (c) 2006 J.T. Beetstra + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ==================================================================== + */ + +package com.beetstra.jutf7; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.util.Arrays; +import java.util.List; + +/** + *+ * Abstract base class for UTF-7 style encoding and decoding. + *
+ * + * @author Jaap Beetstra + */ +abstract class UTF7StyleCharset extends Charset { + private static final List CONTAINED = Arrays.asList(new String[] { + "US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE" + }); + final boolean strict; + Base64Util base64; + + /** + *+ * Besides the name and aliases, two additional parameters are required. + * First the base 64 alphabet used; in modified UTF-7 a slightly different + * alphabet is used. Additionally, it should be specified if encoders and + * decoders should be strict about the interpretation of malformed encoded + * sequences. This is used since modified UTF-7 specifically disallows some + * constructs which are allowed (or not specifically disallowed) in UTF-7 + * (RFC 2152). + *
+ * + * @param canonicalName The name as defined in java.nio.charset.Charset + * @param aliases The aliases as defined in java.nio.charset.Charset + * @param alphabet The base 64 alphabet used + * @param strict True if strict handling of sequences is requested + */ + protected UTF7StyleCharset(String canonicalName, String[] aliases, String alphabet, + boolean strict) { + super(canonicalName, aliases); + this.base64 = new Base64Util(alphabet); + this.strict = strict; + } + + /* + * (non-Javadoc) + * @see java.nio.charset.Charset#contains(java.nio.charset.Charset) + */ + public boolean contains(final Charset cs) { + return CONTAINED.contains(cs.name()); + } + + /* + * (non-Javadoc) + * @see java.nio.charset.Charset#newDecoder() + */ + public CharsetDecoder newDecoder() { + return new UTF7StyleCharsetDecoder(this, base64, strict); + } + + /* + * (non-Javadoc) + * @see java.nio.charset.Charset#newEncoder() + */ + public CharsetEncoder newEncoder() { + return new UTF7StyleCharsetEncoder(this, base64, strict); + } + + /** + * Tells if a character can be encoded using simple (US-ASCII) encoding or + * requires base 64 encoding. + * + * @param ch The character + * @return True if the character can be encoded directly, false otherwise + */ + abstract boolean canEncodeDirectly(char ch); + + /** + * Returns character used to switch to base 64 encoding. + * + * @return The shift character + */ + abstract byte shift(); + + /** + * Returns character used to switch from base 64 encoding to simple + * encoding. + * + * @return The unshift character + */ + abstract byte unshift(); +} diff --git a/src/com/beetstra/jutf7/UTF7StyleCharsetDecoder.java b/src/com/beetstra/jutf7/UTF7StyleCharsetDecoder.java index 2fa9d343581bdf6e245573e49f966e9dc297ece8..ecaf7e52e54fff34d2bcbbaec3aa840a36725873 100644 --- a/src/com/beetstra/jutf7/UTF7StyleCharsetDecoder.java +++ b/src/com/beetstra/jutf7/UTF7StyleCharsetDecoder.java @@ -1,195 +1,195 @@ -/* ==================================================================== - * Copyright (c) 2006 J.T. Beetstra - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ==================================================================== - */ - -package com.beetstra.jutf7; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CoderResult; - -/** - *- * The CharsetDecoder used to decode both variants of the UTF-7 charset and the - * modified-UTF-7 charset. - *
- * - * @author Jaap Beetstra - */ -class UTF7StyleCharsetDecoder extends CharsetDecoder { - private final Base64Util base64; - private final byte shift; - private final byte unshift; - private final boolean strict; - private boolean base64mode; - private int bitsRead; - private int tempChar; - private boolean justShifted; - private boolean justUnshifted; - - UTF7StyleCharsetDecoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) { - super(cs, 0.6f, 1.0f); - this.base64 = base64; - this.strict = strict; - this.shift = cs.shift(); - this.unshift = cs.unshift(); - } - - /* - * (non-Javadoc) - * @see java.nio.charset.CharsetDecoder#decodeLoop(java.nio.ByteBuffer, - * java.nio.CharBuffer) - */ - protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { - while (in.hasRemaining()) { - byte b = in.get(); - if (base64mode) { - if (b == unshift) { - if (base64bitsWaiting()) - return malformed(in); - if (justShifted) { - if (!out.hasRemaining()) - return overflow(in); - out.put((char)shift); - } else - justUnshifted = true; - setUnshifted(); - } else { - if (!out.hasRemaining()) - return overflow(in); - CoderResult result = handleBase64(in, out, b); - if (result != null) - return result; - } - justShifted = false; - } else { - if (b == shift) { - base64mode = true; - if (justUnshifted && strict) - return malformed(in); - justShifted = true; - continue; - } - if (!out.hasRemaining()) - return overflow(in); - out.put((char)b); - justUnshifted = false; - } - } - return CoderResult.UNDERFLOW; - } - - private CoderResult overflow(ByteBuffer in) { - in.position(in.position() - 1); - return CoderResult.OVERFLOW; - } - - /** - *- * Decodes a byte in base 64 mode. Will directly write a character to - * the output buffer if completed. - *
- * - * @param in The input buffer - * @param out The output buffer - * @param lastRead Last byte read from the input buffer - * @return CoderResult.malformed if a non-base 64 character was encountered - * in strict mode, null otherwise - */ - private CoderResult handleBase64(ByteBuffer in, CharBuffer out, byte lastRead) { - CoderResult result = null; - int sextet = base64.getSextet(lastRead); - if (sextet >= 0) { - bitsRead += 6; - if (bitsRead < 16) { - tempChar += sextet << (16 - bitsRead); - } else { - bitsRead -= 16; - tempChar += sextet >> (bitsRead); - out.put((char)tempChar); - tempChar = (sextet << (16 - bitsRead)) & 0xFFFF; - } - } else { - if (strict) - return malformed(in); - out.put((char)lastRead); - if (base64bitsWaiting()) - result = malformed(in); - setUnshifted(); - } - return result; - } - - /* - * (non-Javadoc) - * @see java.nio.charset.CharsetDecoder#implFlush(java.nio.CharBuffer) - */ - protected CoderResult implFlush(CharBuffer out) { - if ((base64mode && strict) || base64bitsWaiting()) - return CoderResult.malformedForLength(1); - return CoderResult.UNDERFLOW; - } - - /* - * (non-Javadoc) - * @see java.nio.charset.CharsetDecoder#implReset() - */ - protected void implReset() { - setUnshifted(); - justUnshifted = false; - } - - /** - *- * Resets the input buffer position to just before the last byte read, and - * returns a result indicating to skip the last byte. - *
- * - * @param in The input buffer - * @return CoderResult.malformedForLength(1); - */ - private CoderResult malformed(ByteBuffer in) { - in.position(in.position() - 1); - return CoderResult.malformedForLength(1); - } - - /** - * @return True if there are base64 encoded characters waiting to be written - */ - private boolean base64bitsWaiting() { - return tempChar != 0 || bitsRead >= 6; - } - - /** - *- * Updates internal state to reflect the decoder is no longer in base 64 - * mode - *
- */ - private void setUnshifted() { - base64mode = false; - bitsRead = 0; - tempChar = 0; - } -} +/* ==================================================================== + * Copyright (c) 2006 J.T. Beetstra + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ==================================================================== + */ + +package com.beetstra.jutf7; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; + +/** + *+ * The CharsetDecoder used to decode both variants of the UTF-7 charset and the + * modified-UTF-7 charset. + *
+ * + * @author Jaap Beetstra + */ +class UTF7StyleCharsetDecoder extends CharsetDecoder { + private final Base64Util base64; + private final byte shift; + private final byte unshift; + private final boolean strict; + private boolean base64mode; + private int bitsRead; + private int tempChar; + private boolean justShifted; + private boolean justUnshifted; + + UTF7StyleCharsetDecoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) { + super(cs, 0.6f, 1.0f); + this.base64 = base64; + this.strict = strict; + this.shift = cs.shift(); + this.unshift = cs.unshift(); + } + + /* + * (non-Javadoc) + * @see java.nio.charset.CharsetDecoder#decodeLoop(java.nio.ByteBuffer, + * java.nio.CharBuffer) + */ + protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { + while (in.hasRemaining()) { + byte b = in.get(); + if (base64mode) { + if (b == unshift) { + if (base64bitsWaiting()) + return malformed(in); + if (justShifted) { + if (!out.hasRemaining()) + return overflow(in); + out.put((char)shift); + } else + justUnshifted = true; + setUnshifted(); + } else { + if (!out.hasRemaining()) + return overflow(in); + CoderResult result = handleBase64(in, out, b); + if (result != null) + return result; + } + justShifted = false; + } else { + if (b == shift) { + base64mode = true; + if (justUnshifted && strict) + return malformed(in); + justShifted = true; + continue; + } + if (!out.hasRemaining()) + return overflow(in); + out.put((char)b); + justUnshifted = false; + } + } + return CoderResult.UNDERFLOW; + } + + private CoderResult overflow(ByteBuffer in) { + in.position(in.position() - 1); + return CoderResult.OVERFLOW; + } + + /** + *+ * Decodes a byte in base 64 mode. Will directly write a character to + * the output buffer if completed. + *
+ * + * @param in The input buffer + * @param out The output buffer + * @param lastRead Last byte read from the input buffer + * @return CoderResult.malformed if a non-base 64 character was encountered + * in strict mode, null otherwise + */ + private CoderResult handleBase64(ByteBuffer in, CharBuffer out, byte lastRead) { + CoderResult result = null; + int sextet = base64.getSextet(lastRead); + if (sextet >= 0) { + bitsRead += 6; + if (bitsRead < 16) { + tempChar += sextet << (16 - bitsRead); + } else { + bitsRead -= 16; + tempChar += sextet >> (bitsRead); + out.put((char)tempChar); + tempChar = (sextet << (16 - bitsRead)) & 0xFFFF; + } + } else { + if (strict) + return malformed(in); + out.put((char)lastRead); + if (base64bitsWaiting()) + result = malformed(in); + setUnshifted(); + } + return result; + } + + /* + * (non-Javadoc) + * @see java.nio.charset.CharsetDecoder#implFlush(java.nio.CharBuffer) + */ + protected CoderResult implFlush(CharBuffer out) { + if ((base64mode && strict) || base64bitsWaiting()) + return CoderResult.malformedForLength(1); + return CoderResult.UNDERFLOW; + } + + /* + * (non-Javadoc) + * @see java.nio.charset.CharsetDecoder#implReset() + */ + protected void implReset() { + setUnshifted(); + justUnshifted = false; + } + + /** + *+ * Resets the input buffer position to just before the last byte read, and + * returns a result indicating to skip the last byte. + *
+ * + * @param in The input buffer + * @return CoderResult.malformedForLength(1); + */ + private CoderResult malformed(ByteBuffer in) { + in.position(in.position() - 1); + return CoderResult.malformedForLength(1); + } + + /** + * @return True if there are base64 encoded characters waiting to be written + */ + private boolean base64bitsWaiting() { + return tempChar != 0 || bitsRead >= 6; + } + + /** + *+ * Updates internal state to reflect the decoder is no longer in base 64 + * mode + *
+ */ + private void setUnshifted() { + base64mode = false; + bitsRead = 0; + tempChar = 0; + } +} diff --git a/src/com/beetstra/jutf7/UTF7StyleCharsetEncoder.java b/src/com/beetstra/jutf7/UTF7StyleCharsetEncoder.java index de8239713461233325e86feba95ca1866a289e0b..b59ef07b2d3a9eb7f68291fac9ba679f9f274ec3 100644 --- a/src/com/beetstra/jutf7/UTF7StyleCharsetEncoder.java +++ b/src/com/beetstra/jutf7/UTF7StyleCharsetEncoder.java @@ -1,217 +1,217 @@ -/* ==================================================================== - * Copyright (c) 2006 J.T. Beetstra - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ==================================================================== - */ - -package com.beetstra.jutf7; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; - -/** - *- * The CharsetEncoder used to encode both variants of the UTF-7 charset and the - * modified-UTF-7 charset. - *
- *- * Please note this class does not behave strictly according to the - * specification in Sun Java VMs before 1.6. This is done to get around - * a bug in the implementation of - * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)}. Unfortunately, - * that method cannot be overridden. - *
- * - * @see JDK - * bug 6221056< /a> - * @author Jaap Beetstra - */ -class UTF7StyleCharsetEncoder extends CharsetEncoder { - private static final float AVG_BYTES_PER_CHAR = 1.5f; - private static final float MAX_BYTES_PER_CHAR = 5.0f; - private final UTF7StyleCharset cs; - private final Base64Util base64; - private final byte shift; - private final byte unshift; - private final boolean strict; - private boolean base64mode; - private int bitsToOutput; - private int sextet; - static boolean useUglyHackToForceCallToFlushInJava5; - static { - String version = System.getProperty("java.specification.version"); - String vendor = System.getProperty("java.vm.vendor"); - useUglyHackToForceCallToFlushInJava5 = "1.4".equals(version) || "1.5".equals(version); - useUglyHackToForceCallToFlushInJava5 &= "Sun Microsystems Inc.".equals(vendor); - } - - UTF7StyleCharsetEncoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) { - super(cs, AVG_BYTES_PER_CHAR, MAX_BYTES_PER_CHAR); - this.cs = cs; - this.base64 = base64; - this.strict = strict; - this.shift = cs.shift(); - this.unshift = cs.unshift(); - } - - /* - * (non-Javadoc) - * @see java.nio.charset.CharsetEncoder#implReset() - */ - protected void implReset() { - base64mode = false; - sextet = 0; - bitsToOutput = 0; - } - - /** - * {@inheritDoc} - *
- * Note that this method might return CoderResult.OVERFLOW
(as
- * is required by the specification) if insufficient space is available in
- * the output buffer. However, calling it again on JDKs before Java 6
- * triggers a bug in
- * {@link java.nio.charset.CharsetEncoder#flush(ByteBuffer)} causing it to
- * throw an IllegalStateException (the buggy method is final
,
- * thus cannot be overridden).
- *
- * Note that this method might return CoderResult.OVERFLOW
,
- * even though there is sufficient space available in the output buffer.
- * This is done to force the broken implementation of
- * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)} to call flush
- * (the buggy method is final
, thus cannot be overridden).
- *
- * However, String.getBytes() fails if CoderResult.OVERFLOW is returned, - * since this assumes it always allocates sufficient bytes (maxBytesPerChar - * * nr_of_chars). Thus, as an extra check, the size of the input buffer is - * compared against the size of the output buffer. A static variable is used - * to indicate if a broken java version is used. - *
- *- * It is not possible to directly write the last few bytes, since more bytes - * might be waiting to be encoded then those available in the input buffer. - *
- * - * @see - * JDK bug 6221056< /a> - * @param in The input character buffer - * @param out The output byte buffer - * @return A coder-result object describing the reason for termination - */ - protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { - while (in.hasRemaining()) { - if (out.remaining() < 4) - return CoderResult.OVERFLOW; - char ch = in.get(); - if (cs.canEncodeDirectly(ch)) { - unshift(out, ch); - out.put((byte)ch); - } else if (!base64mode && ch == shift) { - out.put(shift); - out.put(unshift); - } else - encodeBase64(ch, out); - } - /* - *- * Writes the bytes necessary to leave base 64 mode. This might - * include an unshift character. - *
- * - * @param out - * @param ch - */ - private void unshift(ByteBuffer out, char ch) { - if (!base64mode) - return; - if (bitsToOutput != 0) - out.put(base64.getChar(sextet)); - if (base64.contains(ch) || ch == unshift || strict) - out.put(unshift); - base64mode = false; - sextet = 0; - bitsToOutput = 0; - } - - /** - *
- * Writes the bytes necessary to encode a character in base 64 mode.
- * All bytes which are fully determined will be written. The fields
- * bitsToOutput
and sextet
are used to remember
- * the bytes not yet fully determined.
- *
+ * The CharsetEncoder used to encode both variants of the UTF-7 charset and the + * modified-UTF-7 charset. + *
+ *+ * Please note this class does not behave strictly according to the + * specification in Sun Java VMs before 1.6. This is done to get around + * a bug in the implementation of + * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)}. Unfortunately, + * that method cannot be overridden. + *
+ * + * @see JDK + * bug 6221056< /a> + * @author Jaap Beetstra + */ +class UTF7StyleCharsetEncoder extends CharsetEncoder { + private static final float AVG_BYTES_PER_CHAR = 1.5f; + private static final float MAX_BYTES_PER_CHAR = 5.0f; + private final UTF7StyleCharset cs; + private final Base64Util base64; + private final byte shift; + private final byte unshift; + private final boolean strict; + private boolean base64mode; + private int bitsToOutput; + private int sextet; + static boolean useUglyHackToForceCallToFlushInJava5; + static { + String version = System.getProperty("java.specification.version"); + String vendor = System.getProperty("java.vm.vendor"); + useUglyHackToForceCallToFlushInJava5 = "1.4".equals(version) || "1.5".equals(version); + useUglyHackToForceCallToFlushInJava5 &= "Sun Microsystems Inc.".equals(vendor); + } + + UTF7StyleCharsetEncoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) { + super(cs, AVG_BYTES_PER_CHAR, MAX_BYTES_PER_CHAR); + this.cs = cs; + this.base64 = base64; + this.strict = strict; + this.shift = cs.shift(); + this.unshift = cs.unshift(); + } + + /* + * (non-Javadoc) + * @see java.nio.charset.CharsetEncoder#implReset() + */ + protected void implReset() { + base64mode = false; + sextet = 0; + bitsToOutput = 0; + } + + /** + * {@inheritDoc} + *
+ * Note that this method might return CoderResult.OVERFLOW
(as
+ * is required by the specification) if insufficient space is available in
+ * the output buffer. However, calling it again on JDKs before Java 6
+ * triggers a bug in
+ * {@link java.nio.charset.CharsetEncoder#flush(ByteBuffer)} causing it to
+ * throw an IllegalStateException (the buggy method is final
,
+ * thus cannot be overridden).
+ *
+ * Note that this method might return CoderResult.OVERFLOW
,
+ * even though there is sufficient space available in the output buffer.
+ * This is done to force the broken implementation of
+ * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)} to call flush
+ * (the buggy method is final
, thus cannot be overridden).
+ *
+ * However, String.getBytes() fails if CoderResult.OVERFLOW is returned, + * since this assumes it always allocates sufficient bytes (maxBytesPerChar + * * nr_of_chars). Thus, as an extra check, the size of the input buffer is + * compared against the size of the output buffer. A static variable is used + * to indicate if a broken java version is used. + *
+ *+ * It is not possible to directly write the last few bytes, since more bytes + * might be waiting to be encoded then those available in the input buffer. + *
+ * + * @see + * JDK bug 6221056< /a> + * @param in The input character buffer + * @param out The output byte buffer + * @return A coder-result object describing the reason for termination + */ + protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { + while (in.hasRemaining()) { + if (out.remaining() < 4) + return CoderResult.OVERFLOW; + char ch = in.get(); + if (cs.canEncodeDirectly(ch)) { + unshift(out, ch); + out.put((byte)ch); + } else if (!base64mode && ch == shift) { + out.put(shift); + out.put(unshift); + } else + encodeBase64(ch, out); + } + /* + *+ * Writes the bytes necessary to leave base 64 mode. This might + * include an unshift character. + *
+ * + * @param out + * @param ch + */ + private void unshift(ByteBuffer out, char ch) { + if (!base64mode) + return; + if (bitsToOutput != 0) + out.put(base64.getChar(sextet)); + if (base64.contains(ch) || ch == unshift || strict) + out.put(unshift); + base64mode = false; + sextet = 0; + bitsToOutput = 0; + } + + /** + *
+ * Writes the bytes necessary to encode a character in base 64 mode.
+ * All bytes which are fully determined will be written. The fields
+ * bitsToOutput
and sextet
are used to remember
+ * the bytes not yet fully determined.
+ *
FontSizes
object with default values.
- */
- public FontSizes()
- {
- accountName = MEDIUM;
- accountDescription = SMALL;
-
- folderName = LARGE;
- folderStatus = SMALL;
-
- messageListSubject = SMALL;
- messageListSender = SMALL;
- messageListDate = SMALL;
-
- messageViewSender = SMALL;
- messageViewTo = FONT_12DIP;
- messageViewCC = FONT_12DIP;
- messageViewAdditionalHeaders = FONT_12DIP;
- messageViewSubject = FONT_12DIP;
- messageViewTime = FONT_10DIP;
- messageViewDate = FONT_10DIP;
- }
-
- /**
- * Permanently save the font size settings.
- *
- * @param editor Used to save the font size settings.
- */
- public void save(SharedPreferences.Editor editor)
- {
- editor.putInt(ACCOUNT_NAME, accountName);
- editor.putInt(ACCOUNT_DESCRIPTION, accountDescription);
-
- editor.putInt(FOLDER_NAME, folderName);
- editor.putInt(FOLDER_STATUS, folderStatus);
-
- editor.putInt(MESSAGE_LIST_SUBJECT, messageListSubject);
- editor.putInt(MESSAGE_LIST_SENDER, messageListSender);
- editor.putInt(MESSAGE_LIST_DATE, messageListDate);
-
- editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject);
- editor.putInt(MESSAGE_VIEW_TO, messageViewTo);
- editor.putInt(MESSAGE_VIEW_CC, messageViewCC);
- editor.putInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
- editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender);
- editor.putInt(MESSAGE_VIEW_TIME, messageViewTime);
- editor.putInt(MESSAGE_VIEW_DATE, messageViewDate);
- editor.putInt(MESSAGE_VIEW_CONTENT, getMessageViewContentAsInt());
- }
-
- /**
- * Load the font size settings from permanent storage.
- *
- * @param prefs Used to load the font size settings.
- */
- public void load(SharedPreferences prefs)
- {
- accountName = prefs.getInt(ACCOUNT_NAME, accountName);
- accountDescription = prefs.getInt(ACCOUNT_DESCRIPTION, accountDescription);
-
- folderName = prefs.getInt(FOLDER_NAME, folderName);
- folderStatus = prefs.getInt(FOLDER_STATUS, folderStatus);
-
- messageListSubject = prefs.getInt(MESSAGE_LIST_SUBJECT, messageListSubject);
- messageListSender = prefs.getInt(MESSAGE_LIST_SENDER, messageListSender);
- messageListDate = prefs.getInt(MESSAGE_LIST_DATE, messageListDate);
-
- messageViewSubject = prefs.getInt(MESSAGE_VIEW_SENDER, FONT_12DIP);
- messageViewTo = prefs.getInt(MESSAGE_VIEW_TO, messageViewTo);
- messageViewCC = prefs.getInt(MESSAGE_VIEW_CC, messageViewCC);
- messageViewAdditionalHeaders = prefs.getInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
- messageViewSender = prefs.getInt(MESSAGE_VIEW_SUBJECT, messageViewSender);
- messageViewTime = prefs.getInt(MESSAGE_VIEW_TIME, messageViewTime);
- messageViewDate = prefs.getInt(MESSAGE_VIEW_DATE, messageViewDate);
- setMessageViewContent(prefs.getInt(MESSAGE_VIEW_CONTENT, 3));
- }
-
- public int getAccountName()
- {
- return accountName;
- }
-
- public void setAccountName(int accountName)
- {
- this.accountName = accountName;
- }
-
- public int getAccountDescription()
- {
- return accountDescription;
- }
-
- public void setAccountDescription(int accountDescription)
- {
- this.accountDescription = accountDescription;
- }
-
- public int getFolderName()
- {
- return folderName;
- }
-
- public void setFolderName(int folderName)
- {
- this.folderName = folderName;
- }
-
- public int getFolderStatus()
- {
- return folderStatus;
- }
-
- public void setFolderStatus(int folderStatus)
- {
- this.folderStatus = folderStatus;
- }
-
- public int getMessageListSubject()
- {
- return messageListSubject;
- }
-
- public void setMessageListSubject(int messageListSubject)
- {
- this.messageListSubject = messageListSubject;
- }
-
- public int getMessageListSender()
- {
- return messageListSender;
- }
-
- public void setMessageListSender(int messageListSender)
- {
- this.messageListSender = messageListSender;
- }
-
- public int getMessageListDate()
- {
- return messageListDate;
- }
-
- public void setMessageListDate(int messageListDate)
- {
- this.messageListDate = messageListDate;
- }
-
- public int getMessageViewSender()
- {
- return messageViewSender;
- }
-
- public void setMessageViewSender(int messageViewSender)
- {
- this.messageViewSender = messageViewSender;
- }
-
- public int getMessageViewTo()
- {
- return messageViewTo;
- }
-
- public void setMessageViewTo(int messageViewTo)
- {
- this.messageViewTo = messageViewTo;
- }
-
- public int getMessageViewCC()
- {
- return messageViewCC;
- }
-
- public void setMessageViewCC(int messageViewCC)
- {
- this.messageViewCC = messageViewCC;
- }
-
- public int getMessageViewAdditionalHeaders()
- {
- return messageViewAdditionalHeaders;
- }
-
- public void setMessageViewAdditionalHeaders(int messageViewAdditionalHeaders)
- {
- this.messageViewAdditionalHeaders = messageViewAdditionalHeaders;
- }
-
- public int getMessageViewSubject()
- {
- return messageViewSubject;
- }
-
- public void setMessageViewSubject(int messageViewSubject)
- {
- this.messageViewSubject = messageViewSubject;
- }
-
- public int getMessageViewTime()
- {
- return messageViewTime;
- }
-
- public void setMessageViewTime(int messageViewTime)
- {
- this.messageViewTime = messageViewTime;
- }
-
- public int getMessageViewDate()
- {
- return messageViewDate;
- }
-
- public void setMessageViewDate(int messageViewDate)
- {
- this.messageViewDate = messageViewDate;
- }
-
- public TextSize getMessageViewContent()
- {
- return messageViewContent;
- }
-
- public int getMessageViewContentAsInt()
- {
- switch (messageViewContent)
- {
- case SMALLEST:
- return 1;
- case SMALLER:
- return 2;
- default:
- case NORMAL:
- return 3;
- case LARGER:
- return 4;
- case LARGEST:
- return 5;
- }
- }
-
- public void setMessageViewContent(int size)
- {
- switch (size)
- {
- case 1:
- messageViewContent = TextSize.SMALLEST;
- break;
- case 2:
- messageViewContent = TextSize.SMALLER;
- break;
- case 3:
- messageViewContent = TextSize.NORMAL;
- break;
- case 4:
- messageViewContent = TextSize.LARGER;
- break;
- case 5:
- messageViewContent = TextSize.LARGEST;
- break;
- }
- }
-}
+package com.fsck.k9;
+
+import android.content.SharedPreferences;
+import android.webkit.WebSettings.TextSize;
+
+/**
+ * Manage font size of the information displayed in the account list, folder
+ * list, message list and in the message view.
+ */
+public class FontSizes
+{
+ /*
+ * Keys for the preference storage.
+ */
+ private static final String ACCOUNT_NAME = "fontSizeAccountName";
+ private static final String ACCOUNT_DESCRIPTION = "fontSizeAccountDescription";
+ private static final String FOLDER_NAME = "fontSizeFolderName";
+ private static final String FOLDER_STATUS = "fontSizeFolderStatus";
+ private static final String MESSAGE_LIST_SUBJECT = "fontSizeMessageListSubject";
+ private static final String MESSAGE_LIST_SENDER = "fontSizeMessageListSender";
+ private static final String MESSAGE_LIST_DATE = "fontSizeMessageListDate";
+ private static final String MESSAGE_VIEW_SENDER = "fontSizeMessageViewSender";
+ private static final String MESSAGE_VIEW_TO = "fontSizeMessageViewTo";
+ private static final String MESSAGE_VIEW_CC = "fontSizeMessageViewCC";
+ private static final String MESSAGE_VIEW_ADDITIONAL_HEADERS = "fontSizeMessageViewAdditionalHeaders";
+ private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject";
+ private static final String MESSAGE_VIEW_TIME = "fontSizeMessageViewTime";
+ private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate";
+ private static final String MESSAGE_VIEW_CONTENT = "fontSizeMessageViewContent";
+
+ /*
+ * Values for the font sizes in DIP (device independent pixel)
+ */
+ public static final int FONT_10DIP = 10;
+ public static final int FONT_12DIP = 12;
+ public static final int SMALL = 14; // ?android:attr/textAppearanceSmall
+ public static final int FONT_16DIP = 16;
+ public static final int MEDIUM = 18; // ?android:attr/textAppearanceMedium
+ public static final int FONT_20DIP = 20;
+ public static final int LARGE = 22; // ?android:attr/textAppearanceLarge
+
+
+ /**
+ * Font size of account names in the account list activity.
+ */
+ private int accountName;
+
+ /**
+ * Font size of account descriptions in the account list activity.
+ */
+ private int accountDescription;
+
+ /**
+ * Font size of folder names in the folder list activity.
+ */
+ private int folderName;
+
+ /**
+ * Font size of the folder status in the folder list activity.
+ */
+ private int folderStatus;
+
+ /**
+ * Font size of message subjects in the message list activity.
+ */
+ private int messageListSubject;
+
+ /**
+ * Font size of message senders in the message list activity.
+ */
+ private int messageListSender;
+
+ /**
+ * Font size of message dates in the message list activity.
+ */
+ private int messageListDate;
+
+ /**
+ * Font size of the message sender in the message view activity.
+ */
+ private int messageViewSender;
+
+ /**
+ * Font size of the message receiver(s) (To) in the message view activity.
+ */
+ private int messageViewTo;
+
+ /**
+ * Font size of the message receiver(s) (CC) in the message view activity.
+ */
+ private int messageViewCC;
+
+ /**
+ * Font size of additional headers in the message view activity.
+ */
+ private int messageViewAdditionalHeaders;
+
+ /**
+ * Font size of the message subject in the message view activity.
+ */
+ private int messageViewSubject;
+
+ /**
+ * Font size of the message time in the message view activity.
+ */
+ private int messageViewTime;
+
+ /**
+ * Font size of the message date in the message view activity.
+ */
+ private int messageViewDate;
+
+ /**
+ * Font size of the message content in the message view activity.
+ *
+ * Note: The unit is WebSettings.TextSize
+ */
+ private TextSize messageViewContent = TextSize.NORMAL;
+
+ /**
+ * Create a FontSizes
object with default values.
+ */
+ public FontSizes()
+ {
+ accountName = MEDIUM;
+ accountDescription = SMALL;
+
+ folderName = LARGE;
+ folderStatus = SMALL;
+
+ messageListSubject = SMALL;
+ messageListSender = SMALL;
+ messageListDate = SMALL;
+
+ messageViewSender = SMALL;
+ messageViewTo = FONT_12DIP;
+ messageViewCC = FONT_12DIP;
+ messageViewAdditionalHeaders = FONT_12DIP;
+ messageViewSubject = FONT_12DIP;
+ messageViewTime = FONT_10DIP;
+ messageViewDate = FONT_10DIP;
+ }
+
+ /**
+ * Permanently save the font size settings.
+ *
+ * @param editor Used to save the font size settings.
+ */
+ public void save(SharedPreferences.Editor editor)
+ {
+ editor.putInt(ACCOUNT_NAME, accountName);
+ editor.putInt(ACCOUNT_DESCRIPTION, accountDescription);
+
+ editor.putInt(FOLDER_NAME, folderName);
+ editor.putInt(FOLDER_STATUS, folderStatus);
+
+ editor.putInt(MESSAGE_LIST_SUBJECT, messageListSubject);
+ editor.putInt(MESSAGE_LIST_SENDER, messageListSender);
+ editor.putInt(MESSAGE_LIST_DATE, messageListDate);
+
+ editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject);
+ editor.putInt(MESSAGE_VIEW_TO, messageViewTo);
+ editor.putInt(MESSAGE_VIEW_CC, messageViewCC);
+ editor.putInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
+ editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender);
+ editor.putInt(MESSAGE_VIEW_TIME, messageViewTime);
+ editor.putInt(MESSAGE_VIEW_DATE, messageViewDate);
+ editor.putInt(MESSAGE_VIEW_CONTENT, getMessageViewContentAsInt());
+ }
+
+ /**
+ * Load the font size settings from permanent storage.
+ *
+ * @param prefs Used to load the font size settings.
+ */
+ public void load(SharedPreferences prefs)
+ {
+ accountName = prefs.getInt(ACCOUNT_NAME, accountName);
+ accountDescription = prefs.getInt(ACCOUNT_DESCRIPTION, accountDescription);
+
+ folderName = prefs.getInt(FOLDER_NAME, folderName);
+ folderStatus = prefs.getInt(FOLDER_STATUS, folderStatus);
+
+ messageListSubject = prefs.getInt(MESSAGE_LIST_SUBJECT, messageListSubject);
+ messageListSender = prefs.getInt(MESSAGE_LIST_SENDER, messageListSender);
+ messageListDate = prefs.getInt(MESSAGE_LIST_DATE, messageListDate);
+
+ messageViewSubject = prefs.getInt(MESSAGE_VIEW_SENDER, FONT_12DIP);
+ messageViewTo = prefs.getInt(MESSAGE_VIEW_TO, messageViewTo);
+ messageViewCC = prefs.getInt(MESSAGE_VIEW_CC, messageViewCC);
+ messageViewAdditionalHeaders = prefs.getInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
+ messageViewSender = prefs.getInt(MESSAGE_VIEW_SUBJECT, messageViewSender);
+ messageViewTime = prefs.getInt(MESSAGE_VIEW_TIME, messageViewTime);
+ messageViewDate = prefs.getInt(MESSAGE_VIEW_DATE, messageViewDate);
+ setMessageViewContent(prefs.getInt(MESSAGE_VIEW_CONTENT, 3));
+ }
+
+ public int getAccountName()
+ {
+ return accountName;
+ }
+
+ public void setAccountName(int accountName)
+ {
+ this.accountName = accountName;
+ }
+
+ public int getAccountDescription()
+ {
+ return accountDescription;
+ }
+
+ public void setAccountDescription(int accountDescription)
+ {
+ this.accountDescription = accountDescription;
+ }
+
+ public int getFolderName()
+ {
+ return folderName;
+ }
+
+ public void setFolderName(int folderName)
+ {
+ this.folderName = folderName;
+ }
+
+ public int getFolderStatus()
+ {
+ return folderStatus;
+ }
+
+ public void setFolderStatus(int folderStatus)
+ {
+ this.folderStatus = folderStatus;
+ }
+
+ public int getMessageListSubject()
+ {
+ return messageListSubject;
+ }
+
+ public void setMessageListSubject(int messageListSubject)
+ {
+ this.messageListSubject = messageListSubject;
+ }
+
+ public int getMessageListSender()
+ {
+ return messageListSender;
+ }
+
+ public void setMessageListSender(int messageListSender)
+ {
+ this.messageListSender = messageListSender;
+ }
+
+ public int getMessageListDate()
+ {
+ return messageListDate;
+ }
+
+ public void setMessageListDate(int messageListDate)
+ {
+ this.messageListDate = messageListDate;
+ }
+
+ public int getMessageViewSender()
+ {
+ return messageViewSender;
+ }
+
+ public void setMessageViewSender(int messageViewSender)
+ {
+ this.messageViewSender = messageViewSender;
+ }
+
+ public int getMessageViewTo()
+ {
+ return messageViewTo;
+ }
+
+ public void setMessageViewTo(int messageViewTo)
+ {
+ this.messageViewTo = messageViewTo;
+ }
+
+ public int getMessageViewCC()
+ {
+ return messageViewCC;
+ }
+
+ public void setMessageViewCC(int messageViewCC)
+ {
+ this.messageViewCC = messageViewCC;
+ }
+
+ public int getMessageViewAdditionalHeaders()
+ {
+ return messageViewAdditionalHeaders;
+ }
+
+ public void setMessageViewAdditionalHeaders(int messageViewAdditionalHeaders)
+ {
+ this.messageViewAdditionalHeaders = messageViewAdditionalHeaders;
+ }
+
+ public int getMessageViewSubject()
+ {
+ return messageViewSubject;
+ }
+
+ public void setMessageViewSubject(int messageViewSubject)
+ {
+ this.messageViewSubject = messageViewSubject;
+ }
+
+ public int getMessageViewTime()
+ {
+ return messageViewTime;
+ }
+
+ public void setMessageViewTime(int messageViewTime)
+ {
+ this.messageViewTime = messageViewTime;
+ }
+
+ public int getMessageViewDate()
+ {
+ return messageViewDate;
+ }
+
+ public void setMessageViewDate(int messageViewDate)
+ {
+ this.messageViewDate = messageViewDate;
+ }
+
+ public TextSize getMessageViewContent()
+ {
+ return messageViewContent;
+ }
+
+ public int getMessageViewContentAsInt()
+ {
+ switch (messageViewContent)
+ {
+ case SMALLEST:
+ return 1;
+ case SMALLER:
+ return 2;
+ default:
+ case NORMAL:
+ return 3;
+ case LARGER:
+ return 4;
+ case LARGEST:
+ return 5;
+ }
+ }
+
+ public void setMessageViewContent(int size)
+ {
+ switch (size)
+ {
+ case 1:
+ messageViewContent = TextSize.SMALLEST;
+ break;
+ case 2:
+ messageViewContent = TextSize.SMALLER;
+ break;
+ case 3:
+ messageViewContent = TextSize.NORMAL;
+ break;
+ case 4:
+ messageViewContent = TextSize.LARGER;
+ break;
+ case 5:
+ messageViewContent = TextSize.LARGEST;
+ break;
+ }
+ }
+}
diff --git a/src/com/fsck/k9/Identity.java b/src/com/fsck/k9/Identity.java
index 8386fa7b1291b9564b8f1d0ce4e1745082714b59..aa09625e3a9263aefd789895ef29919ec8b6da9e 100644
--- a/src/com/fsck/k9/Identity.java
+++ b/src/com/fsck/k9/Identity.java
@@ -1,79 +1,79 @@
-package com.fsck.k9;
-
-import java.io.Serializable;
-
-public class Identity implements Serializable
-{
- private String mDescription;
- private String mName;
- private String mEmail;
- private String mSignature;
- private boolean mSignatureUse;
- private String replyTo;
-
- public synchronized String getName()
- {
- return mName;
- }
-
- public synchronized void setName(String name)
- {
- mName = name;
- }
-
- public synchronized String getEmail()
- {
- return mEmail;
- }
-
- public synchronized void setEmail(String email)
- {
- mEmail = email;
- }
-
- public synchronized boolean getSignatureUse()
- {
- return mSignatureUse;
- }
-
- public synchronized void setSignatureUse(boolean signatureUse)
- {
- mSignatureUse = signatureUse;
- }
-
- public synchronized String getSignature()
- {
- return mSignature;
- }
-
- public synchronized void setSignature(String signature)
- {
- mSignature = signature;
- }
-
- public synchronized String getDescription()
- {
- return mDescription;
- }
-
- public synchronized void setDescription(String description)
- {
- mDescription = description;
- }
-
- public synchronized String getReplyTo()
- {
- return replyTo;
- }
-
- public synchronized void setReplyTo(String replyTo)
- {
- this.replyTo = replyTo;
- }
-
- @Override
- public synchronized String toString()
- {
- return "Account.Identity(description=" + mDescription + ", name=" + mName + ", email=" + mEmail + ", replyTo=" + replyTo + ", signature=" + mSignature;
- }
-}
+package com.fsck.k9;
+
+import java.io.Serializable;
+
+public class Identity implements Serializable
+{
+ private String mDescription;
+ private String mName;
+ private String mEmail;
+ private String mSignature;
+ private boolean mSignatureUse;
+ private String replyTo;
+
+ public synchronized String getName()
+ {
+ return mName;
+ }
+
+ public synchronized void setName(String name)
+ {
+ mName = name;
+ }
+
+ public synchronized String getEmail()
+ {
+ return mEmail;
+ }
+
+ public synchronized void setEmail(String email)
+ {
+ mEmail = email;
+ }
+
+ public synchronized boolean getSignatureUse()
+ {
+ return mSignatureUse;
+ }
+
+ public synchronized void setSignatureUse(boolean signatureUse)
+ {
+ mSignatureUse = signatureUse;
+ }
+
+ public synchronized String getSignature()
+ {
+ return mSignature;
+ }
+
+ public synchronized void setSignature(String signature)
+ {
+ mSignature = signature;
+ }
+
+ public synchronized String getDescription()
+ {
+ return mDescription;
+ }
+
+ public synchronized void setDescription(String description)
+ {
+ mDescription = description;
+ }
+
+ public synchronized String getReplyTo()
+ {
+ return replyTo;
+ }
+
+ public synchronized void setReplyTo(String replyTo)
+ {
+ this.replyTo = replyTo;
+ }
+
+ @Override
+ public synchronized String toString()
+ {
+ return "Account.Identity(description=" + mDescription + ", name=" + mName + ", email=" + mEmail + ", replyTo=" + replyTo + ", signature=" + mSignature;
+ }
+}
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 9274ac8401ababfb7e6bb34a667c993891a600ad..d81e80b2578fb5c4e3162a432c58d614fc5bd9ae 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -1,2278 +1,2278 @@
-package com.fsck.k9.activity;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.Spannable;
-import android.text.style.TextAppearanceSpan;
-import android.util.Config;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.ImageButton;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.fsck.k9.Account;
-import com.fsck.k9.AccountStats;
-import com.fsck.k9.FontSizes;
-import com.fsck.k9.K9;
-import com.fsck.k9.Preferences;
-import com.fsck.k9.R;
-import com.fsck.k9.SearchSpecification;
-import com.fsck.k9.activity.setup.AccountSettings;
-import com.fsck.k9.activity.setup.FolderSettings;
-import com.fsck.k9.activity.setup.Prefs;
-import com.fsck.k9.controller.MessagingController;
-import com.fsck.k9.controller.MessagingController.SORT_TYPE;
-import com.fsck.k9.controller.MessagingListener;
-import com.fsck.k9.helper.Utility;
-import com.fsck.k9.mail.Address;
-import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.Folder;
-import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.Message.RecipientType;
-import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.LocalStore;
-import com.fsck.k9.mail.store.LocalStore.LocalFolder;
-import com.fsck.k9.mail.store.LocalStore.LocalMessage;
-
-
-/**
- * MessageList is the primary user interface for the program. This Activity
- * shows a list of messages.
- * From this Activity the user can perform all standard message operations.
- */
-public class MessageList
- extends K9Activity
- implements OnClickListener, AdapterView.OnItemClickListener
-{
- private static final int DIALOG_MARK_ALL_AS_READ = 1;
-
- private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
- private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
- private static final int ACTIVITY_CHOOSE_FOLDER_MOVE_BATCH = 3;
- private static final int ACTIVITY_CHOOSE_FOLDER_COPY_BATCH = 4;
-
- private static final String EXTRA_ACCOUNT = "account";
- private static final String EXTRA_FOLDER = "folder";
- private static final String EXTRA_QUERY = "query";
- private static final String EXTRA_QUERY_FLAGS = "queryFlags";
- private static final String EXTRA_FORBIDDEN_FLAGS = "forbiddenFlags";
- private static final String EXTRA_INTEGRATE = "integrate";
- private static final String EXTRA_ACCOUNT_UUIDS = "accountUuids";
- private static final String EXTRA_FOLDER_NAMES = "folderNames";
- private static final String EXTRA_TITLE = "title";
- private static final String EXTRA_LIST_POSITION = "listPosition";
-
- private ListView mListView;
-
- private boolean mTouchView = true;
-
- private MessageListAdapter mAdapter;
-
- private FolderInfoHolder mCurrentFolder;
-
- private LayoutInflater mInflater;
-
- private MessagingController mController;
-
- private Account mAccount;
- private int mUnreadMessageCount = 0;
-
- private GestureDetector gestureDetector;
- private View.OnTouchListener gestureListener;
- /**
- * Stores the name of the folder that we want to open as soon as possible
- * after load.
- */
- private String mFolderName;
-
- /**
- * If we're doing a search, this contains the query string.
- */
- private String mQueryString;
- private Flag[] mQueryFlags = null;
- private Flag[] mForbiddenFlags = null;
- private boolean mIntegrate = false;
- private String[] mAccountUuids = null;
- private String[] mFolderNames = null;
- private String mTitle;
-
- private MessageListHandler mHandler = new MessageListHandler();
-
- private SORT_TYPE sortType = SORT_TYPE.SORT_DATE;
-
- private boolean sortAscending = true;
- private boolean sortDateAscending = false;
-
- private boolean mStars = true;
- private boolean mCheckboxes = true;
- private int mSelectedCount = 0;
-
- private View mBatchButtonArea;
- private ImageButton mBatchReadButton;
- private ImageButton mBatchDeleteButton;
- private ImageButton mBatchFlagButton;
- private ImageButton mBatchDoneButton;
-
- private FontSizes mFontSizes = K9.getFontSizes();
-
- private Bundle mState = null;
-
- class MessageListHandler extends Handler
- {
- public void removeMessage(final List- * A FetchProfile is a list of items that should be downloaded in bulk for a set of messages. - * FetchProfile can contain the following objects: - * FetchProfile.Item: Described below. - * Message: Indicates that the body of the entire message should be fetched. - * Synonymous with FetchProfile.Item.BODY. - * Part: Indicates that the given Part should be fetched. The provider - * is expected have previously created the given BodyPart and stored - * any information it needs to download the content. - *- */ -public class FetchProfile extends ArrayList
+ * A FetchProfile is a list of items that should be downloaded in bulk for a set of messages. + * FetchProfile can contain the following objects: + * FetchProfile.Item: Described below. + * Message: Indicates that the body of the entire message should be fetched. + * Synonymous with FetchProfile.Item.BODY. + * Part: Indicates that the given Part should be fetched. The provider + * is expected have previously created the given BodyPart and stored + * any information it needs to download the content. + *+ */ +public class FetchProfile extends ArrayList
InputStream
, Reader
,
- * String
and byte[]
) and destinations
- * (OutputStream
, Writer
, String
and
- * byte[]
).
- *
- * Unless otherwise noted, these copy
methods do not
- * flush or close the streams. Often doing so would require making non-portable
- * assumptions about the streams' origin and further use. This means that both
- * streams' close()
methods must be called after copying. if one
- * omits this step, then the stream resources (sockets, file descriptors) are
- * released when the associated Stream is garbage-collected. It is not a good
- * idea to rely on this mechanism. For a good overview of the distinction
- * between "memory management" and "resource management", see
- * this
- * UnixReview article.
- *
- * For byte-to-char methods, a copy
variant allows the encoding
- * to be selected (otherwise the platform default is used). We would like to
- * encourage you to always specify the encoding because relying on the platform
- * default can lead to unexpected results.
- *
copy methods that - * let you specify the buffer size because in modern VMs the impact on speed - * seems to be minimal. We're using a default buffer size of 4 KB. - *
- * The copy
methods use an internal buffer when copying. It is
- * therefore advisable not to deliberately wrap the stream arguments
- * to the copy
methods in Buffered*
streams. For
- * example, don't do the following:
- *
- * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); - *- * The rationale is as follows: - *
- * Imagine that an InputStream's read() is a very expensive operation, which
- * would usually suggest wrapping in a BufferedInputStream. The
- * BufferedInputStream works by issuing infrequent
- * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the
- * underlying InputStream, to fill an internal buffer, from which further
- * read
requests can inexpensively get their data (until the buffer
- * runs out).
- *
- * However, the copy
methods do the same thing, keeping an
- * internal buffer, populated by
- * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two
- * buffers (or three if the destination stream is also buffered) is pointless,
- * and the unnecessary buffer management hurts performance slightly (about 3%,
- * according to some simple experiments).
- *
- * Behold, intrepid explorers; a map of this class: - *
- * Method Input Output Dependency - * ------ ----- ------ ------- - * 1 copy InputStream OutputStream (primitive) - * 2 copy Reader Writer (primitive) - * - * 3 copy InputStream Writer 2 - * - * 4 copy Reader OutputStream 2 - * - * 5 copy String OutputStream 2 - * 6 copy String Writer (trivial) - * - * 7 copy byte[] Writer 3 - * 8 copy byte[] OutputStream (trivial) - *- *
- * Note that only the first two methods shuffle bytes; the rest use these - * two, or (if possible) copy using native Java copy methods. As there are - * method variants to specify the encoding, each row may - * correspond to up to 2 methods. - *
- * Origin of code: Excalibur.
- *
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @version $Id: CopyUtils.java 437680 2006-08-28 11:57:00Z scolebourne $
- * @deprecated Use IOUtils. Will be removed in 2.0.
- * Methods renamed to IOUtils.write() or IOUtils.copy().
- * Null handling behaviour changed in IOUtils (null data does not
- * throw NullPointerException).
- */
-public class CopyUtils {
-
- /**
- * The default size of the buffer.
- */
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public CopyUtils() { }
-
- // ----------------------------------------------------------------
- // byte[] -> OutputStream
- // ----------------------------------------------------------------
-
- /**
- * Copy bytes from a byte[]
to an OutputStream
.
- * @param input the byte array to read from
- * @param output the OutputStream
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(byte[] input, OutputStream output)
- throws IOException {
- output.write(input);
- }
-
- // ----------------------------------------------------------------
- // byte[] -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copy and convert bytes from a byte[]
to chars on a
- * Writer
.
- * The platform's default encoding is used for the byte-to-char conversion.
- * @param input the byte array to read from
- * @param output the Writer
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(byte[] input, Writer output)
- throws IOException {
- ByteArrayInputStream in = new ByteArrayInputStream(input);
- copy(in, output);
- }
-
-
- /**
- * Copy and convert bytes from a byte[]
to chars on a
- * Writer
, using the specified encoding.
- * @param input the byte array to read from
- * @param output the Writer
to write to
- * @param encoding The name of a supported character encoding. See the
- * IANA
- * Charset Registry for a list of valid encoding types.
- * @throws IOException In case of an I/O problem
- */
- public static void copy(
- byte[] input,
- Writer output,
- String encoding)
- throws IOException {
- ByteArrayInputStream in = new ByteArrayInputStream(input);
- copy(in, output, encoding);
- }
-
-
- // ----------------------------------------------------------------
- // Core copy methods
- // ----------------------------------------------------------------
-
- /**
- * Copy bytes from an InputStream
to an
- * OutputStream
.
- * @param input the InputStream
to read from
- * @param output the OutputStream
to write to
- * @return the number of bytes copied
- * @throws IOException In case of an I/O problem
- */
- public static int copy(
- InputStream input,
- OutputStream output)
- throws IOException {
- byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- int count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- // ----------------------------------------------------------------
- // Reader -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copy chars from a Reader
to a Writer
.
- * @param input the Reader
to read from
- * @param output the Writer
to write to
- * @return the number of characters copied
- * @throws IOException In case of an I/O problem
- */
- public static int copy(
- Reader input,
- Writer output)
- throws IOException {
- char[] buffer = new char[DEFAULT_BUFFER_SIZE];
- int count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- // ----------------------------------------------------------------
- // InputStream -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copy and convert bytes from an InputStream
to chars on a
- * Writer
.
- * The platform's default encoding is used for the byte-to-char conversion.
- * @param input the InputStream
to read from
- * @param output the Writer
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(
- InputStream input,
- Writer output)
- throws IOException {
- InputStreamReader in = new InputStreamReader(input);
- copy(in, output);
- }
-
- /**
- * Copy and convert bytes from an InputStream
to chars on a
- * Writer
, using the specified encoding.
- * @param input the InputStream
to read from
- * @param output the Writer
to write to
- * @param encoding The name of a supported character encoding. See the
- * IANA
- * Charset Registry for a list of valid encoding types.
- * @throws IOException In case of an I/O problem
- */
- public static void copy(
- InputStream input,
- Writer output,
- String encoding)
- throws IOException {
- InputStreamReader in = new InputStreamReader(input, encoding);
- copy(in, output);
- }
-
-
- // ----------------------------------------------------------------
- // Reader -> OutputStream
- // ----------------------------------------------------------------
-
- /**
- * Serialize chars from a Reader
to bytes on an
- * OutputStream
, and flush the OutputStream
.
- * @param input the Reader
to read from
- * @param output the OutputStream
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(
- Reader input,
- OutputStream output)
- throws IOException {
- OutputStreamWriter out = new OutputStreamWriter(output);
- copy(input, out);
- // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
- // have to flush here.
- out.flush();
- }
-
- // ----------------------------------------------------------------
- // String -> OutputStream
- // ----------------------------------------------------------------
-
- /**
- * Serialize chars from a String
to bytes on an
- * OutputStream
, and
- * flush the OutputStream
.
- * @param input the String
to read from
- * @param output the OutputStream
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(
- String input,
- OutputStream output)
- throws IOException {
- StringReader in = new StringReader(input);
- OutputStreamWriter out = new OutputStreamWriter(output);
- copy(in, out);
- // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
- // have to flush here.
- out.flush();
- }
-
- // ----------------------------------------------------------------
- // String -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copy chars from a String
to a Writer
.
- * @param input the String
to read from
- * @param output the Writer
to write to
- * @throws IOException In case of an I/O problem
- */
- public static void copy(String input, Writer output)
- throws IOException {
- output.write(input);
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+
+/**
+ * This class provides static utility methods for buffered
+ * copying between sources (InputStream
, Reader
,
+ * String
and byte[]
) and destinations
+ * (OutputStream
, Writer
, String
and
+ * byte[]
).
+ *
+ * Unless otherwise noted, these copy
methods do not
+ * flush or close the streams. Often doing so would require making non-portable
+ * assumptions about the streams' origin and further use. This means that both
+ * streams' close()
methods must be called after copying. if one
+ * omits this step, then the stream resources (sockets, file descriptors) are
+ * released when the associated Stream is garbage-collected. It is not a good
+ * idea to rely on this mechanism. For a good overview of the distinction
+ * between "memory management" and "resource management", see
+ * this
+ * UnixReview article.
+ *
+ * For byte-to-char methods, a copy
variant allows the encoding
+ * to be selected (otherwise the platform default is used). We would like to
+ * encourage you to always specify the encoding because relying on the platform
+ * default can lead to unexpected results.
+ *
copy methods that + * let you specify the buffer size because in modern VMs the impact on speed + * seems to be minimal. We're using a default buffer size of 4 KB. + *
+ * The copy
methods use an internal buffer when copying. It is
+ * therefore advisable not to deliberately wrap the stream arguments
+ * to the copy
methods in Buffered*
streams. For
+ * example, don't do the following:
+ *
+ * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); + *+ * The rationale is as follows: + *
+ * Imagine that an InputStream's read() is a very expensive operation, which
+ * would usually suggest wrapping in a BufferedInputStream. The
+ * BufferedInputStream works by issuing infrequent
+ * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the
+ * underlying InputStream, to fill an internal buffer, from which further
+ * read
requests can inexpensively get their data (until the buffer
+ * runs out).
+ *
+ * However, the copy
methods do the same thing, keeping an
+ * internal buffer, populated by
+ * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two
+ * buffers (or three if the destination stream is also buffered) is pointless,
+ * and the unnecessary buffer management hurts performance slightly (about 3%,
+ * according to some simple experiments).
+ *
+ * Behold, intrepid explorers; a map of this class: + *
+ * Method Input Output Dependency + * ------ ----- ------ ------- + * 1 copy InputStream OutputStream (primitive) + * 2 copy Reader Writer (primitive) + * + * 3 copy InputStream Writer 2 + * + * 4 copy Reader OutputStream 2 + * + * 5 copy String OutputStream 2 + * 6 copy String Writer (trivial) + * + * 7 copy byte[] Writer 3 + * 8 copy byte[] OutputStream (trivial) + *+ *
+ * Note that only the first two methods shuffle bytes; the rest use these + * two, or (if possible) copy using native Java copy methods. As there are + * method variants to specify the encoding, each row may + * correspond to up to 2 methods. + *
+ * Origin of code: Excalibur.
+ *
+ * @author Peter Donald
+ * @author Jeff Turner
+ * @author Matthew Hawthorne
+ * @version $Id: CopyUtils.java 437680 2006-08-28 11:57:00Z scolebourne $
+ * @deprecated Use IOUtils. Will be removed in 2.0.
+ * Methods renamed to IOUtils.write() or IOUtils.copy().
+ * Null handling behaviour changed in IOUtils (null data does not
+ * throw NullPointerException).
+ */
+public class CopyUtils {
+
+ /**
+ * The default size of the buffer.
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public CopyUtils() { }
+
+ // ----------------------------------------------------------------
+ // byte[] -> OutputStream
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy bytes from a byte[]
to an OutputStream
.
+ * @param input the byte array to read from
+ * @param output the OutputStream
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(byte[] input, OutputStream output)
+ throws IOException {
+ output.write(input);
+ }
+
+ // ----------------------------------------------------------------
+ // byte[] -> Writer
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy and convert bytes from a byte[]
to chars on a
+ * Writer
.
+ * The platform's default encoding is used for the byte-to-char conversion.
+ * @param input the byte array to read from
+ * @param output the Writer
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(byte[] input, Writer output)
+ throws IOException {
+ ByteArrayInputStream in = new ByteArrayInputStream(input);
+ copy(in, output);
+ }
+
+
+ /**
+ * Copy and convert bytes from a byte[]
to chars on a
+ * Writer
, using the specified encoding.
+ * @param input the byte array to read from
+ * @param output the Writer
to write to
+ * @param encoding The name of a supported character encoding. See the
+ * IANA
+ * Charset Registry for a list of valid encoding types.
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(
+ byte[] input,
+ Writer output,
+ String encoding)
+ throws IOException {
+ ByteArrayInputStream in = new ByteArrayInputStream(input);
+ copy(in, output, encoding);
+ }
+
+
+ // ----------------------------------------------------------------
+ // Core copy methods
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy bytes from an InputStream
to an
+ * OutputStream
.
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @return the number of bytes copied
+ * @throws IOException In case of an I/O problem
+ */
+ public static int copy(
+ InputStream input,
+ OutputStream output)
+ throws IOException {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ int count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ // ----------------------------------------------------------------
+ // Reader -> Writer
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy chars from a Reader
to a Writer
.
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @return the number of characters copied
+ * @throws IOException In case of an I/O problem
+ */
+ public static int copy(
+ Reader input,
+ Writer output)
+ throws IOException {
+ char[] buffer = new char[DEFAULT_BUFFER_SIZE];
+ int count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ // ----------------------------------------------------------------
+ // InputStream -> Writer
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy and convert bytes from an InputStream
to chars on a
+ * Writer
.
+ * The platform's default encoding is used for the byte-to-char conversion.
+ * @param input the InputStream
to read from
+ * @param output the Writer
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(
+ InputStream input,
+ Writer output)
+ throws IOException {
+ InputStreamReader in = new InputStreamReader(input);
+ copy(in, output);
+ }
+
+ /**
+ * Copy and convert bytes from an InputStream
to chars on a
+ * Writer
, using the specified encoding.
+ * @param input the InputStream
to read from
+ * @param output the Writer
to write to
+ * @param encoding The name of a supported character encoding. See the
+ * IANA
+ * Charset Registry for a list of valid encoding types.
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(
+ InputStream input,
+ Writer output,
+ String encoding)
+ throws IOException {
+ InputStreamReader in = new InputStreamReader(input, encoding);
+ copy(in, output);
+ }
+
+
+ // ----------------------------------------------------------------
+ // Reader -> OutputStream
+ // ----------------------------------------------------------------
+
+ /**
+ * Serialize chars from a Reader
to bytes on an
+ * OutputStream
, and flush the OutputStream
.
+ * @param input the Reader
to read from
+ * @param output the OutputStream
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(
+ Reader input,
+ OutputStream output)
+ throws IOException {
+ OutputStreamWriter out = new OutputStreamWriter(output);
+ copy(input, out);
+ // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
+ // have to flush here.
+ out.flush();
+ }
+
+ // ----------------------------------------------------------------
+ // String -> OutputStream
+ // ----------------------------------------------------------------
+
+ /**
+ * Serialize chars from a String
to bytes on an
+ * OutputStream
, and
+ * flush the OutputStream
.
+ * @param input the String
to read from
+ * @param output the OutputStream
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(
+ String input,
+ OutputStream output)
+ throws IOException {
+ StringReader in = new StringReader(input);
+ OutputStreamWriter out = new OutputStreamWriter(output);
+ copy(in, out);
+ // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
+ // have to flush here.
+ out.flush();
+ }
+
+ // ----------------------------------------------------------------
+ // String -> Writer
+ // ----------------------------------------------------------------
+
+ /**
+ * Copy chars from a String
to a Writer
.
+ * @param input the String
to read from
+ * @param output the Writer
to write to
+ * @throws IOException In case of an I/O problem
+ */
+ public static void copy(String input, Writer output)
+ throws IOException {
+ output.write(input);
+ }
+
+}
diff --git a/src/org/apache/commons/io/DirectoryWalker.java b/src/org/apache/commons/io/DirectoryWalker.java
index 9e564ae86c6fe08639770a3d74660964050838b5..71a27fbba22af343eaf744dfdd1da68ae03d9550 100644
--- a/src/org/apache/commons/io/DirectoryWalker.java
+++ b/src/org/apache/commons/io/DirectoryWalker.java
@@ -1,620 +1,620 @@
-/*
- * 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.commons.io;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.util.Collection;
-
-import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.TrueFileFilter;
-
-/**
- * Abstract class that walks through a directory hierarchy and provides
- * subclasses with convenient hooks to add specific behaviour.
- *
- * This class operates with a {@link FileFilter} and maximum depth to - * limit the files and direcories visited. - * Commons IO supplies many common filter implementations in the - * filefilter package. - *
- * The following sections describe: - *
FileCleaner
implementation.DirectoryWalker
.- * public class FileCleaner extends DirectoryWalker { - * - * public FileCleaner() { - * super(); - * } - * - * public List clean(File startDirectory) { - * List results = new ArrayList(); - * walk(startDirectory, results); - * return results; - * } - * - * protected boolean handleDirectory(File directory, int depth, Collection results) { - * // delete svn directories and then skip - * if (".svn".equals(directory.getName())) { - * directory.delete(); - * return false; - * } else { - * return true; - * } - * - * } - * - * protected void handleFile(File file, int depth, Collection results) { - * // delete file and add to list of deleted - * file.delete(); - * results.add(file); - * } - * } - *- * - * - *
- * The first option is to visit all directories and files. - * This is achieved via the no-args constructor. - *
- * The second constructor option is to supply a single {@link FileFilter} - * that describes the files and directories to visit. Care must be taken - * with this option as the same filter is used for both directories - * and files. - *
- * For example, if you wanted all directories which are not hidden - * and files which end in ".txt": - *
- * public class FooDirectoryWalker extends DirectoryWalker { - * public FooDirectoryWalker(FileFilter filter) { - * super(filter, -1); - * } - * } - * - * // Build up the filters and create the walker - * // Create a filter for Non-hidden directories - * IOFileFilter fooDirFilter = - * FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter, - * HiddenFileFilter.VISIBLE); - * - * // Create a filter for Files ending in ".txt" - * IOFileFilter fooFileFilter = - * FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter, - * FileFilterUtils.suffixFileFilter(".txt")); - * - * // Combine the directory and file filters using an OR condition - * java.io.FileFilter fooFilter = - * FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter); - * - * // Use the filter to construct a DirectoryWalker implementation - * FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter); - *- *
- * The third constructor option is to specify separate filters, one for
- * directories and one for files. These are combined internally to form
- * the correct FileFilter
, something which is very easy to
- * get wrong when attempted manually, particularly when trying to
- * express constructs like 'any file in directories named docs'.
- *
- * For example, if you wanted all directories which are not hidden - * and files which end in ".txt": - *
- * public class FooDirectoryWalker extends DirectoryWalker { - * public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter) { - * super(dirFilter, fileFilter, -1); - * } - * } - * - * // Use the filters to construct the walker - * FooDirectoryWalker walker = new FooDirectoryWalker( - * HiddenFileFilter.VISIBLE, - * FileFilterUtils.suffixFileFilter(".txt"), - * ); - *- * This is much simpler than the previous example, and is why it is the preferred - * option for filtering. - * - * - *
- * What DirectoryWalker
does provide for cancellation is:
- *
walk()
method traps thrown {@link CancelException}
- * and calls the handleCancelled()
method, providing
- * a place for custom cancel processing.- * Implementations need to provide: - *
handleCancelled()
method.
- * - * Two possible scenarios are envisaged for cancellation: - *
- * The following sections provide example implementations for these two different - * scenarios. - * - * - *
cancel()
method that can be
- * called by another thread to stop the processing. A typical example use-case
- * would be a cancel button on a GUI. Calling this method sets a
- *
- * volatile flag to ensure it will work properly in a multi-threaded environment.
- * The flag is returned by the handleIsCancelled()
method, which
- * will cause the walk to stop immediately. The handleCancelled()
- * method will be the next, and last, callback method received once cancellation
- * has occurred.
- *
- * - * public class FooDirectoryWalker extends DirectoryWalker { - * - * private volatile boolean cancelled = false; - * - * public void cancel() { - * cancelled = true; - * } - * - * private void handleIsCancelled(File file, int depth, Collection results) { - * return cancelled; - * } - * - * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { - * // implement processing required when a cancellation occurs - * } - * } - *- * - * - *
- * public class BarDirectoryWalker extends DirectoryWalker { - * - * protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { - * // cancel if hidden directory - * if (directory.isHidden()) { - * throw new CancelException(file, depth); - * } - * return true; - * } - * - * protected void handleFile(File file, int depth, Collection results) throws IOException { - * // cancel if read-only file - * if (!file.canWrite()) { - * throw new CancelException(file, depth); - * } - * results.add(file); - * } - * - * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { - * // implement processing required when a cancellation occurs - * } - * } - *- * - * @since Commons IO 1.3 - * @version $Revision: 424748 $ - */ -public abstract class DirectoryWalker { - - /** - * The file filter to use to filter files and directories. - */ - private final FileFilter filter; - /** - * The limit on the directory depth to walk. - */ - private final int depthLimit; - - /** - * Construct an instance with no filtering and unlimited depth. - */ - protected DirectoryWalker() { - this(null, -1); - } - - /** - * Construct an instance with a filter and limit the depth navigated to. - *
- * The filter controls which files and directories will be navigated to as
- * part of the walk. The {@link FileFilterUtils} class is useful for combining
- * various filters together. A null
filter means that no
- * filtering should occur and all files and directories will be visited.
- *
- * @param filter the filter to apply, null means visit all files
- * @param depthLimit controls how deep the hierarchy is
- * navigated to (less than 0 means unlimited)
- */
- protected DirectoryWalker(FileFilter filter, int depthLimit) {
- this.filter = filter;
- this.depthLimit = depthLimit;
- }
-
- /**
- * Construct an instance with a directory and a file filter and an optional
- * limit on the depth navigated to.
- *
- * The filters control which files and directories will be navigated to as part
- * of the walk. This constructor uses {@link FileFilterUtils#makeDirectoryOnly(IOFileFilter)}
- * and {@link FileFilterUtils#makeFileOnly(IOFileFilter)} internally to combine the filters.
- * A null
filter means that no filtering should occur.
- *
- * @param directoryFilter the filter to apply to directories, null means visit all directories
- * @param fileFilter the filter to apply to files, null means visit all files
- * @param depthLimit controls how deep the hierarchy is
- * navigated to (less than 0 means unlimited)
- */
- protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, int depthLimit) {
- if (directoryFilter == null && fileFilter == null) {
- this.filter = null;
- } else {
- directoryFilter = (directoryFilter != null ? directoryFilter : TrueFileFilter.TRUE);
- fileFilter = (fileFilter != null ? fileFilter : TrueFileFilter.TRUE);
- directoryFilter = FileFilterUtils.makeDirectoryOnly(directoryFilter);
- fileFilter = FileFilterUtils.makeFileOnly(fileFilter);
- this.filter = FileFilterUtils.orFileFilter(directoryFilter, fileFilter);
- }
- this.depthLimit = depthLimit;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Internal method that walks the directory hierarchy in a depth-first manner.
- *
- * Users of this class do not need to call this method. This method will - * be called automatically by another (public) method on the specific subclass. - *
- * Writers of subclasses should call this method to start the directory walk.
- * Once called, this method will emit events as it walks the hierarchy.
- * The event methods have the prefix handle
.
- *
- * @param startDirectory the directory to start from, not null
- * @param results the collection of result objects, may be updated
- * @throws NullPointerException if the start directory is null
- * @throws IOException if an I/O Error occurs
- */
- protected final void walk(File startDirectory, Collection results) throws IOException {
- if (startDirectory == null) {
- throw new NullPointerException("Start Directory is null");
- }
- try {
- handleStart(startDirectory, results);
- walk(startDirectory, 0, results);
- handleEnd(results);
- } catch(CancelException cancel) {
- handleCancelled(startDirectory, results, cancel);
- }
- }
-
- /**
- * Main recursive method to examine the directory hierarchy.
- *
- * @param directory the directory to examine, not null
- * @param depth the directory level (starting directory = 0)
- * @param results the collection of result objects, may be updated
- * @throws IOException if an I/O Error occurs
- */
- private void walk(File directory, int depth, Collection results) throws IOException {
- checkIfCancelled(directory, depth, results);
- if (handleDirectory(directory, depth, results)) {
- handleDirectoryStart(directory, depth, results);
- int childDepth = depth + 1;
- if (depthLimit < 0 || childDepth <= depthLimit) {
- checkIfCancelled(directory, depth, results);
- File[] childFiles = (filter == null ? directory.listFiles() : directory.listFiles(filter));
- if (childFiles == null) {
- handleRestricted(directory, childDepth, results);
- } else {
- for (int i = 0; i < childFiles.length; i++) {
- File childFile = childFiles[i];
- if (childFile.isDirectory()) {
- walk(childFile, childDepth, results);
- } else {
- checkIfCancelled(childFile, childDepth, results);
- handleFile(childFile, childDepth, results);
- checkIfCancelled(childFile, childDepth, results);
- }
- }
- }
- }
- handleDirectoryEnd(directory, depth, results);
- }
- checkIfCancelled(directory, depth, results);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks whether the walk has been cancelled by calling {@link #handleIsCancelled},
- * throwing a CancelException
if it has.
- *
- * Writers of subclasses should not normally call this method as it is called - * automatically by the walk of the tree. However, sometimes a single method, - * typically {@link #handleFile}, may take a long time to run. In that case, - * you may wish to check for cancellation by calling this method. - * - * @param file the current file being processed - * @param depth the current file level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected final void checkIfCancelled(File file, int depth, Collection results) throws IOException { - if (handleIsCancelled(file, depth, results)) { - throw new CancelException(file, depth); - } - } - - /** - * Overridable callback method invoked to determine if the entire walk - * operation should be immediately cancelled. - *
- * This method should be implemented by those subclasses that want to
- * provide a public cancel()
method available from another
- * thread. The design pattern for the subclass should be as follows:
- *
- * public class FooDirectoryWalker extends DirectoryWalker { - * private volatile boolean cancelled = false; - * - * public void cancel() { - * cancelled = true; - * } - * private void handleIsCancelled(File file, int depth, Collection results) { - * return cancelled; - * } - * protected void handleCancelled(File startDirectory, - * Collection results, CancelException cancel) { - * // implement processing required when a cancellation occurs - * } - * } - *- *
- * If this method returns true, then the directory walk is immediately - * cancelled. The next callback method will be {@link #handleCancelled}. - *
- * This implementation returns false. - * - * @param file the file or directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @return true if the walk has been cancelled - * @throws IOException if an I/O Error occurs - */ - protected boolean handleIsCancelled( - File file, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - return false; // not cancelled - } - - /** - * Overridable callback method invoked when the operation is cancelled. - * The file being processed when the cancellation occurred can be - * obtained from the exception. - *
- * This implementation just re-throws the {@link CancelException}. - * - * @param startDirectory the directory that the walk started from - * @param results the collection of result objects, may be updated - * @param cancel the exception throw to cancel further processing - * containing details at the point of cancellation. - * @throws IOException if an I/O Error occurs - */ - protected void handleCancelled(File startDirectory, Collection results, - CancelException cancel) throws IOException { - // re-throw exception - overridable by subclass - throw cancel; - } - - //----------------------------------------------------------------------- - /** - * Overridable callback method invoked at the start of processing. - *
- * This implementation does nothing. - * - * @param startDirectory the directory to start from - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected void handleStart(File startDirectory, Collection results) throws IOException { - // do nothing - overridable by subclass - } - - /** - * Overridable callback method invoked to determine if a directory should be processed. - *
- * This method returns a boolean to indicate if the directory should be examined or not. - * If you return false, the entire directory and any subdirectories will be skipped. - * Note that this functionality is in addition to the filtering by file filter. - *
- * This implementation does nothing and returns true. - * - * @param directory the current directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @return true to process this directory, false to skip this directory - * @throws IOException if an I/O Error occurs - */ - protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - return true; // process directory - } - - /** - * Overridable callback method invoked at the start of processing each directory. - *
- * This implementation does nothing. - * - * @param directory the current directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected void handleDirectoryStart(File directory, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - } - - /** - * Overridable callback method invoked for each (non-directory) file. - *
- * This implementation does nothing. - * - * @param file the current file being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected void handleFile(File file, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - } - - /** - * Overridable callback method invoked for each restricted directory. - *
- * This implementation does nothing. - * - * @param directory the restricted directory - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected void handleRestricted(File directory, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - } - - /** - * Overridable callback method invoked at the end of processing each directory. - *
- * This implementation does nothing. - * - * @param directory the directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs - */ - protected void handleDirectoryEnd(File directory, int depth, Collection results) throws IOException { - // do nothing - overridable by subclass - } - - /** - * Overridable callback method invoked at the end of processing. - *
- * This implementation does nothing.
- *
- * @param results the collection of result objects, may be updated
- * @throws IOException if an I/O Error occurs
- */
- protected void handleEnd(Collection results) throws IOException {
- // do nothing - overridable by subclass
- }
-
- //-----------------------------------------------------------------------
- /**
- * CancelException is thrown in DirectoryWalker to cancel the current
- * processing.
- */
- public static class CancelException extends IOException {
-
- /** Serialization id. */
- private static final long serialVersionUID = 1347339620135041008L;
-
- /** The file being processed when the exception was thrown. */
- private File file;
- /** The file depth when the exception was thrown. */
- private int depth = -1;
-
- /**
- * Constructs a CancelException
with
- * the file and depth when cancellation occurred.
- *
- * @param file the file when the operation was cancelled, may be null
- * @param depth the depth when the operation was cancelled, may be null
- */
- public CancelException(File file, int depth) {
- this("Operation Cancelled", file, depth);
- }
-
- /**
- * Constructs a CancelException
with
- * an appropriate message and the file and depth when
- * cancellation occurred.
- *
- * @param message the detail message
- * @param file the file when the operation was cancelled
- * @param depth the depth when the operation was cancelled
- */
- public CancelException(String message, File file, int depth) {
- super(message);
- this.file = file;
- this.depth = depth;
- }
-
- /**
- * Return the file when the operation was cancelled.
- *
- * @return the file when the operation was cancelled
- */
- public File getFile() {
- return file;
- }
-
- /**
- * Return the depth when the operation was cancelled.
- *
- * @return the depth when the operation was cancelled
- */
- public int getDepth() {
- return depth;
- }
- }
-}
+/*
+ * 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.commons.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+
+/**
+ * Abstract class that walks through a directory hierarchy and provides
+ * subclasses with convenient hooks to add specific behaviour.
+ *
+ * This class operates with a {@link FileFilter} and maximum depth to + * limit the files and direcories visited. + * Commons IO supplies many common filter implementations in the + * filefilter package. + *
+ * The following sections describe: + *
FileCleaner
implementation.DirectoryWalker
.+ * public class FileCleaner extends DirectoryWalker { + * + * public FileCleaner() { + * super(); + * } + * + * public List clean(File startDirectory) { + * List results = new ArrayList(); + * walk(startDirectory, results); + * return results; + * } + * + * protected boolean handleDirectory(File directory, int depth, Collection results) { + * // delete svn directories and then skip + * if (".svn".equals(directory.getName())) { + * directory.delete(); + * return false; + * } else { + * return true; + * } + * + * } + * + * protected void handleFile(File file, int depth, Collection results) { + * // delete file and add to list of deleted + * file.delete(); + * results.add(file); + * } + * } + *+ * + * + *
+ * The first option is to visit all directories and files. + * This is achieved via the no-args constructor. + *
+ * The second constructor option is to supply a single {@link FileFilter} + * that describes the files and directories to visit. Care must be taken + * with this option as the same filter is used for both directories + * and files. + *
+ * For example, if you wanted all directories which are not hidden + * and files which end in ".txt": + *
+ * public class FooDirectoryWalker extends DirectoryWalker { + * public FooDirectoryWalker(FileFilter filter) { + * super(filter, -1); + * } + * } + * + * // Build up the filters and create the walker + * // Create a filter for Non-hidden directories + * IOFileFilter fooDirFilter = + * FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter, + * HiddenFileFilter.VISIBLE); + * + * // Create a filter for Files ending in ".txt" + * IOFileFilter fooFileFilter = + * FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter, + * FileFilterUtils.suffixFileFilter(".txt")); + * + * // Combine the directory and file filters using an OR condition + * java.io.FileFilter fooFilter = + * FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter); + * + * // Use the filter to construct a DirectoryWalker implementation + * FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter); + *+ *
+ * The third constructor option is to specify separate filters, one for
+ * directories and one for files. These are combined internally to form
+ * the correct FileFilter
, something which is very easy to
+ * get wrong when attempted manually, particularly when trying to
+ * express constructs like 'any file in directories named docs'.
+ *
+ * For example, if you wanted all directories which are not hidden + * and files which end in ".txt": + *
+ * public class FooDirectoryWalker extends DirectoryWalker { + * public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter) { + * super(dirFilter, fileFilter, -1); + * } + * } + * + * // Use the filters to construct the walker + * FooDirectoryWalker walker = new FooDirectoryWalker( + * HiddenFileFilter.VISIBLE, + * FileFilterUtils.suffixFileFilter(".txt"), + * ); + *+ * This is much simpler than the previous example, and is why it is the preferred + * option for filtering. + * + * + *
+ * What DirectoryWalker
does provide for cancellation is:
+ *
walk()
method traps thrown {@link CancelException}
+ * and calls the handleCancelled()
method, providing
+ * a place for custom cancel processing.+ * Implementations need to provide: + *
handleCancelled()
method.
+ * + * Two possible scenarios are envisaged for cancellation: + *
+ * The following sections provide example implementations for these two different + * scenarios. + * + * + *
cancel()
method that can be
+ * called by another thread to stop the processing. A typical example use-case
+ * would be a cancel button on a GUI. Calling this method sets a
+ *
+ * volatile flag to ensure it will work properly in a multi-threaded environment.
+ * The flag is returned by the handleIsCancelled()
method, which
+ * will cause the walk to stop immediately. The handleCancelled()
+ * method will be the next, and last, callback method received once cancellation
+ * has occurred.
+ *
+ * + * public class FooDirectoryWalker extends DirectoryWalker { + * + * private volatile boolean cancelled = false; + * + * public void cancel() { + * cancelled = true; + * } + * + * private void handleIsCancelled(File file, int depth, Collection results) { + * return cancelled; + * } + * + * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { + * // implement processing required when a cancellation occurs + * } + * } + *+ * + * + *
+ * public class BarDirectoryWalker extends DirectoryWalker { + * + * protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { + * // cancel if hidden directory + * if (directory.isHidden()) { + * throw new CancelException(file, depth); + * } + * return true; + * } + * + * protected void handleFile(File file, int depth, Collection results) throws IOException { + * // cancel if read-only file + * if (!file.canWrite()) { + * throw new CancelException(file, depth); + * } + * results.add(file); + * } + * + * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { + * // implement processing required when a cancellation occurs + * } + * } + *+ * + * @since Commons IO 1.3 + * @version $Revision: 424748 $ + */ +public abstract class DirectoryWalker { + + /** + * The file filter to use to filter files and directories. + */ + private final FileFilter filter; + /** + * The limit on the directory depth to walk. + */ + private final int depthLimit; + + /** + * Construct an instance with no filtering and unlimited depth. + */ + protected DirectoryWalker() { + this(null, -1); + } + + /** + * Construct an instance with a filter and limit the depth navigated to. + *
+ * The filter controls which files and directories will be navigated to as
+ * part of the walk. The {@link FileFilterUtils} class is useful for combining
+ * various filters together. A null
filter means that no
+ * filtering should occur and all files and directories will be visited.
+ *
+ * @param filter the filter to apply, null means visit all files
+ * @param depthLimit controls how deep the hierarchy is
+ * navigated to (less than 0 means unlimited)
+ */
+ protected DirectoryWalker(FileFilter filter, int depthLimit) {
+ this.filter = filter;
+ this.depthLimit = depthLimit;
+ }
+
+ /**
+ * Construct an instance with a directory and a file filter and an optional
+ * limit on the depth navigated to.
+ *
+ * The filters control which files and directories will be navigated to as part
+ * of the walk. This constructor uses {@link FileFilterUtils#makeDirectoryOnly(IOFileFilter)}
+ * and {@link FileFilterUtils#makeFileOnly(IOFileFilter)} internally to combine the filters.
+ * A null
filter means that no filtering should occur.
+ *
+ * @param directoryFilter the filter to apply to directories, null means visit all directories
+ * @param fileFilter the filter to apply to files, null means visit all files
+ * @param depthLimit controls how deep the hierarchy is
+ * navigated to (less than 0 means unlimited)
+ */
+ protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, int depthLimit) {
+ if (directoryFilter == null && fileFilter == null) {
+ this.filter = null;
+ } else {
+ directoryFilter = (directoryFilter != null ? directoryFilter : TrueFileFilter.TRUE);
+ fileFilter = (fileFilter != null ? fileFilter : TrueFileFilter.TRUE);
+ directoryFilter = FileFilterUtils.makeDirectoryOnly(directoryFilter);
+ fileFilter = FileFilterUtils.makeFileOnly(fileFilter);
+ this.filter = FileFilterUtils.orFileFilter(directoryFilter, fileFilter);
+ }
+ this.depthLimit = depthLimit;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Internal method that walks the directory hierarchy in a depth-first manner.
+ *
+ * Users of this class do not need to call this method. This method will + * be called automatically by another (public) method on the specific subclass. + *
+ * Writers of subclasses should call this method to start the directory walk.
+ * Once called, this method will emit events as it walks the hierarchy.
+ * The event methods have the prefix handle
.
+ *
+ * @param startDirectory the directory to start from, not null
+ * @param results the collection of result objects, may be updated
+ * @throws NullPointerException if the start directory is null
+ * @throws IOException if an I/O Error occurs
+ */
+ protected final void walk(File startDirectory, Collection results) throws IOException {
+ if (startDirectory == null) {
+ throw new NullPointerException("Start Directory is null");
+ }
+ try {
+ handleStart(startDirectory, results);
+ walk(startDirectory, 0, results);
+ handleEnd(results);
+ } catch(CancelException cancel) {
+ handleCancelled(startDirectory, results, cancel);
+ }
+ }
+
+ /**
+ * Main recursive method to examine the directory hierarchy.
+ *
+ * @param directory the directory to examine, not null
+ * @param depth the directory level (starting directory = 0)
+ * @param results the collection of result objects, may be updated
+ * @throws IOException if an I/O Error occurs
+ */
+ private void walk(File directory, int depth, Collection results) throws IOException {
+ checkIfCancelled(directory, depth, results);
+ if (handleDirectory(directory, depth, results)) {
+ handleDirectoryStart(directory, depth, results);
+ int childDepth = depth + 1;
+ if (depthLimit < 0 || childDepth <= depthLimit) {
+ checkIfCancelled(directory, depth, results);
+ File[] childFiles = (filter == null ? directory.listFiles() : directory.listFiles(filter));
+ if (childFiles == null) {
+ handleRestricted(directory, childDepth, results);
+ } else {
+ for (int i = 0; i < childFiles.length; i++) {
+ File childFile = childFiles[i];
+ if (childFile.isDirectory()) {
+ walk(childFile, childDepth, results);
+ } else {
+ checkIfCancelled(childFile, childDepth, results);
+ handleFile(childFile, childDepth, results);
+ checkIfCancelled(childFile, childDepth, results);
+ }
+ }
+ }
+ }
+ handleDirectoryEnd(directory, depth, results);
+ }
+ checkIfCancelled(directory, depth, results);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether the walk has been cancelled by calling {@link #handleIsCancelled},
+ * throwing a CancelException
if it has.
+ *
+ * Writers of subclasses should not normally call this method as it is called + * automatically by the walk of the tree. However, sometimes a single method, + * typically {@link #handleFile}, may take a long time to run. In that case, + * you may wish to check for cancellation by calling this method. + * + * @param file the current file being processed + * @param depth the current file level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected final void checkIfCancelled(File file, int depth, Collection results) throws IOException { + if (handleIsCancelled(file, depth, results)) { + throw new CancelException(file, depth); + } + } + + /** + * Overridable callback method invoked to determine if the entire walk + * operation should be immediately cancelled. + *
+ * This method should be implemented by those subclasses that want to
+ * provide a public cancel()
method available from another
+ * thread. The design pattern for the subclass should be as follows:
+ *
+ * public class FooDirectoryWalker extends DirectoryWalker { + * private volatile boolean cancelled = false; + * + * public void cancel() { + * cancelled = true; + * } + * private void handleIsCancelled(File file, int depth, Collection results) { + * return cancelled; + * } + * protected void handleCancelled(File startDirectory, + * Collection results, CancelException cancel) { + * // implement processing required when a cancellation occurs + * } + * } + *+ *
+ * If this method returns true, then the directory walk is immediately + * cancelled. The next callback method will be {@link #handleCancelled}. + *
+ * This implementation returns false. + * + * @param file the file or directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @return true if the walk has been cancelled + * @throws IOException if an I/O Error occurs + */ + protected boolean handleIsCancelled( + File file, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + return false; // not cancelled + } + + /** + * Overridable callback method invoked when the operation is cancelled. + * The file being processed when the cancellation occurred can be + * obtained from the exception. + *
+ * This implementation just re-throws the {@link CancelException}. + * + * @param startDirectory the directory that the walk started from + * @param results the collection of result objects, may be updated + * @param cancel the exception throw to cancel further processing + * containing details at the point of cancellation. + * @throws IOException if an I/O Error occurs + */ + protected void handleCancelled(File startDirectory, Collection results, + CancelException cancel) throws IOException { + // re-throw exception - overridable by subclass + throw cancel; + } + + //----------------------------------------------------------------------- + /** + * Overridable callback method invoked at the start of processing. + *
+ * This implementation does nothing. + * + * @param startDirectory the directory to start from + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleStart(File startDirectory, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked to determine if a directory should be processed. + *
+ * This method returns a boolean to indicate if the directory should be examined or not. + * If you return false, the entire directory and any subdirectories will be skipped. + * Note that this functionality is in addition to the filtering by file filter. + *
+ * This implementation does nothing and returns true. + * + * @param directory the current directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @return true to process this directory, false to skip this directory + * @throws IOException if an I/O Error occurs + */ + protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + return true; // process directory + } + + /** + * Overridable callback method invoked at the start of processing each directory. + *
+ * This implementation does nothing. + * + * @param directory the current directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleDirectoryStart(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked for each (non-directory) file. + *
+ * This implementation does nothing. + * + * @param file the current file being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleFile(File file, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked for each restricted directory. + *
+ * This implementation does nothing. + * + * @param directory the restricted directory + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleRestricted(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked at the end of processing each directory. + *
+ * This implementation does nothing. + * + * @param directory the directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleDirectoryEnd(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked at the end of processing. + *
+ * This implementation does nothing.
+ *
+ * @param results the collection of result objects, may be updated
+ * @throws IOException if an I/O Error occurs
+ */
+ protected void handleEnd(Collection results) throws IOException {
+ // do nothing - overridable by subclass
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * CancelException is thrown in DirectoryWalker to cancel the current
+ * processing.
+ */
+ public static class CancelException extends IOException {
+
+ /** Serialization id. */
+ private static final long serialVersionUID = 1347339620135041008L;
+
+ /** The file being processed when the exception was thrown. */
+ private File file;
+ /** The file depth when the exception was thrown. */
+ private int depth = -1;
+
+ /**
+ * Constructs a CancelException
with
+ * the file and depth when cancellation occurred.
+ *
+ * @param file the file when the operation was cancelled, may be null
+ * @param depth the depth when the operation was cancelled, may be null
+ */
+ public CancelException(File file, int depth) {
+ this("Operation Cancelled", file, depth);
+ }
+
+ /**
+ * Constructs a CancelException
with
+ * an appropriate message and the file and depth when
+ * cancellation occurred.
+ *
+ * @param message the detail message
+ * @param file the file when the operation was cancelled
+ * @param depth the depth when the operation was cancelled
+ */
+ public CancelException(String message, File file, int depth) {
+ super(message);
+ this.file = file;
+ this.depth = depth;
+ }
+
+ /**
+ * Return the file when the operation was cancelled.
+ *
+ * @return the file when the operation was cancelled
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Return the depth when the operation was cancelled.
+ *
+ * @return the depth when the operation was cancelled
+ */
+ public int getDepth() {
+ return depth;
+ }
+ }
+}
diff --git a/src/org/apache/commons/io/EndianUtils.java b/src/org/apache/commons/io/EndianUtils.java
index 810feac04db4ecd887399f0c4a43f48f2192908a..e7f1eee99db3e8f5a93c176a2e9097ad101ccf25 100644
--- a/src/org/apache/commons/io/EndianUtils.java
+++ b/src/org/apache/commons/io/EndianUtils.java
@@ -1,489 +1,489 @@
-/*
- * 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.commons.io;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Utility code for dealing with different endian systems.
- *
- * Different computer architectures adopt different conventions for - * byte ordering. In so-called "Little Endian" architectures (eg Intel), - * the low-order byte is stored in memory at the lowest address, and - * subsequent bytes at higher addresses. For "Big Endian" architectures - * (eg Motorola), the situation is reversed. - * This class helps you solve this incompatability. - *
- * Origin of code: Excalibur - * - * @author Peter Donald - * @version $Id: EndianUtils.java 539632 2007-05-18 23:37:59Z bayard $ - * @see org.apache.commons.io.input.SwappedDataInputStream - */ -public class EndianUtils { - - /** - * Instances should NOT be constructed in standard programming. - */ - public EndianUtils() { - super(); - } - - // ========================================== Swapping routines - - /** - * Converts a "short" value between endian systems. - * @param value value to convert - * @return the converted value - */ - public static short swapShort(short value) { - return (short) ( ( ( ( value >> 0 ) & 0xff ) << 8 ) + - ( ( ( value >> 8 ) & 0xff ) << 0 ) ); - } - - /** - * Converts a "int" value between endian systems. - * @param value value to convert - * @return the converted value - */ - public static int swapInteger(int value) { - return - ( ( ( value >> 0 ) & 0xff ) << 24 ) + - ( ( ( value >> 8 ) & 0xff ) << 16 ) + - ( ( ( value >> 16 ) & 0xff ) << 8 ) + - ( ( ( value >> 24 ) & 0xff ) << 0 ); - } - - /** - * Converts a "long" value between endian systems. - * @param value value to convert - * @return the converted value - */ - public static long swapLong(long value) { - return - ( ( ( value >> 0 ) & 0xff ) << 56 ) + - ( ( ( value >> 8 ) & 0xff ) << 48 ) + - ( ( ( value >> 16 ) & 0xff ) << 40 ) + - ( ( ( value >> 24 ) & 0xff ) << 32 ) + - ( ( ( value >> 32 ) & 0xff ) << 24 ) + - ( ( ( value >> 40 ) & 0xff ) << 16 ) + - ( ( ( value >> 48 ) & 0xff ) << 8 ) + - ( ( ( value >> 56 ) & 0xff ) << 0 ); - } - - /** - * Converts a "float" value between endian systems. - * @param value value to convert - * @return the converted value - */ - public static float swapFloat(float value) { - return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) ); - } - - /** - * Converts a "double" value between endian systems. - * @param value value to convert - * @return the converted value - */ - public static double swapDouble(double value) { - return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) ); - } - - // ========================================== Swapping read/write routines - - /** - * Writes a "short" value to a byte array at a given offset. The value is - * converted to the opposed endian system while writing. - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - */ - public static void writeSwappedShort(byte[] data, int offset, short value) { - data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); - data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); - } - - /** - * Reads a "short" value from a byte array at a given offset. The value is - * converted to the opposed endian system while reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static short readSwappedShort(byte[] data, int offset) { - return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + - ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); - } - - /** - * Reads an unsigned short (16-bit) value from a byte array at a given - * offset. The value is converted to the opposed endian system while - * reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static int readSwappedUnsignedShort(byte[] data, int offset) { - return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + - ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); - } - - /** - * Writes a "int" value to a byte array at a given offset. The value is - * converted to the opposed endian system while writing. - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - */ - public static void writeSwappedInteger(byte[] data, int offset, int value) { - data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); - data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); - data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); - data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); - } - - /** - * Reads a "int" value from a byte array at a given offset. The value is - * converted to the opposed endian system while reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static int readSwappedInteger(byte[] data, int offset) { - return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + - ( ( data[ offset + 1 ] & 0xff ) << 8 ) + - ( ( data[ offset + 2 ] & 0xff ) << 16 ) + - ( ( data[ offset + 3 ] & 0xff ) << 24 ) ); - } - - /** - * Reads an unsigned integer (32-bit) value from a byte array at a given - * offset. The value is converted to the opposed endian system while - * reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static long readSwappedUnsignedInteger(byte[] data, int offset) { - long low = ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + - ( ( data[ offset + 1 ] & 0xff ) << 8 ) + - ( ( data[ offset + 2 ] & 0xff ) << 16 ) ); - - long high = data[ offset + 3 ] & 0xff; - - return (high << 24) + (0xffffffffL & low); - } - - /** - * Writes a "long" value to a byte array at a given offset. The value is - * converted to the opposed endian system while writing. - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - */ - public static void writeSwappedLong(byte[] data, int offset, long value) { - data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); - data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); - data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); - data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); - data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff ); - data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff ); - data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff ); - data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff ); - } - - /** - * Reads a "long" value from a byte array at a given offset. The value is - * converted to the opposed endian system while reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static long readSwappedLong(byte[] data, int offset) { - long low = - ( ( data[ offset + 0 ] & 0xff ) << 0 ) + - ( ( data[ offset + 1 ] & 0xff ) << 8 ) + - ( ( data[ offset + 2 ] & 0xff ) << 16 ) + - ( ( data[ offset + 3 ] & 0xff ) << 24 ); - long high = - ( ( data[ offset + 4 ] & 0xff ) << 0 ) + - ( ( data[ offset + 5 ] & 0xff ) << 8 ) + - ( ( data[ offset + 6 ] & 0xff ) << 16 ) + - ( ( data[ offset + 7 ] & 0xff ) << 24 ); - return (high << 32) + (0xffffffffL & low); - } - - /** - * Writes a "float" value to a byte array at a given offset. The value is - * converted to the opposed endian system while writing. - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - */ - public static void writeSwappedFloat(byte[] data, int offset, float value) { - writeSwappedInteger( data, offset, Float.floatToIntBits( value ) ); - } - - /** - * Reads a "float" value from a byte array at a given offset. The value is - * converted to the opposed endian system while reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static float readSwappedFloat(byte[] data, int offset) { - return Float.intBitsToFloat( readSwappedInteger( data, offset ) ); - } - - /** - * Writes a "double" value to a byte array at a given offset. The value is - * converted to the opposed endian system while writing. - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - */ - public static void writeSwappedDouble(byte[] data, int offset, double value) { - writeSwappedLong( data, offset, Double.doubleToLongBits( value ) ); - } - - /** - * Reads a "double" value from a byte array at a given offset. The value is - * converted to the opposed endian system while reading. - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - */ - public static double readSwappedDouble(byte[] data, int offset) { - return Double.longBitsToDouble( readSwappedLong( data, offset ) ); - } - - /** - * Writes a "short" value to an OutputStream. The value is - * converted to the opposed endian system while writing. - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem - */ - public static void writeSwappedShort(OutputStream output, short value) - throws IOException - { - output.write( (byte)( ( value >> 0 ) & 0xff ) ); - output.write( (byte)( ( value >> 8 ) & 0xff ) ); - } - - /** - * Reads a "short" value from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static short readSwappedShort(InputStream input) - throws IOException - { - return (short)( ( ( read( input ) & 0xff ) << 0 ) + - ( ( read( input ) & 0xff ) << 8 ) ); - } - - /** - * Reads a unsigned short (16-bit) from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static int readSwappedUnsignedShort(InputStream input) - throws IOException - { - int value1 = read( input ); - int value2 = read( input ); - - return ( ( ( value1 & 0xff ) << 0 ) + - ( ( value2 & 0xff ) << 8 ) ); - } - - /** - * Writes a "int" value to an OutputStream. The value is - * converted to the opposed endian system while writing. - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem - */ - public static void writeSwappedInteger(OutputStream output, int value) - throws IOException - { - output.write( (byte)( ( value >> 0 ) & 0xff ) ); - output.write( (byte)( ( value >> 8 ) & 0xff ) ); - output.write( (byte)( ( value >> 16 ) & 0xff ) ); - output.write( (byte)( ( value >> 24 ) & 0xff ) ); - } - - /** - * Reads a "int" value from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static int readSwappedInteger(InputStream input) - throws IOException - { - int value1 = read( input ); - int value2 = read( input ); - int value3 = read( input ); - int value4 = read( input ); - - return ( ( value1 & 0xff ) << 0 ) + - ( ( value2 & 0xff ) << 8 ) + - ( ( value3 & 0xff ) << 16 ) + - ( ( value4 & 0xff ) << 24 ); - } - - /** - * Reads a unsigned integer (32-bit) from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static long readSwappedUnsignedInteger(InputStream input) - throws IOException - { - int value1 = read( input ); - int value2 = read( input ); - int value3 = read( input ); - int value4 = read( input ); - - long low = ( ( ( value1 & 0xff ) << 0 ) + - ( ( value2 & 0xff ) << 8 ) + - ( ( value3 & 0xff ) << 16 ) ); - - long high = value4 & 0xff; - - return (high << 24) + (0xffffffffL & low); - } - - /** - * Writes a "long" value to an OutputStream. The value is - * converted to the opposed endian system while writing. - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem - */ - public static void writeSwappedLong(OutputStream output, long value) - throws IOException - { - output.write( (byte)( ( value >> 0 ) & 0xff ) ); - output.write( (byte)( ( value >> 8 ) & 0xff ) ); - output.write( (byte)( ( value >> 16 ) & 0xff ) ); - output.write( (byte)( ( value >> 24 ) & 0xff ) ); - output.write( (byte)( ( value >> 32 ) & 0xff ) ); - output.write( (byte)( ( value >> 40 ) & 0xff ) ); - output.write( (byte)( ( value >> 48 ) & 0xff ) ); - output.write( (byte)( ( value >> 56 ) & 0xff ) ); - } - - /** - * Reads a "long" value from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static long readSwappedLong(InputStream input) - throws IOException - { - byte[] bytes = new byte[8]; - for ( int i=0; i<8; i++ ) { - bytes[i] = (byte) read( input ); - } - return readSwappedLong( bytes, 0 ); - } - - /** - * Writes a "float" value to an OutputStream. The value is - * converted to the opposed endian system while writing. - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem - */ - public static void writeSwappedFloat(OutputStream output, float value) - throws IOException - { - writeSwappedInteger( output, Float.floatToIntBits( value ) ); - } - - /** - * Reads a "float" value from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static float readSwappedFloat(InputStream input) - throws IOException - { - return Float.intBitsToFloat( readSwappedInteger( input ) ); - } - - /** - * Writes a "double" value to an OutputStream. The value is - * converted to the opposed endian system while writing. - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem - */ - public static void writeSwappedDouble(OutputStream output, double value) - throws IOException - { - writeSwappedLong( output, Double.doubleToLongBits( value ) ); - } - - /** - * Reads a "double" value from an InputStream. The value is - * converted to the opposed endian system while reading. - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem - */ - public static double readSwappedDouble(InputStream input) - throws IOException - { - return Double.longBitsToDouble( readSwappedLong( input ) ); - } - - /** - * Reads the next byte from the input stream. - * @param input the stream - * @return the byte - * @throws IOException if the end of file is reached - */ - private static int read(InputStream input) - throws IOException - { - int value = input.read(); - - if( -1 == value ) { - throw new EOFException( "Unexpected EOF reached" ); - } - - return value; - } -} +/* + * 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.commons.io; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Utility code for dealing with different endian systems. + *
+ * Different computer architectures adopt different conventions for + * byte ordering. In so-called "Little Endian" architectures (eg Intel), + * the low-order byte is stored in memory at the lowest address, and + * subsequent bytes at higher addresses. For "Big Endian" architectures + * (eg Motorola), the situation is reversed. + * This class helps you solve this incompatability. + *
+ * Origin of code: Excalibur + * + * @author Peter Donald + * @version $Id: EndianUtils.java 539632 2007-05-18 23:37:59Z bayard $ + * @see org.apache.commons.io.input.SwappedDataInputStream + */ +public class EndianUtils { + + /** + * Instances should NOT be constructed in standard programming. + */ + public EndianUtils() { + super(); + } + + // ========================================== Swapping routines + + /** + * Converts a "short" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static short swapShort(short value) { + return (short) ( ( ( ( value >> 0 ) & 0xff ) << 8 ) + + ( ( ( value >> 8 ) & 0xff ) << 0 ) ); + } + + /** + * Converts a "int" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static int swapInteger(int value) { + return + ( ( ( value >> 0 ) & 0xff ) << 24 ) + + ( ( ( value >> 8 ) & 0xff ) << 16 ) + + ( ( ( value >> 16 ) & 0xff ) << 8 ) + + ( ( ( value >> 24 ) & 0xff ) << 0 ); + } + + /** + * Converts a "long" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static long swapLong(long value) { + return + ( ( ( value >> 0 ) & 0xff ) << 56 ) + + ( ( ( value >> 8 ) & 0xff ) << 48 ) + + ( ( ( value >> 16 ) & 0xff ) << 40 ) + + ( ( ( value >> 24 ) & 0xff ) << 32 ) + + ( ( ( value >> 32 ) & 0xff ) << 24 ) + + ( ( ( value >> 40 ) & 0xff ) << 16 ) + + ( ( ( value >> 48 ) & 0xff ) << 8 ) + + ( ( ( value >> 56 ) & 0xff ) << 0 ); + } + + /** + * Converts a "float" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static float swapFloat(float value) { + return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) ); + } + + /** + * Converts a "double" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static double swapDouble(double value) { + return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) ); + } + + // ========================================== Swapping read/write routines + + /** + * Writes a "short" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedShort(byte[] data, int offset, short value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + } + + /** + * Reads a "short" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static short readSwappedShort(byte[] data, int offset) { + return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); + } + + /** + * Reads an unsigned short (16-bit) value from a byte array at a given + * offset. The value is converted to the opposed endian system while + * reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static int readSwappedUnsignedShort(byte[] data, int offset) { + return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); + } + + /** + * Writes a "int" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedInteger(byte[] data, int offset, int value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); + data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); + } + + /** + * Reads a "int" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static int readSwappedInteger(byte[] data, int offset) { + return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) + + ( ( data[ offset + 3 ] & 0xff ) << 24 ) ); + } + + /** + * Reads an unsigned integer (32-bit) value from a byte array at a given + * offset. The value is converted to the opposed endian system while + * reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static long readSwappedUnsignedInteger(byte[] data, int offset) { + long low = ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) ); + + long high = data[ offset + 3 ] & 0xff; + + return (high << 24) + (0xffffffffL & low); + } + + /** + * Writes a "long" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedLong(byte[] data, int offset, long value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); + data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); + data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff ); + data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff ); + data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff ); + data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff ); + } + + /** + * Reads a "long" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static long readSwappedLong(byte[] data, int offset) { + long low = + ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) + + ( ( data[ offset + 3 ] & 0xff ) << 24 ); + long high = + ( ( data[ offset + 4 ] & 0xff ) << 0 ) + + ( ( data[ offset + 5 ] & 0xff ) << 8 ) + + ( ( data[ offset + 6 ] & 0xff ) << 16 ) + + ( ( data[ offset + 7 ] & 0xff ) << 24 ); + return (high << 32) + (0xffffffffL & low); + } + + /** + * Writes a "float" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedFloat(byte[] data, int offset, float value) { + writeSwappedInteger( data, offset, Float.floatToIntBits( value ) ); + } + + /** + * Reads a "float" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static float readSwappedFloat(byte[] data, int offset) { + return Float.intBitsToFloat( readSwappedInteger( data, offset ) ); + } + + /** + * Writes a "double" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedDouble(byte[] data, int offset, double value) { + writeSwappedLong( data, offset, Double.doubleToLongBits( value ) ); + } + + /** + * Reads a "double" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static double readSwappedDouble(byte[] data, int offset) { + return Double.longBitsToDouble( readSwappedLong( data, offset ) ); + } + + /** + * Writes a "short" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedShort(OutputStream output, short value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + } + + /** + * Reads a "short" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static short readSwappedShort(InputStream input) + throws IOException + { + return (short)( ( ( read( input ) & 0xff ) << 0 ) + + ( ( read( input ) & 0xff ) << 8 ) ); + } + + /** + * Reads a unsigned short (16-bit) from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static int readSwappedUnsignedShort(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + + return ( ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) ); + } + + /** + * Writes a "int" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedInteger(OutputStream output, int value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + output.write( (byte)( ( value >> 16 ) & 0xff ) ); + output.write( (byte)( ( value >> 24 ) & 0xff ) ); + } + + /** + * Reads a "int" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static int readSwappedInteger(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + int value3 = read( input ); + int value4 = read( input ); + + return ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) + + ( ( value3 & 0xff ) << 16 ) + + ( ( value4 & 0xff ) << 24 ); + } + + /** + * Reads a unsigned integer (32-bit) from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static long readSwappedUnsignedInteger(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + int value3 = read( input ); + int value4 = read( input ); + + long low = ( ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) + + ( ( value3 & 0xff ) << 16 ) ); + + long high = value4 & 0xff; + + return (high << 24) + (0xffffffffL & low); + } + + /** + * Writes a "long" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedLong(OutputStream output, long value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + output.write( (byte)( ( value >> 16 ) & 0xff ) ); + output.write( (byte)( ( value >> 24 ) & 0xff ) ); + output.write( (byte)( ( value >> 32 ) & 0xff ) ); + output.write( (byte)( ( value >> 40 ) & 0xff ) ); + output.write( (byte)( ( value >> 48 ) & 0xff ) ); + output.write( (byte)( ( value >> 56 ) & 0xff ) ); + } + + /** + * Reads a "long" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static long readSwappedLong(InputStream input) + throws IOException + { + byte[] bytes = new byte[8]; + for ( int i=0; i<8; i++ ) { + bytes[i] = (byte) read( input ); + } + return readSwappedLong( bytes, 0 ); + } + + /** + * Writes a "float" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedFloat(OutputStream output, float value) + throws IOException + { + writeSwappedInteger( output, Float.floatToIntBits( value ) ); + } + + /** + * Reads a "float" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static float readSwappedFloat(InputStream input) + throws IOException + { + return Float.intBitsToFloat( readSwappedInteger( input ) ); + } + + /** + * Writes a "double" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedDouble(OutputStream output, double value) + throws IOException + { + writeSwappedLong( output, Double.doubleToLongBits( value ) ); + } + + /** + * Reads a "double" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static double readSwappedDouble(InputStream input) + throws IOException + { + return Double.longBitsToDouble( readSwappedLong( input ) ); + } + + /** + * Reads the next byte from the input stream. + * @param input the stream + * @return the byte + * @throws IOException if the end of file is reached + */ + private static int read(InputStream input) + throws IOException + { + int value = input.read(); + + if( -1 == value ) { + throw new EOFException( "Unexpected EOF reached" ); + } + + return value; + } +} diff --git a/src/org/apache/commons/io/FileCleaner.java b/src/org/apache/commons/io/FileCleaner.java index 59c2f410947e9f4674dfe2ba41102974dd86b417..ead4f8fad910ff910f914eacc098e082ca205193 100644 --- a/src/org/apache/commons/io/FileCleaner.java +++ b/src/org/apache/commons/io/FileCleaner.java @@ -1,154 +1,154 @@ -/* - * 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.commons.io; - -import java.io.File; - -/** - * Keeps track of files awaiting deletion, and deletes them when an associated - * marker object is reclaimed by the garbage collector. - *
- * This utility creates a background thread to handle file deletion. - * Each file to be deleted is registered with a handler object. - * When the handler object is garbage collected, the file is deleted. - *
- * In an environment with multiple class loaders (a servlet container, for - * example), you should consider stopping the background thread if it is no - * longer needed. This is done by invoking the method - * {@link #exitWhenFinished}, typically in - * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar. - * - * @author Noel Bergman - * @author Martin Cooper - * @version $Id: FileCleaner.java 553012 2007-07-03 23:01:07Z ggregory $ - * @deprecated Use {@link FileCleaningTracker} - */ -public class FileCleaner { - /** - * The instance to use for the deprecated, static methods. - */ - static final FileCleaningTracker theInstance = new FileCleaningTracker(); - - //----------------------------------------------------------------------- - /** - * Track the specified file, using the provided marker, deleting the file - * when the marker instance is garbage collected. - * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. - * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the file is null - * @deprecated Use {@link FileCleaningTracker#track(File, Object)}. - */ - public static void track(File file, Object marker) { - theInstance.track(file, marker); - } - - /** - * Track the specified file, using the provided marker, deleting the file - * when the marker instance is garbage collected. - * The speified deletion strategy is used. - * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the file is null - * @deprecated Use {@link FileCleaningTracker#track(File, Object, FileDeleteStrategy)}. - */ - public static void track(File file, Object marker, FileDeleteStrategy deleteStrategy) { - theInstance.track(file, marker, deleteStrategy); - } - - /** - * Track the specified file, using the provided marker, deleting the file - * when the marker instance is garbage collected. - * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. - * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the path is null - * @deprecated Use {@link FileCleaningTracker#track(String, Object)}. - */ - public static void track(String path, Object marker) { - theInstance.track(path, marker); - } - - /** - * Track the specified file, using the provided marker, deleting the file - * when the marker instance is garbage collected. - * The speified deletion strategy is used. - * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the path is null - * @deprecated Use {@link FileCleaningTracker#track(String, Object, FileDeleteStrategy)}. - */ - public static void track(String path, Object marker, FileDeleteStrategy deleteStrategy) { - theInstance.track(path, marker, deleteStrategy); - } - - //----------------------------------------------------------------------- - /** - * Retrieve the number of files currently being tracked, and therefore - * awaiting deletion. - * - * @return the number of files being tracked - * @deprecated Use {@link FileCleaningTracker#getTrackCount()}. - */ - public static int getTrackCount() { - return theInstance.getTrackCount(); - } - - /** - * Call this method to cause the file cleaner thread to terminate when - * there are no more objects being tracked for deletion. - *
- * In a simple environment, you don't need this method as the file cleaner - * thread will simply exit when the JVM exits. In a more complex environment, - * with multiple class loaders (such as an application server), you should be - * aware that the file cleaner thread will continue running even if the class - * loader it was started from terminates. This can consitute a memory leak. - *
- * For example, suppose that you have developed a web application, which - * contains the commons-io jar file in your WEB-INF/lib directory. In other - * words, the FileCleaner class is loaded through the class loader of your - * web application. If the web application is terminated, but the servlet - * container is still running, then the file cleaner thread will still exist, - * posing a memory leak. - *
- * This method allows the thread to be terminated. Simply call this method - * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}. - * One called, no new objects can be tracked by the file cleaner. - * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}. - */ - public static synchronized void exitWhenFinished() { - theInstance.exitWhenFinished(); - } - - /** - * Returns the singleton instance, which is used by the deprecated, static methods. - * This is mainly useful for code, which wants to support the new - * {@link FileCleaningTracker} class while maintain compatibility with the - * deprecated {@link FileCleaner}. - * - * @return the singleton instance - */ - public static FileCleaningTracker getInstance() { - return theInstance; - } -} +/* + * 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.commons.io; + +import java.io.File; + +/** + * Keeps track of files awaiting deletion, and deletes them when an associated + * marker object is reclaimed by the garbage collector. + *
+ * This utility creates a background thread to handle file deletion. + * Each file to be deleted is registered with a handler object. + * When the handler object is garbage collected, the file is deleted. + *
+ * In an environment with multiple class loaders (a servlet container, for + * example), you should consider stopping the background thread if it is no + * longer needed. This is done by invoking the method + * {@link #exitWhenFinished}, typically in + * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar. + * + * @author Noel Bergman + * @author Martin Cooper + * @version $Id: FileCleaner.java 553012 2007-07-03 23:01:07Z ggregory $ + * @deprecated Use {@link FileCleaningTracker} + */ +public class FileCleaner { + /** + * The instance to use for the deprecated, static methods. + */ + static final FileCleaningTracker theInstance = new FileCleaningTracker(); + + //----------------------------------------------------------------------- + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the file is null + * @deprecated Use {@link FileCleaningTracker#track(File, Object)}. + */ + public static void track(File file, Object marker) { + theInstance.track(file, marker); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the file is null + * @deprecated Use {@link FileCleaningTracker#track(File, Object, FileDeleteStrategy)}. + */ + public static void track(File file, Object marker, FileDeleteStrategy deleteStrategy) { + theInstance.track(file, marker, deleteStrategy); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the path is null + * @deprecated Use {@link FileCleaningTracker#track(String, Object)}. + */ + public static void track(String path, Object marker) { + theInstance.track(path, marker); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the path is null + * @deprecated Use {@link FileCleaningTracker#track(String, Object, FileDeleteStrategy)}. + */ + public static void track(String path, Object marker, FileDeleteStrategy deleteStrategy) { + theInstance.track(path, marker, deleteStrategy); + } + + //----------------------------------------------------------------------- + /** + * Retrieve the number of files currently being tracked, and therefore + * awaiting deletion. + * + * @return the number of files being tracked + * @deprecated Use {@link FileCleaningTracker#getTrackCount()}. + */ + public static int getTrackCount() { + return theInstance.getTrackCount(); + } + + /** + * Call this method to cause the file cleaner thread to terminate when + * there are no more objects being tracked for deletion. + *
+ * In a simple environment, you don't need this method as the file cleaner + * thread will simply exit when the JVM exits. In a more complex environment, + * with multiple class loaders (such as an application server), you should be + * aware that the file cleaner thread will continue running even if the class + * loader it was started from terminates. This can consitute a memory leak. + *
+ * For example, suppose that you have developed a web application, which + * contains the commons-io jar file in your WEB-INF/lib directory. In other + * words, the FileCleaner class is loaded through the class loader of your + * web application. If the web application is terminated, but the servlet + * container is still running, then the file cleaner thread will still exist, + * posing a memory leak. + *
+ * This method allows the thread to be terminated. Simply call this method + * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}. + * One called, no new objects can be tracked by the file cleaner. + * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}. + */ + public static synchronized void exitWhenFinished() { + theInstance.exitWhenFinished(); + } + + /** + * Returns the singleton instance, which is used by the deprecated, static methods. + * This is mainly useful for code, which wants to support the new + * {@link FileCleaningTracker} class while maintain compatibility with the + * deprecated {@link FileCleaner}. + * + * @return the singleton instance + */ + public static FileCleaningTracker getInstance() { + return theInstance; + } +} diff --git a/src/org/apache/commons/io/FileCleaningTracker.java b/src/org/apache/commons/io/FileCleaningTracker.java index ea976d60a712044ddd71196fb8e9779b7494182c..7f4a8ee87953c45138ad6f96c7363aa57fc529a5 100644 --- a/src/org/apache/commons/io/FileCleaningTracker.java +++ b/src/org/apache/commons/io/FileCleaningTracker.java @@ -1,258 +1,258 @@ -/* - * 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.commons.io; - -import java.io.File; -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; -import java.util.Collection; -import java.util.Vector; - -/** - * Keeps track of files awaiting deletion, and deletes them when an associated - * marker object is reclaimed by the garbage collector. - *
- * This utility creates a background thread to handle file deletion. - * Each file to be deleted is registered with a handler object. - * When the handler object is garbage collected, the file is deleted. - *
- * In an environment with multiple class loaders (a servlet container, for
- * example), you should consider stopping the background thread if it is no
- * longer needed. This is done by invoking the method
- * {@link #exitWhenFinished}, typically in
- * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar.
- *
- * @author Noel Bergman
- * @author Martin Cooper
- * @version $Id: FileCleaner.java 490987 2006-12-29 12:11:48Z scolebourne $
- */
-public class FileCleaningTracker {
- /**
- * Queue of Tracker
instances being watched.
- */
- ReferenceQueue /* Tracker */ q = new ReferenceQueue();
- /**
- * Collection of Tracker
instances in existence.
- */
- final Collection /* Tracker */ trackers = new Vector(); // synchronized
- /**
- * Whether to terminate the thread when the tracking is complete.
- */
- volatile boolean exitWhenFinished = false;
- /**
- * The thread that will clean up registered files.
- */
- Thread reaper;
-
- //-----------------------------------------------------------------------
- /**
- * Track the specified file, using the provided marker, deleting the file
- * when the marker instance is garbage collected.
- * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
- *
- * @param file the file to be tracked, not null
- * @param marker the marker object used to track the file, not null
- * @throws NullPointerException if the file is null
- */
- public void track(File file, Object marker) {
- track(file, marker, (FileDeleteStrategy) null);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * when the marker instance is garbage collected.
- * The speified deletion strategy is used.
- *
- * @param file the file to be tracked, not null
- * @param marker the marker object used to track the file, not null
- * @param deleteStrategy the strategy to delete the file, null means normal
- * @throws NullPointerException if the file is null
- */
- public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) {
- if (file == null) {
- throw new NullPointerException("The file must not be null");
- }
- addTracker(file.getPath(), marker, deleteStrategy);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * when the marker instance is garbage collected.
- * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
- *
- * @param path the full path to the file to be tracked, not null
- * @param marker the marker object used to track the file, not null
- * @throws NullPointerException if the path is null
- */
- public void track(String path, Object marker) {
- track(path, marker, (FileDeleteStrategy) null);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * when the marker instance is garbage collected.
- * The speified deletion strategy is used.
- *
- * @param path the full path to the file to be tracked, not null
- * @param marker the marker object used to track the file, not null
- * @param deleteStrategy the strategy to delete the file, null means normal
- * @throws NullPointerException if the path is null
- */
- public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {
- if (path == null) {
- throw new NullPointerException("The path must not be null");
- }
- addTracker(path, marker, deleteStrategy);
- }
-
- /**
- * Adds a tracker to the list of trackers.
- *
- * @param path the full path to the file to be tracked, not null
- * @param marker the marker object used to track the file, not null
- * @param deleteStrategy the strategy to delete the file, null means normal
- */
- private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) {
- // synchronized block protects reaper
- if (exitWhenFinished) {
- throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called");
- }
- if (reaper == null) {
- reaper = new Reaper();
- reaper.start();
- }
- trackers.add(new Tracker(path, deleteStrategy, marker, q));
- }
-
- //-----------------------------------------------------------------------
- /**
- * Retrieve the number of files currently being tracked, and therefore
- * awaiting deletion.
- *
- * @return the number of files being tracked
- */
- public int getTrackCount() {
- return trackers.size();
- }
-
- /**
- * Call this method to cause the file cleaner thread to terminate when
- * there are no more objects being tracked for deletion.
- *
- * In a simple environment, you don't need this method as the file cleaner - * thread will simply exit when the JVM exits. In a more complex environment, - * with multiple class loaders (such as an application server), you should be - * aware that the file cleaner thread will continue running even if the class - * loader it was started from terminates. This can consitute a memory leak. - *
- * For example, suppose that you have developed a web application, which - * contains the commons-io jar file in your WEB-INF/lib directory. In other - * words, the FileCleaner class is loaded through the class loader of your - * web application. If the web application is terminated, but the servlet - * container is still running, then the file cleaner thread will still exist, - * posing a memory leak. - *
- * This method allows the thread to be terminated. Simply call this method
- * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}.
- * One called, no new objects can be tracked by the file cleaner.
- */
- public synchronized void exitWhenFinished() {
- // synchronized block protects reaper
- exitWhenFinished = true;
- if (reaper != null) {
- synchronized (reaper) {
- reaper.interrupt();
- }
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * The reaper thread.
- */
- private final class Reaper extends Thread {
- /** Construct a new Reaper */
- Reaper() {
- super("File Reaper");
- setPriority(Thread.MAX_PRIORITY);
- setDaemon(true);
- }
-
- /**
- * Run the reaper thread that will delete files as their associated
- * marker objects are reclaimed by the garbage collector.
- */
- public void run() {
- // thread exits when exitWhenFinished is true and there are no more tracked objects
- while (exitWhenFinished == false || trackers.size() > 0) {
- Tracker tracker = null;
- try {
- // Wait for a tracker to remove.
- tracker = (Tracker) q.remove();
- } catch (Exception e) {
- continue;
- }
- if (tracker != null) {
- tracker.delete();
- tracker.clear();
- trackers.remove(tracker);
- }
- }
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Inner class which acts as the reference for a file pending deletion.
- */
- private static final class Tracker extends PhantomReference {
-
- /**
- * The full path to the file being tracked.
- */
- private final String path;
- /**
- * The strategy for deleting files.
- */
- private final FileDeleteStrategy deleteStrategy;
-
- /**
- * Constructs an instance of this class from the supplied parameters.
- *
- * @param path the full path to the file to be tracked, not null
- * @param deleteStrategy the strategy to delete the file, null means normal
- * @param marker the marker object used to track the file, not null
- * @param queue the queue on to which the tracker will be pushed, not null
- */
- Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue queue) {
- super(marker, queue);
- this.path = path;
- this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy);
- }
-
- /**
- * Deletes the file associated with this tracker instance.
- *
- * @return true
if the file was deleted successfully;
- * false
otherwise.
- */
- public boolean delete() {
- return deleteStrategy.deleteQuietly(new File(path));
- }
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.File;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Collection;
+import java.util.Vector;
+
+/**
+ * Keeps track of files awaiting deletion, and deletes them when an associated
+ * marker object is reclaimed by the garbage collector.
+ *
+ * This utility creates a background thread to handle file deletion. + * Each file to be deleted is registered with a handler object. + * When the handler object is garbage collected, the file is deleted. + *
+ * In an environment with multiple class loaders (a servlet container, for
+ * example), you should consider stopping the background thread if it is no
+ * longer needed. This is done by invoking the method
+ * {@link #exitWhenFinished}, typically in
+ * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar.
+ *
+ * @author Noel Bergman
+ * @author Martin Cooper
+ * @version $Id: FileCleaner.java 490987 2006-12-29 12:11:48Z scolebourne $
+ */
+public class FileCleaningTracker {
+ /**
+ * Queue of Tracker
instances being watched.
+ */
+ ReferenceQueue /* Tracker */ q = new ReferenceQueue();
+ /**
+ * Collection of Tracker
instances in existence.
+ */
+ final Collection /* Tracker */ trackers = new Vector(); // synchronized
+ /**
+ * Whether to terminate the thread when the tracking is complete.
+ */
+ volatile boolean exitWhenFinished = false;
+ /**
+ * The thread that will clean up registered files.
+ */
+ Thread reaper;
+
+ //-----------------------------------------------------------------------
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * when the marker instance is garbage collected.
+ * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
+ *
+ * @param file the file to be tracked, not null
+ * @param marker the marker object used to track the file, not null
+ * @throws NullPointerException if the file is null
+ */
+ public void track(File file, Object marker) {
+ track(file, marker, (FileDeleteStrategy) null);
+ }
+
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * when the marker instance is garbage collected.
+ * The speified deletion strategy is used.
+ *
+ * @param file the file to be tracked, not null
+ * @param marker the marker object used to track the file, not null
+ * @param deleteStrategy the strategy to delete the file, null means normal
+ * @throws NullPointerException if the file is null
+ */
+ public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) {
+ if (file == null) {
+ throw new NullPointerException("The file must not be null");
+ }
+ addTracker(file.getPath(), marker, deleteStrategy);
+ }
+
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * when the marker instance is garbage collected.
+ * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
+ *
+ * @param path the full path to the file to be tracked, not null
+ * @param marker the marker object used to track the file, not null
+ * @throws NullPointerException if the path is null
+ */
+ public void track(String path, Object marker) {
+ track(path, marker, (FileDeleteStrategy) null);
+ }
+
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * when the marker instance is garbage collected.
+ * The speified deletion strategy is used.
+ *
+ * @param path the full path to the file to be tracked, not null
+ * @param marker the marker object used to track the file, not null
+ * @param deleteStrategy the strategy to delete the file, null means normal
+ * @throws NullPointerException if the path is null
+ */
+ public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {
+ if (path == null) {
+ throw new NullPointerException("The path must not be null");
+ }
+ addTracker(path, marker, deleteStrategy);
+ }
+
+ /**
+ * Adds a tracker to the list of trackers.
+ *
+ * @param path the full path to the file to be tracked, not null
+ * @param marker the marker object used to track the file, not null
+ * @param deleteStrategy the strategy to delete the file, null means normal
+ */
+ private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) {
+ // synchronized block protects reaper
+ if (exitWhenFinished) {
+ throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called");
+ }
+ if (reaper == null) {
+ reaper = new Reaper();
+ reaper.start();
+ }
+ trackers.add(new Tracker(path, deleteStrategy, marker, q));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Retrieve the number of files currently being tracked, and therefore
+ * awaiting deletion.
+ *
+ * @return the number of files being tracked
+ */
+ public int getTrackCount() {
+ return trackers.size();
+ }
+
+ /**
+ * Call this method to cause the file cleaner thread to terminate when
+ * there are no more objects being tracked for deletion.
+ *
+ * In a simple environment, you don't need this method as the file cleaner + * thread will simply exit when the JVM exits. In a more complex environment, + * with multiple class loaders (such as an application server), you should be + * aware that the file cleaner thread will continue running even if the class + * loader it was started from terminates. This can consitute a memory leak. + *
+ * For example, suppose that you have developed a web application, which + * contains the commons-io jar file in your WEB-INF/lib directory. In other + * words, the FileCleaner class is loaded through the class loader of your + * web application. If the web application is terminated, but the servlet + * container is still running, then the file cleaner thread will still exist, + * posing a memory leak. + *
+ * This method allows the thread to be terminated. Simply call this method
+ * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}.
+ * One called, no new objects can be tracked by the file cleaner.
+ */
+ public synchronized void exitWhenFinished() {
+ // synchronized block protects reaper
+ exitWhenFinished = true;
+ if (reaper != null) {
+ synchronized (reaper) {
+ reaper.interrupt();
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * The reaper thread.
+ */
+ private final class Reaper extends Thread {
+ /** Construct a new Reaper */
+ Reaper() {
+ super("File Reaper");
+ setPriority(Thread.MAX_PRIORITY);
+ setDaemon(true);
+ }
+
+ /**
+ * Run the reaper thread that will delete files as their associated
+ * marker objects are reclaimed by the garbage collector.
+ */
+ public void run() {
+ // thread exits when exitWhenFinished is true and there are no more tracked objects
+ while (exitWhenFinished == false || trackers.size() > 0) {
+ Tracker tracker = null;
+ try {
+ // Wait for a tracker to remove.
+ tracker = (Tracker) q.remove();
+ } catch (Exception e) {
+ continue;
+ }
+ if (tracker != null) {
+ tracker.delete();
+ tracker.clear();
+ trackers.remove(tracker);
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Inner class which acts as the reference for a file pending deletion.
+ */
+ private static final class Tracker extends PhantomReference {
+
+ /**
+ * The full path to the file being tracked.
+ */
+ private final String path;
+ /**
+ * The strategy for deleting files.
+ */
+ private final FileDeleteStrategy deleteStrategy;
+
+ /**
+ * Constructs an instance of this class from the supplied parameters.
+ *
+ * @param path the full path to the file to be tracked, not null
+ * @param deleteStrategy the strategy to delete the file, null means normal
+ * @param marker the marker object used to track the file, not null
+ * @param queue the queue on to which the tracker will be pushed, not null
+ */
+ Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue queue) {
+ super(marker, queue);
+ this.path = path;
+ this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy);
+ }
+
+ /**
+ * Deletes the file associated with this tracker instance.
+ *
+ * @return true
if the file was deleted successfully;
+ * false
otherwise.
+ */
+ public boolean delete() {
+ return deleteStrategy.deleteQuietly(new File(path));
+ }
+ }
+
+}
diff --git a/src/org/apache/commons/io/FileDeleteStrategy.java b/src/org/apache/commons/io/FileDeleteStrategy.java
index 8b6b4b9aad5caa6e6998426528c60018f767ca7b..3518df190e8091f94ce229271d5b1f53f7a994fe 100644
--- a/src/org/apache/commons/io/FileDeleteStrategy.java
+++ b/src/org/apache/commons/io/FileDeleteStrategy.java
@@ -1,156 +1,156 @@
-/*
- * 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.commons.io;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Strategy for deleting files.
- *
- * There is more than one way to delete a file. - * You may want to limit access to certain directories, to only delete - * directories if they are empty, or maybe to force deletion. - *
- * This class captures the strategy to use and is designed for user subclassing.
- *
- * @author Stephen Colebourne
- * @version $Id: FileDeleteStrategy.java 453903 2006-10-07 13:47:06Z scolebourne $
- * @since Commons IO 1.3
- */
-public class FileDeleteStrategy {
-
- /**
- * The singleton instance for normal file deletion, which does not permit
- * the deletion of directories that are not empty.
- */
- public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal");
- /**
- * The singleton instance for forced file deletion, which always deletes,
- * even if the file represents a non-empty directory.
- */
- public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy();
-
- /** The name of the strategy. */
- private final String name;
-
- //-----------------------------------------------------------------------
- /**
- * Restricted constructor.
- *
- * @param name the name by which the strategy is known
- */
- protected FileDeleteStrategy(String name) {
- this.name = name;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Deletes the file object, which may be a file or a directory.
- * All IOException
s are caught and false returned instead.
- * If the file does not exist or is null, true is returned.
- *
- * Subclass writers should override {@link #doDelete(File)}, not this method. - * - * @param fileToDelete the file to delete, null returns true - * @return true if the file was deleted, or there was no such file - */ - public boolean deleteQuietly(File fileToDelete) { - if (fileToDelete == null || fileToDelete.exists() == false) { - return true; - } - try { - return doDelete(fileToDelete); - } catch (IOException ex) { - return false; - } - } - - /** - * Deletes the file object, which may be a file or a directory. - * If the file does not exist, the method just returns. - *
- * Subclass writers should override {@link #doDelete(File)}, not this method. - * - * @param fileToDelete the file to delete, not null - * @throws NullPointerException if the file is null - * @throws IOException if an error occurs during file deletion - */ - public void delete(File fileToDelete) throws IOException { - if (fileToDelete.exists() && doDelete(fileToDelete) == false) { - throw new IOException("Deletion failed: " + fileToDelete); - } - } - - /** - * Actually deletes the file object, which may be a file or a directory. - *
- * This method is designed for subclasses to override.
- * The implementation may return either false or an IOException
- * when deletion fails. The {@link #delete(File)} and {@link #deleteQuietly(File)}
- * methods will handle either response appropriately.
- * A check has been made to ensure that the file will exist.
- *
- * This implementation uses {@link File#delete()}. - * - * @param fileToDelete the file to delete, exists, not null - * @return true if the file was deleteds - * @throws NullPointerException if the file is null - * @throws IOException if an error occurs during file deletion - */ - protected boolean doDelete(File fileToDelete) throws IOException { - return fileToDelete.delete(); - } - - //----------------------------------------------------------------------- - /** - * Gets a string describing the delete strategy. - * - * @return a string describing the delete strategy - */ - public String toString() { - return "FileDeleteStrategy[" + name + "]"; - } - - //----------------------------------------------------------------------- - /** - * Force file deletion strategy. - */ - static class ForceFileDeleteStrategy extends FileDeleteStrategy { - /** Default Constructor */ - ForceFileDeleteStrategy() { - super("Force"); - } - - /** - * Deletes the file object. - *
- * This implementation uses
+ * There is more than one way to delete a file.
+ * You may want to limit access to certain directories, to only delete
+ * directories if they are empty, or maybe to force deletion.
+ *
+ * This class captures the strategy to use and is designed for user subclassing.
+ *
+ * @author Stephen Colebourne
+ * @version $Id: FileDeleteStrategy.java 453903 2006-10-07 13:47:06Z scolebourne $
+ * @since Commons IO 1.3
+ */
+public class FileDeleteStrategy {
+
+ /**
+ * The singleton instance for normal file deletion, which does not permit
+ * the deletion of directories that are not empty.
+ */
+ public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal");
+ /**
+ * The singleton instance for forced file deletion, which always deletes,
+ * even if the file represents a non-empty directory.
+ */
+ public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy();
+
+ /** The name of the strategy. */
+ private final String name;
+
+ //-----------------------------------------------------------------------
+ /**
+ * Restricted constructor.
+ *
+ * @param name the name by which the strategy is known
+ */
+ protected FileDeleteStrategy(String name) {
+ this.name = name;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Deletes the file object, which may be a file or a directory.
+ * All
+ * Subclass writers should override {@link #doDelete(File)}, not this method.
+ *
+ * @param fileToDelete the file to delete, null returns true
+ * @return true if the file was deleted, or there was no such file
+ */
+ public boolean deleteQuietly(File fileToDelete) {
+ if (fileToDelete == null || fileToDelete.exists() == false) {
+ return true;
+ }
+ try {
+ return doDelete(fileToDelete);
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Deletes the file object, which may be a file or a directory.
+ * If the file does not exist, the method just returns.
+ *
+ * Subclass writers should override {@link #doDelete(File)}, not this method.
+ *
+ * @param fileToDelete the file to delete, not null
+ * @throws NullPointerException if the file is null
+ * @throws IOException if an error occurs during file deletion
+ */
+ public void delete(File fileToDelete) throws IOException {
+ if (fileToDelete.exists() && doDelete(fileToDelete) == false) {
+ throw new IOException("Deletion failed: " + fileToDelete);
+ }
+ }
+
+ /**
+ * Actually deletes the file object, which may be a file or a directory.
+ *
+ * This method is designed for subclasses to override.
+ * The implementation may return either false or an
+ * This implementation uses {@link File#delete()}.
+ *
+ * @param fileToDelete the file to delete, exists, not null
+ * @return true if the file was deleteds
+ * @throws NullPointerException if the file is null
+ * @throws IOException if an error occurs during file deletion
+ */
+ protected boolean doDelete(File fileToDelete) throws IOException {
+ return fileToDelete.delete();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a string describing the delete strategy.
+ *
+ * @return a string describing the delete strategy
+ */
+ public String toString() {
+ return "FileDeleteStrategy[" + name + "]";
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Force file deletion strategy.
+ */
+ static class ForceFileDeleteStrategy extends FileDeleteStrategy {
+ /** Default Constructor */
+ ForceFileDeleteStrategy() {
+ super("Force");
+ }
+
+ /**
+ * Deletes the file object.
+ *
+ * This implementation uses
- * This class provides static utility methods for general file system
- * functions not provided via the JDK {@link java.io.File File} class.
- *
- * The current functions provided are:
- *
- * Note that some OS's are NOT currently supported, including OS/390,
- * OpenVMS and and SunOS 5. (SunOS is supported by
- * In order to work, you must be running Windows, or have a implementation of
- * Unix df that supports GNU format when passed -k (or -kP). If you are going
- * to rely on this code, please check that it works on your OS by running
- * some simple tests to compare the command line with the output from this class.
- * If your operating system isn't supported, please raise a JIRA call detailing
- * the exact result from df -k and as much other detail as possible, thanks.
- *
- * @param path the path to get free space for, not null, not empty on Unix
- * @return the amount of free drive space on the drive or volume in kilobytes
- * @throws IllegalArgumentException if the path is invalid
- * @throws IllegalStateException if an error occurred in initialisation
- * @throws IOException if an error occurs when finding the free space
- * @since Commons IO 1.2, enhanced OS support in 1.3
- */
- public static long freeSpaceKb(String path) throws IOException {
- return INSTANCE.freeSpaceOS(path, OS, true);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns the free space on a drive or volume in a cross-platform manner.
- * Note that some OS's are NOT currently supported, including OS/390.
- *
+ * This class provides static utility methods for general file system
+ * functions not provided via the JDK {@link java.io.File File} class.
+ *
+ * The current functions provided are:
+ *
+ * Note that some OS's are NOT currently supported, including OS/390,
+ * OpenVMS and and SunOS 5. (SunOS is supported by
+ * In order to work, you must be running Windows, or have a implementation of
+ * Unix df that supports GNU format when passed -k (or -kP). If you are going
+ * to rely on this code, please check that it works on your OS by running
+ * some simple tests to compare the command line with the output from this class.
+ * If your operating system isn't supported, please raise a JIRA call detailing
+ * the exact result from df -k and as much other detail as possible, thanks.
+ *
+ * @param path the path to get free space for, not null, not empty on Unix
+ * @return the amount of free drive space on the drive or volume in kilobytes
+ * @throws IllegalArgumentException if the path is invalid
+ * @throws IllegalStateException if an error occurred in initialisation
+ * @throws IOException if an error occurs when finding the free space
+ * @since Commons IO 1.2, enhanced OS support in 1.3
+ */
+ public static long freeSpaceKb(String path) throws IOException {
+ return INSTANCE.freeSpaceOS(path, OS, true);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the free space on a drive or volume in a cross-platform manner.
+ * Note that some OS's are NOT currently supported, including OS/390.
+ *
- * Facilities are provided in the following areas:
- *
- * Origin of code: Excalibur, Alexandria, Commons-Utils
- *
- * @author Kevin A. Burton
- * @author Scott Sanders
- * @author Daniel Rall
- * @author Christoph.Reck
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @author Jeremias Maerki
- * @author Stephen Colebourne
- * @author Ian Springer
- * @author Chris Eldredge
- * @author Jim Harrington
- * @author Niall Pemberton
- * @author Sandy McArthur
- * @version $Id: FileUtils.java 610810 2008-01-10 15:04:49Z niallp $
- */
-public class FileUtils {
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public FileUtils() {
- super();
- }
-
- /**
- * The number of bytes in a kilobyte.
- */
- public static final long ONE_KB = 1024;
-
- /**
- * The number of bytes in a megabyte.
- */
- public static final long ONE_MB = ONE_KB * ONE_KB;
-
- /**
- * The number of bytes in a gigabyte.
- */
- public static final long ONE_GB = ONE_KB * ONE_MB;
-
- /**
- * An empty array of type
- * At the end of the method either the stream will be successfully opened,
- * or an exception will have been thrown.
- *
- * An exception is thrown if the file does not exist.
- * An exception is thrown if the file object exists but is a directory.
- * An exception is thrown if the file exists but cannot be read.
- *
- * @param file the file to open for input, must not be
- * At the end of the method either the stream will be successfully opened,
- * or an exception will have been thrown.
- *
- * The parent directory will be created if it does not exist.
- * The file will be created if it does not exist.
- * An exception is thrown if the file object exists but is a directory.
- * An exception is thrown if the file exists but cannot be written to.
- * An exception is thrown if the parent directory cannot be created.
- *
- * @param file the file to open for output, must not be
- * NOTE: As from v1.3, this method throws an IOException if the last
- * modified date of the file cannot be set. Also, as from v1.3 this method
- * creates parent directories if they do not exist.
- *
- * @param file the File to touch
- * @throws IOException If an I/O problem occurs
- */
- public static void touch(File file) throws IOException {
- if (!file.exists()) {
- OutputStream out = openOutputStream(file);
- IOUtils.closeQuietly(out);
- }
- boolean success = file.setLastModified(System.currentTimeMillis());
- if (!success) {
- throw new IOException("Unable to set the last modification time for " + file);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Converts a Collection containing java.io.File instanced into array
- * representation. This is to account for the difference between
- * File.listFiles() and FileUtils.listFiles().
- *
- * @param files a Collection containing java.io.File instances
- * @return an array of java.io.File
- */
- public static File[] convertFileCollectionToFileArray(Collection files) {
- return (File[]) files.toArray(new File[files.size()]);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Finds files within a given directory (and optionally its
- * subdirectories). All files found are filtered by an IOFileFilter.
- *
- * @param files the collection of files found.
- * @param directory the directory to search in.
- * @param filter the filter to apply to files and directories.
- */
- private static void innerListFiles(Collection files, File directory,
- IOFileFilter filter) {
- File[] found = directory.listFiles((FileFilter) filter);
- if (found != null) {
- for (int i = 0; i < found.length; i++) {
- if (found[i].isDirectory()) {
- innerListFiles(files, found[i], filter);
- } else {
- files.add(found[i]);
- }
- }
- }
- }
-
- /**
- * Finds files within a given directory (and optionally its
- * subdirectories). All files found are filtered by an IOFileFilter.
- *
- * If your search should recurse into subdirectories you can pass in
- * an IOFileFilter for directories. You don't need to bind a
- * DirectoryFileFilter (via logical AND) to this filter. This method does
- * that for you.
- *
- * An example: If you want to search through all directories called
- * "temp" you pass in
- * Another common usage of this method is find files in a directory
- * tree but ignoring the directories generated CVS. You can simply pass
- * in
- * All files found are filtered by an IOFileFilter. This method is
- * based on {@link #listFiles(File, IOFileFilter, IOFileFilter)}.
- *
- * @param directory the directory to search in
- * @param fileFilter filter to apply when finding files.
- * @param dirFilter optional filter to apply when finding subdirectories.
- * If this parameter is
- * This method checks to see if the two files are different lengths
- * or if they point to the same file, before resorting to byte-by-byte
- * comparison of the contents.
- *
- * Code origin: Avalon
- *
- * @param file1 the first file
- * @param file2 the second file
- * @return true if the content of the files are equal or they both don't
- * exist, false otherwise
- * @throws IOException in case of an I/O error
- */
- public static boolean contentEquals(File file1, File file2) throws IOException {
- boolean file1Exists = file1.exists();
- if (file1Exists != file2.exists()) {
- return false;
- }
-
- if (!file1Exists) {
- // two not existing files are equal
- return true;
- }
-
- if (file1.isDirectory() || file2.isDirectory()) {
- // don't want to compare directory contents
- throw new IOException("Can't compare directories, only files");
- }
-
- if (file1.length() != file2.length()) {
- // lengths differ, cannot be equal
- return false;
- }
-
- if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {
- // same file
- return true;
- }
-
- InputStream input1 = null;
- InputStream input2 = null;
- try {
- input1 = new FileInputStream(file1);
- input2 = new FileInputStream(file2);
- return IOUtils.contentEquals(input1, input2);
-
- } finally {
- IOUtils.closeQuietly(input1);
- IOUtils.closeQuietly(input2);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Convert from a
- * From version 1.1 this method will decode the URL.
- * Syntax such as
- * Returns an array of the same size as the input.
- * If the input is
- * This method will decode the URL.
- * Syntax such as
- * Returns an array of the same size as the input.
- *
- * @param files the files to convert
- * @return an array of URLs matching the input
- * @throws IOException if a file cannot be converted
- */
- public static URL[] toURLs(File[] files) throws IOException {
- URL[] urls = new URL[files.length];
-
- for (int i = 0; i < urls.length; i++) {
- urls[i] = files[i].toURL();
- }
-
- return urls;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Copies a file to a directory preserving the file date.
- *
- * This method copies the contents of the specified source file
- * to a file of the same name in the specified destination directory.
- * The destination directory is created if it does not exist.
- * If the destination file exists, then this method will overwrite it.
- *
- * @param srcFile an existing file to copy, must not be
- * This method copies the contents of the specified source file
- * to a file of the same name in the specified destination directory.
- * The destination directory is created if it does not exist.
- * If the destination file exists, then this method will overwrite it.
- *
- * @param srcFile an existing file to copy, must not be
- * This method copies the contents of the specified source file to the
- * specified destination file. The directory holding the destination file is
- * created if it does not exist. If the destination file exists, then this
- * method will overwrite it.
- *
- * @param srcFile an existing file to copy, must not be
- * This method copies the contents of the specified source file
- * to the specified destination file.
- * The directory holding the destination file is created if it does not exist.
- * If the destination file exists, then this method will overwrite it.
- *
- * @param srcFile an existing file to copy, must not be
- * This method copies the source directory and all its contents to a
- * directory of the same name in the specified destination directory.
- *
- * The destination directory is created if it does not exist.
- * If the destination directory did exist, then this method merges
- * the source with the destination, with the source taking precedence.
- *
- * @param srcDir an existing directory to copy, must not be
- * This method copies the specified directory and all its child
- * directories and files to the specified destination.
- * The destination is the new location and name of the directory.
- *
- * The destination directory is created if it does not exist.
- * If the destination directory did exist, then this method merges
- * the source with the destination, with the source taking precedence.
- *
- * @param srcDir an existing directory to copy, must not be
- * This method copies the contents of the specified source directory
- * to within the specified destination directory.
- *
- * The destination directory is created if it does not exist.
- * If the destination directory did exist, then this method merges
- * the source with the destination, with the source taking precedence.
- *
- * @param srcDir an existing directory to copy, must not be
- * This method copies the contents of the specified source directory
- * to within the specified destination directory.
- *
- * The destination directory is created if it does not exist.
- * If the destination directory did exist, then this method merges
- * the source with the destination, with the source taking precedence.
- *
- *
- * This method copies the contents of the specified source directory
- * to within the specified destination directory.
- *
- * The destination directory is created if it does not exist.
- * If the destination directory did exist, then this method merges
- * the source with the destination, with the source taking precedence.
- *
- *
- * The difference between File.delete() and this method are:
- *
- * This method repeatedly tests {@link File#exists()} until it returns
- * true up to the maximum time specified in seconds.
- *
- * @param file the file to check, must not be
- * This method opens an
- * The recommended usage pattern is:
- *
- * If an exception occurs during the creation of the iterator, the
- * underlying stream is closed.
- *
- * @param file the file to open for input, must not be
- * NOTE: As from v1.3, the parent directories of the file will be created
- * if they do not exist.
- *
- * @param file the file to write to
- * @param data the content to write to the file
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.1
- */
- public static void writeByteArrayToFile(File file, byte[] data) throws IOException {
- OutputStream out = null;
- try {
- out = openOutputStream(file);
- out.write(data);
- } finally {
- IOUtils.closeQuietly(out);
- }
- }
-
- /**
- * Writes the
- * NOTE: As from v1.3, the parent directories of the file will be created
- * if they do not exist.
- *
- * @param file the file to write to
- * @param encoding the encoding to use,
- * NOTE: As from v1.3, the parent directories of the file will be created
- * if they do not exist.
- *
- * @param file the file to write to
- * @param encoding the encoding to use,
- * The difference between File.delete() and this method are:
- *
- * When the destination directory is on another file system, do a "copy and delete".
- *
- * @param srcDir the directory to be moved
- * @param destDir the destination directory
- * @throws NullPointerException if source or destination is
- * When the destination file is on another file system, do a "copy and delete".
- *
- * @param srcFile the file to be moved
- * @param destFile the destination file
- * @throws NullPointerException if source or destination is
- * When the destination is on another file system, do a "copy and delete".
- *
- * @param src the file or directory to be moved
- * @param destDir the destination directory
- * @param createDestDir If
+ * Facilities are provided in the following areas:
+ *
+ * Origin of code: Excalibur, Alexandria, Commons-Utils
+ *
+ * @author Kevin A. Burton
+ * @author Scott Sanders
+ * @author Daniel Rall
+ * @author Christoph.Reck
+ * @author Peter Donald
+ * @author Jeff Turner
+ * @author Matthew Hawthorne
+ * @author Jeremias Maerki
+ * @author Stephen Colebourne
+ * @author Ian Springer
+ * @author Chris Eldredge
+ * @author Jim Harrington
+ * @author Niall Pemberton
+ * @author Sandy McArthur
+ * @version $Id: FileUtils.java 610810 2008-01-10 15:04:49Z niallp $
+ */
+public class FileUtils {
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public FileUtils() {
+ super();
+ }
+
+ /**
+ * The number of bytes in a kilobyte.
+ */
+ public static final long ONE_KB = 1024;
+
+ /**
+ * The number of bytes in a megabyte.
+ */
+ public static final long ONE_MB = ONE_KB * ONE_KB;
+
+ /**
+ * The number of bytes in a gigabyte.
+ */
+ public static final long ONE_GB = ONE_KB * ONE_MB;
+
+ /**
+ * An empty array of type
+ * At the end of the method either the stream will be successfully opened,
+ * or an exception will have been thrown.
+ *
+ * An exception is thrown if the file does not exist.
+ * An exception is thrown if the file object exists but is a directory.
+ * An exception is thrown if the file exists but cannot be read.
+ *
+ * @param file the file to open for input, must not be
+ * At the end of the method either the stream will be successfully opened,
+ * or an exception will have been thrown.
+ *
+ * The parent directory will be created if it does not exist.
+ * The file will be created if it does not exist.
+ * An exception is thrown if the file object exists but is a directory.
+ * An exception is thrown if the file exists but cannot be written to.
+ * An exception is thrown if the parent directory cannot be created.
+ *
+ * @param file the file to open for output, must not be
+ * NOTE: As from v1.3, this method throws an IOException if the last
+ * modified date of the file cannot be set. Also, as from v1.3 this method
+ * creates parent directories if they do not exist.
+ *
+ * @param file the File to touch
+ * @throws IOException If an I/O problem occurs
+ */
+ public static void touch(File file) throws IOException {
+ if (!file.exists()) {
+ OutputStream out = openOutputStream(file);
+ IOUtils.closeQuietly(out);
+ }
+ boolean success = file.setLastModified(System.currentTimeMillis());
+ if (!success) {
+ throw new IOException("Unable to set the last modification time for " + file);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts a Collection containing java.io.File instanced into array
+ * representation. This is to account for the difference between
+ * File.listFiles() and FileUtils.listFiles().
+ *
+ * @param files a Collection containing java.io.File instances
+ * @return an array of java.io.File
+ */
+ public static File[] convertFileCollectionToFileArray(Collection files) {
+ return (File[]) files.toArray(new File[files.size()]);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Finds files within a given directory (and optionally its
+ * subdirectories). All files found are filtered by an IOFileFilter.
+ *
+ * @param files the collection of files found.
+ * @param directory the directory to search in.
+ * @param filter the filter to apply to files and directories.
+ */
+ private static void innerListFiles(Collection files, File directory,
+ IOFileFilter filter) {
+ File[] found = directory.listFiles((FileFilter) filter);
+ if (found != null) {
+ for (int i = 0; i < found.length; i++) {
+ if (found[i].isDirectory()) {
+ innerListFiles(files, found[i], filter);
+ } else {
+ files.add(found[i]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Finds files within a given directory (and optionally its
+ * subdirectories). All files found are filtered by an IOFileFilter.
+ *
+ * If your search should recurse into subdirectories you can pass in
+ * an IOFileFilter for directories. You don't need to bind a
+ * DirectoryFileFilter (via logical AND) to this filter. This method does
+ * that for you.
+ *
+ * An example: If you want to search through all directories called
+ * "temp" you pass in
+ * Another common usage of this method is find files in a directory
+ * tree but ignoring the directories generated CVS. You can simply pass
+ * in
+ * All files found are filtered by an IOFileFilter. This method is
+ * based on {@link #listFiles(File, IOFileFilter, IOFileFilter)}.
+ *
+ * @param directory the directory to search in
+ * @param fileFilter filter to apply when finding files.
+ * @param dirFilter optional filter to apply when finding subdirectories.
+ * If this parameter is
+ * This method checks to see if the two files are different lengths
+ * or if they point to the same file, before resorting to byte-by-byte
+ * comparison of the contents.
+ *
+ * Code origin: Avalon
+ *
+ * @param file1 the first file
+ * @param file2 the second file
+ * @return true if the content of the files are equal or they both don't
+ * exist, false otherwise
+ * @throws IOException in case of an I/O error
+ */
+ public static boolean contentEquals(File file1, File file2) throws IOException {
+ boolean file1Exists = file1.exists();
+ if (file1Exists != file2.exists()) {
+ return false;
+ }
+
+ if (!file1Exists) {
+ // two not existing files are equal
+ return true;
+ }
+
+ if (file1.isDirectory() || file2.isDirectory()) {
+ // don't want to compare directory contents
+ throw new IOException("Can't compare directories, only files");
+ }
+
+ if (file1.length() != file2.length()) {
+ // lengths differ, cannot be equal
+ return false;
+ }
+
+ if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {
+ // same file
+ return true;
+ }
+
+ InputStream input1 = null;
+ InputStream input2 = null;
+ try {
+ input1 = new FileInputStream(file1);
+ input2 = new FileInputStream(file2);
+ return IOUtils.contentEquals(input1, input2);
+
+ } finally {
+ IOUtils.closeQuietly(input1);
+ IOUtils.closeQuietly(input2);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Convert from a
+ * From version 1.1 this method will decode the URL.
+ * Syntax such as
+ * Returns an array of the same size as the input.
+ * If the input is
+ * This method will decode the URL.
+ * Syntax such as
+ * Returns an array of the same size as the input.
+ *
+ * @param files the files to convert
+ * @return an array of URLs matching the input
+ * @throws IOException if a file cannot be converted
+ */
+ public static URL[] toURLs(File[] files) throws IOException {
+ URL[] urls = new URL[files.length];
+
+ for (int i = 0; i < urls.length; i++) {
+ urls[i] = files[i].toURL();
+ }
+
+ return urls;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Copies a file to a directory preserving the file date.
+ *
+ * This method copies the contents of the specified source file
+ * to a file of the same name in the specified destination directory.
+ * The destination directory is created if it does not exist.
+ * If the destination file exists, then this method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be
+ * This method copies the contents of the specified source file
+ * to a file of the same name in the specified destination directory.
+ * The destination directory is created if it does not exist.
+ * If the destination file exists, then this method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be
+ * This method copies the contents of the specified source file to the
+ * specified destination file. The directory holding the destination file is
+ * created if it does not exist. If the destination file exists, then this
+ * method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be
+ * This method copies the contents of the specified source file
+ * to the specified destination file.
+ * The directory holding the destination file is created if it does not exist.
+ * If the destination file exists, then this method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be
+ * This method copies the source directory and all its contents to a
+ * directory of the same name in the specified destination directory.
+ *
+ * The destination directory is created if it does not exist.
+ * If the destination directory did exist, then this method merges
+ * the source with the destination, with the source taking precedence.
+ *
+ * @param srcDir an existing directory to copy, must not be
+ * This method copies the specified directory and all its child
+ * directories and files to the specified destination.
+ * The destination is the new location and name of the directory.
+ *
+ * The destination directory is created if it does not exist.
+ * If the destination directory did exist, then this method merges
+ * the source with the destination, with the source taking precedence.
+ *
+ * @param srcDir an existing directory to copy, must not be
+ * This method copies the contents of the specified source directory
+ * to within the specified destination directory.
+ *
+ * The destination directory is created if it does not exist.
+ * If the destination directory did exist, then this method merges
+ * the source with the destination, with the source taking precedence.
+ *
+ * @param srcDir an existing directory to copy, must not be
+ * This method copies the contents of the specified source directory
+ * to within the specified destination directory.
+ *
+ * The destination directory is created if it does not exist.
+ * If the destination directory did exist, then this method merges
+ * the source with the destination, with the source taking precedence.
+ *
+ *
+ * This method copies the contents of the specified source directory
+ * to within the specified destination directory.
+ *
+ * The destination directory is created if it does not exist.
+ * If the destination directory did exist, then this method merges
+ * the source with the destination, with the source taking precedence.
+ *
+ *
+ * The difference between File.delete() and this method are:
+ *
+ * This method repeatedly tests {@link File#exists()} until it returns
+ * true up to the maximum time specified in seconds.
+ *
+ * @param file the file to check, must not be
+ * This method opens an
+ * The recommended usage pattern is:
+ *
+ * If an exception occurs during the creation of the iterator, the
+ * underlying stream is closed.
+ *
+ * @param file the file to open for input, must not be
+ * NOTE: As from v1.3, the parent directories of the file will be created
+ * if they do not exist.
+ *
+ * @param file the file to write to
+ * @param data the content to write to the file
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.1
+ */
+ public static void writeByteArrayToFile(File file, byte[] data) throws IOException {
+ OutputStream out = null;
+ try {
+ out = openOutputStream(file);
+ out.write(data);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * Writes the
+ * NOTE: As from v1.3, the parent directories of the file will be created
+ * if they do not exist.
+ *
+ * @param file the file to write to
+ * @param encoding the encoding to use,
+ * NOTE: As from v1.3, the parent directories of the file will be created
+ * if they do not exist.
+ *
+ * @param file the file to write to
+ * @param encoding the encoding to use,
+ * The difference between File.delete() and this method are:
+ *
+ * When the destination directory is on another file system, do a "copy and delete".
+ *
+ * @param srcDir the directory to be moved
+ * @param destDir the destination directory
+ * @throws NullPointerException if source or destination is
+ * When the destination file is on another file system, do a "copy and delete".
+ *
+ * @param srcFile the file to be moved
+ * @param destFile the destination file
+ * @throws NullPointerException if source or destination is
+ * When the destination is on another file system, do a "copy and delete".
+ *
+ * @param src the file or directory to be moved
+ * @param destDir the destination directory
+ * @param createDestDir If
- * When dealing with filenames you can hit problems when moving from a Windows
- * based development machine to a Unix based production machine.
- * This class aims to help avoid those problems.
- *
- * NOTE: You may be able to avoid using this class entirely simply by
- * using JDK {@link java.io.File File} objects and the two argument constructor
- * {@link java.io.File#File(java.io.File, java.lang.String) File(File,String)}.
- *
- * Most methods on this class are designed to work the same on both Unix and Windows.
- * Those that don't include 'System', 'Unix' or 'Windows' in their name.
- *
- * Most methods recognise both separators (forward and back), and both
- * sets of prefixes. See the javadoc of each method for details.
- *
- * This class defines six components within a filename
- * (example C:\dev\project\file.txt):
- *
- * This class only supports Unix and Windows style names.
- * Prefixes are matched as follows:
- *
- * Origin of code: Excalibur, Alexandria, Tomcat, Commons-Utils.
- *
- * @author Kevin A. Burton
- * @author Scott Sanders
- * @author Daniel Rall
- * @author Christoph.Reck
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @author Martin Cooper
- * @author Jeremias Maerki
- * @author Stephen Colebourne
- * @version $Id: FilenameUtils.java 609870 2008-01-08 04:46:26Z niallp $
- * @since Commons IO 1.1
- */
-public class FilenameUtils {
-
- /**
- * The extension separator character.
- * @since Commons IO 1.4
- */
- public static final char EXTENSION_SEPARATOR = '.';
-
- /**
- * The extension separator String.
- * @since Commons IO 1.4
- */
- public static final String EXTENSION_SEPARATOR_STR = (new Character(EXTENSION_SEPARATOR)).toString();
-
- /**
- * The Unix separator character.
- */
- private static final char UNIX_SEPARATOR = '/';
-
- /**
- * The Windows separator character.
- */
- private static final char WINDOWS_SEPARATOR = '\\';
-
- /**
- * The system separator character.
- */
- private static final char SYSTEM_SEPARATOR = File.separatorChar;
-
- /**
- * The separator character that is the opposite of the system separator.
- */
- private static final char OTHER_SEPARATOR;
- static {
- if (isSystemWindows()) {
- OTHER_SEPARATOR = UNIX_SEPARATOR;
- } else {
- OTHER_SEPARATOR = WINDOWS_SEPARATOR;
- }
- }
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public FilenameUtils() {
- super();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Determines if Windows file system is in use.
- *
- * @return true if the system is Windows
- */
- static boolean isSystemWindows() {
- return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks if the character is a separator.
- *
- * @param ch the character to check
- * @return true if it is a separator character
- */
- private static boolean isSeparator(char ch) {
- return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Normalizes a path, removing double and single dot path steps.
- *
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format of the system.
- *
- * A trailing slash will be retained.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with,
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format of the system.
- *
- * A trailing slash will be removed.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with,
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * The effect is equivalent to resultant directory after changing
- * directory to the first argument, followed by changing directory to
- * the second argument.
- *
- * The first argument is the base path, the second is the path to concatenate.
- * The returned path is always normalized via {@link #normalize(String)},
- * thus
- * If
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * This method will handle a file in either Unix or Windows format.
- *
- * The prefix length includes the first slash in the full filename
- * if applicable. Thus, it is possible that the length returned is greater
- * than the length of the input string.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- * ie. both Unix and Windows prefixes are matched regardless.
- *
- * @param filename the filename to find the prefix in, null returns -1
- * @return the length of the prefix, -1 if invalid or null
- */
- public static int getPrefixLength(String filename) {
- if (filename == null) {
- return -1;
- }
- int len = filename.length();
- if (len == 0) {
- return 0;
- }
- char ch0 = filename.charAt(0);
- if (ch0 == ':') {
- return -1;
- }
- if (len == 1) {
- if (ch0 == '~') {
- return 2; // return a length greater than the input
- }
- return (isSeparator(ch0) ? 1 : 0);
- } else {
- if (ch0 == '~') {
- int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
- int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
- if (posUnix == -1 && posWin == -1) {
- return len + 1; // return a length greater than the input
- }
- posUnix = (posUnix == -1 ? posWin : posUnix);
- posWin = (posWin == -1 ? posUnix : posWin);
- return Math.min(posUnix, posWin) + 1;
- }
- char ch1 = filename.charAt(1);
- if (ch1 == ':') {
- ch0 = Character.toUpperCase(ch0);
- if (ch0 >= 'A' && ch0 <= 'Z') {
- if (len == 2 || isSeparator(filename.charAt(2)) == false) {
- return 2;
- }
- return 3;
- }
- return -1;
-
- } else if (isSeparator(ch0) && isSeparator(ch1)) {
- int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
- int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
- if ((posUnix == -1 && posWin == -1) || posUnix == 2 || posWin == 2) {
- return -1;
- }
- posUnix = (posUnix == -1 ? posWin : posUnix);
- posWin = (posWin == -1 ? posUnix : posWin);
- return Math.min(posUnix, posWin) + 1;
- } else {
- return (isSeparator(ch0) ? 1 : 0);
- }
- }
- }
-
- /**
- * Returns the index of the last directory separator character.
- *
- * This method will handle a file in either Unix or Windows format.
- * The position of the last forward or backslash is returned.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to find the last path separator in, null returns -1
- * @return the index of the last separator character, or -1 if there
- * is no such character
- */
- public static int indexOfLastSeparator(String filename) {
- if (filename == null) {
- return -1;
- }
- int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
- int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
- return Math.max(lastUnixPos, lastWindowsPos);
- }
-
- /**
- * Returns the index of the last extension separator character, which is a dot.
- *
- * This method also checks that there is no directory separator after the last dot.
- * To do this it uses {@link #indexOfLastSeparator(String)} which will
- * handle a file in either Unix or Windows format.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to find the last path separator in, null returns -1
- * @return the index of the last separator character, or -1 if there
- * is no such character
- */
- public static int indexOfExtension(String filename) {
- if (filename == null) {
- return -1;
- }
- int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
- int lastSeparator = indexOfLastSeparator(filename);
- return (lastSeparator > extensionPos ? -1 : extensionPos);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets the prefix from a full filename, such as
- * This method will handle a file in either Unix or Windows format.
- * The prefix includes the first slash in the full filename where applicable.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- * ie. both Unix and Windows prefixes are matched regardless.
- *
- * @param filename the filename to query, null returns null
- * @return the prefix of the file, null if invalid
- */
- public static String getPrefix(String filename) {
- if (filename == null) {
- return null;
- }
- int len = getPrefixLength(filename);
- if (len < 0) {
- return null;
- }
- if (len > filename.length()) {
- return filename + UNIX_SEPARATOR; // we know this only happens for unix
- }
- return filename.substring(0, len);
- }
-
- /**
- * Gets the path from a full filename, which excludes the prefix.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before and
- * including the last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * This method drops the prefix from the result.
- * See {@link #getFullPath(String)} for the method that retains the prefix.
- *
- * @param filename the filename to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid
- */
- public static String getPath(String filename) {
- return doGetPath(filename, 1);
- }
-
- /**
- * Gets the path from a full filename, which excludes the prefix, and
- * also excluding the final directory separator.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before the
- * last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * This method drops the prefix from the result.
- * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix.
- *
- * @param filename the filename to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid
- */
- public static String getPathNoEndSeparator(String filename) {
- return doGetPath(filename, 0);
- }
-
- /**
- * Does the work of getting the path.
- *
- * @param filename the filename
- * @param separatorAdd 0 to omit the end separator, 1 to return it
- * @return the path
- */
- private static String doGetPath(String filename, int separatorAdd) {
- if (filename == null) {
- return null;
- }
- int prefix = getPrefixLength(filename);
- if (prefix < 0) {
- return null;
- }
- int index = indexOfLastSeparator(filename);
- if (prefix >= filename.length() || index < 0) {
- return "";
- }
- return filename.substring(prefix, index + separatorAdd);
- }
-
- /**
- * Gets the full path from a full filename, which is the prefix + path.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before and
- * including the last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid
- */
- public static String getFullPath(String filename) {
- return doGetFullPath(filename, true);
- }
-
- /**
- * Gets the full path from a full filename, which is the prefix + path,
- * and also excluding the final directory separator.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before the
- * last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid
- */
- public static String getFullPathNoEndSeparator(String filename) {
- return doGetFullPath(filename, false);
- }
-
- /**
- * Does the work of getting the path.
- *
- * @param filename the filename
- * @param includeSeparator true to include the end separator
- * @return the path
- */
- private static String doGetFullPath(String filename, boolean includeSeparator) {
- if (filename == null) {
- return null;
- }
- int prefix = getPrefixLength(filename);
- if (prefix < 0) {
- return null;
- }
- if (prefix >= filename.length()) {
- if (includeSeparator) {
- return getPrefix(filename); // add end slash if necessary
- } else {
- return filename;
- }
- }
- int index = indexOfLastSeparator(filename);
- if (index < 0) {
- return filename.substring(0, prefix);
- }
- int end = index + (includeSeparator ? 1 : 0);
- return filename.substring(0, end);
- }
-
- /**
- * Gets the name minus the path from a full filename.
- *
- * This method will handle a file in either Unix or Windows format.
- * The text after the last forward or backslash is returned.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to query, null returns null
- * @return the name of the file without the path, or an empty string if none exists
- */
- public static String getName(String filename) {
- if (filename == null) {
- return null;
- }
- int index = indexOfLastSeparator(filename);
- return filename.substring(index + 1);
- }
-
- /**
- * Gets the base name, minus the full path and extension, from a full filename.
- *
- * This method will handle a file in either Unix or Windows format.
- * The text after the last forward or backslash and before the last dot is returned.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to query, null returns null
- * @return the name of the file without the path, or an empty string if none exists
- */
- public static String getBaseName(String filename) {
- return removeExtension(getName(filename));
- }
-
- /**
- * Gets the extension of a filename.
- *
- * This method returns the textual part of the filename after the last dot.
- * There must be no directory separator after the dot.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to retrieve the extension of.
- * @return the extension of the file or an empty string if none exists.
- */
- public static String getExtension(String filename) {
- if (filename == null) {
- return null;
- }
- int index = indexOfExtension(filename);
- if (index == -1) {
- return "";
- } else {
- return filename.substring(index + 1);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Removes the extension from a filename.
- *
- * This method returns the textual part of the filename before the last dot.
- * There must be no directory separator after the dot.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param filename the filename to query, null returns null
- * @return the filename minus the extension
- */
- public static String removeExtension(String filename) {
- if (filename == null) {
- return null;
- }
- int index = indexOfExtension(filename);
- if (index == -1) {
- return filename;
- } else {
- return filename.substring(0, index);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks whether two filenames are equal exactly.
- *
- * No processing is performed on the filenames other than comparison,
- * thus this is merely a null-safe case-sensitive equals.
- *
- * @param filename1 the first filename to query, may be null
- * @param filename2 the second filename to query, may be null
- * @return true if the filenames are equal, null equals null
- * @see IOCase#SENSITIVE
- */
- public static boolean equals(String filename1, String filename2) {
- return equals(filename1, filename2, false, IOCase.SENSITIVE);
- }
-
- /**
- * Checks whether two filenames are equal using the case rules of the system.
- *
- * No processing is performed on the filenames other than comparison.
- * The check is case-sensitive on Unix and case-insensitive on Windows.
- *
- * @param filename1 the first filename to query, may be null
- * @param filename2 the second filename to query, may be null
- * @return true if the filenames are equal, null equals null
- * @see IOCase#SYSTEM
- */
- public static boolean equalsOnSystem(String filename1, String filename2) {
- return equals(filename1, filename2, false, IOCase.SYSTEM);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks whether two filenames are equal after both have been normalized.
- *
- * Both filenames are first passed to {@link #normalize(String)}.
- * The check is then performed in a case-sensitive manner.
- *
- * @param filename1 the first filename to query, may be null
- * @param filename2 the second filename to query, may be null
- * @return true if the filenames are equal, null equals null
- * @see IOCase#SENSITIVE
- */
- public static boolean equalsNormalized(String filename1, String filename2) {
- return equals(filename1, filename2, true, IOCase.SENSITIVE);
- }
-
- /**
- * Checks whether two filenames are equal after both have been normalized
- * and using the case rules of the system.
- *
- * Both filenames are first passed to {@link #normalize(String)}.
- * The check is then performed case-sensitive on Unix and
- * case-insensitive on Windows.
- *
- * @param filename1 the first filename to query, may be null
- * @param filename2 the second filename to query, may be null
- * @return true if the filenames are equal, null equals null
- * @see IOCase#SYSTEM
- */
- public static boolean equalsNormalizedOnSystem(String filename1, String filename2) {
- return equals(filename1, filename2, true, IOCase.SYSTEM);
- }
-
- /**
- * Checks whether two filenames are equal, optionally normalizing and providing
- * control over the case-sensitivity.
- *
- * @param filename1 the first filename to query, may be null
- * @param filename2 the second filename to query, may be null
- * @param normalized whether to normalize the filenames
- * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
- * @return true if the filenames are equal, null equals null
- * @since Commons IO 1.3
- */
- public static boolean equals(
- String filename1, String filename2,
- boolean normalized, IOCase caseSensitivity) {
-
- if (filename1 == null || filename2 == null) {
- return filename1 == filename2;
- }
- if (normalized) {
- filename1 = normalize(filename1);
- filename2 = normalize(filename2);
- if (filename1 == null || filename2 == null) {
- throw new NullPointerException(
- "Error normalizing one or both of the file names");
- }
- }
- if (caseSensitivity == null) {
- caseSensitivity = IOCase.SENSITIVE;
- }
- return caseSensitivity.checkEquals(filename1, filename2);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks whether the extension of the filename is that specified.
- *
- * This method obtains the extension as the textual part of the filename
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
- *
- * @param filename the filename to query, null returns false
- * @param extension the extension to check for, null or empty checks for no extension
- * @return true if the filename has the specified extension
- */
- public static boolean isExtension(String filename, String extension) {
- if (filename == null) {
- return false;
- }
- if (extension == null || extension.length() == 0) {
- return (indexOfExtension(filename) == -1);
- }
- String fileExt = getExtension(filename);
- return fileExt.equals(extension);
- }
-
- /**
- * Checks whether the extension of the filename is one of those specified.
- *
- * This method obtains the extension as the textual part of the filename
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
- *
- * @param filename the filename to query, null returns false
- * @param extensions the extensions to check for, null checks for no extension
- * @return true if the filename is one of the extensions
- */
- public static boolean isExtension(String filename, String[] extensions) {
- if (filename == null) {
- return false;
- }
- if (extensions == null || extensions.length == 0) {
- return (indexOfExtension(filename) == -1);
- }
- String fileExt = getExtension(filename);
- for (int i = 0; i < extensions.length; i++) {
- if (fileExt.equals(extensions[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether the extension of the filename is one of those specified.
- *
- * This method obtains the extension as the textual part of the filename
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
- *
- * @param filename the filename to query, null returns false
- * @param extensions the extensions to check for, null checks for no extension
- * @return true if the filename is one of the extensions
- */
- public static boolean isExtension(String filename, Collection extensions) {
- if (filename == null) {
- return false;
- }
- if (extensions == null || extensions.isEmpty()) {
- return (indexOfExtension(filename) == -1);
- }
- String fileExt = getExtension(filename);
- for (Iterator it = extensions.iterator(); it.hasNext();) {
- if (fileExt.equals(it.next())) {
- return true;
- }
- }
- return false;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks a filename to see if it matches the specified wildcard matcher,
- * always testing case-sensitive.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
- * The check is case-sensitive always.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
- * The check is case-sensitive on Unix and case-insensitive on Windows.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple wildcard characters.
- *
- * @param filename the filename to match on
- * @param wildcardMatcher the wildcard string to match against
- * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
- * @return true if the filename matches the wilcard string
- * @since Commons IO 1.3
- */
- public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
- if (filename == null && wildcardMatcher == null) {
- return true;
- }
- if (filename == null || wildcardMatcher == null) {
- return false;
- }
- if (caseSensitivity == null) {
- caseSensitivity = IOCase.SENSITIVE;
- }
- filename = caseSensitivity.convertCase(filename);
- wildcardMatcher = caseSensitivity.convertCase(wildcardMatcher);
- String[] wcs = splitOnTokens(wildcardMatcher);
- boolean anyChars = false;
- int textIdx = 0;
- int wcsIdx = 0;
- Stack backtrack = new Stack();
-
- // loop around a backtrack stack, to handle complex * matching
- do {
- if (backtrack.size() > 0) {
- int[] array = (int[]) backtrack.pop();
- wcsIdx = array[0];
- textIdx = array[1];
- anyChars = true;
- }
-
- // loop whilst tokens and text left to process
- while (wcsIdx < wcs.length) {
-
- if (wcs[wcsIdx].equals("?")) {
- // ? so move to next text char
- textIdx++;
- anyChars = false;
-
- } else if (wcs[wcsIdx].equals("*")) {
- // set any chars status
- anyChars = true;
- if (wcsIdx == wcs.length - 1) {
- textIdx = filename.length();
- }
-
- } else {
- // matching text token
- if (anyChars) {
- // any chars then try to locate text token
- textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
- if (textIdx == -1) {
- // token not found
- break;
- }
- int repeat = filename.indexOf(wcs[wcsIdx], textIdx + 1);
- if (repeat >= 0) {
- backtrack.push(new int[] {wcsIdx, repeat});
- }
- } else {
- // matching from current position
- if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
- // couldnt match token
- break;
- }
- }
-
- // matched text token, move text index to end of matched token
- textIdx += wcs[wcsIdx].length();
- anyChars = false;
- }
-
- wcsIdx++;
- }
-
- // full match
- if (wcsIdx == wcs.length && textIdx == filename.length()) {
- return true;
- }
-
- } while (backtrack.size() > 0);
-
- return false;
- }
-
- /**
- * Splits a string into a number of tokens.
- *
- * @param text the text to split
- * @return the tokens, never null
- */
- static String[] splitOnTokens(String text) {
- // used by wildcardMatch
- // package level so a unit test may run on this
-
- if (text.indexOf("?") == -1 && text.indexOf("*") == -1) {
- return new String[] { text };
- }
-
- char[] array = text.toCharArray();
- ArrayList list = new ArrayList();
- StringBuffer buffer = new StringBuffer();
- for (int i = 0; i < array.length; i++) {
- if (array[i] == '?' || array[i] == '*') {
- if (buffer.length() != 0) {
- list.add(buffer.toString());
- buffer.setLength(0);
- }
- if (array[i] == '?') {
- list.add("?");
- } else if (list.size() == 0 ||
- (i > 0 && list.get(list.size() - 1).equals("*") == false)) {
- list.add("*");
- }
- } else {
- buffer.append(array[i]);
- }
- }
- if (buffer.length() != 0) {
- list.add(buffer.toString());
- }
-
- return (String[]) list.toArray( new String[ list.size() ] );
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Stack;
+
+/**
+ * General filename and filepath manipulation utilities.
+ *
+ * When dealing with filenames you can hit problems when moving from a Windows
+ * based development machine to a Unix based production machine.
+ * This class aims to help avoid those problems.
+ *
+ * NOTE: You may be able to avoid using this class entirely simply by
+ * using JDK {@link java.io.File File} objects and the two argument constructor
+ * {@link java.io.File#File(java.io.File, java.lang.String) File(File,String)}.
+ *
+ * Most methods on this class are designed to work the same on both Unix and Windows.
+ * Those that don't include 'System', 'Unix' or 'Windows' in their name.
+ *
+ * Most methods recognise both separators (forward and back), and both
+ * sets of prefixes. See the javadoc of each method for details.
+ *
+ * This class defines six components within a filename
+ * (example C:\dev\project\file.txt):
+ *
+ * This class only supports Unix and Windows style names.
+ * Prefixes are matched as follows:
+ *
+ * Origin of code: Excalibur, Alexandria, Tomcat, Commons-Utils.
+ *
+ * @author Kevin A. Burton
+ * @author Scott Sanders
+ * @author Daniel Rall
+ * @author Christoph.Reck
+ * @author Peter Donald
+ * @author Jeff Turner
+ * @author Matthew Hawthorne
+ * @author Martin Cooper
+ * @author Jeremias Maerki
+ * @author Stephen Colebourne
+ * @version $Id: FilenameUtils.java 609870 2008-01-08 04:46:26Z niallp $
+ * @since Commons IO 1.1
+ */
+public class FilenameUtils {
+
+ /**
+ * The extension separator character.
+ * @since Commons IO 1.4
+ */
+ public static final char EXTENSION_SEPARATOR = '.';
+
+ /**
+ * The extension separator String.
+ * @since Commons IO 1.4
+ */
+ public static final String EXTENSION_SEPARATOR_STR = (new Character(EXTENSION_SEPARATOR)).toString();
+
+ /**
+ * The Unix separator character.
+ */
+ private static final char UNIX_SEPARATOR = '/';
+
+ /**
+ * The Windows separator character.
+ */
+ private static final char WINDOWS_SEPARATOR = '\\';
+
+ /**
+ * The system separator character.
+ */
+ private static final char SYSTEM_SEPARATOR = File.separatorChar;
+
+ /**
+ * The separator character that is the opposite of the system separator.
+ */
+ private static final char OTHER_SEPARATOR;
+ static {
+ if (isSystemWindows()) {
+ OTHER_SEPARATOR = UNIX_SEPARATOR;
+ } else {
+ OTHER_SEPARATOR = WINDOWS_SEPARATOR;
+ }
+ }
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public FilenameUtils() {
+ super();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Determines if Windows file system is in use.
+ *
+ * @return true if the system is Windows
+ */
+ static boolean isSystemWindows() {
+ return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks if the character is a separator.
+ *
+ * @param ch the character to check
+ * @return true if it is a separator character
+ */
+ private static boolean isSeparator(char ch) {
+ return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Normalizes a path, removing double and single dot path steps.
+ *
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format of the system.
+ *
+ * A trailing slash will be retained.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with,
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
+ *
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format of the system.
+ *
+ * A trailing slash will be removed.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with,
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
+ *
+ * The effect is equivalent to resultant directory after changing
+ * directory to the first argument, followed by changing directory to
+ * the second argument.
+ *
+ * The first argument is the base path, the second is the path to concatenate.
+ * The returned path is always normalized via {@link #normalize(String)},
+ * thus
+ * If
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ *
+ * The prefix length includes the first slash in the full filename
+ * if applicable. Thus, it is possible that the length returned is greater
+ * than the length of the input string.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ * ie. both Unix and Windows prefixes are matched regardless.
+ *
+ * @param filename the filename to find the prefix in, null returns -1
+ * @return the length of the prefix, -1 if invalid or null
+ */
+ public static int getPrefixLength(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int len = filename.length();
+ if (len == 0) {
+ return 0;
+ }
+ char ch0 = filename.charAt(0);
+ if (ch0 == ':') {
+ return -1;
+ }
+ if (len == 1) {
+ if (ch0 == '~') {
+ return 2; // return a length greater than the input
+ }
+ return (isSeparator(ch0) ? 1 : 0);
+ } else {
+ if (ch0 == '~') {
+ int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
+ int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
+ if (posUnix == -1 && posWin == -1) {
+ return len + 1; // return a length greater than the input
+ }
+ posUnix = (posUnix == -1 ? posWin : posUnix);
+ posWin = (posWin == -1 ? posUnix : posWin);
+ return Math.min(posUnix, posWin) + 1;
+ }
+ char ch1 = filename.charAt(1);
+ if (ch1 == ':') {
+ ch0 = Character.toUpperCase(ch0);
+ if (ch0 >= 'A' && ch0 <= 'Z') {
+ if (len == 2 || isSeparator(filename.charAt(2)) == false) {
+ return 2;
+ }
+ return 3;
+ }
+ return -1;
+
+ } else if (isSeparator(ch0) && isSeparator(ch1)) {
+ int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
+ int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
+ if ((posUnix == -1 && posWin == -1) || posUnix == 2 || posWin == 2) {
+ return -1;
+ }
+ posUnix = (posUnix == -1 ? posWin : posUnix);
+ posWin = (posWin == -1 ? posUnix : posWin);
+ return Math.min(posUnix, posWin) + 1;
+ } else {
+ return (isSeparator(ch0) ? 1 : 0);
+ }
+ }
+ }
+
+ /**
+ * Returns the index of the last directory separator character.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The position of the last forward or backslash is returned.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to find the last path separator in, null returns -1
+ * @return the index of the last separator character, or -1 if there
+ * is no such character
+ */
+ public static int indexOfLastSeparator(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
+ int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
+ return Math.max(lastUnixPos, lastWindowsPos);
+ }
+
+ /**
+ * Returns the index of the last extension separator character, which is a dot.
+ *
+ * This method also checks that there is no directory separator after the last dot.
+ * To do this it uses {@link #indexOfLastSeparator(String)} which will
+ * handle a file in either Unix or Windows format.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to find the last path separator in, null returns -1
+ * @return the index of the last separator character, or -1 if there
+ * is no such character
+ */
+ public static int indexOfExtension(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
+ int lastSeparator = indexOfLastSeparator(filename);
+ return (lastSeparator > extensionPos ? -1 : extensionPos);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the prefix from a full filename, such as
+ * This method will handle a file in either Unix or Windows format.
+ * The prefix includes the first slash in the full filename where applicable.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ * ie. both Unix and Windows prefixes are matched regardless.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the prefix of the file, null if invalid
+ */
+ public static String getPrefix(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int len = getPrefixLength(filename);
+ if (len < 0) {
+ return null;
+ }
+ if (len > filename.length()) {
+ return filename + UNIX_SEPARATOR; // we know this only happens for unix
+ }
+ return filename.substring(0, len);
+ }
+
+ /**
+ * Gets the path from a full filename, which excludes the prefix.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before and
+ * including the last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * This method drops the prefix from the result.
+ * See {@link #getFullPath(String)} for the method that retains the prefix.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ */
+ public static String getPath(String filename) {
+ return doGetPath(filename, 1);
+ }
+
+ /**
+ * Gets the path from a full filename, which excludes the prefix, and
+ * also excluding the final directory separator.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before the
+ * last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * This method drops the prefix from the result.
+ * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ */
+ public static String getPathNoEndSeparator(String filename) {
+ return doGetPath(filename, 0);
+ }
+
+ /**
+ * Does the work of getting the path.
+ *
+ * @param filename the filename
+ * @param separatorAdd 0 to omit the end separator, 1 to return it
+ * @return the path
+ */
+ private static String doGetPath(String filename, int separatorAdd) {
+ if (filename == null) {
+ return null;
+ }
+ int prefix = getPrefixLength(filename);
+ if (prefix < 0) {
+ return null;
+ }
+ int index = indexOfLastSeparator(filename);
+ if (prefix >= filename.length() || index < 0) {
+ return "";
+ }
+ return filename.substring(prefix, index + separatorAdd);
+ }
+
+ /**
+ * Gets the full path from a full filename, which is the prefix + path.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before and
+ * including the last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ */
+ public static String getFullPath(String filename) {
+ return doGetFullPath(filename, true);
+ }
+
+ /**
+ * Gets the full path from a full filename, which is the prefix + path,
+ * and also excluding the final directory separator.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before the
+ * last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ */
+ public static String getFullPathNoEndSeparator(String filename) {
+ return doGetFullPath(filename, false);
+ }
+
+ /**
+ * Does the work of getting the path.
+ *
+ * @param filename the filename
+ * @param includeSeparator true to include the end separator
+ * @return the path
+ */
+ private static String doGetFullPath(String filename, boolean includeSeparator) {
+ if (filename == null) {
+ return null;
+ }
+ int prefix = getPrefixLength(filename);
+ if (prefix < 0) {
+ return null;
+ }
+ if (prefix >= filename.length()) {
+ if (includeSeparator) {
+ return getPrefix(filename); // add end slash if necessary
+ } else {
+ return filename;
+ }
+ }
+ int index = indexOfLastSeparator(filename);
+ if (index < 0) {
+ return filename.substring(0, prefix);
+ }
+ int end = index + (includeSeparator ? 1 : 0);
+ return filename.substring(0, end);
+ }
+
+ /**
+ * Gets the name minus the path from a full filename.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash is returned.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the name of the file without the path, or an empty string if none exists
+ */
+ public static String getName(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int index = indexOfLastSeparator(filename);
+ return filename.substring(index + 1);
+ }
+
+ /**
+ * Gets the base name, minus the full path and extension, from a full filename.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash and before the last dot is returned.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the name of the file without the path, or an empty string if none exists
+ */
+ public static String getBaseName(String filename) {
+ return removeExtension(getName(filename));
+ }
+
+ /**
+ * Gets the extension of a filename.
+ *
+ * This method returns the textual part of the filename after the last dot.
+ * There must be no directory separator after the dot.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to retrieve the extension of.
+ * @return the extension of the file or an empty string if none exists.
+ */
+ public static String getExtension(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int index = indexOfExtension(filename);
+ if (index == -1) {
+ return "";
+ } else {
+ return filename.substring(index + 1);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Removes the extension from a filename.
+ *
+ * This method returns the textual part of the filename before the last dot.
+ * There must be no directory separator after the dot.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to query, null returns null
+ * @return the filename minus the extension
+ */
+ public static String removeExtension(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int index = indexOfExtension(filename);
+ if (index == -1) {
+ return filename;
+ } else {
+ return filename.substring(0, index);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether two filenames are equal exactly.
+ *
+ * No processing is performed on the filenames other than comparison,
+ * thus this is merely a null-safe case-sensitive equals.
+ *
+ * @param filename1 the first filename to query, may be null
+ * @param filename2 the second filename to query, may be null
+ * @return true if the filenames are equal, null equals null
+ * @see IOCase#SENSITIVE
+ */
+ public static boolean equals(String filename1, String filename2) {
+ return equals(filename1, filename2, false, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Checks whether two filenames are equal using the case rules of the system.
+ *
+ * No processing is performed on the filenames other than comparison.
+ * The check is case-sensitive on Unix and case-insensitive on Windows.
+ *
+ * @param filename1 the first filename to query, may be null
+ * @param filename2 the second filename to query, may be null
+ * @return true if the filenames are equal, null equals null
+ * @see IOCase#SYSTEM
+ */
+ public static boolean equalsOnSystem(String filename1, String filename2) {
+ return equals(filename1, filename2, false, IOCase.SYSTEM);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether two filenames are equal after both have been normalized.
+ *
+ * Both filenames are first passed to {@link #normalize(String)}.
+ * The check is then performed in a case-sensitive manner.
+ *
+ * @param filename1 the first filename to query, may be null
+ * @param filename2 the second filename to query, may be null
+ * @return true if the filenames are equal, null equals null
+ * @see IOCase#SENSITIVE
+ */
+ public static boolean equalsNormalized(String filename1, String filename2) {
+ return equals(filename1, filename2, true, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Checks whether two filenames are equal after both have been normalized
+ * and using the case rules of the system.
+ *
+ * Both filenames are first passed to {@link #normalize(String)}.
+ * The check is then performed case-sensitive on Unix and
+ * case-insensitive on Windows.
+ *
+ * @param filename1 the first filename to query, may be null
+ * @param filename2 the second filename to query, may be null
+ * @return true if the filenames are equal, null equals null
+ * @see IOCase#SYSTEM
+ */
+ public static boolean equalsNormalizedOnSystem(String filename1, String filename2) {
+ return equals(filename1, filename2, true, IOCase.SYSTEM);
+ }
+
+ /**
+ * Checks whether two filenames are equal, optionally normalizing and providing
+ * control over the case-sensitivity.
+ *
+ * @param filename1 the first filename to query, may be null
+ * @param filename2 the second filename to query, may be null
+ * @param normalized whether to normalize the filenames
+ * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
+ * @return true if the filenames are equal, null equals null
+ * @since Commons IO 1.3
+ */
+ public static boolean equals(
+ String filename1, String filename2,
+ boolean normalized, IOCase caseSensitivity) {
+
+ if (filename1 == null || filename2 == null) {
+ return filename1 == filename2;
+ }
+ if (normalized) {
+ filename1 = normalize(filename1);
+ filename2 = normalize(filename2);
+ if (filename1 == null || filename2 == null) {
+ throw new NullPointerException(
+ "Error normalizing one or both of the file names");
+ }
+ }
+ if (caseSensitivity == null) {
+ caseSensitivity = IOCase.SENSITIVE;
+ }
+ return caseSensitivity.checkEquals(filename1, filename2);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether the extension of the filename is that specified.
+ *
+ * This method obtains the extension as the textual part of the filename
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
+ *
+ * @param filename the filename to query, null returns false
+ * @param extension the extension to check for, null or empty checks for no extension
+ * @return true if the filename has the specified extension
+ */
+ public static boolean isExtension(String filename, String extension) {
+ if (filename == null) {
+ return false;
+ }
+ if (extension == null || extension.length() == 0) {
+ return (indexOfExtension(filename) == -1);
+ }
+ String fileExt = getExtension(filename);
+ return fileExt.equals(extension);
+ }
+
+ /**
+ * Checks whether the extension of the filename is one of those specified.
+ *
+ * This method obtains the extension as the textual part of the filename
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
+ *
+ * @param filename the filename to query, null returns false
+ * @param extensions the extensions to check for, null checks for no extension
+ * @return true if the filename is one of the extensions
+ */
+ public static boolean isExtension(String filename, String[] extensions) {
+ if (filename == null) {
+ return false;
+ }
+ if (extensions == null || extensions.length == 0) {
+ return (indexOfExtension(filename) == -1);
+ }
+ String fileExt = getExtension(filename);
+ for (int i = 0; i < extensions.length; i++) {
+ if (fileExt.equals(extensions[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether the extension of the filename is one of those specified.
+ *
+ * This method obtains the extension as the textual part of the filename
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
+ *
+ * @param filename the filename to query, null returns false
+ * @param extensions the extensions to check for, null checks for no extension
+ * @return true if the filename is one of the extensions
+ */
+ public static boolean isExtension(String filename, Collection extensions) {
+ if (filename == null) {
+ return false;
+ }
+ if (extensions == null || extensions.isEmpty()) {
+ return (indexOfExtension(filename) == -1);
+ }
+ String fileExt = getExtension(filename);
+ for (Iterator it = extensions.iterator(); it.hasNext();) {
+ if (fileExt.equals(it.next())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks a filename to see if it matches the specified wildcard matcher,
+ * always testing case-sensitive.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple wildcard characters.
+ * This is the same as often found on Dos/Unix command lines.
+ * The check is case-sensitive always.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple wildcard characters.
+ * This is the same as often found on Dos/Unix command lines.
+ * The check is case-sensitive on Unix and case-insensitive on Windows.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple wildcard characters.
+ *
+ * @param filename the filename to match on
+ * @param wildcardMatcher the wildcard string to match against
+ * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
+ * @return true if the filename matches the wilcard string
+ * @since Commons IO 1.3
+ */
+ public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
+ if (filename == null && wildcardMatcher == null) {
+ return true;
+ }
+ if (filename == null || wildcardMatcher == null) {
+ return false;
+ }
+ if (caseSensitivity == null) {
+ caseSensitivity = IOCase.SENSITIVE;
+ }
+ filename = caseSensitivity.convertCase(filename);
+ wildcardMatcher = caseSensitivity.convertCase(wildcardMatcher);
+ String[] wcs = splitOnTokens(wildcardMatcher);
+ boolean anyChars = false;
+ int textIdx = 0;
+ int wcsIdx = 0;
+ Stack backtrack = new Stack();
+
+ // loop around a backtrack stack, to handle complex * matching
+ do {
+ if (backtrack.size() > 0) {
+ int[] array = (int[]) backtrack.pop();
+ wcsIdx = array[0];
+ textIdx = array[1];
+ anyChars = true;
+ }
+
+ // loop whilst tokens and text left to process
+ while (wcsIdx < wcs.length) {
+
+ if (wcs[wcsIdx].equals("?")) {
+ // ? so move to next text char
+ textIdx++;
+ anyChars = false;
+
+ } else if (wcs[wcsIdx].equals("*")) {
+ // set any chars status
+ anyChars = true;
+ if (wcsIdx == wcs.length - 1) {
+ textIdx = filename.length();
+ }
+
+ } else {
+ // matching text token
+ if (anyChars) {
+ // any chars then try to locate text token
+ textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
+ if (textIdx == -1) {
+ // token not found
+ break;
+ }
+ int repeat = filename.indexOf(wcs[wcsIdx], textIdx + 1);
+ if (repeat >= 0) {
+ backtrack.push(new int[] {wcsIdx, repeat});
+ }
+ } else {
+ // matching from current position
+ if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
+ // couldnt match token
+ break;
+ }
+ }
+
+ // matched text token, move text index to end of matched token
+ textIdx += wcs[wcsIdx].length();
+ anyChars = false;
+ }
+
+ wcsIdx++;
+ }
+
+ // full match
+ if (wcsIdx == wcs.length && textIdx == filename.length()) {
+ return true;
+ }
+
+ } while (backtrack.size() > 0);
+
+ return false;
+ }
+
+ /**
+ * Splits a string into a number of tokens.
+ *
+ * @param text the text to split
+ * @return the tokens, never null
+ */
+ static String[] splitOnTokens(String text) {
+ // used by wildcardMatch
+ // package level so a unit test may run on this
+
+ if (text.indexOf("?") == -1 && text.indexOf("*") == -1) {
+ return new String[] { text };
+ }
+
+ char[] array = text.toCharArray();
+ ArrayList list = new ArrayList();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == '?' || array[i] == '*') {
+ if (buffer.length() != 0) {
+ list.add(buffer.toString());
+ buffer.setLength(0);
+ }
+ if (array[i] == '?') {
+ list.add("?");
+ } else if (list.size() == 0 ||
+ (i > 0 && list.get(list.size() - 1).equals("*") == false)) {
+ list.add("*");
+ }
+ } else {
+ buffer.append(array[i]);
+ }
+ }
+ if (buffer.length() != 0) {
+ list.add(buffer.toString());
+ }
+
+ return (String[]) list.toArray( new String[ list.size() ] );
+ }
+
+}
diff --git a/src/org/apache/commons/io/HexDump.java b/src/org/apache/commons/io/HexDump.java
index b0d468d185d0edc74d52dc17b8af2459471bd140..8293430bcc6a029fa57f50099ee5d4a92fa2ec59 100644
--- a/src/org/apache/commons/io/HexDump.java
+++ b/src/org/apache/commons/io/HexDump.java
@@ -1,149 +1,149 @@
-/*
- * 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.commons.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Dumps data in hexadecimal format.
- *
- * Provides a single function to take an array of bytes and display it
- * in hexadecimal form.
- *
- * Origin of code: POI.
- *
- * @author Scott Sanders
- * @author Marc Johnson
- * @version $Id: HexDump.java 596667 2007-11-20 13:50:14Z niallp $
- */
-public class HexDump {
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public HexDump() {
- super();
- }
-
- /**
- * Dump an array of bytes to an OutputStream.
- *
- * @param data the byte array to be dumped
- * @param offset its offset, whatever that might mean
- * @param stream the OutputStream to which the data is to be
- * written
- * @param index initial index into the byte array
- *
- * @throws IOException is thrown if anything goes wrong writing
- * the data to stream
- * @throws ArrayIndexOutOfBoundsException if the index is
- * outside the data array's bounds
- * @throws IllegalArgumentException if the output stream is null
- */
-
- public static void dump(byte[] data, long offset,
- OutputStream stream, int index)
- throws IOException, ArrayIndexOutOfBoundsException,
- IllegalArgumentException {
-
- if ((index < 0) || (index >= data.length)) {
- throw new ArrayIndexOutOfBoundsException(
- "illegal index: " + index + " into array of length "
- + data.length);
- }
- if (stream == null) {
- throw new IllegalArgumentException("cannot write to nullstream");
- }
- long display_offset = offset + index;
- StringBuffer buffer = new StringBuffer(74);
-
- for (int j = index; j < data.length; j += 16) {
- int chars_read = data.length - j;
-
- if (chars_read > 16) {
- chars_read = 16;
- }
- dump(buffer, display_offset).append(' ');
- for (int k = 0; k < 16; k++) {
- if (k < chars_read) {
- dump(buffer, data[k + j]);
- } else {
- buffer.append(" ");
- }
- buffer.append(' ');
- }
- for (int k = 0; k < chars_read; k++) {
- if ((data[k + j] >= ' ') && (data[k + j] < 127)) {
- buffer.append((char) data[k + j]);
- } else {
- buffer.append('.');
- }
- }
- buffer.append(EOL);
- stream.write(buffer.toString().getBytes());
- stream.flush();
- buffer.setLength(0);
- display_offset += chars_read;
- }
- }
-
- /**
- * The line-separator (initializes to "line.separator" system property.
- */
- public static final String EOL =
- System.getProperty("line.separator");
- private static final char[] _hexcodes =
- {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'
- };
- private static final int[] _shifts =
- {
- 28, 24, 20, 16, 12, 8, 4, 0
- };
-
- /**
- * Dump a long value into a StringBuffer.
- *
- * @param _lbuffer the StringBuffer to dump the value in
- * @param value the long value to be dumped
- * @return StringBuffer containing the dumped value.
- */
- private static StringBuffer dump(StringBuffer _lbuffer, long value) {
- for (int j = 0; j < 8; j++) {
- _lbuffer
- .append(_hexcodes[((int) (value >> _shifts[j])) & 15]);
- }
- return _lbuffer;
- }
-
- /**
- * Dump a byte value into a StringBuffer.
- *
- * @param _cbuffer the StringBuffer to dump the value in
- * @param value the byte value to be dumped
- * @return StringBuffer containing the dumped value.
- */
- private static StringBuffer dump(StringBuffer _cbuffer, byte value) {
- for (int j = 0; j < 2; j++) {
- _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]);
- }
- return _cbuffer;
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Dumps data in hexadecimal format.
+ *
+ * Provides a single function to take an array of bytes and display it
+ * in hexadecimal form.
+ *
+ * Origin of code: POI.
+ *
+ * @author Scott Sanders
+ * @author Marc Johnson
+ * @version $Id: HexDump.java 596667 2007-11-20 13:50:14Z niallp $
+ */
+public class HexDump {
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public HexDump() {
+ super();
+ }
+
+ /**
+ * Dump an array of bytes to an OutputStream.
+ *
+ * @param data the byte array to be dumped
+ * @param offset its offset, whatever that might mean
+ * @param stream the OutputStream to which the data is to be
+ * written
+ * @param index initial index into the byte array
+ *
+ * @throws IOException is thrown if anything goes wrong writing
+ * the data to stream
+ * @throws ArrayIndexOutOfBoundsException if the index is
+ * outside the data array's bounds
+ * @throws IllegalArgumentException if the output stream is null
+ */
+
+ public static void dump(byte[] data, long offset,
+ OutputStream stream, int index)
+ throws IOException, ArrayIndexOutOfBoundsException,
+ IllegalArgumentException {
+
+ if ((index < 0) || (index >= data.length)) {
+ throw new ArrayIndexOutOfBoundsException(
+ "illegal index: " + index + " into array of length "
+ + data.length);
+ }
+ if (stream == null) {
+ throw new IllegalArgumentException("cannot write to nullstream");
+ }
+ long display_offset = offset + index;
+ StringBuffer buffer = new StringBuffer(74);
+
+ for (int j = index; j < data.length; j += 16) {
+ int chars_read = data.length - j;
+
+ if (chars_read > 16) {
+ chars_read = 16;
+ }
+ dump(buffer, display_offset).append(' ');
+ for (int k = 0; k < 16; k++) {
+ if (k < chars_read) {
+ dump(buffer, data[k + j]);
+ } else {
+ buffer.append(" ");
+ }
+ buffer.append(' ');
+ }
+ for (int k = 0; k < chars_read; k++) {
+ if ((data[k + j] >= ' ') && (data[k + j] < 127)) {
+ buffer.append((char) data[k + j]);
+ } else {
+ buffer.append('.');
+ }
+ }
+ buffer.append(EOL);
+ stream.write(buffer.toString().getBytes());
+ stream.flush();
+ buffer.setLength(0);
+ display_offset += chars_read;
+ }
+ }
+
+ /**
+ * The line-separator (initializes to "line.separator" system property.
+ */
+ public static final String EOL =
+ System.getProperty("line.separator");
+ private static final char[] _hexcodes =
+ {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ private static final int[] _shifts =
+ {
+ 28, 24, 20, 16, 12, 8, 4, 0
+ };
+
+ /**
+ * Dump a long value into a StringBuffer.
+ *
+ * @param _lbuffer the StringBuffer to dump the value in
+ * @param value the long value to be dumped
+ * @return StringBuffer containing the dumped value.
+ */
+ private static StringBuffer dump(StringBuffer _lbuffer, long value) {
+ for (int j = 0; j < 8; j++) {
+ _lbuffer
+ .append(_hexcodes[((int) (value >> _shifts[j])) & 15]);
+ }
+ return _lbuffer;
+ }
+
+ /**
+ * Dump a byte value into a StringBuffer.
+ *
+ * @param _cbuffer the StringBuffer to dump the value in
+ * @param value the byte value to be dumped
+ * @return StringBuffer containing the dumped value.
+ */
+ private static StringBuffer dump(StringBuffer _cbuffer, byte value) {
+ for (int j = 0; j < 2; j++) {
+ _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]);
+ }
+ return _cbuffer;
+ }
+
+}
diff --git a/src/org/apache/commons/io/IOCase.java b/src/org/apache/commons/io/IOCase.java
index 4230f450d98cfee1cbbd6f93ebdd1ef46f043502..2f9bf18f3bbe259a91f884e62815bae1ce12e02d 100644
--- a/src/org/apache/commons/io/IOCase.java
+++ b/src/org/apache/commons/io/IOCase.java
@@ -1,238 +1,238 @@
-/*
- * 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.commons.io;
-
-import java.io.Serializable;
-
-/**
- * Enumeration of IO case sensitivity.
- *
- * Different filing systems have different rules for case-sensitivity.
- * Windows is case-insensitive, Unix is case-sensitive.
- *
- * This class captures that difference, providing an enumeration to
- * control how filename comparisons should be performed. It also provides
- * methods that use the enumeration to perform comparisons.
- *
- * Wherever possible, you should use the
- * If you derialize this constant of Windows, and deserialize on Unix, or vice
- * versa, then the value of the case-sensitivity flag will change.
- */
- public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
-
- /** Serialization version. */
- private static final long serialVersionUID = -6343169151696340687L;
-
- /** The enumeration name. */
- private final String name;
-
- /** The sensitivity flag. */
- private final transient boolean sensitive;
-
- //-----------------------------------------------------------------------
- /**
- * Factory method to create an IOCase from a name.
- *
- * @param name the name to find
- * @return the IOCase object
- * @throws IllegalArgumentException if the name is invalid
- */
- public static IOCase forName(String name) {
- if (IOCase.SENSITIVE.name.equals(name)){
- return IOCase.SENSITIVE;
- }
- if (IOCase.INSENSITIVE.name.equals(name)){
- return IOCase.INSENSITIVE;
- }
- if (IOCase.SYSTEM.name.equals(name)){
- return IOCase.SYSTEM;
- }
- throw new IllegalArgumentException("Invalid IOCase name: " + name);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Private constructor.
- *
- * @param name the name
- * @param sensitive the sensitivity
- */
- private IOCase(String name, boolean sensitive) {
- this.name = name;
- this.sensitive = sensitive;
- }
-
- /**
- * Replaces the enumeration from the stream with a real one.
- * This ensures that the correct flag is set for SYSTEM.
- *
- * @return the resolved object
- */
- private Object readResolve() {
- return forName(name);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets the name of the constant.
- *
- * @return the name of the constant
- */
- public String getName() {
- return name;
- }
-
- /**
- * Does the object represent case sensitive comparison.
- *
- * @return true if case sensitive
- */
- public boolean isCaseSensitive() {
- return sensitive;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares two strings using the case-sensitivity rule.
- *
- * This method mimics {@link String#compareTo} but takes case-sensitivity
- * into account.
- *
- * @param str1 the first string to compare, not null
- * @param str2 the second string to compare, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public int checkCompareTo(String str1, String str2) {
- if (str1 == null || str2 == null) {
- throw new NullPointerException("The strings must not be null");
- }
- return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2);
- }
-
- /**
- * Compares two strings using the case-sensitivity rule.
- *
- * This method mimics {@link String#equals} but takes case-sensitivity
- * into account.
- *
- * @param str1 the first string to compare, not null
- * @param str2 the second string to compare, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkEquals(String str1, String str2) {
- if (str1 == null || str2 == null) {
- throw new NullPointerException("The strings must not be null");
- }
- return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
- }
-
- /**
- * Checks if one string starts with another using the case-sensitivity rule.
- *
- * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
- * into account.
- *
- * @param str the string to check, not null
- * @param start the start to compare against, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkStartsWith(String str, String start) {
- return str.regionMatches(!sensitive, 0, start, 0, start.length());
- }
-
- /**
- * Checks if one string ends with another using the case-sensitivity rule.
- *
- * This method mimics {@link String#endsWith} but takes case-sensitivity
- * into account.
- *
- * @param str the string to check, not null
- * @param end the end to compare against, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkEndsWith(String str, String end) {
- int endLen = end.length();
- return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
- }
-
- /**
- * Checks if one string contains another at a specific index using the case-sensitivity rule.
- *
- * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)}
- * but takes case-sensitivity into account.
- *
- * @param str the string to check, not null
- * @param strStartIndex the index to start at in str
- * @param search the start to search for, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkRegionMatches(String str, int strStartIndex, String search) {
- return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
- }
-
- /**
- * Converts the case of the input String to a standard format.
- * Subsequent operations can then use standard String methods.
- *
- * @param str the string to convert, null returns null
- * @return the lower-case version if case-insensitive
- */
- String convertCase(String str) {
- if (str == null) {
- return null;
- }
- return sensitive ? str : str.toLowerCase();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets a string describing the sensitivity.
- *
- * @return a string describing the sensitivity
- */
- public String toString() {
- return name;
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.Serializable;
+
+/**
+ * Enumeration of IO case sensitivity.
+ *
+ * Different filing systems have different rules for case-sensitivity.
+ * Windows is case-insensitive, Unix is case-sensitive.
+ *
+ * This class captures that difference, providing an enumeration to
+ * control how filename comparisons should be performed. It also provides
+ * methods that use the enumeration to perform comparisons.
+ *
+ * Wherever possible, you should use the
+ * If you derialize this constant of Windows, and deserialize on Unix, or vice
+ * versa, then the value of the case-sensitivity flag will change.
+ */
+ public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
+
+ /** Serialization version. */
+ private static final long serialVersionUID = -6343169151696340687L;
+
+ /** The enumeration name. */
+ private final String name;
+
+ /** The sensitivity flag. */
+ private final transient boolean sensitive;
+
+ //-----------------------------------------------------------------------
+ /**
+ * Factory method to create an IOCase from a name.
+ *
+ * @param name the name to find
+ * @return the IOCase object
+ * @throws IllegalArgumentException if the name is invalid
+ */
+ public static IOCase forName(String name) {
+ if (IOCase.SENSITIVE.name.equals(name)){
+ return IOCase.SENSITIVE;
+ }
+ if (IOCase.INSENSITIVE.name.equals(name)){
+ return IOCase.INSENSITIVE;
+ }
+ if (IOCase.SYSTEM.name.equals(name)){
+ return IOCase.SYSTEM;
+ }
+ throw new IllegalArgumentException("Invalid IOCase name: " + name);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Private constructor.
+ *
+ * @param name the name
+ * @param sensitive the sensitivity
+ */
+ private IOCase(String name, boolean sensitive) {
+ this.name = name;
+ this.sensitive = sensitive;
+ }
+
+ /**
+ * Replaces the enumeration from the stream with a real one.
+ * This ensures that the correct flag is set for SYSTEM.
+ *
+ * @return the resolved object
+ */
+ private Object readResolve() {
+ return forName(name);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the name of the constant.
+ *
+ * @return the name of the constant
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Does the object represent case sensitive comparison.
+ *
+ * @return true if case sensitive
+ */
+ public boolean isCaseSensitive() {
+ return sensitive;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Compares two strings using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#compareTo} but takes case-sensitivity
+ * into account.
+ *
+ * @param str1 the first string to compare, not null
+ * @param str2 the second string to compare, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public int checkCompareTo(String str1, String str2) {
+ if (str1 == null || str2 == null) {
+ throw new NullPointerException("The strings must not be null");
+ }
+ return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2);
+ }
+
+ /**
+ * Compares two strings using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#equals} but takes case-sensitivity
+ * into account.
+ *
+ * @param str1 the first string to compare, not null
+ * @param str2 the second string to compare, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkEquals(String str1, String str2) {
+ if (str1 == null || str2 == null) {
+ throw new NullPointerException("The strings must not be null");
+ }
+ return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
+ }
+
+ /**
+ * Checks if one string starts with another using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
+ * into account.
+ *
+ * @param str the string to check, not null
+ * @param start the start to compare against, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkStartsWith(String str, String start) {
+ return str.regionMatches(!sensitive, 0, start, 0, start.length());
+ }
+
+ /**
+ * Checks if one string ends with another using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#endsWith} but takes case-sensitivity
+ * into account.
+ *
+ * @param str the string to check, not null
+ * @param end the end to compare against, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkEndsWith(String str, String end) {
+ int endLen = end.length();
+ return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
+ }
+
+ /**
+ * Checks if one string contains another at a specific index using the case-sensitivity rule.
+ *
+ * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)}
+ * but takes case-sensitivity into account.
+ *
+ * @param str the string to check, not null
+ * @param strStartIndex the index to start at in str
+ * @param search the start to search for, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkRegionMatches(String str, int strStartIndex, String search) {
+ return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
+ }
+
+ /**
+ * Converts the case of the input String to a standard format.
+ * Subsequent operations can then use standard String methods.
+ *
+ * @param str the string to convert, null returns null
+ * @return the lower-case version if case-insensitive
+ */
+ String convertCase(String str) {
+ if (str == null) {
+ return null;
+ }
+ return sensitive ? str : str.toLowerCase();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a string describing the sensitivity.
+ *
+ * @return a string describing the sensitivity
+ */
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/src/org/apache/commons/io/IOExceptionWithCause.java b/src/org/apache/commons/io/IOExceptionWithCause.java
index a15815a220b8620acfc9518730a11f539dd8a3f5..0d81d31f4630b3f1d1a5799f1f9091cfd80d0a54 100644
--- a/src/org/apache/commons/io/IOExceptionWithCause.java
+++ b/src/org/apache/commons/io/IOExceptionWithCause.java
@@ -1,69 +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.commons.io;
-
-import java.io.IOException;
-
-/**
- * Subclasses IOException with the {@link Throwable} constructors missing before Java 6. If you are using Java 6,
- * consider this class deprecated and use {@link IOException}.
- *
- * @author Apache Commons IO
- * @version $Id$
- * @since Commons IO 1.4
- */
-public class IOExceptionWithCause extends IOException {
-
- /**
- * Defines the serial version UID.
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructs a new instance with the given message and cause.
- *
- * As specified in {@link Throwable}, the message in the given
- * The message is set to
+ * As specified in {@link Throwable}, the message in the given
+ * The message is set to
- * This class provides static utility methods for input/output operations.
- *
- * The byte-to-char methods and char-to-byte methods involve a conversion step.
- * Two methods are provided in each case, one that uses the platform default
- * encoding and the other which allows you to specify an encoding. You are
- * encouraged to always specify an encoding because relying on the platform
- * default can lead to unexpected results, for example when moving from
- * development to production.
- *
- * All the methods in this class that read a stream are buffered internally.
- * This means that there is no cause to use a
- * Wherever possible, the methods in this class do not flush or close
- * the stream. This is to avoid making non-portable assumptions about the
- * streams' origin and further use. Thus the caller is still responsible for
- * closing streams after use.
- *
- * Origin of code: Excalibur.
- *
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @author Stephen Colebourne
- * @author Gareth Davis
- * @author Ian Springer
- * @author Niall Pemberton
- * @author Sandy McArthur
- * @version $Id: IOUtils.java 481854 2006-12-03 18:30:07Z scolebourne $
- */
-public class IOUtils {
- // NOTE: This class is focussed on InputStream, OutputStream, Reader and
- // Writer. Each method should take at least one of these as a parameter,
- // or return one of them.
-
- /**
- * The Unix directory separator character.
- */
- public static final char DIR_SEPARATOR_UNIX = '/';
- /**
- * The Windows directory separator character.
- */
- public static final char DIR_SEPARATOR_WINDOWS = '\\';
- /**
- * The system directory separator character.
- */
- public static final char DIR_SEPARATOR = File.separatorChar;
- /**
- * The Unix line separator string.
- */
- public static final String LINE_SEPARATOR_UNIX = "\n";
- /**
- * The Windows line separator string.
- */
- public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
- /**
- * The system line separator string.
- */
- public static final String LINE_SEPARATOR;
- static {
- // avoid security issues
- StringWriter buf = new StringWriter(4);
- PrintWriter out = new PrintWriter(buf);
- out.println();
- LINE_SEPARATOR = buf.toString();
- }
-
- /**
- * The default buffer size to use.
- */
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public IOUtils() {
- super();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Unconditionally close an
- * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
- * This is typically used in finally blocks.
- *
- * @param input the Reader to close, may be null or already closed
- */
- public static void closeQuietly(Reader input) {
- try {
- if (input != null) {
- input.close();
- }
- } catch (IOException ioe) {
- // ignore
- }
- }
-
- /**
- * Unconditionally close a
- * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
- * This is typically used in finally blocks.
- *
- * @param output the Writer to close, may be null or already closed
- */
- public static void closeQuietly(Writer output) {
- try {
- if (output != null) {
- output.close();
- }
- } catch (IOException ioe) {
- // ignore
- }
- }
-
- /**
- * Unconditionally close an
- * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
- * This is typically used in finally blocks.
- *
- * @param input the InputStream to close, may be null or already closed
- */
- public static void closeQuietly(InputStream input) {
- try {
- if (input != null) {
- input.close();
- }
- } catch (IOException ioe) {
- // ignore
- }
- }
-
- /**
- * Unconditionally close an
- * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
- * This is typically used in finally blocks.
- *
- * @param output the OutputStream to close, may be null or already closed
- */
- public static void closeQuietly(OutputStream output) {
- try {
- if (output != null) {
- output.close();
- }
- } catch (IOException ioe) {
- // ignore
- }
- }
-
- // read toByteArray
- //-----------------------------------------------------------------------
- /**
- * Get the contents of an
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This is the same as {@link String#getBytes()}.
- *
- * @param input the
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * @param input the byte array to read from
- * @param encoding the encoding to use, null means platform default
- * @return the requested String
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs (never occurs)
- * @deprecated Use {@link String#String(byte[],String)}
- */
- public static String toString(byte[] input, String encoding)
- throws IOException {
- if (encoding == null) {
- return new String(input);
- } else {
- return new String(input, encoding);
- }
- }
-
- // readLines
- //-----------------------------------------------------------------------
- /**
- * Get the contents of an
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- *
- * The recommended usage pattern is:
- *
- *
- * The recommended usage pattern is:
- *
- * Character encoding names can be found at
- * IANA.
- *
- * @param input the string to convert
- * @param encoding the encoding to use, null means platform default
- * @throws IOException if the encoding is invalid
- * @return an input stream
- * @since Commons IO 1.1
- */
- public static InputStream toInputStream(String input, String encoding) throws IOException {
- byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
- return new ByteArrayInputStream(bytes);
- }
-
- // write byte[]
- //-----------------------------------------------------------------------
- /**
- * Writes bytes from a
- * This method uses {@link String#String(byte[])}.
- *
- * @param data the byte array to write, do not modify during output,
- * null ignored
- * @param output the
- * Character encoding names can be found at
- * IANA.
- *
- * This method uses {@link String#String(byte[], String)}.
- *
- * @param data the byte array to write, do not modify during output,
- * null ignored
- * @param output the
- * This method uses {@link String#String(char[])} and
- * {@link String#getBytes()}.
- *
- * @param data the char array to write, do not modify during output,
- * null ignored
- * @param output the
- * Character encoding names can be found at
- * IANA.
- *
- * This method uses {@link String#String(char[])} and
- * {@link String#getBytes(String)}.
- *
- * @param data the char array to write, do not modify during output,
- * null ignored
- * @param output the
- * This method uses {@link String#getBytes()}.
- *
- * @param data the
- * Character encoding names can be found at
- * IANA.
- *
- * This method uses {@link String#getBytes(String)}.
- *
- * @param data the
- * This method uses {@link String#getBytes()}.
- *
- * @param data the
- * Character encoding names can be found at
- * IANA.
- *
- * This method uses {@link String#getBytes(String)}.
- *
- * @param data the
- * Character encoding names can be found at
- * IANA.
- *
- * @param lines the lines to write, null entries produce blank lines
- * @param lineEnding the line separator to use, null is system default
- * @param output the
- * This method buffers the input internally, so there is no need to use a
- *
- * Large streams (over 2GB) will return a bytes copied value of
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method uses {@link InputStreamReader}.
- *
- * @param input the
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * This method uses {@link InputStreamReader}.
- *
- * @param input the
- * This method buffers the input internally, so there is no need to use a
- *
- * Large streams (over 2GB) will return a chars copied value of
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * This method buffers the input internally, so there is no need to use a
- *
- * Due to the implementation of OutputStreamWriter, this method performs a
- * flush.
- *
- * This method uses {@link OutputStreamWriter}.
- *
- * @param input the
- * This method buffers the input internally, so there is no need to use a
- *
- * Character encoding names can be found at
- * IANA.
- *
- * Due to the implementation of OutputStreamWriter, this method performs a
- * flush.
- *
- * This method uses {@link OutputStreamWriter}.
- *
- * @param input the
- * This method buffers the input internally using
- *
- * This method buffers the input internally using
- *
+ * This class provides static utility methods for input/output operations.
+ *
+ * The byte-to-char methods and char-to-byte methods involve a conversion step.
+ * Two methods are provided in each case, one that uses the platform default
+ * encoding and the other which allows you to specify an encoding. You are
+ * encouraged to always specify an encoding because relying on the platform
+ * default can lead to unexpected results, for example when moving from
+ * development to production.
+ *
+ * All the methods in this class that read a stream are buffered internally.
+ * This means that there is no cause to use a
+ * Wherever possible, the methods in this class do not flush or close
+ * the stream. This is to avoid making non-portable assumptions about the
+ * streams' origin and further use. Thus the caller is still responsible for
+ * closing streams after use.
+ *
+ * Origin of code: Excalibur.
+ *
+ * @author Peter Donald
+ * @author Jeff Turner
+ * @author Matthew Hawthorne
+ * @author Stephen Colebourne
+ * @author Gareth Davis
+ * @author Ian Springer
+ * @author Niall Pemberton
+ * @author Sandy McArthur
+ * @version $Id: IOUtils.java 481854 2006-12-03 18:30:07Z scolebourne $
+ */
+public class IOUtils {
+ // NOTE: This class is focussed on InputStream, OutputStream, Reader and
+ // Writer. Each method should take at least one of these as a parameter,
+ // or return one of them.
+
+ /**
+ * The Unix directory separator character.
+ */
+ public static final char DIR_SEPARATOR_UNIX = '/';
+ /**
+ * The Windows directory separator character.
+ */
+ public static final char DIR_SEPARATOR_WINDOWS = '\\';
+ /**
+ * The system directory separator character.
+ */
+ public static final char DIR_SEPARATOR = File.separatorChar;
+ /**
+ * The Unix line separator string.
+ */
+ public static final String LINE_SEPARATOR_UNIX = "\n";
+ /**
+ * The Windows line separator string.
+ */
+ public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
+ /**
+ * The system line separator string.
+ */
+ public static final String LINE_SEPARATOR;
+ static {
+ // avoid security issues
+ StringWriter buf = new StringWriter(4);
+ PrintWriter out = new PrintWriter(buf);
+ out.println();
+ LINE_SEPARATOR = buf.toString();
+ }
+
+ /**
+ * The default buffer size to use.
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public IOUtils() {
+ super();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Unconditionally close an
+ * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param input the Reader to close, may be null or already closed
+ */
+ public static void closeQuietly(Reader input) {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close a
+ * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param output the Writer to close, may be null or already closed
+ */
+ public static void closeQuietly(Writer output) {
+ try {
+ if (output != null) {
+ output.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close an
+ * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param input the InputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(InputStream input) {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close an
+ * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param output the OutputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(OutputStream output) {
+ try {
+ if (output != null) {
+ output.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ // read toByteArray
+ //-----------------------------------------------------------------------
+ /**
+ * Get the contents of an
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This is the same as {@link String#getBytes()}.
+ *
+ * @param input the
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * @param input the byte array to read from
+ * @param encoding the encoding to use, null means platform default
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs (never occurs)
+ * @deprecated Use {@link String#String(byte[],String)}
+ */
+ public static String toString(byte[] input, String encoding)
+ throws IOException {
+ if (encoding == null) {
+ return new String(input);
+ } else {
+ return new String(input, encoding);
+ }
+ }
+
+ // readLines
+ //-----------------------------------------------------------------------
+ /**
+ * Get the contents of an
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ *
+ * The recommended usage pattern is:
+ *
+ *
+ * The recommended usage pattern is:
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * @param input the string to convert
+ * @param encoding the encoding to use, null means platform default
+ * @throws IOException if the encoding is invalid
+ * @return an input stream
+ * @since Commons IO 1.1
+ */
+ public static InputStream toInputStream(String input, String encoding) throws IOException {
+ byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
+ return new ByteArrayInputStream(bytes);
+ }
+
+ // write byte[]
+ //-----------------------------------------------------------------------
+ /**
+ * Writes bytes from a
+ * This method uses {@link String#String(byte[])}.
+ *
+ * @param data the byte array to write, do not modify during output,
+ * null ignored
+ * @param output the
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method uses {@link String#String(byte[], String)}.
+ *
+ * @param data the byte array to write, do not modify during output,
+ * null ignored
+ * @param output the
+ * This method uses {@link String#String(char[])} and
+ * {@link String#getBytes()}.
+ *
+ * @param data the char array to write, do not modify during output,
+ * null ignored
+ * @param output the
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method uses {@link String#String(char[])} and
+ * {@link String#getBytes(String)}.
+ *
+ * @param data the char array to write, do not modify during output,
+ * null ignored
+ * @param output the
+ * This method uses {@link String#getBytes()}.
+ *
+ * @param data the
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method uses {@link String#getBytes(String)}.
+ *
+ * @param data the
+ * This method uses {@link String#getBytes()}.
+ *
+ * @param data the
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method uses {@link String#getBytes(String)}.
+ *
+ * @param data the
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * @param lines the lines to write, null entries produce blank lines
+ * @param lineEnding the line separator to use, null is system default
+ * @param output the
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Large streams (over 2GB) will return a bytes copied value of
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method uses {@link InputStreamReader}.
+ *
+ * @param input the
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * This method uses {@link InputStreamReader}.
+ *
+ * @param input the
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Large streams (over 2GB) will return a chars copied value of
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Due to the implementation of OutputStreamWriter, this method performs a
+ * flush.
+ *
+ * This method uses {@link OutputStreamWriter}.
+ *
+ * @param input the
+ * This method buffers the input internally, so there is no need to use a
+ *
+ * Character encoding names can be found at
+ * IANA.
+ *
+ * Due to the implementation of OutputStreamWriter, this method performs a
+ * flush.
+ *
+ * This method uses {@link OutputStreamWriter}.
+ *
+ * @param input the
+ * This method buffers the input internally using
+ *
+ * This method buffers the input internally using
+ *
- *
- * The recommended usage pattern is:
- *
+ *
+ * The recommended usage pattern is:
+ *
- * This comparator can be used to sort lists or arrays of files
- * by using the default file comparison.
- *
- * Example of sorting a list of files using the
- * {@link #DEFAULT_COMPARATOR} singleton instance:
- *
- * Example of doing a reverse sort of an array of files using the
- * {@link #DEFAULT_REVERSE} singleton instance:
- *
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class DefaultFileComparator implements Comparator, Serializable {
-
- /** Singleton default comparator instance */
- public static final Comparator DEFAULT_COMPARATOR = new DefaultFileComparator();
-
- /** Singleton reverse default comparator instance */
- public static final Comparator DEFAULT_REVERSE = new ReverseComparator(DEFAULT_COMPARATOR);
-
- /**
- * Compare the two files using the {@link File#compareTo(File)} method.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return the result of calling file1's
- * {@link File#compareTo(File)} with file2 as the parameter.
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- return file1.compareTo(file2);
- }
-}
+/*
+ * 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.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Compare two files using the default {@link File#compareTo(File)} method.
+ *
+ * This comparator can be used to sort lists or arrays of files
+ * by using the default file comparison.
+ *
+ * Example of sorting a list of files using the
+ * {@link #DEFAULT_COMPARATOR} singleton instance:
+ *
+ * Example of doing a reverse sort of an array of files using the
+ * {@link #DEFAULT_REVERSE} singleton instance:
+ *
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class DefaultFileComparator implements Comparator, Serializable {
+
+ /** Singleton default comparator instance */
+ public static final Comparator DEFAULT_COMPARATOR = new DefaultFileComparator();
+
+ /** Singleton reverse default comparator instance */
+ public static final Comparator DEFAULT_REVERSE = new ReverseComparator(DEFAULT_COMPARATOR);
+
+ /**
+ * Compare the two files using the {@link File#compareTo(File)} method.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return the result of calling file1's
+ * {@link File#compareTo(File)} with file2 as the parameter.
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ return file1.compareTo(file2);
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/ExtensionFileComparator.java b/src/org/apache/commons/io/comparator/ExtensionFileComparator.java
index 158480fb397a91de98e72f4602497979f58481be..492b2f537a85cf04620ddd33ec89f470f8b7043a 100644
--- a/src/org/apache/commons/io/comparator/ExtensionFileComparator.java
+++ b/src/org/apache/commons/io/comparator/ExtensionFileComparator.java
@@ -1,112 +1,112 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOCase;
-
-/**
- * Compare the file name extensions for order
- * (see {@link FilenameUtils#getExtension(String)}).
- *
- * This comparator can be used to sort lists or arrays of files
- * by their file extension either in a case-sensitive, case-insensitive or
- * system dependant case sensitive way. A number of singleton instances
- * are provided for the various case sensitivity options (using {@link IOCase})
- * and the reverse of those options.
- *
- * Example of a case-sensitive file extension sort using the
- * {@link #EXTENSION_COMPARATOR} singleton instance:
- *
- * Example of a reverse case-insensitive file extension sort using the
- * {@link #EXTENSION_INSENSITIVE_REVERSE} singleton instance:
- *
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class ExtensionFileComparator implements Comparator, Serializable {
-
- /** Case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator EXTENSION_COMPARATOR = new ExtensionFileComparator();
-
- /** Reverse case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator EXTENSION_REVERSE = new ReverseComparator(EXTENSION_COMPARATOR);
-
- /** Case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator EXTENSION_INSENSITIVE_COMPARATOR = new ExtensionFileComparator(IOCase.INSENSITIVE);
-
- /** Reverse case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator EXTENSION_INSENSITIVE_REVERSE
- = new ReverseComparator(EXTENSION_INSENSITIVE_COMPARATOR);
-
- /** System sensitive extension comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator EXTENSION_SYSTEM_COMPARATOR = new ExtensionFileComparator(IOCase.SYSTEM);
-
- /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator EXTENSION_SYSTEM_REVERSE = new ReverseComparator(EXTENSION_SYSTEM_COMPARATOR);
-
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Construct a case sensitive file extension comparator instance.
- */
- public ExtensionFileComparator() {
- this.caseSensitivity = IOCase.SENSITIVE;
- }
-
- /**
- * Construct a file extension comparator instance with the specified case-sensitivity.
- *
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- */
- public ExtensionFileComparator(IOCase caseSensitivity) {
- this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
- }
-
- /**
- * Compare the extensions of two files the specified case sensitivity.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return a negative value if the first file's extension
- * is less than the second, zero if the extensions are the
- * same and a positive value if the first files extension
- * is greater than the second file.
- *
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- String suffix1 = FilenameUtils.getExtension(file1.getName());
- String suffix2 = FilenameUtils.getExtension(file2.getName());
- return caseSensitivity.checkCompareTo(suffix1, suffix2);
- }
-}
+/*
+ * 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.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOCase;
+
+/**
+ * Compare the file name extensions for order
+ * (see {@link FilenameUtils#getExtension(String)}).
+ *
+ * This comparator can be used to sort lists or arrays of files
+ * by their file extension either in a case-sensitive, case-insensitive or
+ * system dependant case sensitive way. A number of singleton instances
+ * are provided for the various case sensitivity options (using {@link IOCase})
+ * and the reverse of those options.
+ *
+ * Example of a case-sensitive file extension sort using the
+ * {@link #EXTENSION_COMPARATOR} singleton instance:
+ *
+ * Example of a reverse case-insensitive file extension sort using the
+ * {@link #EXTENSION_INSENSITIVE_REVERSE} singleton instance:
+ *
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class ExtensionFileComparator implements Comparator, Serializable {
+
+ /** Case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator EXTENSION_COMPARATOR = new ExtensionFileComparator();
+
+ /** Reverse case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator EXTENSION_REVERSE = new ReverseComparator(EXTENSION_COMPARATOR);
+
+ /** Case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator EXTENSION_INSENSITIVE_COMPARATOR = new ExtensionFileComparator(IOCase.INSENSITIVE);
+
+ /** Reverse case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator EXTENSION_INSENSITIVE_REVERSE
+ = new ReverseComparator(EXTENSION_INSENSITIVE_COMPARATOR);
+
+ /** System sensitive extension comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator EXTENSION_SYSTEM_COMPARATOR = new ExtensionFileComparator(IOCase.SYSTEM);
+
+ /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator EXTENSION_SYSTEM_REVERSE = new ReverseComparator(EXTENSION_SYSTEM_COMPARATOR);
+
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Construct a case sensitive file extension comparator instance.
+ */
+ public ExtensionFileComparator() {
+ this.caseSensitivity = IOCase.SENSITIVE;
+ }
+
+ /**
+ * Construct a file extension comparator instance with the specified case-sensitivity.
+ *
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ */
+ public ExtensionFileComparator(IOCase caseSensitivity) {
+ this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+ }
+
+ /**
+ * Compare the extensions of two files the specified case sensitivity.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return a negative value if the first file's extension
+ * is less than the second, zero if the extensions are the
+ * same and a positive value if the first files extension
+ * is greater than the second file.
+ *
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ String suffix1 = FilenameUtils.getExtension(file1.getName());
+ String suffix2 = FilenameUtils.getExtension(file2.getName());
+ return caseSensitivity.checkCompareTo(suffix1, suffix2);
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/LastModifiedFileComparator.java b/src/org/apache/commons/io/comparator/LastModifiedFileComparator.java
index 8265023d06c3cfae43f3f64676cbf04a2362266f..cd966a4e742834e15096c732f6d95a3b9021b1b1 100644
--- a/src/org/apache/commons/io/comparator/LastModifiedFileComparator.java
+++ b/src/org/apache/commons/io/comparator/LastModifiedFileComparator.java
@@ -1,79 +1,79 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-/**
- * Compare the last modified date/time of two files for order
- * (see {@link File#lastModified()}).
- *
- * This comparator can be used to sort lists or arrays of files
- * by their last modified date/time.
- *
- * Example of sorting a list of files using the
- * {@link #LASTMODIFIED_COMPARATOR} singleton instance:
- *
- * Example of doing a reverse sort of an array of files using the
- * {@link #LASTMODIFIED_REVERSE} singleton instance:
- *
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class LastModifiedFileComparator implements Comparator, Serializable {
-
- /** Last modified comparator instance */
- public static final Comparator LASTMODIFIED_COMPARATOR = new LastModifiedFileComparator();
-
- /** Reverse last modified comparator instance */
- public static final Comparator LASTMODIFIED_REVERSE = new ReverseComparator(LASTMODIFIED_COMPARATOR);
-
- /**
- * Compare the last the last modified date/time of two files.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return a negative value if the first file's lastmodified date/time
- * is less than the second, zero if the lastmodified date/time are the
- * same and a positive value if the first files lastmodified date/time
- * is greater than the second file.
- *
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- long result = file1.lastModified() - file2.lastModified();
- if (result < 0) {
- return -1;
- } else if (result > 0) {
- return 1;
- } else {
- return 0;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Compare the last modified date/time of two files for order
+ * (see {@link File#lastModified()}).
+ *
+ * This comparator can be used to sort lists or arrays of files
+ * by their last modified date/time.
+ *
+ * Example of sorting a list of files using the
+ * {@link #LASTMODIFIED_COMPARATOR} singleton instance:
+ *
+ * Example of doing a reverse sort of an array of files using the
+ * {@link #LASTMODIFIED_REVERSE} singleton instance:
+ *
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class LastModifiedFileComparator implements Comparator, Serializable {
+
+ /** Last modified comparator instance */
+ public static final Comparator LASTMODIFIED_COMPARATOR = new LastModifiedFileComparator();
+
+ /** Reverse last modified comparator instance */
+ public static final Comparator LASTMODIFIED_REVERSE = new ReverseComparator(LASTMODIFIED_COMPARATOR);
+
+ /**
+ * Compare the last the last modified date/time of two files.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return a negative value if the first file's lastmodified date/time
+ * is less than the second, zero if the lastmodified date/time are the
+ * same and a positive value if the first files lastmodified date/time
+ * is greater than the second file.
+ *
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ long result = file1.lastModified() - file2.lastModified();
+ if (result < 0) {
+ return -1;
+ } else if (result > 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/NameFileComparator.java b/src/org/apache/commons/io/comparator/NameFileComparator.java
index 76af21eeb6934c8919f5d0fd6d3f1d8851d71f35..cbaf4c47545447836fc79c3fbd2aabd903c8c2d3 100644
--- a/src/org/apache/commons/io/comparator/NameFileComparator.java
+++ b/src/org/apache/commons/io/comparator/NameFileComparator.java
@@ -1,106 +1,106 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Compare the names of two files for order (see {@link File#getName()}).
- *
- * This comparator can be used to sort lists or arrays of files
- * by their name either in a case-sensitive, case-insensitive or
- * system dependant case sensitive way. A number of singleton instances
- * are provided for the various case sensitivity options (using {@link IOCase})
- * and the reverse of those options.
- *
- * Example of a case-sensitive file name sort using the
- * {@link #NAME_COMPARATOR} singleton instance:
- *
- * Example of a reverse case-insensitive file name sort using the
- * {@link #NAME_INSENSITIVE_REVERSE} singleton instance:
- *
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class NameFileComparator implements Comparator, Serializable {
-
- /** Case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator NAME_COMPARATOR = new NameFileComparator();
-
- /** Reverse case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator NAME_REVERSE = new ReverseComparator(NAME_COMPARATOR);
-
- /** Case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator NAME_INSENSITIVE_COMPARATOR = new NameFileComparator(IOCase.INSENSITIVE);
-
- /** Reverse case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator NAME_INSENSITIVE_REVERSE = new ReverseComparator(NAME_INSENSITIVE_COMPARATOR);
-
- /** System sensitive name comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator NAME_SYSTEM_COMPARATOR = new NameFileComparator(IOCase.SYSTEM);
-
- /** Reverse system sensitive name comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator NAME_SYSTEM_REVERSE = new ReverseComparator(NAME_SYSTEM_COMPARATOR);
-
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Construct a case sensitive file name comparator instance.
- */
- public NameFileComparator() {
- this.caseSensitivity = IOCase.SENSITIVE;
- }
-
- /**
- * Construct a file name comparator instance with the specified case-sensitivity.
- *
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- */
- public NameFileComparator(IOCase caseSensitivity) {
- this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
- }
-
- /**
- * Compare the names of two files with the specified case sensitivity.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return a negative value if the first file's name
- * is less than the second, zero if the names are the
- * same and a positive value if the first files name
- * is greater than the second file.
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- return caseSensitivity.checkCompareTo(file1.getName(), file2.getName());
- }
-}
+/*
+ * 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.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Compare the names of two files for order (see {@link File#getName()}).
+ *
+ * This comparator can be used to sort lists or arrays of files
+ * by their name either in a case-sensitive, case-insensitive or
+ * system dependant case sensitive way. A number of singleton instances
+ * are provided for the various case sensitivity options (using {@link IOCase})
+ * and the reverse of those options.
+ *
+ * Example of a case-sensitive file name sort using the
+ * {@link #NAME_COMPARATOR} singleton instance:
+ *
+ * Example of a reverse case-insensitive file name sort using the
+ * {@link #NAME_INSENSITIVE_REVERSE} singleton instance:
+ *
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class NameFileComparator implements Comparator, Serializable {
+
+ /** Case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator NAME_COMPARATOR = new NameFileComparator();
+
+ /** Reverse case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator NAME_REVERSE = new ReverseComparator(NAME_COMPARATOR);
+
+ /** Case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator NAME_INSENSITIVE_COMPARATOR = new NameFileComparator(IOCase.INSENSITIVE);
+
+ /** Reverse case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator NAME_INSENSITIVE_REVERSE = new ReverseComparator(NAME_INSENSITIVE_COMPARATOR);
+
+ /** System sensitive name comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator NAME_SYSTEM_COMPARATOR = new NameFileComparator(IOCase.SYSTEM);
+
+ /** Reverse system sensitive name comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator NAME_SYSTEM_REVERSE = new ReverseComparator(NAME_SYSTEM_COMPARATOR);
+
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Construct a case sensitive file name comparator instance.
+ */
+ public NameFileComparator() {
+ this.caseSensitivity = IOCase.SENSITIVE;
+ }
+
+ /**
+ * Construct a file name comparator instance with the specified case-sensitivity.
+ *
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ */
+ public NameFileComparator(IOCase caseSensitivity) {
+ this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+ }
+
+ /**
+ * Compare the names of two files with the specified case sensitivity.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return a negative value if the first file's name
+ * is less than the second, zero if the names are the
+ * same and a positive value if the first files name
+ * is greater than the second file.
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ return caseSensitivity.checkCompareTo(file1.getName(), file2.getName());
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/PathFileComparator.java b/src/org/apache/commons/io/comparator/PathFileComparator.java
index 0b28b696020231ebbdabeee14c12939e096809bc..cf6c36185f238ae3db9aadd39ed226ca9889bf72 100644
--- a/src/org/apache/commons/io/comparator/PathFileComparator.java
+++ b/src/org/apache/commons/io/comparator/PathFileComparator.java
@@ -1,107 +1,107 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Compare the path of two files for order (see {@link File#getPath()}).
- *
- * This comparator can be used to sort lists or arrays of files
- * by their path either in a case-sensitive, case-insensitive or
- * system dependant case sensitive way. A number of singleton instances
- * are provided for the various case sensitivity options (using {@link IOCase})
- * and the reverse of those options.
- *
- * Example of a case-sensitive file path sort using the
- * {@link #PATH_COMPARATOR} singleton instance:
- *
- * Example of a reverse case-insensitive file path sort using the
- * {@link #PATH_INSENSITIVE_REVERSE} singleton instance:
- *
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class PathFileComparator implements Comparator, Serializable {
-
- /** Case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator PATH_COMPARATOR = new PathFileComparator();
-
- /** Reverse case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */
- public static final Comparator PATH_REVERSE = new ReverseComparator(PATH_COMPARATOR);
-
- /** Case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator PATH_INSENSITIVE_COMPARATOR = new PathFileComparator(IOCase.INSENSITIVE);
-
- /** Reverse case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */
- public static final Comparator PATH_INSENSITIVE_REVERSE = new ReverseComparator(PATH_INSENSITIVE_COMPARATOR);
-
- /** System sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator PATH_SYSTEM_COMPARATOR = new PathFileComparator(IOCase.SYSTEM);
-
- /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
- public static final Comparator PATH_SYSTEM_REVERSE = new ReverseComparator(PATH_SYSTEM_COMPARATOR);
-
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Construct a case sensitive file path comparator instance.
- */
- public PathFileComparator() {
- this.caseSensitivity = IOCase.SENSITIVE;
- }
-
- /**
- * Construct a file path comparator instance with the specified case-sensitivity.
- *
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- */
- public PathFileComparator(IOCase caseSensitivity) {
- this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
- }
-
- /**
- * Compare the paths of two files the specified case sensitivity.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return a negative value if the first file's path
- * is less than the second, zero if the paths are the
- * same and a positive value if the first files path
- * is greater than the second file.
- *
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- return caseSensitivity.checkCompareTo(file1.getPath(), file2.getPath());
- }
-}
+/*
+ * 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.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Compare the path of two files for order (see {@link File#getPath()}).
+ *
+ * This comparator can be used to sort lists or arrays of files
+ * by their path either in a case-sensitive, case-insensitive or
+ * system dependant case sensitive way. A number of singleton instances
+ * are provided for the various case sensitivity options (using {@link IOCase})
+ * and the reverse of those options.
+ *
+ * Example of a case-sensitive file path sort using the
+ * {@link #PATH_COMPARATOR} singleton instance:
+ *
+ * Example of a reverse case-insensitive file path sort using the
+ * {@link #PATH_INSENSITIVE_REVERSE} singleton instance:
+ *
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class PathFileComparator implements Comparator, Serializable {
+
+ /** Case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator PATH_COMPARATOR = new PathFileComparator();
+
+ /** Reverse case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */
+ public static final Comparator PATH_REVERSE = new ReverseComparator(PATH_COMPARATOR);
+
+ /** Case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator PATH_INSENSITIVE_COMPARATOR = new PathFileComparator(IOCase.INSENSITIVE);
+
+ /** Reverse case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */
+ public static final Comparator PATH_INSENSITIVE_REVERSE = new ReverseComparator(PATH_INSENSITIVE_COMPARATOR);
+
+ /** System sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator PATH_SYSTEM_COMPARATOR = new PathFileComparator(IOCase.SYSTEM);
+
+ /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */
+ public static final Comparator PATH_SYSTEM_REVERSE = new ReverseComparator(PATH_SYSTEM_COMPARATOR);
+
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Construct a case sensitive file path comparator instance.
+ */
+ public PathFileComparator() {
+ this.caseSensitivity = IOCase.SENSITIVE;
+ }
+
+ /**
+ * Construct a file path comparator instance with the specified case-sensitivity.
+ *
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ */
+ public PathFileComparator(IOCase caseSensitivity) {
+ this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+ }
+
+ /**
+ * Compare the paths of two files the specified case sensitivity.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return a negative value if the first file's path
+ * is less than the second, zero if the paths are the
+ * same and a positive value if the first files path
+ * is greater than the second file.
+ *
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ return caseSensitivity.checkCompareTo(file1.getPath(), file2.getPath());
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/ReverseComparator.java b/src/org/apache/commons/io/comparator/ReverseComparator.java
index af9749ee3e374b3c873e55c9f20bab991e2c8030..30846a3cae5b69310414534e2c750b9266960bcd 100644
--- a/src/org/apache/commons/io/comparator/ReverseComparator.java
+++ b/src/org/apache/commons/io/comparator/ReverseComparator.java
@@ -1,57 +1,57 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-/**
- * Reverses the result of comparing two objects using
- * the delegate {@link Comparator}.
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-class ReverseComparator implements Comparator, Serializable {
-
- private final Comparator delegate;
-
- /**
- * Construct an instance with the sepecified delegate {@link Comparator}.
- *
- * @param delegate The comparator to delegate to
- */
- public ReverseComparator(Comparator delegate) {
- if (delegate == null) {
- throw new IllegalArgumentException("Delegate comparator is missing");
- }
- this.delegate = delegate;
- }
-
- /**
- * Compare using the delegate Comparator, but reversing the result.
- *
- * @param obj1 The first object to compare
- * @param obj2 The second object to compare
- * @return the result from the delegate {@link Comparator#compare(Object, Object)}
- * reversing the value (i.e. positive becomes negative and vice versa)
- */
- public int compare(Object obj1, Object obj2) {
- return delegate.compare(obj2, obj1); // parameters switched round
- }
-
-}
+/*
+ * 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.commons.io.comparator;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Reverses the result of comparing two objects using
+ * the delegate {@link Comparator}.
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+class ReverseComparator implements Comparator, Serializable {
+
+ private final Comparator delegate;
+
+ /**
+ * Construct an instance with the sepecified delegate {@link Comparator}.
+ *
+ * @param delegate The comparator to delegate to
+ */
+ public ReverseComparator(Comparator delegate) {
+ if (delegate == null) {
+ throw new IllegalArgumentException("Delegate comparator is missing");
+ }
+ this.delegate = delegate;
+ }
+
+ /**
+ * Compare using the delegate Comparator, but reversing the result.
+ *
+ * @param obj1 The first object to compare
+ * @param obj2 The second object to compare
+ * @return the result from the delegate {@link Comparator#compare(Object, Object)}
+ * reversing the value (i.e. positive becomes negative and vice versa)
+ */
+ public int compare(Object obj1, Object obj2) {
+ return delegate.compare(obj2, obj1); // parameters switched round
+ }
+
+}
diff --git a/src/org/apache/commons/io/comparator/SizeFileComparator.java b/src/org/apache/commons/io/comparator/SizeFileComparator.java
index a1621671c2febf0b7cb1d9bb968bb2ba1ccbf758..4a3f67249b644095b82e9b3d2c92b02a7c4a6cf9 100644
--- a/src/org/apache/commons/io/comparator/SizeFileComparator.java
+++ b/src/org/apache/commons/io/comparator/SizeFileComparator.java
@@ -1,132 +1,132 @@
-/*
- * 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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.commons.io.FileUtils;
-
-/**
- * Compare the length/size of two files for order (see
- * {@link File#length()} and {@link FileUtils#sizeOfDirectory(File)}).
- *
- * This comparator can be used to sort lists or arrays of files
- * by their length/size.
- *
- * Example of sorting a list of files using the
- * {@link #SIZE_COMPARATOR} singleton instance:
- *
- * Example of doing a reverse sort of an array of files using the
- * {@link #SIZE_REVERSE} singleton instance:
- *
- * N.B. Directories are treated as zero size unless
- *
- * If the
+ * This comparator can be used to sort lists or arrays of files
+ * by their length/size.
+ *
+ * Example of sorting a list of files using the
+ * {@link #SIZE_COMPARATOR} singleton instance:
+ *
+ * Example of doing a reverse sort of an array of files using the
+ * {@link #SIZE_REVERSE} singleton instance:
+ *
+ * N.B. Directories are treated as zero size unless
+ *
+ * If the This package provides various {@link java.util.Comparator} implementations
-for {@link java.io.File}s.
- This package provides various {@link java.util.Comparator} implementations
+for {@link java.io.File}s.
+
- * Note that a subclass must override one of the accept methods,
- * otherwise your class will infinitely loop.
- *
- * @since Commons IO 1.0
- * @version $Revision: 539231 $ $Date: 2007-05-18 04:10:33 +0100 (Fri, 18 May 2007) $
- *
- * @author Stephen Colebourne
- */
-public abstract class AbstractFileFilter implements IOFileFilter {
-
- /**
- * Checks to see if the File should be accepted by this filter.
- *
- * @param file the File to check
- * @return true if this file matches the test
- */
- public boolean accept(File file) {
- return accept(file.getParentFile(), file.getName());
- }
-
- /**
- * Checks to see if the File should be accepted by this filter.
- *
- * @param dir the directory File to check
- * @param name the filename within the directory to check
- * @return true if this file matches the test
- */
- public boolean accept(File dir, String name) {
- return accept(new File(dir, name));
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- String name = getClass().getName();
- int period = name.lastIndexOf('.');
- return (period > 0 ? name.substring(period + 1) : name);
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+
+/**
+ * An abstract class which implements the Java FileFilter and FilenameFilter
+ * interfaces via the IOFileFilter interface.
+ *
+ * Note that a subclass must override one of the accept methods,
+ * otherwise your class will infinitely loop.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 539231 $ $Date: 2007-05-18 04:10:33 +0100 (Fri, 18 May 2007) $
+ *
+ * @author Stephen Colebourne
+ */
+public abstract class AbstractFileFilter implements IOFileFilter {
+
+ /**
+ * Checks to see if the File should be accepted by this filter.
+ *
+ * @param file the File to check
+ * @return true if this file matches the test
+ */
+ public boolean accept(File file) {
+ return accept(file.getParentFile(), file.getName());
+ }
+
+ /**
+ * Checks to see if the File should be accepted by this filter.
+ *
+ * @param dir the directory File to check
+ * @param name the filename within the directory to check
+ * @return true if this file matches the test
+ */
+ public boolean accept(File dir, String name) {
+ return accept(new File(dir, name));
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ String name = getClass().getName();
+ int period = name.lastIndexOf('.');
+ return (period > 0 ? name.substring(period + 1) : name);
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/AgeFileFilter.java b/src/org/apache/commons/io/filefilter/AgeFileFilter.java
index ab73cb840ef779561e94c0a5f801f76a4077c51f..0139e681422bc5657ed71311cf9c2c62589a9839 100644
--- a/src/org/apache/commons/io/filefilter/AgeFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/AgeFileFilter.java
@@ -1,150 +1,150 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Date;
-
-import org.apache.commons.io.FileUtils;
-
-/**
- * Filters files based on a cutoff time, can filter either newer
- * files or files equal to or older.
- *
- * For example, to print all files and directories in the
- * current directory older than one day:
- *
- *
- * If last modification time equals cutoff and newer files are required,
- * file IS NOT selected.
- * If last modification time equals cutoff and older files are required,
- * file IS selected.
- *
- * @param file the File to check
- * @return true if the filename matches
- */
- public boolean accept(File file) {
- boolean newer = FileUtils.isFileNewer(file, cutoff);
- return acceptOlder ? !newer : newer;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- String condition = acceptOlder ? "<=" : ">";
- return super.toString() + "(" + condition + cutoff + ")";
- }
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Date;
+
+import org.apache.commons.io.FileUtils;
+
+/**
+ * Filters files based on a cutoff time, can filter either newer
+ * files or files equal to or older.
+ *
+ * For example, to print all files and directories in the
+ * current directory older than one day:
+ *
+ *
+ * If last modification time equals cutoff and newer files are required,
+ * file IS NOT selected.
+ * If last modification time equals cutoff and older files are required,
+ * file IS selected.
+ *
+ * @param file the File to check
+ * @return true if the filename matches
+ */
+ public boolean accept(File file) {
+ boolean newer = FileUtils.isFileNewer(file, cutoff);
+ return acceptOlder ? !newer : newer;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ String condition = acceptOlder ? "<=" : ">";
+ return super.toString() + "(" + condition + cutoff + ")";
+ }
+}
diff --git a/src/org/apache/commons/io/filefilter/AndFileFilter.java b/src/org/apache/commons/io/filefilter/AndFileFilter.java
index deda11f93bebd749fcdd044de0d8a60952247b87..a8375271b8c5b5e70b8da9450987e1675b888466 100644
--- a/src/org/apache/commons/io/filefilter/AndFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/AndFileFilter.java
@@ -1,167 +1,167 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A {@link java.io.FileFilter} providing conditional AND logic across a list of
- * file filters. This filter returns
- * Example, showing how to print out a list of the
- * current directory's readable files:
- *
- *
- * Example, showing how to print out a list of the
- * current directory's un-readable files:
- *
- *
- * Example, showing how to print out a list of the
- * current directory's read-only files:
- *
- *
+ * Example, showing how to print out a list of the
+ * current directory's readable files:
+ *
+ *
+ * Example, showing how to print out a list of the
+ * current directory's un-readable files:
+ *
+ *
+ * Example, showing how to print out a list of the
+ * current directory's read-only files:
+ *
+ *
- * Example, showing how to print out a list of the
- * current directory's writable files:
- *
- *
- * Example, showing how to print out a list of the
- * current directory's un-writable files:
- *
- *
- * N.B. For read-only files, use
- *
+ * Example, showing how to print out a list of the
+ * current directory's writable files:
+ *
+ *
+ * Example, showing how to print out a list of the
+ * current directory's un-writable files:
+ *
+ *
+ * N.B. For read-only files, use
+ *
- * For example, here is how to print out a list of the
- * current directory's subdirectories:
- *
- *
+ * For example, here is how to print out a list of the
+ * current directory's subdirectories:
+ *
+ *
- * If the
- * Example, showing how to print out a list of the
- * current directory's empty files/directories:
- *
- *
- * Example, showing how to print out a list of the
- * current directory's non-empty files/directories:
- *
- *
+ * If the
+ * Example, showing how to print out a list of the
+ * current directory's empty files/directories:
+ *
+ *
+ * Example, showing how to print out a list of the
+ * current directory's non-empty files/directories:
+ *
+ *
- * For example, here is how to print out a list of the real files
- * within the current directory:
- *
- *
+ * For example, here is how to print out a list of the real files
+ * within the current directory:
+ *
+ *
- * Example, showing how to print out a list of the
- * current directory's hidden files:
- *
- *
- * Example, showing how to print out a list of the
- * current directory's visible (i.e. not hidden) files:
- *
- *
+ * Example, showing how to print out a list of the
+ * current directory's hidden files:
+ *
+ *
+ * Example, showing how to print out a list of the
+ * current directory's visible (i.e. not hidden) files:
+ *
+ *
- * Defined in {@link java.io.FileFilter}.
- *
- * @param file the File to check
- * @return true if this file matches the test
- */
- public boolean accept(File file);
-
- /**
- * Checks to see if the File should be accepted by this filter.
- *
- * Defined in {@link java.io.FilenameFilter}.
- *
- * @param dir the directory File to check
- * @param name the filename within the directory to check
- * @return true if this file matches the test
- */
- public boolean accept(File dir, String name);
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+
+/**
+ * An interface which brings the FileFilter and FilenameFilter
+ * interfaces together.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 471628 $ $Date: 2006-11-06 04:06:45 +0000 (Mon, 06 Nov 2006) $
+ *
+ * @author Stephen Colebourne
+ */
+public interface IOFileFilter extends FileFilter, FilenameFilter {
+
+ /**
+ * Checks to see if the File should be accepted by this filter.
+ *
+ * Defined in {@link java.io.FileFilter}.
+ *
+ * @param file the File to check
+ * @return true if this file matches the test
+ */
+ public boolean accept(File file);
+
+ /**
+ * Checks to see if the File should be accepted by this filter.
+ *
+ * Defined in {@link java.io.FilenameFilter}.
+ *
+ * @param dir the directory File to check
+ * @param name the filename within the directory to check
+ * @return true if this file matches the test
+ */
+ public boolean accept(File dir, String name);
+
+}
diff --git a/src/org/apache/commons/io/filefilter/NameFileFilter.java b/src/org/apache/commons/io/filefilter/NameFileFilter.java
index fa1c80f730f9a0c37b20446edccc48ca26f48bda..92c4353ad0fa8524262513894e255afe931e8478 100644
--- a/src/org/apache/commons/io/filefilter/NameFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/NameFileFilter.java
@@ -1,191 +1,191 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Filters filenames for a certain name.
- *
- * For example, to print all files and directories in the
- * current directory whose name is
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param names the names to allow, must not be null
- * @throws IllegalArgumentException if the names array is null
- */
- public NameFileFilter(String[] names) {
- this(names, null);
- }
-
- /**
- * Constructs a new name file filter for an array of names specifying case-sensitivity.
- *
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param names the names to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the names array is null
- */
- public NameFileFilter(String[] names, IOCase caseSensitivity) {
- if (names == null) {
- throw new IllegalArgumentException("The array of names must not be null");
- }
- this.names = names;
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new case-sensitive name file filter for a list of names.
- *
- * @param names the names to allow, must not be null
- * @throws IllegalArgumentException if the name list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public NameFileFilter(List names) {
- this(names, null);
- }
-
- /**
- * Constructs a new name file filter for a list of names specifying case-sensitivity.
- *
- * @param names the names to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the name list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public NameFileFilter(List names, IOCase caseSensitivity) {
- if (names == null) {
- throw new IllegalArgumentException("The list of names must not be null");
- }
- this.names = (String[]) names.toArray(new String[names.size()]);
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks to see if the filename matches.
- *
- * @param file the File to check
- * @return true if the filename matches
- */
- public boolean accept(File file) {
- String name = file.getName();
- for (int i = 0; i < this.names.length; i++) {
- if (caseSensitivity.checkEquals(name, names[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks to see if the filename matches.
- *
- * @param file the File directory
- * @param name the filename
- * @return true if the filename matches
- */
- public boolean accept(File file, String name) {
- for (int i = 0; i < names.length; i++) {
- if (caseSensitivity.checkEquals(name, names[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (names != null) {
- for (int i = 0; i < names.length; i++) {
- if (i > 0) {
- buffer.append(",");
- }
- buffer.append(names[i]);
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Filters filenames for a certain name.
+ *
+ * For example, to print all files and directories in the
+ * current directory whose name is
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param names the names to allow, must not be null
+ * @throws IllegalArgumentException if the names array is null
+ */
+ public NameFileFilter(String[] names) {
+ this(names, null);
+ }
+
+ /**
+ * Constructs a new name file filter for an array of names specifying case-sensitivity.
+ *
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param names the names to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the names array is null
+ */
+ public NameFileFilter(String[] names, IOCase caseSensitivity) {
+ if (names == null) {
+ throw new IllegalArgumentException("The array of names must not be null");
+ }
+ this.names = names;
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new case-sensitive name file filter for a list of names.
+ *
+ * @param names the names to allow, must not be null
+ * @throws IllegalArgumentException if the name list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public NameFileFilter(List names) {
+ this(names, null);
+ }
+
+ /**
+ * Constructs a new name file filter for a list of names specifying case-sensitivity.
+ *
+ * @param names the names to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the name list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public NameFileFilter(List names, IOCase caseSensitivity) {
+ if (names == null) {
+ throw new IllegalArgumentException("The list of names must not be null");
+ }
+ this.names = (String[]) names.toArray(new String[names.size()]);
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks to see if the filename matches.
+ *
+ * @param file the File to check
+ * @return true if the filename matches
+ */
+ public boolean accept(File file) {
+ String name = file.getName();
+ for (int i = 0; i < this.names.length; i++) {
+ if (caseSensitivity.checkEquals(name, names[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the filename matches.
+ *
+ * @param file the File directory
+ * @param name the filename
+ * @return true if the filename matches
+ */
+ public boolean accept(File file, String name) {
+ for (int i = 0; i < names.length; i++) {
+ if (caseSensitivity.checkEquals(name, names[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (names != null) {
+ for (int i = 0; i < names.length; i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(names[i]);
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/NotFileFilter.java b/src/org/apache/commons/io/filefilter/NotFileFilter.java
index 710c8ecf31a431b31b37470258b0fe9993a95e1a..3991f5d45e6243732acf3efa057e8cd4941276b2 100644
--- a/src/org/apache/commons/io/filefilter/NotFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/NotFileFilter.java
@@ -1,78 +1,78 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter produces a logical NOT of the filters specified.
- *
- * @since Commons IO 1.0
- * @version $Revision: 591058 $ $Date: 2007-11-01 15:47:05 +0000 (Thu, 01 Nov 2007) $
- *
- * @author Stephen Colebourne
- */
-public class NotFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The filter */
- private final IOFileFilter filter;
-
- /**
- * Constructs a new file filter that NOTs the result of another filters.
- *
- * @param filter the filter, must not be null
- * @throws IllegalArgumentException if the filter is null
- */
- public NotFileFilter(IOFileFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("The filter must not be null");
- }
- this.filter = filter;
- }
-
- /**
- * Checks to see if both filters are true.
- *
- * @param file the File to check
- * @return true if the filter returns false
- */
- public boolean accept(File file) {
- return ! filter.accept(file);
- }
-
- /**
- * Checks to see if both filters are true.
- *
- * @param file the File directory
- * @param name the filename
- * @return true if the filter returns false
- */
- public boolean accept(File file, String name) {
- return ! filter.accept(file, name);
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- return super.toString() + "(" + filter.toString() + ")";
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter produces a logical NOT of the filters specified.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 591058 $ $Date: 2007-11-01 15:47:05 +0000 (Thu, 01 Nov 2007) $
+ *
+ * @author Stephen Colebourne
+ */
+public class NotFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The filter */
+ private final IOFileFilter filter;
+
+ /**
+ * Constructs a new file filter that NOTs the result of another filters.
+ *
+ * @param filter the filter, must not be null
+ * @throws IllegalArgumentException if the filter is null
+ */
+ public NotFileFilter(IOFileFilter filter) {
+ if (filter == null) {
+ throw new IllegalArgumentException("The filter must not be null");
+ }
+ this.filter = filter;
+ }
+
+ /**
+ * Checks to see if both filters are true.
+ *
+ * @param file the File to check
+ * @return true if the filter returns false
+ */
+ public boolean accept(File file) {
+ return ! filter.accept(file);
+ }
+
+ /**
+ * Checks to see if both filters are true.
+ *
+ * @param file the File directory
+ * @param name the filename
+ * @return true if the filter returns false
+ */
+ public boolean accept(File file, String name) {
+ return ! filter.accept(file, name);
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ return super.toString() + "(" + filter.toString() + ")";
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/OrFileFilter.java b/src/org/apache/commons/io/filefilter/OrFileFilter.java
index 59cc0f2b04a81cc3f6dfc1dae1cc09ed7717b95a..bcbb78690267b1a89ce70d7da9f62e916db7bc64 100644
--- a/src/org/apache/commons/io/filefilter/OrFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/OrFileFilter.java
@@ -1,161 +1,161 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A {@link java.io.FileFilter} providing conditional OR logic across a list of
- * file filters. This filter returns
- * For example, to print all files and directories in the
- * current directory whose name starts with
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param prefixes the prefixes to allow, must not be null
- * @throws IllegalArgumentException if the prefix array is null
- */
- public PrefixFileFilter(String[] prefixes) {
- this(prefixes, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Prefix file filter for any of an array of prefixes
- * specifying case-sensitivity.
- *
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param prefixes the prefixes to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the prefix is null
- * @since Commons IO 1.4
- */
- public PrefixFileFilter(String[] prefixes, IOCase caseSensitivity) {
- if (prefixes == null) {
- throw new IllegalArgumentException("The array of prefixes must not be null");
- }
- this.prefixes = prefixes;
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new Prefix file filter for a list of prefixes.
- *
- * @param prefixes the prefixes to allow, must not be null
- * @throws IllegalArgumentException if the prefix list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public PrefixFileFilter(List prefixes) {
- this(prefixes, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Prefix file filter for a list of prefixes
- * specifying case-sensitivity.
- *
- * @param prefixes the prefixes to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the prefix list is null
- * @throws ClassCastException if the list does not contain Strings
- * @since Commons IO 1.4
- */
- public PrefixFileFilter(List prefixes, IOCase caseSensitivity) {
- if (prefixes == null) {
- throw new IllegalArgumentException("The list of prefixes must not be null");
- }
- this.prefixes = (String[]) prefixes.toArray(new String[prefixes.size()]);
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Checks to see if the filename starts with the prefix.
- *
- * @param file the File to check
- * @return true if the filename starts with one of our prefixes
- */
- public boolean accept(File file) {
- String name = file.getName();
- for (int i = 0; i < this.prefixes.length; i++) {
- if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks to see if the filename starts with the prefix.
- *
- * @param file the File directory
- * @param name the filename
- * @return true if the filename starts with one of our prefixes
- */
- public boolean accept(File file, String name) {
- for (int i = 0; i < prefixes.length; i++) {
- if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (prefixes != null) {
- for (int i = 0; i < prefixes.length; i++) {
- if (i > 0) {
- buffer.append(",");
- }
- buffer.append(prefixes[i]);
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Filters filenames for a certain prefix.
+ *
+ * For example, to print all files and directories in the
+ * current directory whose name starts with
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param prefixes the prefixes to allow, must not be null
+ * @throws IllegalArgumentException if the prefix array is null
+ */
+ public PrefixFileFilter(String[] prefixes) {
+ this(prefixes, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Prefix file filter for any of an array of prefixes
+ * specifying case-sensitivity.
+ *
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param prefixes the prefixes to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the prefix is null
+ * @since Commons IO 1.4
+ */
+ public PrefixFileFilter(String[] prefixes, IOCase caseSensitivity) {
+ if (prefixes == null) {
+ throw new IllegalArgumentException("The array of prefixes must not be null");
+ }
+ this.prefixes = prefixes;
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new Prefix file filter for a list of prefixes.
+ *
+ * @param prefixes the prefixes to allow, must not be null
+ * @throws IllegalArgumentException if the prefix list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public PrefixFileFilter(List prefixes) {
+ this(prefixes, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Prefix file filter for a list of prefixes
+ * specifying case-sensitivity.
+ *
+ * @param prefixes the prefixes to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the prefix list is null
+ * @throws ClassCastException if the list does not contain Strings
+ * @since Commons IO 1.4
+ */
+ public PrefixFileFilter(List prefixes, IOCase caseSensitivity) {
+ if (prefixes == null) {
+ throw new IllegalArgumentException("The list of prefixes must not be null");
+ }
+ this.prefixes = (String[]) prefixes.toArray(new String[prefixes.size()]);
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Checks to see if the filename starts with the prefix.
+ *
+ * @param file the File to check
+ * @return true if the filename starts with one of our prefixes
+ */
+ public boolean accept(File file) {
+ String name = file.getName();
+ for (int i = 0; i < this.prefixes.length; i++) {
+ if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the filename starts with the prefix.
+ *
+ * @param file the File directory
+ * @param name the filename
+ * @return true if the filename starts with one of our prefixes
+ */
+ public boolean accept(File file, String name) {
+ for (int i = 0; i < prefixes.length; i++) {
+ if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (prefixes != null) {
+ for (int i = 0; i < prefixes.length; i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(prefixes[i]);
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/RegexFileFilter.java b/src/org/apache/commons/io/filefilter/RegexFileFilter.java
index b49a1bd3b5524c90f19960494f8c15586fd8bb91..d47d834a0fb193bfaa1ff08a54ddb138b77e200d 100644
--- a/src/org/apache/commons/io/filefilter/RegexFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/RegexFileFilter.java
@@ -1,122 +1,122 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Filters files using supplied regular expression(s).
- *
- * For example, to print all files and directories in the
- * current directory whose size is greater than 1 MB:
- *
- *
- * If size equals threshold and smaller files are required,
- * file IS NOT selected.
- * If size equals threshold and larger files are required,
- * file IS selected.
- *
- * @param file the File to check
- * @return true if the filename matches
- */
- public boolean accept(File file) {
- boolean smaller = file.length() < size;
- return acceptLarger ? !smaller : smaller;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- String condition = acceptLarger ? ">=" : "<";
- return super.toString() + "(" + condition + size + ")";
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * Filters files based on size, can filter either smaller files or
+ * files equal to or larger than a given threshold.
+ *
+ * For example, to print all files and directories in the
+ * current directory whose size is greater than 1 MB:
+ *
+ *
+ * If size equals threshold and smaller files are required,
+ * file IS NOT selected.
+ * If size equals threshold and larger files are required,
+ * file IS selected.
+ *
+ * @param file the File to check
+ * @return true if the filename matches
+ */
+ public boolean accept(File file) {
+ boolean smaller = file.length() < size;
+ return acceptLarger ? !smaller : smaller;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ String condition = acceptLarger ? ">=" : "<";
+ return super.toString() + "(" + condition + size + ")";
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/SuffixFileFilter.java b/src/org/apache/commons/io/filefilter/SuffixFileFilter.java
index bee34402c48954acd782beccc36bc3a2c2ab5ee6..192e9b59510a488b4b5e91d8e4eaebfbe81b3d2e 100644
--- a/src/org/apache/commons/io/filefilter/SuffixFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/SuffixFileFilter.java
@@ -1,198 +1,198 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Filters files based on the suffix (what the filename ends with).
- * This is used in retrieving all the files of a particular type.
- *
- * For example, to retrieve and print all
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param suffixes the suffixes to allow, must not be null
- * @throws IllegalArgumentException if the suffix array is null
- */
- public SuffixFileFilter(String[] suffixes) {
- this(suffixes, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Suffix file filter for an array of suffixs
- * specifying case-sensitivity.
- *
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param suffixes the suffixes to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the suffix array is null
- * @since Commons IO 1.4
- */
- public SuffixFileFilter(String[] suffixes, IOCase caseSensitivity) {
- if (suffixes == null) {
- throw new IllegalArgumentException("The array of suffixes must not be null");
- }
- this.suffixes = suffixes;
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new Suffix file filter for a list of suffixes.
- *
- * @param suffixes the suffixes to allow, must not be null
- * @throws IllegalArgumentException if the suffix list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public SuffixFileFilter(List suffixes) {
- this(suffixes, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Suffix file filter for a list of suffixes
- * specifying case-sensitivity.
- *
- * @param suffixes the suffixes to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the suffix list is null
- * @throws ClassCastException if the list does not contain Strings
- * @since Commons IO 1.4
- */
- public SuffixFileFilter(List suffixes, IOCase caseSensitivity) {
- if (suffixes == null) {
- throw new IllegalArgumentException("The list of suffixes must not be null");
- }
- this.suffixes = (String[]) suffixes.toArray(new String[suffixes.size()]);
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Checks to see if the filename ends with the suffix.
- *
- * @param file the File to check
- * @return true if the filename ends with one of our suffixes
- */
- public boolean accept(File file) {
- String name = file.getName();
- for (int i = 0; i < this.suffixes.length; i++) {
- if (caseSensitivity.checkEndsWith(name, suffixes[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks to see if the filename ends with the suffix.
- *
- * @param file the File directory
- * @param name the filename
- * @return true if the filename ends with one of our suffixes
- */
- public boolean accept(File file, String name) {
- for (int i = 0; i < this.suffixes.length; i++) {
- if (caseSensitivity.checkEndsWith(name, suffixes[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (suffixes != null) {
- for (int i = 0; i < suffixes.length; i++) {
- if (i > 0) {
- buffer.append(",");
- }
- buffer.append(suffixes[i]);
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Filters files based on the suffix (what the filename ends with).
+ * This is used in retrieving all the files of a particular type.
+ *
+ * For example, to retrieve and print all
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param suffixes the suffixes to allow, must not be null
+ * @throws IllegalArgumentException if the suffix array is null
+ */
+ public SuffixFileFilter(String[] suffixes) {
+ this(suffixes, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Suffix file filter for an array of suffixs
+ * specifying case-sensitivity.
+ *
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param suffixes the suffixes to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the suffix array is null
+ * @since Commons IO 1.4
+ */
+ public SuffixFileFilter(String[] suffixes, IOCase caseSensitivity) {
+ if (suffixes == null) {
+ throw new IllegalArgumentException("The array of suffixes must not be null");
+ }
+ this.suffixes = suffixes;
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new Suffix file filter for a list of suffixes.
+ *
+ * @param suffixes the suffixes to allow, must not be null
+ * @throws IllegalArgumentException if the suffix list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public SuffixFileFilter(List suffixes) {
+ this(suffixes, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Suffix file filter for a list of suffixes
+ * specifying case-sensitivity.
+ *
+ * @param suffixes the suffixes to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the suffix list is null
+ * @throws ClassCastException if the list does not contain Strings
+ * @since Commons IO 1.4
+ */
+ public SuffixFileFilter(List suffixes, IOCase caseSensitivity) {
+ if (suffixes == null) {
+ throw new IllegalArgumentException("The list of suffixes must not be null");
+ }
+ this.suffixes = (String[]) suffixes.toArray(new String[suffixes.size()]);
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Checks to see if the filename ends with the suffix.
+ *
+ * @param file the File to check
+ * @return true if the filename ends with one of our suffixes
+ */
+ public boolean accept(File file) {
+ String name = file.getName();
+ for (int i = 0; i < this.suffixes.length; i++) {
+ if (caseSensitivity.checkEndsWith(name, suffixes[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the filename ends with the suffix.
+ *
+ * @param file the File directory
+ * @param name the filename
+ * @return true if the filename ends with one of our suffixes
+ */
+ public boolean accept(File file, String name) {
+ for (int i = 0; i < this.suffixes.length; i++) {
+ if (caseSensitivity.checkEndsWith(name, suffixes[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (suffixes != null) {
+ for (int i = 0; i < suffixes.length; i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(suffixes[i]);
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/TrueFileFilter.java b/src/org/apache/commons/io/filefilter/TrueFileFilter.java
index be1b13a7e6ec96e8c3cbf3a90d0ce1ab63bac8c6..9eb1e756c801e662b9ecb6be0a80f65427a01e7f 100644
--- a/src/org/apache/commons/io/filefilter/TrueFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/TrueFileFilter.java
@@ -1,72 +1,72 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * A file filter that always returns true.
- *
- * @since Commons IO 1.0
- * @version $Revision: 587978 $ $Date: 2007-10-24 20:36:51 +0100 (Wed, 24 Oct 2007) $
- *
- * @author Stephen Colebourne
- */
-public class TrueFileFilter implements IOFileFilter, Serializable {
-
- /**
- * Singleton instance of true filter.
- * @since Commons IO 1.3
- */
- public static final IOFileFilter TRUE = new TrueFileFilter();
- /**
- * Singleton instance of true filter.
- * Please use the identical TrueFileFilter.TRUE constant.
- * The new name is more JDK 1.5 friendly as it doesn't clash with other
- * values when using static imports.
- */
- public static final IOFileFilter INSTANCE = TRUE;
-
- /**
- * Restrictive consructor.
- */
- protected TrueFileFilter() {
- }
-
- /**
- * Returns true.
- *
- * @param file the file to check
- * @return true
- */
- public boolean accept(File file) {
- return true;
- }
-
- /**
- * Returns true.
- *
- * @param dir the directory to check
- * @param name the filename
- * @return true
- */
- public boolean accept(File dir, String name) {
- return true;
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * A file filter that always returns true.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 587978 $ $Date: 2007-10-24 20:36:51 +0100 (Wed, 24 Oct 2007) $
+ *
+ * @author Stephen Colebourne
+ */
+public class TrueFileFilter implements IOFileFilter, Serializable {
+
+ /**
+ * Singleton instance of true filter.
+ * @since Commons IO 1.3
+ */
+ public static final IOFileFilter TRUE = new TrueFileFilter();
+ /**
+ * Singleton instance of true filter.
+ * Please use the identical TrueFileFilter.TRUE constant.
+ * The new name is more JDK 1.5 friendly as it doesn't clash with other
+ * values when using static imports.
+ */
+ public static final IOFileFilter INSTANCE = TRUE;
+
+ /**
+ * Restrictive consructor.
+ */
+ protected TrueFileFilter() {
+ }
+
+ /**
+ * Returns true.
+ *
+ * @param file the file to check
+ * @return true
+ */
+ public boolean accept(File file) {
+ return true;
+ }
+
+ /**
+ * Returns true.
+ *
+ * @param dir the directory to check
+ * @param name the filename
+ * @return true
+ */
+ public boolean accept(File dir, String name) {
+ return true;
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/WildcardFileFilter.java b/src/org/apache/commons/io/filefilter/WildcardFileFilter.java
index 791fe985bf07e5e0b57529d664ce994eea68ba07..2946980271f984154f0c83fbe8b73ea023fb9b31 100644
--- a/src/org/apache/commons/io/filefilter/WildcardFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/WildcardFileFilter.java
@@ -1,196 +1,196 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOCase;
-
-/**
- * Filters files using the supplied wildcards.
- *
- * This filter selects files and directories based on one or more wildcards.
- * Testing is case-sensitive by default, but this can be configured.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
- * The extension check is case-sensitive by .
- * See {@link FilenameUtils#wildcardMatchOnSystem} for more information.
- *
- * For example:
- *
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param wildcards the array of wildcards to match
- * @throws IllegalArgumentException if the pattern array is null
- */
- public WildcardFileFilter(String[] wildcards) {
- this(wildcards, null);
- }
-
- /**
- * Construct a new wildcard filter for an array of wildcards specifying case-sensitivity.
- *
- * The array is not cloned, so could be changed after constructing the
- * instance. This would be inadvisable however.
- *
- * @param wildcards the array of wildcards to match, not null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the pattern array is null
- */
- public WildcardFileFilter(String[] wildcards, IOCase caseSensitivity) {
- if (wildcards == null) {
- throw new IllegalArgumentException("The wildcard array must not be null");
- }
- this.wildcards = wildcards;
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Construct a new case-sensitive wildcard filter for a list of wildcards.
- *
- * @param wildcards the list of wildcards to match, not null
- * @throws IllegalArgumentException if the pattern list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public WildcardFileFilter(List wildcards) {
- this(wildcards, null);
- }
-
- /**
- * Construct a new wildcard filter for a list of wildcards specifying case-sensitivity.
- *
- * @param wildcards the list of wildcards to match, not null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the pattern list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public WildcardFileFilter(List wildcards, IOCase caseSensitivity) {
- if (wildcards == null) {
- throw new IllegalArgumentException("The wildcard list must not be null");
- }
- this.wildcards = (String[]) wildcards.toArray(new String[wildcards.size()]);
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks to see if the filename matches one of the wildcards.
- *
- * @param dir the file directory
- * @param name the filename
- * @return true if the filename matches one of the wildcards
- */
- public boolean accept(File dir, String name) {
- for (int i = 0; i < wildcards.length; i++) {
- if (FilenameUtils.wildcardMatch(name, wildcards[i], caseSensitivity)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks to see if the filename matches one of the wildcards.
- *
- * @param file the file to check
- * @return true if the filename matches one of the wildcards
- */
- public boolean accept(File file) {
- String name = file.getName();
- for (int i = 0; i < wildcards.length; i++) {
- if (FilenameUtils.wildcardMatch(name, wildcards[i], caseSensitivity)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (wildcards != null) {
- for (int i = 0; i < wildcards.length; i++) {
- if (i > 0) {
- buffer.append(",");
- }
- buffer.append(wildcards[i]);
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOCase;
+
+/**
+ * Filters files using the supplied wildcards.
+ *
+ * This filter selects files and directories based on one or more wildcards.
+ * Testing is case-sensitive by default, but this can be configured.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple wildcard characters.
+ * This is the same as often found on Dos/Unix command lines.
+ * The extension check is case-sensitive by .
+ * See {@link FilenameUtils#wildcardMatchOnSystem} for more information.
+ *
+ * For example:
+ *
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param wildcards the array of wildcards to match
+ * @throws IllegalArgumentException if the pattern array is null
+ */
+ public WildcardFileFilter(String[] wildcards) {
+ this(wildcards, null);
+ }
+
+ /**
+ * Construct a new wildcard filter for an array of wildcards specifying case-sensitivity.
+ *
+ * The array is not cloned, so could be changed after constructing the
+ * instance. This would be inadvisable however.
+ *
+ * @param wildcards the array of wildcards to match, not null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the pattern array is null
+ */
+ public WildcardFileFilter(String[] wildcards, IOCase caseSensitivity) {
+ if (wildcards == null) {
+ throw new IllegalArgumentException("The wildcard array must not be null");
+ }
+ this.wildcards = wildcards;
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Construct a new case-sensitive wildcard filter for a list of wildcards.
+ *
+ * @param wildcards the list of wildcards to match, not null
+ * @throws IllegalArgumentException if the pattern list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public WildcardFileFilter(List wildcards) {
+ this(wildcards, null);
+ }
+
+ /**
+ * Construct a new wildcard filter for a list of wildcards specifying case-sensitivity.
+ *
+ * @param wildcards the list of wildcards to match, not null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the pattern list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public WildcardFileFilter(List wildcards, IOCase caseSensitivity) {
+ if (wildcards == null) {
+ throw new IllegalArgumentException("The wildcard list must not be null");
+ }
+ this.wildcards = (String[]) wildcards.toArray(new String[wildcards.size()]);
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks to see if the filename matches one of the wildcards.
+ *
+ * @param dir the file directory
+ * @param name the filename
+ * @return true if the filename matches one of the wildcards
+ */
+ public boolean accept(File dir, String name) {
+ for (int i = 0; i < wildcards.length; i++) {
+ if (FilenameUtils.wildcardMatch(name, wildcards[i], caseSensitivity)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the filename matches one of the wildcards.
+ *
+ * @param file the file to check
+ * @return true if the filename matches one of the wildcards
+ */
+ public boolean accept(File file) {
+ String name = file.getName();
+ for (int i = 0; i < wildcards.length; i++) {
+ if (FilenameUtils.wildcardMatch(name, wildcards[i], caseSensitivity)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (wildcards != null) {
+ for (int i = 0; i < wildcards.length; i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(wildcards[i]);
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/WildcardFilter.java b/src/org/apache/commons/io/filefilter/WildcardFilter.java
index 2a6e0dde03d1932e944bb5d611b17ebf19e3b535..e9ec0258614e8f16c69edcdf2605924f0df16ddf 100644
--- a/src/org/apache/commons/io/filefilter/WildcardFilter.java
+++ b/src/org/apache/commons/io/filefilter/WildcardFilter.java
@@ -1,140 +1,140 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.commons.io.FilenameUtils;
-
-/**
- * Filters files using the supplied wildcards.
- *
- * This filter selects files, but not directories, based on one or more wildcards
- * and using case-sensitive comparison.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
- * The extension check is case-sensitive.
- * See {@link FilenameUtils#wildcardMatch} for more information.
- *
- * For example:
- *
+ * This filter selects files, but not directories, based on one or more wildcards
+ * and using case-sensitive comparison.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple wildcard characters.
+ * This is the same as often found on Dos/Unix command lines.
+ * The extension check is case-sensitive.
+ * See {@link FilenameUtils#wildcardMatch} for more information.
+ *
+ * For example:
+ * This package defines an interface (IOFileFilter) that combines both
-{@link java.io.FileFilter} and {@link java.io.FilenameFilter}. Besides
-that the package offers a series of ready-to-use implementations of the
-IOFileFilter interface including implementation that allow you to combine
-other such filters. These filter can be used to list files or in {@link java.awt.FileDialog},
-for example. There are a number of 'primitive' filters: And there are five 'boolean' filters: These boolean FilenameFilters can be nested, to allow arbitrary expressions.
-For example, here is how one could print all non-directory files in the
-current directory, starting with "A", and ending in ".java" or ".class": This package also contains a utility class:
-FileFilterUtils. It allows you to use all
-file filters without having to put them in the import section. Here's how the
-above example will look using FileFilterUtils: There are a few other goodies in that class so please have a look at the
-documentation in detail. This package defines an interface (IOFileFilter) that combines both
+{@link java.io.FileFilter} and {@link java.io.FilenameFilter}. Besides
+that the package offers a series of ready-to-use implementations of the
+IOFileFilter interface including implementation that allow you to combine
+other such filters. These filter can be used to list files or in {@link java.awt.FileDialog},
+for example. There are a number of 'primitive' filters: And there are five 'boolean' filters: These boolean FilenameFilters can be nested, to allow arbitrary expressions.
+For example, here is how one could print all non-directory files in the
+current directory, starting with "A", and ending in ".java" or ".class": This package also contains a utility class:
+FileFilterUtils. It allows you to use all
+file filters without having to put them in the import section. Here's how the
+above example will look using FileFilterUtils: There are a few other goodies in that class so please have a look at the
+documentation in detail.
- * This class is typically used to release any resources related to an open
- * stream as soon as possible even if the client application (by not explicitly
- * closing the stream when no longer needed) or the underlying stream (by not
- * releasing resources once the last byte has been read) do not do that.
- *
- * @version $Id: AutoCloseInputStream.java 610010 2008-01-08 14:50:59Z niallp $
- * @since Commons IO 1.4
- */
-public class AutoCloseInputStream extends ProxyInputStream {
-
- /**
- * Creates an automatically closing proxy for the given input stream.
- *
- * @param in underlying input stream
- */
- public AutoCloseInputStream(InputStream in) {
- super(in);
- }
-
- /**
- * Closes the underlying input stream and replaces the reference to it
- * with a {@link ClosedInputStream} instance.
- *
- * This method is automatically called by the read methods when the end
- * of input has been reached.
- *
- * Note that it is safe to call this method any number of times. The original
- * underlying input stream is closed and discarded only once when this
- * method is first called.
- *
- * @throws IOException if the underlying input stream can not be closed
- */
- public void close() throws IOException {
- in.close();
- in = new ClosedInputStream();
- }
-
- /**
- * Reads and returns a single byte from the underlying input stream.
- * If the underlying stream returns -1, the {@link #close()} method is
- * called to automatically close and discard the stream.
- *
- * @return next byte in the stream, or -1 if no more bytes are available
- * @throws IOException if the stream could not be read or closed
- */
- public int read() throws IOException {
- int n = in.read();
- if (n == -1) {
- close();
- }
- return n;
- }
-
- /**
- * Reads and returns bytes from the underlying input stream to the given
- * buffer. If the underlying stream returns -1, the {@link #close()} method
- * i called to automatically close and discard the stream.
- *
- * @param b buffer to which bytes from the stream are written
- * @return number of bytes read, or -1 if no more bytes are available
- * @throws IOException if the stream could not be read or closed
- */
- public int read(byte[] b) throws IOException {
- int n = in.read(b);
- if (n == -1) {
- close();
- }
- return n;
- }
-
- /**
- * Reads and returns bytes from the underlying input stream to the given
- * buffer. If the underlying stream returns -1, the {@link #close()} method
- * i called to automatically close and discard the stream.
- *
- * @param b buffer to which bytes from the stream are written
- * @param off start offset within the buffer
- * @param len maximum number of bytes to read
- * @return number of bytes read, or -1 if no more bytes are available
- * @throws IOException if the stream could not be read or closed
- */
- public int read(byte[] b, int off, int len) throws IOException {
- int n = in.read(b, off, len);
- if (n == -1) {
- close();
- }
- return n;
- }
-
- /**
- * Ensures that the stream is closed before it gets garbage-collected.
- * As mentioned in {@link #close()}, this is a no-op if the stream has
- * already been closed.
- * @throws Throwable if an error occurs
- */
- protected void finalize() throws Throwable {
- close();
- super.finalize();
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Proxy stream that closes and discards the underlying stream as soon as the
+ * end of input has been reached or when the stream is explicitly closed.
+ * Not even a reference to the underlying stream is kept after it has been
+ * closed, so any allocated in-memory buffers can be freed even if the
+ * client application still keeps a reference to the proxy stream.
+ *
+ * This class is typically used to release any resources related to an open
+ * stream as soon as possible even if the client application (by not explicitly
+ * closing the stream when no longer needed) or the underlying stream (by not
+ * releasing resources once the last byte has been read) do not do that.
+ *
+ * @version $Id: AutoCloseInputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ * @since Commons IO 1.4
+ */
+public class AutoCloseInputStream extends ProxyInputStream {
+
+ /**
+ * Creates an automatically closing proxy for the given input stream.
+ *
+ * @param in underlying input stream
+ */
+ public AutoCloseInputStream(InputStream in) {
+ super(in);
+ }
+
+ /**
+ * Closes the underlying input stream and replaces the reference to it
+ * with a {@link ClosedInputStream} instance.
+ *
+ * This method is automatically called by the read methods when the end
+ * of input has been reached.
+ *
+ * Note that it is safe to call this method any number of times. The original
+ * underlying input stream is closed and discarded only once when this
+ * method is first called.
+ *
+ * @throws IOException if the underlying input stream can not be closed
+ */
+ public void close() throws IOException {
+ in.close();
+ in = new ClosedInputStream();
+ }
+
+ /**
+ * Reads and returns a single byte from the underlying input stream.
+ * If the underlying stream returns -1, the {@link #close()} method is
+ * called to automatically close and discard the stream.
+ *
+ * @return next byte in the stream, or -1 if no more bytes are available
+ * @throws IOException if the stream could not be read or closed
+ */
+ public int read() throws IOException {
+ int n = in.read();
+ if (n == -1) {
+ close();
+ }
+ return n;
+ }
+
+ /**
+ * Reads and returns bytes from the underlying input stream to the given
+ * buffer. If the underlying stream returns -1, the {@link #close()} method
+ * i called to automatically close and discard the stream.
+ *
+ * @param b buffer to which bytes from the stream are written
+ * @return number of bytes read, or -1 if no more bytes are available
+ * @throws IOException if the stream could not be read or closed
+ */
+ public int read(byte[] b) throws IOException {
+ int n = in.read(b);
+ if (n == -1) {
+ close();
+ }
+ return n;
+ }
+
+ /**
+ * Reads and returns bytes from the underlying input stream to the given
+ * buffer. If the underlying stream returns -1, the {@link #close()} method
+ * i called to automatically close and discard the stream.
+ *
+ * @param b buffer to which bytes from the stream are written
+ * @param off start offset within the buffer
+ * @param len maximum number of bytes to read
+ * @return number of bytes read, or -1 if no more bytes are available
+ * @throws IOException if the stream could not be read or closed
+ */
+ public int read(byte[] b, int off, int len) throws IOException {
+ int n = in.read(b, off, len);
+ if (n == -1) {
+ close();
+ }
+ return n;
+ }
+
+ /**
+ * Ensures that the stream is closed before it gets garbage-collected.
+ * As mentioned in {@link #close()}, this is a no-op if the stream has
+ * already been closed.
+ * @throws Throwable if an error occurs
+ */
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/CharSequenceReader.java b/src/org/apache/commons/io/input/CharSequenceReader.java
index 6ee11d87d1528cacf84b42fb4e1ce0f76e389d9a..1be52821029cd3b1f0e81dd74887cfa67e99f9e7 100644
--- a/src/org/apache/commons/io/input/CharSequenceReader.java
+++ b/src/org/apache/commons/io/input/CharSequenceReader.java
@@ -1,155 +1,155 @@
-/*
- * 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.commons.io.input;
-
-import java.io.Reader;
-import java.io.Serializable;
-
-/**
- * {@link Reader} implementation that can read from String, StringBuffer,
- * StringBuilder or CharBuffer.
- *
- * Note: Supports {@link #mark(int)} and {@link #reset()}.
- *
- * @version $Revision: 610516 $ $Date: 2008-01-09 19:05:05 +0000 (Wed, 09 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class CharSequenceReader extends Reader implements Serializable {
-
- private final CharSequence charSequence;
- private int idx;
- private int mark;
-
- /**
- * Construct a new instance with the specified character sequence.
- *
- * @param charSequence The character sequence, may be
+ * Note: Supports {@link #mark(int)} and {@link #reset()}.
+ *
+ * @version $Revision: 610516 $ $Date: 2008-01-09 19:05:05 +0000 (Wed, 09 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class CharSequenceReader extends Reader implements Serializable {
+
+ private final CharSequence charSequence;
+ private int idx;
+ private int mark;
+
+ /**
+ * Construct a new instance with the specified character sequence.
+ *
+ * @param charSequence The character sequence, may be
- * This is useful in dynamic container environments.
- *
- * @author Paul Hammant
- * @version $Id: ClassLoaderObjectInputStream.java 437567 2006-08-28 06:39:07Z bayard $
- * @since Commons IO 1.1
- */
-public class ClassLoaderObjectInputStream extends ObjectInputStream {
-
- /** The class loader to use. */
- private ClassLoader classLoader;
-
- /**
- * Constructs a new ClassLoaderObjectInputStream.
- *
- * @param classLoader the ClassLoader from which classes should be loaded
- * @param inputStream the InputStream to work on
- * @throws IOException in case of an I/O error
- * @throws StreamCorruptedException if the stream is corrupted
- */
- public ClassLoaderObjectInputStream(
- ClassLoader classLoader, InputStream inputStream)
- throws IOException, StreamCorruptedException {
- super(inputStream);
- this.classLoader = classLoader;
- }
-
- /**
- * Resolve a class specified by the descriptor using the
- * specified ClassLoader or the super ClassLoader.
- *
- * @param objectStreamClass descriptor of the class
- * @return the Class object described by the ObjectStreamClass
- * @throws IOException in case of an I/O error
- * @throws ClassNotFoundException if the Class cannot be found
- */
- protected Class resolveClass(ObjectStreamClass objectStreamClass)
- throws IOException, ClassNotFoundException {
-
- Class clazz = Class.forName(objectStreamClass.getName(), false, classLoader);
-
- if (clazz != null) {
- // the classloader knows of the class
- return clazz;
- } else {
- // classloader knows not of class, let the super classloader do it
- return super.resolveClass(objectStreamClass);
- }
- }
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.StreamCorruptedException;
+
+/**
+ * A special ObjectInputStream that loads a class based on a specified
+ *
+ * This is useful in dynamic container environments.
+ *
+ * @author Paul Hammant
+ * @version $Id: ClassLoaderObjectInputStream.java 437567 2006-08-28 06:39:07Z bayard $
+ * @since Commons IO 1.1
+ */
+public class ClassLoaderObjectInputStream extends ObjectInputStream {
+
+ /** The class loader to use. */
+ private ClassLoader classLoader;
+
+ /**
+ * Constructs a new ClassLoaderObjectInputStream.
+ *
+ * @param classLoader the ClassLoader from which classes should be loaded
+ * @param inputStream the InputStream to work on
+ * @throws IOException in case of an I/O error
+ * @throws StreamCorruptedException if the stream is corrupted
+ */
+ public ClassLoaderObjectInputStream(
+ ClassLoader classLoader, InputStream inputStream)
+ throws IOException, StreamCorruptedException {
+ super(inputStream);
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Resolve a class specified by the descriptor using the
+ * specified ClassLoader or the super ClassLoader.
+ *
+ * @param objectStreamClass descriptor of the class
+ * @return the Class object described by the ObjectStreamClass
+ * @throws IOException in case of an I/O error
+ * @throws ClassNotFoundException if the Class cannot be found
+ */
+ protected Class resolveClass(ObjectStreamClass objectStreamClass)
+ throws IOException, ClassNotFoundException {
+
+ Class clazz = Class.forName(objectStreamClass.getName(), false, classLoader);
+
+ if (clazz != null) {
+ // the classloader knows of the class
+ return clazz;
+ } else {
+ // classloader knows not of class, let the super classloader do it
+ return super.resolveClass(objectStreamClass);
+ }
+ }
+}
diff --git a/src/org/apache/commons/io/input/CloseShieldInputStream.java b/src/org/apache/commons/io/input/CloseShieldInputStream.java
index 2058beeb2ade58896df5d3d41301afc9d50c800d..59641046b14b048496e150d5e7d2ab25b13a8d8b 100644
--- a/src/org/apache/commons/io/input/CloseShieldInputStream.java
+++ b/src/org/apache/commons/io/input/CloseShieldInputStream.java
@@ -1,52 +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.commons.io.input;
-
-import java.io.InputStream;
-
-/**
- * Proxy stream that prevents the underlying input stream from being closed.
- *
- * This class is typically used in cases where an input stream needs to be
- * passed to a component that wants to explicitly close the stream even if
- * more input would still be available to other components.
- *
- * @version $Id: CloseShieldInputStream.java 587913 2007-10-24 15:47:30Z niallp $
- * @since Commons IO 1.4
- */
-public class CloseShieldInputStream extends ProxyInputStream {
-
- /**
- * Creates a proxy that shields the given input stream from being
- * closed.
- *
- * @param in underlying input stream
- */
- public CloseShieldInputStream(InputStream in) {
- super(in);
- }
-
- /**
- * Replaces the underlying input stream with a {@link ClosedInputStream}
- * sentinel. The original input stream will remain open, but this proxy
- * will appear closed.
- */
- public void close() {
- in = new ClosedInputStream();
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.InputStream;
+
+/**
+ * Proxy stream that prevents the underlying input stream from being closed.
+ *
+ * This class is typically used in cases where an input stream needs to be
+ * passed to a component that wants to explicitly close the stream even if
+ * more input would still be available to other components.
+ *
+ * @version $Id: CloseShieldInputStream.java 587913 2007-10-24 15:47:30Z niallp $
+ * @since Commons IO 1.4
+ */
+public class CloseShieldInputStream extends ProxyInputStream {
+
+ /**
+ * Creates a proxy that shields the given input stream from being
+ * closed.
+ *
+ * @param in underlying input stream
+ */
+ public CloseShieldInputStream(InputStream in) {
+ super(in);
+ }
+
+ /**
+ * Replaces the underlying input stream with a {@link ClosedInputStream}
+ * sentinel. The original input stream will remain open, but this proxy
+ * will appear closed.
+ */
+ public void close() {
+ in = new ClosedInputStream();
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/ClosedInputStream.java b/src/org/apache/commons/io/input/ClosedInputStream.java
index 86c83c90308ad670f84a258887881b95ea6485d8..b0a7ccdf644ac2c3e3231a3711012b91c78d434e 100644
--- a/src/org/apache/commons/io/input/ClosedInputStream.java
+++ b/src/org/apache/commons/io/input/ClosedInputStream.java
@@ -1,48 +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.commons.io.input;
-
-import java.io.InputStream;
-
-/**
- * Closed input stream. This stream returns -1 to all attempts to read
- * something from the stream.
- *
- * Typically uses of this class include testing for corner cases in methods
- * that accept input streams and acting as a sentinel value instead of a
- *
+ * Typically uses of this class include testing for corner cases in methods
+ * that accept input streams and acting as a sentinel value instead of a
+ *
- * A typical use case would be during debugging, to ensure that data is being
- * read as expected.
- *
- * @author Marcelo Liberato
- * @version $Id: CountingInputStream.java 471628 2006-11-06 04:06:45Z bayard $
- */
-public class CountingInputStream extends ProxyInputStream {
-
- /** The count of bytes that have passed. */
- private long count;
-
- /**
- * Constructs a new CountingInputStream.
- *
- * @param in the InputStream to delegate to
- */
- public CountingInputStream(InputStream in) {
- super(in);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Reads a number of bytes into the byte array, keeping count of the
- * number read.
- *
- * @param b the buffer into which the data is read, not null
- * @return the total number of bytes read into the buffer, -1 if end of stream
- * @throws IOException if an I/O error occurs
- * @see java.io.InputStream#read(byte[])
- */
- public int read(byte[] b) throws IOException {
- int found = super.read(b);
- this.count += (found >= 0) ? found : 0;
- return found;
- }
-
- /**
- * Reads a number of bytes into the byte array at a specific offset,
- * keeping count of the number read.
- *
- * @param b the buffer into which the data is read, not null
- * @param off the start offset in the buffer
- * @param len the maximum number of bytes to read
- * @return the total number of bytes read into the buffer, -1 if end of stream
- * @throws IOException if an I/O error occurs
- * @see java.io.InputStream#read(byte[], int, int)
- */
- public int read(byte[] b, int off, int len) throws IOException {
- int found = super.read(b, off, len);
- this.count += (found >= 0) ? found : 0;
- return found;
- }
-
- /**
- * Reads the next byte of data adding to the count of bytes received
- * if a byte is successfully read.
- *
- * @return the byte read, -1 if end of stream
- * @throws IOException if an I/O error occurs
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- int found = super.read();
- this.count += (found >= 0) ? 1 : 0;
- return found;
- }
-
- /**
- * Skips the stream over the specified number of bytes, adding the skipped
- * amount to the count.
- *
- * @param length the number of bytes to skip
- * @return the actual number of bytes skipped
- * @throws IOException if an I/O error occurs
- * @see java.io.InputStream#skip(long)
- */
- public long skip(final long length) throws IOException {
- final long skip = super.skip(length);
- this.count += skip;
- return skip;
- }
-
- //-----------------------------------------------------------------------
- /**
- * The number of bytes that have passed through this stream.
- *
- * NOTE: From v1.3 this method throws an ArithmeticException if the
- * count is greater than can be expressed by an
- * NOTE: From v1.3 this method throws an ArithmeticException if the
- * count is greater than can be expressed by an
- * NOTE: This method is an alternative for
- * NOTE: This method is an alternative for
+ * A typical use case would be during debugging, to ensure that data is being
+ * read as expected.
+ *
+ * @author Marcelo Liberato
+ * @version $Id: CountingInputStream.java 471628 2006-11-06 04:06:45Z bayard $
+ */
+public class CountingInputStream extends ProxyInputStream {
+
+ /** The count of bytes that have passed. */
+ private long count;
+
+ /**
+ * Constructs a new CountingInputStream.
+ *
+ * @param in the InputStream to delegate to
+ */
+ public CountingInputStream(InputStream in) {
+ super(in);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Reads a number of bytes into the byte array, keeping count of the
+ * number read.
+ *
+ * @param b the buffer into which the data is read, not null
+ * @return the total number of bytes read into the buffer, -1 if end of stream
+ * @throws IOException if an I/O error occurs
+ * @see java.io.InputStream#read(byte[])
+ */
+ public int read(byte[] b) throws IOException {
+ int found = super.read(b);
+ this.count += (found >= 0) ? found : 0;
+ return found;
+ }
+
+ /**
+ * Reads a number of bytes into the byte array at a specific offset,
+ * keeping count of the number read.
+ *
+ * @param b the buffer into which the data is read, not null
+ * @param off the start offset in the buffer
+ * @param len the maximum number of bytes to read
+ * @return the total number of bytes read into the buffer, -1 if end of stream
+ * @throws IOException if an I/O error occurs
+ * @see java.io.InputStream#read(byte[], int, int)
+ */
+ public int read(byte[] b, int off, int len) throws IOException {
+ int found = super.read(b, off, len);
+ this.count += (found >= 0) ? found : 0;
+ return found;
+ }
+
+ /**
+ * Reads the next byte of data adding to the count of bytes received
+ * if a byte is successfully read.
+ *
+ * @return the byte read, -1 if end of stream
+ * @throws IOException if an I/O error occurs
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ int found = super.read();
+ this.count += (found >= 0) ? 1 : 0;
+ return found;
+ }
+
+ /**
+ * Skips the stream over the specified number of bytes, adding the skipped
+ * amount to the count.
+ *
+ * @param length the number of bytes to skip
+ * @return the actual number of bytes skipped
+ * @throws IOException if an I/O error occurs
+ * @see java.io.InputStream#skip(long)
+ */
+ public long skip(final long length) throws IOException {
+ final long skip = super.skip(length);
+ this.count += skip;
+ return skip;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * The number of bytes that have passed through this stream.
+ *
+ * NOTE: From v1.3 this method throws an ArithmeticException if the
+ * count is greater than can be expressed by an
+ * NOTE: From v1.3 this method throws an ArithmeticException if the
+ * count is greater than can be expressed by an
+ * NOTE: This method is an alternative for
+ * NOTE: This method is an alternative for
- * This implementation provides a light weight
- * object for testing with an {@link InputStream}
- * where the contents don't matter.
- *
- * One use case would be for testing the handling of
- * large {@link InputStream} as it can emulate that
- * scenario without the overhead of actually processing
- * large numbers of bytes - significantly speeding up
- * test execution times.
- *
- * This implementation returns zero from the method that
- * reads a byte and leaves the array unchanged in the read
- * methods that are passed a byte array.
- * If alternative data is required the
- * This implementation returns zero.
- *
- * @return This implementation always returns zero.
- */
- protected int processByte() {
- // do nothing - overridable by subclass
- return 0;
- }
-
- /**
- * Process the bytes for the
- * This implementation leaves the byte array unchanged.
- *
- * @param bytes The byte array
- * @param offset The offset to start at.
- * @param length The number of bytes.
- */
- protected void processBytes(byte[] bytes, int offset, int length) {
- // do nothing - overridable by subclass
- }
-
- /**
- * Handle End of File.
- *
- * @return
+ * This implementation provides a light weight
+ * object for testing with an {@link InputStream}
+ * where the contents don't matter.
+ *
+ * One use case would be for testing the handling of
+ * large {@link InputStream} as it can emulate that
+ * scenario without the overhead of actually processing
+ * large numbers of bytes - significantly speeding up
+ * test execution times.
+ *
+ * This implementation returns zero from the method that
+ * reads a byte and leaves the array unchanged in the read
+ * methods that are passed a byte array.
+ * If alternative data is required the
+ * This implementation returns zero.
+ *
+ * @return This implementation always returns zero.
+ */
+ protected int processByte() {
+ // do nothing - overridable by subclass
+ return 0;
+ }
+
+ /**
+ * Process the bytes for the
+ * This implementation leaves the byte array unchanged.
+ *
+ * @param bytes The byte array
+ * @param offset The offset to start at.
+ * @param length The number of bytes.
+ */
+ protected void processBytes(byte[] bytes, int offset, int length) {
+ // do nothing - overridable by subclass
+ }
+
+ /**
+ * Handle End of File.
+ *
+ * @return
- * This implementation provides a light weight
- * object for testing with an {@link Reader}
- * where the contents don't matter.
- *
- * One use case would be for testing the handling of
- * large {@link Reader} as it can emulate that
- * scenario without the overhead of actually processing
- * large numbers of characters - significantly speeding up
- * test execution times.
- *
- * This implementation returns a space from the method that
- * reads a character and leaves the array unchanged in the read
- * methods that are passed a character array.
- * If alternative data is required the
- * This implementation returns zero.
- *
- * @return This implementation always returns zero.
- */
- protected int processChar() {
- // do nothing - overridable by subclass
- return 0;
- }
-
- /**
- * Process the characters for the
- * This implementation leaves the character array unchanged.
- *
- * @param chars The character array
- * @param offset The offset to start at.
- * @param length The number of characters.
- */
- protected void processChars(char[] chars, int offset, int length) {
- // do nothing - overridable by subclass
- }
-
- /**
- * Handle End of File.
- *
- * @return
+ * This implementation provides a light weight
+ * object for testing with an {@link Reader}
+ * where the contents don't matter.
+ *
+ * One use case would be for testing the handling of
+ * large {@link Reader} as it can emulate that
+ * scenario without the overhead of actually processing
+ * large numbers of characters - significantly speeding up
+ * test execution times.
+ *
+ * This implementation returns a space from the method that
+ * reads a character and leaves the array unchanged in the read
+ * methods that are passed a character array.
+ * If alternative data is required the
+ * This implementation returns zero.
+ *
+ * @return This implementation always returns zero.
+ */
+ protected int processChar() {
+ // do nothing - overridable by subclass
+ return 0;
+ }
+
+ /**
+ * Process the characters for the
+ * This implementation leaves the character array unchanged.
+ *
+ * @param chars The character array
+ * @param offset The offset to start at.
+ * @param length The number of characters.
+ */
+ protected void processChars(char[] chars, int offset, int length) {
+ // do nothing - overridable by subclass
+ }
+
+ /**
+ * Handle End of File.
+ *
+ * @return
- * It is an alternative base class to FilterInputStream
- * to increase reusability, because FilterInputStream changes the
- * methods being called, such as read(byte[]) to read(byte[], int, int).
- *
- * @author Stephen Colebourne
- * @version $Id: ProxyInputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public abstract class ProxyInputStream extends FilterInputStream {
-
- /**
- * Constructs a new ProxyInputStream.
- *
- * @param proxy the InputStream to delegate to
- */
- public ProxyInputStream(InputStream proxy) {
- super(proxy);
- // the proxy is stored in a protected superclass variable named 'in'
- }
-
- /**
- * Invokes the delegate's
+ * It is an alternative base class to FilterInputStream
+ * to increase reusability, because FilterInputStream changes the
+ * methods being called, such as read(byte[]) to read(byte[], int, int).
+ *
+ * @author Stephen Colebourne
+ * @version $Id: ProxyInputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public abstract class ProxyInputStream extends FilterInputStream {
+
+ /**
+ * Constructs a new ProxyInputStream.
+ *
+ * @param proxy the InputStream to delegate to
+ */
+ public ProxyInputStream(InputStream proxy) {
+ super(proxy);
+ // the proxy is stored in a protected superclass variable named 'in'
+ }
+
+ /**
+ * Invokes the delegate's
- * It is an alternative base class to FilterReader
- * to increase reusability, because FilterReader changes the
- * methods being called, such as read(char[]) to read(char[], int, int).
- *
- * @author Stephen Colebourne
- * @version $Id: ProxyReader.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public abstract class ProxyReader extends FilterReader {
-
- /**
- * Constructs a new ProxyReader.
- *
- * @param proxy the Reader to delegate to
- */
- public ProxyReader(Reader proxy) {
- super(proxy);
- // the proxy is stored in a protected superclass variable named 'in'
- }
-
- /**
- * Invokes the delegate's
+ * It is an alternative base class to FilterReader
+ * to increase reusability, because FilterReader changes the
+ * methods being called, such as read(char[]) to read(char[], int, int).
+ *
+ * @author Stephen Colebourne
+ * @version $Id: ProxyReader.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public abstract class ProxyReader extends FilterReader {
+
+ /**
+ * Constructs a new ProxyReader.
+ *
+ * @param proxy the Reader to delegate to
+ */
+ public ProxyReader(Reader proxy) {
+ super(proxy);
+ // the proxy is stored in a protected superclass variable named 'in'
+ }
+
+ /**
+ * Invokes the delegate's
- * Origin of code: Avalon Excalibur (IO)
- *
- * @author Peter Donald
- * @version CVS $Revision: 610010 $ $Date: 2008-01-08 14:50:59 +0000 (Tue, 08 Jan 2008) $
- */
-public class SwappedDataInputStream extends ProxyInputStream
- implements DataInput
-{
-
- /**
- * Constructs a SwappedDataInputStream.
- *
- * @param input InputStream to read from
- */
- public SwappedDataInputStream( InputStream input )
- {
- super( input );
- }
-
- /**
- * Return
+ * Origin of code: Avalon Excalibur (IO)
+ *
+ * @author Peter Donald
+ * @version CVS $Revision: 610010 $ $Date: 2008-01-08 14:50:59 +0000 (Tue, 08 Jan 2008) $
+ */
+public class SwappedDataInputStream extends ProxyInputStream
+ implements DataInput
+{
+
+ /**
+ * Constructs a SwappedDataInputStream.
+ *
+ * @param input InputStream to read from
+ */
+ public SwappedDataInputStream( InputStream input )
+ {
+ super( input );
+ }
+
+ /**
+ * Return
- * The proxied input stream is closed when the {@link #close()} method is
- * called on this proxy. It is configurable whether the associated output
- * stream will also closed.
- *
- * @version $Id: TeeInputStream.java 587913 2007-10-24 15:47:30Z niallp $
- * @since Commons IO 1.4
- */
-public class TeeInputStream extends ProxyInputStream {
-
- /**
- * The output stream that will receive a copy of all bytes read from the
- * proxied input stream.
- */
- private final OutputStream branch;
-
- /**
- * Flag for closing also the associated output stream when this
- * stream is closed.
- */
- private final boolean closeBranch;
-
- /**
- * Creates a TeeInputStream that proxies the given {@link InputStream}
- * and copies all read bytes to the given {@link OutputStream}. The given
- * output stream will not be closed when this stream gets closed.
- *
- * @param input input stream to be proxied
- * @param branch output stream that will receive a copy of all bytes read
- */
- public TeeInputStream(InputStream input, OutputStream branch) {
- this(input, branch, false);
- }
-
- /**
- * Creates a TeeInputStream that proxies the given {@link InputStream}
- * and copies all read bytes to the given {@link OutputStream}. The given
- * output stream will be closed when this stream gets closed if the
- * closeBranch parameter is
+ * The proxied input stream is closed when the {@link #close()} method is
+ * called on this proxy. It is configurable whether the associated output
+ * stream will also closed.
+ *
+ * @version $Id: TeeInputStream.java 587913 2007-10-24 15:47:30Z niallp $
+ * @since Commons IO 1.4
+ */
+public class TeeInputStream extends ProxyInputStream {
+
+ /**
+ * The output stream that will receive a copy of all bytes read from the
+ * proxied input stream.
+ */
+ private final OutputStream branch;
+
+ /**
+ * Flag for closing also the associated output stream when this
+ * stream is closed.
+ */
+ private final boolean closeBranch;
+
+ /**
+ * Creates a TeeInputStream that proxies the given {@link InputStream}
+ * and copies all read bytes to the given {@link OutputStream}. The given
+ * output stream will not be closed when this stream gets closed.
+ *
+ * @param input input stream to be proxied
+ * @param branch output stream that will receive a copy of all bytes read
+ */
+ public TeeInputStream(InputStream input, OutputStream branch) {
+ this(input, branch, false);
+ }
+
+ /**
+ * Creates a TeeInputStream that proxies the given {@link InputStream}
+ * and copies all read bytes to the given {@link OutputStream}. The given
+ * output stream will be closed when this stream gets closed if the
+ * closeBranch parameter is
-This package provides implementations of input classes, such as
-
+This package provides implementations of input classes, such as
+
- * The data can be retrieved using
- * Closing a ByteArrayOutputStream has no effect. The methods in
- * this class can be called after the stream has been closed without
- * generating an IOException.
- *
- * This is an alternative implementation of the java.io.ByteArrayOutputStream
- * class. The original implementation only allocates 32 bytes at the beginning.
- * As this class is designed for heavy duty it starts at 1024 bytes. In contrast
- * to the original it doesn't reallocate the whole memory block but allocates
- * additional buffers. This way no buffers need to be garbage collected and
- * the contents don't have to be copied to the new buffer. This class is
- * designed to behave exactly like the original. The only exception is the
- * deprecated toString(int) method that has been ignored.
- *
- * @author Jeremias Maerki
- * @author Holger Hoffstatte
- * @version $Id: ByteArrayOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class ByteArrayOutputStream extends OutputStream {
-
- /** A singleton empty byte array. */
- private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
- /** The list of buffers, which grows and never reduces. */
- private List buffers = new ArrayList();
- /** The index of the current buffer. */
- private int currentBufferIndex;
- /** The total count of bytes in all the filled buffers. */
- private int filledBufferSum;
- /** The current buffer. */
- private byte[] currentBuffer;
- /** The total count of bytes written. */
- private int count;
-
- /**
- * Creates a new byte array output stream. The buffer capacity is
- * initially 1024 bytes, though its size increases if necessary.
- */
- public ByteArrayOutputStream() {
- this(1024);
- }
-
- /**
- * Creates a new byte array output stream, with a buffer capacity of
- * the specified size, in bytes.
- *
- * @param size the initial size
- * @throws IllegalArgumentException if size is negative
- */
- public ByteArrayOutputStream(int size) {
- if (size < 0) {
- throw new IllegalArgumentException(
- "Negative initial size: " + size);
- }
- needNewBuffer(size);
- }
-
- /**
- * Return the appropriate
+ * The data can be retrieved using
+ * Closing a ByteArrayOutputStream has no effect. The methods in
+ * this class can be called after the stream has been closed without
+ * generating an IOException.
+ *
+ * This is an alternative implementation of the java.io.ByteArrayOutputStream
+ * class. The original implementation only allocates 32 bytes at the beginning.
+ * As this class is designed for heavy duty it starts at 1024 bytes. In contrast
+ * to the original it doesn't reallocate the whole memory block but allocates
+ * additional buffers. This way no buffers need to be garbage collected and
+ * the contents don't have to be copied to the new buffer. This class is
+ * designed to behave exactly like the original. The only exception is the
+ * deprecated toString(int) method that has been ignored.
+ *
+ * @author Jeremias Maerki
+ * @author Holger Hoffstatte
+ * @version $Id: ByteArrayOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class ByteArrayOutputStream extends OutputStream {
+
+ /** A singleton empty byte array. */
+ private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+ /** The list of buffers, which grows and never reduces. */
+ private List buffers = new ArrayList();
+ /** The index of the current buffer. */
+ private int currentBufferIndex;
+ /** The total count of bytes in all the filled buffers. */
+ private int filledBufferSum;
+ /** The current buffer. */
+ private byte[] currentBuffer;
+ /** The total count of bytes written. */
+ private int count;
+
+ /**
+ * Creates a new byte array output stream. The buffer capacity is
+ * initially 1024 bytes, though its size increases if necessary.
+ */
+ public ByteArrayOutputStream() {
+ this(1024);
+ }
+
+ /**
+ * Creates a new byte array output stream, with a buffer capacity of
+ * the specified size, in bytes.
+ *
+ * @param size the initial size
+ * @throws IllegalArgumentException if size is negative
+ */
+ public ByteArrayOutputStream(int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException(
+ "Negative initial size: " + size);
+ }
+ needNewBuffer(size);
+ }
+
+ /**
+ * Return the appropriate
- * This class is typically used in cases where an output stream needs to be
- * passed to a component that wants to explicitly close the stream even if
- * other components would still use the stream for output.
- *
- * @version $Id: CloseShieldOutputStream.java 587913 2007-10-24 15:47:30Z niallp $
- * @since Commons IO 1.4
- */
-public class CloseShieldOutputStream extends ProxyOutputStream {
-
- /**
- * Creates a proxy that shields the given output stream from being
- * closed.
- *
- * @param out underlying output stream
- */
- public CloseShieldOutputStream(OutputStream out) {
- super(out);
- }
-
- /**
- * Replaces the underlying output stream with a {@link ClosedOutputStream}
- * sentinel. The original output stream will remain open, but this proxy
- * will appear closed.
- */
- public void close() {
- out = new ClosedOutputStream();
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.OutputStream;
+
+/**
+ * Proxy stream that prevents the underlying output stream from being closed.
+ *
+ * This class is typically used in cases where an output stream needs to be
+ * passed to a component that wants to explicitly close the stream even if
+ * other components would still use the stream for output.
+ *
+ * @version $Id: CloseShieldOutputStream.java 587913 2007-10-24 15:47:30Z niallp $
+ * @since Commons IO 1.4
+ */
+public class CloseShieldOutputStream extends ProxyOutputStream {
+
+ /**
+ * Creates a proxy that shields the given output stream from being
+ * closed.
+ *
+ * @param out underlying output stream
+ */
+ public CloseShieldOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ /**
+ * Replaces the underlying output stream with a {@link ClosedOutputStream}
+ * sentinel. The original output stream will remain open, but this proxy
+ * will appear closed.
+ */
+ public void close() {
+ out = new ClosedOutputStream();
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/ClosedOutputStream.java b/src/org/apache/commons/io/output/ClosedOutputStream.java
index b585c0cf4ffd7b03b5bd2e6ca4d0a6db09b82e28..8c881c6857bcdc586e22c070b9f1d10b9c4b676d 100644
--- a/src/org/apache/commons/io/output/ClosedOutputStream.java
+++ b/src/org/apache/commons/io/output/ClosedOutputStream.java
@@ -1,50 +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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Closed output stream. This stream throws an exception on all attempts to
- * write something to the stream.
- *
- * Typically uses of this class include testing for corner cases in methods
- * that accept an output stream and acting as a sentinel value instead of
- * a
+ * Typically uses of this class include testing for corner cases in methods
+ * that accept an output stream and acting as a sentinel value instead of
+ * a
- * A typical use case would be during debugging, to ensure that data is being
- * written as expected.
- *
- * @version $Id: CountingOutputStream.java 471628 2006-11-06 04:06:45Z bayard $
- */
-public class CountingOutputStream extends ProxyOutputStream {
-
- /** The count of bytes that have passed. */
- private long count;
-
- /**
- * Constructs a new CountingOutputStream.
- *
- * @param out the OutputStream to write to
- */
- public CountingOutputStream( OutputStream out ) {
- super(out);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Writes the contents of the specified byte array to this output stream
- * keeping count of the number of bytes written.
- *
- * @param b the bytes to write, not null
- * @throws IOException if an I/O error occurs
- * @see java.io.OutputStream#write(byte[])
- */
- public void write(byte[] b) throws IOException {
- count += b.length;
- super.write(b);
- }
-
- /**
- * Writes a portion of the specified byte array to this output stream
- * keeping count of the number of bytes written.
- *
- * @param b the bytes to write, not null
- * @param off the start offset in the buffer
- * @param len the maximum number of bytes to write
- * @throws IOException if an I/O error occurs
- * @see java.io.OutputStream#write(byte[], int, int)
- */
- public void write(byte[] b, int off, int len) throws IOException {
- count += len;
- super.write(b, off, len);
- }
-
- /**
- * Writes a single byte to the output stream adding to the count of the
- * number of bytes written.
- *
- * @param b the byte to write
- * @throws IOException if an I/O error occurs
- * @see java.io.OutputStream#write(int)
- */
- public void write(int b) throws IOException {
- count++;
- super.write(b);
- }
-
- //-----------------------------------------------------------------------
- /**
- * The number of bytes that have passed through this stream.
- *
- * NOTE: From v1.3 this method throws an ArithmeticException if the
- * count is greater than can be expressed by an
- * NOTE: From v1.3 this method throws an ArithmeticException if the
- * count is greater than can be expressed by an
- * NOTE: This method is an alternative for
- * NOTE: This method is an alternative for
+ * A typical use case would be during debugging, to ensure that data is being
+ * written as expected.
+ *
+ * @version $Id: CountingOutputStream.java 471628 2006-11-06 04:06:45Z bayard $
+ */
+public class CountingOutputStream extends ProxyOutputStream {
+
+ /** The count of bytes that have passed. */
+ private long count;
+
+ /**
+ * Constructs a new CountingOutputStream.
+ *
+ * @param out the OutputStream to write to
+ */
+ public CountingOutputStream( OutputStream out ) {
+ super(out);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Writes the contents of the specified byte array to this output stream
+ * keeping count of the number of bytes written.
+ *
+ * @param b the bytes to write, not null
+ * @throws IOException if an I/O error occurs
+ * @see java.io.OutputStream#write(byte[])
+ */
+ public void write(byte[] b) throws IOException {
+ count += b.length;
+ super.write(b);
+ }
+
+ /**
+ * Writes a portion of the specified byte array to this output stream
+ * keeping count of the number of bytes written.
+ *
+ * @param b the bytes to write, not null
+ * @param off the start offset in the buffer
+ * @param len the maximum number of bytes to write
+ * @throws IOException if an I/O error occurs
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ count += len;
+ super.write(b, off, len);
+ }
+
+ /**
+ * Writes a single byte to the output stream adding to the count of the
+ * number of bytes written.
+ *
+ * @param b the byte to write
+ * @throws IOException if an I/O error occurs
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException {
+ count++;
+ super.write(b);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * The number of bytes that have passed through this stream.
+ *
+ * NOTE: From v1.3 this method throws an ArithmeticException if the
+ * count is greater than can be expressed by an
+ * NOTE: From v1.3 this method throws an ArithmeticException if the
+ * count is greater than can be expressed by an
+ * NOTE: This method is an alternative for
+ * NOTE: This method is an alternative for
- * This class originated in FileUpload processing. In this use case, you do
- * not know in advance the size of the file being uploaded. If the file is small
- * you want to store it in memory (for speed), but if the file is large you want
- * to store it to file (to avoid memory issues).
- *
- * @author Martin Cooper
- * @author gaxzerow
- *
- * @version $Id: DeferredFileOutputStream.java 606381 2007-12-22 02:03:16Z ggregory $
- */
-public class DeferredFileOutputStream
- extends ThresholdingOutputStream
-{
-
- // ----------------------------------------------------------- Data members
-
-
- /**
- * The output stream to which data will be written prior to the theshold
- * being reached.
- */
- private ByteArrayOutputStream memoryOutputStream;
-
-
- /**
- * The output stream to which data will be written at any given time. This
- * will always be one of
- * If the constructor specifying the file is used then it returns that
- * same output file, even when threashold has not been reached.
- *
- * If constructor specifying a temporary file prefix/suffix is used
- * then the temporary file created once the threashold is reached is returned
- * If the threshold was not reached then
+ * This class originated in FileUpload processing. In this use case, you do
+ * not know in advance the size of the file being uploaded. If the file is small
+ * you want to store it in memory (for speed), but if the file is large you want
+ * to store it to file (to avoid memory issues).
+ *
+ * @author Martin Cooper
+ * @author gaxzerow
+ *
+ * @version $Id: DeferredFileOutputStream.java 606381 2007-12-22 02:03:16Z ggregory $
+ */
+public class DeferredFileOutputStream
+ extends ThresholdingOutputStream
+{
+
+ // ----------------------------------------------------------- Data members
+
+
+ /**
+ * The output stream to which data will be written prior to the theshold
+ * being reached.
+ */
+ private ByteArrayOutputStream memoryOutputStream;
+
+
+ /**
+ * The output stream to which data will be written at any given time. This
+ * will always be one of
+ * If the constructor specifying the file is used then it returns that
+ * same output file, even when threashold has not been reached.
+ *
+ * If constructor specifying a temporary file prefix/suffix is used
+ * then the temporary file created once the threashold is reached is returned
+ * If the threshold was not reached then
- * This class provides a simple alternative to
- * By default, the file will be overwritten, but this may be changed to append.
- *
- * The encoding must be specified using either the name of the {@link Charset},
- * the {@link Charset}, or a {@link CharsetEncoder}. If the default encoding
- * is required then use the {@link java.io.FileWriter} directly, rather than
- * this implementation.
- *
- *
- *
- * @since Commons IO 1.4
- * @version $Id: FileWriterWithEncoding.java 611634 2008-01-13 20:35:00Z niallp $
- */
-public class FileWriterWithEncoding extends Writer {
- // Cannot extend ProxyWriter, as requires writer to be
- // known when super() is called
-
- /** The writer to decorate. */
- private final Writer out;
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, String encoding) throws IOException {
- this(new File(filename), encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, String encoding, boolean append) throws IOException {
- this(new File(filename), encoding, append);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, Charset encoding) throws IOException {
- this(new File(filename), encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, Charset encoding, boolean append) throws IOException {
- this(new File(filename), encoding, append);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, CharsetEncoder encoding) throws IOException {
- this(new File(filename), encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param filename the name of the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file name or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(String filename, CharsetEncoder encoding, boolean append) throws IOException {
- this(new File(filename), encoding, append);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, String encoding) throws IOException {
- this(file, encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, String encoding, boolean append) throws IOException {
- super();
- this.out = initWriter(file, encoding, append);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, Charset encoding) throws IOException {
- this(file, encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, Charset encoding, boolean append) throws IOException {
- super();
- this.out = initWriter(file, encoding, append);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, CharsetEncoder encoding) throws IOException {
- this(file, encoding, false);
- }
-
- /**
- * Constructs a FileWriterWithEncoding with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException in case of an I/O error
- */
- public FileWriterWithEncoding(File file, CharsetEncoder encoding, boolean append) throws IOException {
- super();
- this.out = initWriter(file, encoding, append);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Initialise the wrapped file writer.
- * Ensure that a cleanup occurs if the writer creation fails.
- *
- * @param file the file to be accessed
- * @param encoding the encoding to use - may be Charset, CharsetEncoder or String
- * @param append true to append
- * @return the initialised writer
- * @throws NullPointerException if the file or encoding is null
- * @throws IOException if an error occurs
- */
- private static Writer initWriter(File file, Object encoding, boolean append) throws IOException {
- if (file == null) {
- throw new NullPointerException("File is missing");
- }
- if (encoding == null) {
- throw new NullPointerException("Encoding is missing");
- }
- boolean fileExistedAlready = file.exists();
- OutputStream stream = null;
- Writer writer = null;
- try {
- stream = new FileOutputStream(file, append);
- if (encoding instanceof Charset) {
- writer = new OutputStreamWriter(stream, (Charset)encoding);
- } else if (encoding instanceof CharsetEncoder) {
- writer = new OutputStreamWriter(stream, (CharsetEncoder)encoding);
- } else {
- writer = new OutputStreamWriter(stream, (String)encoding);
- }
- } catch (IOException ex) {
- IOUtils.closeQuietly(writer);
- IOUtils.closeQuietly(stream);
- if (fileExistedAlready == false) {
- FileUtils.deleteQuietly(file);
- }
- throw ex;
- } catch (RuntimeException ex) {
- IOUtils.closeQuietly(writer);
- IOUtils.closeQuietly(stream);
- if (fileExistedAlready == false) {
- FileUtils.deleteQuietly(file);
- }
- throw ex;
- }
- return writer;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Write a character.
- * @param idx the character to write
- * @throws IOException if an I/O error occurs
- */
- public void write(int idx) throws IOException {
- out.write(idx);
- }
-
- /**
- * Write the characters from an array.
- * @param chr the characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr) throws IOException {
- out.write(chr);
- }
-
- /**
- * Write the specified characters from an array.
- * @param chr the characters to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr, int st, int end) throws IOException {
- out.write(chr, st, end);
- }
-
- /**
- * Write the characters from a string.
- * @param str the string to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str) throws IOException {
- out.write(str);
- }
-
- /**
- * Write the specified characters from a string.
- * @param str the string to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str, int st, int end) throws IOException {
- out.write(str, st, end);
- }
-
- /**
- * Flush the stream.
- * @throws IOException if an I/O error occurs
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Close the stream.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- out.close();
- }
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Writer of files that allows the encoding to be set.
+ *
+ * This class provides a simple alternative to
+ * By default, the file will be overwritten, but this may be changed to append.
+ *
+ * The encoding must be specified using either the name of the {@link Charset},
+ * the {@link Charset}, or a {@link CharsetEncoder}. If the default encoding
+ * is required then use the {@link java.io.FileWriter} directly, rather than
+ * this implementation.
+ *
+ *
+ *
+ * @since Commons IO 1.4
+ * @version $Id: FileWriterWithEncoding.java 611634 2008-01-13 20:35:00Z niallp $
+ */
+public class FileWriterWithEncoding extends Writer {
+ // Cannot extend ProxyWriter, as requires writer to be
+ // known when super() is called
+
+ /** The writer to decorate. */
+ private final Writer out;
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, String encoding) throws IOException {
+ this(new File(filename), encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, String encoding, boolean append) throws IOException {
+ this(new File(filename), encoding, append);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, Charset encoding) throws IOException {
+ this(new File(filename), encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, Charset encoding, boolean append) throws IOException {
+ this(new File(filename), encoding, append);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, CharsetEncoder encoding) throws IOException {
+ this(new File(filename), encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param filename the name of the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file name or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(String filename, CharsetEncoder encoding, boolean append) throws IOException {
+ this(new File(filename), encoding, append);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, String encoding) throws IOException {
+ this(file, encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, String encoding, boolean append) throws IOException {
+ super();
+ this.out = initWriter(file, encoding, append);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, Charset encoding) throws IOException {
+ this(file, encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, Charset encoding, boolean append) throws IOException {
+ super();
+ this.out = initWriter(file, encoding, append);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, CharsetEncoder encoding) throws IOException {
+ this(file, encoding, false);
+ }
+
+ /**
+ * Constructs a FileWriterWithEncoding with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException in case of an I/O error
+ */
+ public FileWriterWithEncoding(File file, CharsetEncoder encoding, boolean append) throws IOException {
+ super();
+ this.out = initWriter(file, encoding, append);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Initialise the wrapped file writer.
+ * Ensure that a cleanup occurs if the writer creation fails.
+ *
+ * @param file the file to be accessed
+ * @param encoding the encoding to use - may be Charset, CharsetEncoder or String
+ * @param append true to append
+ * @return the initialised writer
+ * @throws NullPointerException if the file or encoding is null
+ * @throws IOException if an error occurs
+ */
+ private static Writer initWriter(File file, Object encoding, boolean append) throws IOException {
+ if (file == null) {
+ throw new NullPointerException("File is missing");
+ }
+ if (encoding == null) {
+ throw new NullPointerException("Encoding is missing");
+ }
+ boolean fileExistedAlready = file.exists();
+ OutputStream stream = null;
+ Writer writer = null;
+ try {
+ stream = new FileOutputStream(file, append);
+ if (encoding instanceof Charset) {
+ writer = new OutputStreamWriter(stream, (Charset)encoding);
+ } else if (encoding instanceof CharsetEncoder) {
+ writer = new OutputStreamWriter(stream, (CharsetEncoder)encoding);
+ } else {
+ writer = new OutputStreamWriter(stream, (String)encoding);
+ }
+ } catch (IOException ex) {
+ IOUtils.closeQuietly(writer);
+ IOUtils.closeQuietly(stream);
+ if (fileExistedAlready == false) {
+ FileUtils.deleteQuietly(file);
+ }
+ throw ex;
+ } catch (RuntimeException ex) {
+ IOUtils.closeQuietly(writer);
+ IOUtils.closeQuietly(stream);
+ if (fileExistedAlready == false) {
+ FileUtils.deleteQuietly(file);
+ }
+ throw ex;
+ }
+ return writer;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Write a character.
+ * @param idx the character to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(int idx) throws IOException {
+ out.write(idx);
+ }
+
+ /**
+ * Write the characters from an array.
+ * @param chr the characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr) throws IOException {
+ out.write(chr);
+ }
+
+ /**
+ * Write the specified characters from an array.
+ * @param chr the characters to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr, int st, int end) throws IOException {
+ out.write(chr, st, end);
+ }
+
+ /**
+ * Write the characters from a string.
+ * @param str the string to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str) throws IOException {
+ out.write(str);
+ }
+
+ /**
+ * Write the specified characters from a string.
+ * @param str the string to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str, int st, int end) throws IOException {
+ out.write(str, st, end);
+ }
+
+ /**
+ * Flush the stream.
+ * @throws IOException if an I/O error occurs
+ */
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Close the stream.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ out.close();
+ }
+}
diff --git a/src/org/apache/commons/io/output/LockableFileWriter.java b/src/org/apache/commons/io/output/LockableFileWriter.java
index 6b10bd2823298f495e6cea2d3b0d9bf9f6ff3760..1092926cd4c07e19b0db53b770ecbca6efe0eddf 100644
--- a/src/org/apache/commons/io/output/LockableFileWriter.java
+++ b/src/org/apache/commons/io/output/LockableFileWriter.java
@@ -1,333 +1,333 @@
-/*
- * 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.commons.io.output;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-
-/**
- * FileWriter that will create and honor lock files to allow simple
- * cross thread file lock handling.
- *
- * This class provides a simple alternative to
- * By default, the file will be overwritten, but this may be changed to append.
- * The lock directory may be specified, but defaults to the system property
- *
+ * This class provides a simple alternative to
+ * By default, the file will be overwritten, but this may be changed to append.
+ * The lock directory may be specified, but defaults to the system property
+ *
- * This output stream has no destination (file/socket etc.) and all
- * bytes written to it are ignored and lost.
- *
- * @author Jeremias Maerki
- * @version $Id: NullOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class NullOutputStream extends OutputStream {
-
- /**
- * A singleton.
- */
- public static final NullOutputStream NULL_OUTPUT_STREAM = new NullOutputStream();
-
- /**
- * Does nothing - output to
+ * This output stream has no destination (file/socket etc.) and all
+ * bytes written to it are ignored and lost.
+ *
+ * @author Jeremias Maerki
+ * @version $Id: NullOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class NullOutputStream extends OutputStream {
+
+ /**
+ * A singleton.
+ */
+ public static final NullOutputStream NULL_OUTPUT_STREAM = new NullOutputStream();
+
+ /**
+ * Does nothing - output to
- * This
+ * This
- * This class overrides all
- * NOTE: This implementation may trigger the event before the threshold
- * is actually reached, since it triggers when a pending write operation would
- * cause the threshold to be exceeded.
- *
- * @author Martin Cooper
- *
- * @version $Id: ThresholdingOutputStream.java 540714 2007-05-22 19:39:44Z niallp $
- */
-public abstract class ThresholdingOutputStream
- extends OutputStream
-{
-
- // ----------------------------------------------------------- Data members
-
-
- /**
- * The threshold at which the event will be triggered.
- */
- private int threshold;
-
-
- /**
- * The number of bytes written to the output stream.
- */
- private long written;
-
-
- /**
- * Whether or not the configured threshold has been exceeded.
- */
- private boolean thresholdExceeded;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Constructs an instance of this class which will trigger an event at the
- * specified threshold.
- *
- * @param threshold The number of bytes at which to trigger an event.
- */
- public ThresholdingOutputStream(int threshold)
- {
- this.threshold = threshold;
- }
-
-
- // --------------------------------------------------- OutputStream methods
-
-
- /**
- * Writes the specified byte to this output stream.
- *
- * @param b The byte to be written.
- *
- * @exception IOException if an error occurs.
- */
- public void write(int b) throws IOException
- {
- checkThreshold(1);
- getStream().write(b);
- written++;
- }
-
-
- /**
- * Writes
+ * This class overrides all
+ * NOTE: This implementation may trigger the event before the threshold
+ * is actually reached, since it triggers when a pending write operation would
+ * cause the threshold to be exceeded.
+ *
+ * @author Martin Cooper
+ *
+ * @version $Id: ThresholdingOutputStream.java 540714 2007-05-22 19:39:44Z niallp $
+ */
+public abstract class ThresholdingOutputStream
+ extends OutputStream
+{
+
+ // ----------------------------------------------------------- Data members
+
+
+ /**
+ * The threshold at which the event will be triggered.
+ */
+ private int threshold;
+
+
+ /**
+ * The number of bytes written to the output stream.
+ */
+ private long written;
+
+
+ /**
+ * Whether or not the configured threshold has been exceeded.
+ */
+ private boolean thresholdExceeded;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Constructs an instance of this class which will trigger an event at the
+ * specified threshold.
+ *
+ * @param threshold The number of bytes at which to trigger an event.
+ */
+ public ThresholdingOutputStream(int threshold)
+ {
+ this.threshold = threshold;
+ }
+
+
+ // --------------------------------------------------- OutputStream methods
+
+
+ /**
+ * Writes the specified byte to this output stream.
+ *
+ * @param b The byte to be written.
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void write(int b) throws IOException
+ {
+ checkThreshold(1);
+ getStream().write(b);
+ written++;
+ }
+
+
+ /**
+ * Writes
-This package provides implementations of output classes, such as
-
+This package provides implementations of output classes, such as
+
-The commons-io component contains utility classes,
-filters, streams, readers and writers.
-
-These classes aim to add to the standard JDK IO classes.
-The utilities provide convenience wrappers around the JDK, simplifying
-various operations into pre-tested units of code.
-The filters and streams provide useful implementations that perhaps should
-be in the JDK itself.
-
+The commons-io component contains utility classes,
+filters, streams, readers and writers.
+
+These classes aim to add to the standard JDK IO classes.
+The utilities provide convenience wrappers around the JDK, simplifying
+various operations into pre-tested units of code.
+The filters and streams provide useful implementations that perhaps should
+be in the JDK itself.
+
-This package defines utility classes for working with streams, readers,
-writers and files. The most commonly used classes are described here:
-
-IOUtils is the most frequently used class.
-It provides operations to read, write, copy and close streams.
-
-FileUtils provides operations based around the JDK File class.
-These include reading, writing, copying, comparing and deleting.
-
-FilenameUtils provides utilities based on filenames.
-This utility class manipulates filenames without using File objects.
-It aims to simplify the transition between Windows and Unix.
-Before using this class however, you should consider whether you should
-be using File objects.
-
-FileSystemUtils allows access to the filing system in ways the JDK
-does not support. At present this allows you to get the free space on a drive.
-
-EndianUtils swaps data between Big-Endian and Little-Endian formats.
-
+This package defines utility classes for working with streams, readers,
+writers and files. The most commonly used classes are described here:
+
+IOUtils is the most frequently used class.
+It provides operations to read, write, copy and close streams.
+
+FileUtils provides operations based around the JDK File class.
+These include reading, writing, copying, comparing and deleting.
+
+FilenameUtils provides utilities based on filenames.
+This utility class manipulates filenames without using File objects.
+It aims to simplify the transition between Windows and Unix.
+Before using this class however, you should consider whether you should
+be using File objects.
+
+FileSystemUtils allows access to the filing system in ways the JDK
+does not support. At present this allows you to get the free space on a drive.
+
+EndianUtils swaps data between Big-Endian and Little-Endian formats.
+
- * Receives notifications of the content of a plain RFC822 or MIME message.
- * Implement this interface and register an instance of that implementation
- * with a
- * Events will be generated in the order the corresponding elements occur in
- * the message stream parsed by the parser. E.g.:
- *
- * See MIME RFCs 2045-2049 for more information on the structure of MIME
- * messages and RFC 822 and 2822 for the general structure of Internet mail
- * messages.
- *
+ * Receives notifications of the content of a plain RFC822 or MIME message.
+ * Implement this interface and register an instance of that implementation
+ * with a
+ * Events will be generated in the order the corresponding elements occur in
+ * the message stream parsed by the parser. E.g.:
+ * FileUtils.forceDelete()
- * if the file exists.
- *
- * @param fileToDelete the file to delete, not null
- * @return Always returns
true
- * @throws NullPointerException if the file is null
- * @throws IOException if an error occurs during file deletion
- */
- protected boolean doDelete(File fileToDelete) throws IOException {
- FileUtils.forceDelete(fileToDelete);
- return true;
- }
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Strategy for deleting files.
+ * IOException
s are caught and false returned instead.
+ * If the file does not exist or is null, true is returned.
+ * IOException
+ * when deletion fails. The {@link #delete(File)} and {@link #deleteQuietly(File)}
+ * methods will handle either response appropriately.
+ * A check has been made to ensure that the file will exist.
+ * FileUtils.forceDelete()
+ * if the file exists.
+ *
+ * @param fileToDelete the file to delete, not null
+ * @return Always returns
true
+ * @throws NullPointerException if the file is null
+ * @throws IOException if an error occurs during file deletion
+ */
+ protected boolean doDelete(File fileToDelete) throws IOException {
+ FileUtils.forceDelete(fileToDelete);
+ return true;
+ }
+ }
+
+}
diff --git a/src/org/apache/commons/io/FileSystemUtils.java b/src/org/apache/commons/io/FileSystemUtils.java
index a29dba43902c0004ea80cff00264cbf06334bf10..4c0957256b355314bbe0f773dbedd756d9bc96ad 100644
--- a/src/org/apache/commons/io/FileSystemUtils.java
+++ b/src/org/apache/commons/io/FileSystemUtils.java
@@ -1,457 +1,457 @@
-/*
- * 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.commons.io;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * General File System utilities.
- *
- *
- *
- * @author Frank W. Zammetti
- * @author Stephen Colebourne
- * @author Thomas Ledoux
- * @author James Urie
- * @author Magnus Grimsell
- * @author Thomas Ledoux
- * @version $Id: FileSystemUtils.java 453889 2006-10-07 11:56:25Z scolebourne $
- * @since Commons IO 1.1
- */
-public class FileSystemUtils {
-
- /** Singleton instance, used mainly for testing. */
- private static final FileSystemUtils INSTANCE = new FileSystemUtils();
-
- /** Operating system state flag for error. */
- private static final int INIT_PROBLEM = -1;
- /** Operating system state flag for neither Unix nor Windows. */
- private static final int OTHER = 0;
- /** Operating system state flag for Windows. */
- private static final int WINDOWS = 1;
- /** Operating system state flag for Unix. */
- private static final int UNIX = 2;
- /** Operating system state flag for Posix flavour Unix. */
- private static final int POSIX_UNIX = 3;
-
- /** The operating system flag. */
- private static final int OS;
- static {
- int os = OTHER;
- try {
- String osName = System.getProperty("os.name");
- if (osName == null) {
- throw new IOException("os.name not found");
- }
- osName = osName.toLowerCase();
- // match
- if (osName.indexOf("windows") != -1) {
- os = WINDOWS;
- } else if (osName.indexOf("linux") != -1 ||
- osName.indexOf("sun os") != -1 ||
- osName.indexOf("sunos") != -1 ||
- osName.indexOf("solaris") != -1 ||
- osName.indexOf("mpe/ix") != -1 ||
- osName.indexOf("freebsd") != -1 ||
- osName.indexOf("irix") != -1 ||
- osName.indexOf("digital unix") != -1 ||
- osName.indexOf("unix") != -1 ||
- osName.indexOf("mac os x") != -1) {
- os = UNIX;
- } else if (osName.indexOf("hp-ux") != -1 ||
- osName.indexOf("aix") != -1) {
- os = POSIX_UNIX;
- } else {
- os = OTHER;
- }
-
- } catch (Exception ex) {
- os = INIT_PROBLEM;
- }
- OS = os;
- }
-
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public FileSystemUtils() {
- super();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns the free space on a drive or volume by invoking
- * the command line.
- * This method does not normalize the result, and typically returns
- * bytes on Windows, 512 byte units on OS X and kilobytes on Unix.
- * As this is not very useful, this method is deprecated in favour
- * of {@link #freeSpaceKb(String)} which returns a result in kilobytes.
- * freeSpaceKb
.)
- *
- * FileSystemUtils.freeSpace("C:"); // Windows
- * FileSystemUtils.freeSpace("/volume"); // *nix
- *
- * The free space is calculated via the command line.
- * It uses 'dir /-c' on Windows and 'df' on *nix.
- *
- * @param path the path to get free space for, not null, not empty on Unix
- * @return the amount of free drive space on the drive or volume
- * @throws IllegalArgumentException if the path is invalid
- * @throws IllegalStateException if an error occurred in initialisation
- * @throws IOException if an error occurs when finding the free space
- * @since Commons IO 1.1, enhanced OS support in 1.2 and 1.3
- * @deprecated Use freeSpaceKb(String)
- * Deprecated from 1.3, may be removed in 2.0
- */
- public static long freeSpace(String path) throws IOException {
- return INSTANCE.freeSpaceOS(path, OS, false);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns the free space on a drive or volume in kilobytes by invoking
- * the command line.
- *
- * FileSystemUtils.freeSpaceKb("C:"); // Windows
- * FileSystemUtils.freeSpaceKb("/volume"); // *nix
- *
- * The free space is calculated via the command line.
- * It uses 'dir /-c' on Windows, 'df -kP' on AIX/HP-UX and 'df -k' on other Unix.
- *
- * FileSystemUtils.freeSpace("C:"); // Windows
- * FileSystemUtils.freeSpace("/volume"); // *nix
- *
- * The free space is calculated via the command line.
- * It uses 'dir /-c' on Windows and 'df' on *nix.
- *
- * @param path the path to get free space for, not null, not empty on Unix
- * @param os the operating system code
- * @param kb whether to normalize to kilobytes
- * @return the amount of free drive space on the drive or volume
- * @throws IllegalArgumentException if the path is invalid
- * @throws IllegalStateException if an error occurred in initialisation
- * @throws IOException if an error occurs when finding the free space
- */
- long freeSpaceOS(String path, int os, boolean kb) throws IOException {
- if (path == null) {
- throw new IllegalArgumentException("Path must not be empty");
- }
- switch (os) {
- case WINDOWS:
- return (kb ? freeSpaceWindows(path) / 1024 : freeSpaceWindows(path));
- case UNIX:
- return freeSpaceUnix(path, kb, false);
- case POSIX_UNIX:
- return freeSpaceUnix(path, kb, true);
- case OTHER:
- throw new IllegalStateException("Unsupported operating system");
- default:
- throw new IllegalStateException(
- "Exception caught when determining operating system");
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Find free space on the Windows platform using the 'dir' command.
- *
- * @param path the path to get free space for, including the colon
- * @return the amount of free drive space on the drive
- * @throws IOException if an error occurs
- */
- long freeSpaceWindows(String path) throws IOException {
- path = FilenameUtils.normalize(path);
- if (path.length() > 2 && path.charAt(1) == ':') {
- path = path.substring(0, 2); // seems to make it work
- }
-
- // build and run the 'dir' command
- String[] cmdAttribs = new String[] {"cmd.exe", "/C", "dir /-c " + path};
-
- // read in the output of the command to an ArrayList
- List lines = performCommand(cmdAttribs, Integer.MAX_VALUE);
-
- // now iterate over the lines we just read and find the LAST
- // non-empty line (the free space bytes should be in the last element
- // of the ArrayList anyway, but this will ensure it works even if it's
- // not, still assuming it is on the last non-blank line)
- for (int i = lines.size() - 1; i >= 0; i--) {
- String line = (String) lines.get(i);
- if (line.length() > 0) {
- return parseDir(line, path);
- }
- }
- // all lines are blank
- throw new IOException(
- "Command line 'dir /-c' did not return any info " +
- "for path '" + path + "'");
- }
-
- /**
- * Parses the Windows dir response last line
- *
- * @param line the line to parse
- * @param path the path that was sent
- * @return the number of bytes
- * @throws IOException if an error occurs
- */
- long parseDir(String line, String path) throws IOException {
- // read from the end of the line to find the last numeric
- // character on the line, then continue until we find the first
- // non-numeric character, and everything between that and the last
- // numeric character inclusive is our free space bytes count
- int bytesStart = 0;
- int bytesEnd = 0;
- int j = line.length() - 1;
- innerLoop1: while (j >= 0) {
- char c = line.charAt(j);
- if (Character.isDigit(c)) {
- // found the last numeric character, this is the end of
- // the free space bytes count
- bytesEnd = j + 1;
- break innerLoop1;
- }
- j--;
- }
- innerLoop2: while (j >= 0) {
- char c = line.charAt(j);
- if (!Character.isDigit(c) && c != ',' && c != '.') {
- // found the next non-numeric character, this is the
- // beginning of the free space bytes count
- bytesStart = j + 1;
- break innerLoop2;
- }
- j--;
- }
- if (j < 0) {
- throw new IOException(
- "Command line 'dir /-c' did not return valid info " +
- "for path '" + path + "'");
- }
-
- // remove commas and dots in the bytes count
- StringBuffer buf = new StringBuffer(line.substring(bytesStart, bytesEnd));
- for (int k = 0; k < buf.length(); k++) {
- if (buf.charAt(k) == ',' || buf.charAt(k) == '.') {
- buf.deleteCharAt(k--);
- }
- }
- return parseBytes(buf.toString(), path);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Find free space on the *nix platform using the 'df' command.
- *
- * @param path the path to get free space for
- * @param kb whether to normalize to kilobytes
- * @param posix whether to use the posix standard format flag
- * @return the amount of free drive space on the volume
- * @throws IOException if an error occurs
- */
- long freeSpaceUnix(String path, boolean kb, boolean posix) throws IOException {
- if (path.length() == 0) {
- throw new IllegalArgumentException("Path must not be empty");
- }
- path = FilenameUtils.normalize(path);
-
- // build and run the 'dir' command
- String flags = "-";
- if (kb) {
- flags += "k";
- }
- if (posix) {
- flags += "P";
- }
- String[] cmdAttribs =
- (flags.length() > 1 ? new String[] {"df", flags, path} : new String[] {"df", path});
-
- // perform the command, asking for up to 3 lines (header, interesting, overflow)
- List lines = performCommand(cmdAttribs, 3);
- if (lines.size() < 2) {
- // unknown problem, throw exception
- throw new IOException(
- "Command line 'df' did not return info as expected " +
- "for path '" + path + "'- response was " + lines);
- }
- String line2 = (String) lines.get(1); // the line we're interested in
-
- // Now, we tokenize the string. The fourth element is what we want.
- StringTokenizer tok = new StringTokenizer(line2, " ");
- if (tok.countTokens() < 4) {
- // could be long Filesystem, thus data on third line
- if (tok.countTokens() == 1 && lines.size() >= 3) {
- String line3 = (String) lines.get(2); // the line may be interested in
- tok = new StringTokenizer(line3, " ");
- } else {
- throw new IOException(
- "Command line 'df' did not return data as expected " +
- "for path '" + path + "'- check path is valid");
- }
- } else {
- tok.nextToken(); // Ignore Filesystem
- }
- tok.nextToken(); // Ignore 1K-blocks
- tok.nextToken(); // Ignore Used
- String freeSpace = tok.nextToken();
- return parseBytes(freeSpace, path);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Parses the bytes from a string.
- *
- * @param freeSpace the free space string
- * @param path the path
- * @return the number of bytes
- * @throws IOException if an error occurs
- */
- long parseBytes(String freeSpace, String path) throws IOException {
- try {
- long bytes = Long.parseLong(freeSpace);
- if (bytes < 0) {
- throw new IOException(
- "Command line 'df' did not find free space in response " +
- "for path '" + path + "'- check path is valid");
- }
- return bytes;
-
- } catch (NumberFormatException ex) {
- throw new IOException(
- "Command line 'df' did not return numeric data as expected " +
- "for path '" + path + "'- check path is valid");
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Performs the os command.
- *
- * @param cmdAttribs the command line parameters
- * @param max The maximum limit for the lines returned
- * @return the parsed data
- * @throws IOException if an error occurs
- */
- List performCommand(String[] cmdAttribs, int max) throws IOException {
- // this method does what it can to avoid the 'Too many open files' error
- // based on trial and error and these links:
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4784692
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027
- // http://forum.java.sun.com/thread.jspa?threadID=533029&messageID=2572018
- // however, its still not perfect as the JDK support is so poor
- // (see commond-exec or ant for a better multi-threaded multi-os solution)
-
- List lines = new ArrayList(20);
- Process proc = null;
- InputStream in = null;
- OutputStream out = null;
- InputStream err = null;
- BufferedReader inr = null;
- try {
- proc = openProcess(cmdAttribs);
- in = proc.getInputStream();
- out = proc.getOutputStream();
- err = proc.getErrorStream();
- inr = new BufferedReader(new InputStreamReader(in));
- String line = inr.readLine();
- while (line != null && lines.size() < max) {
- line = line.toLowerCase().trim();
- lines.add(line);
- line = inr.readLine();
- }
-
- proc.waitFor();
- if (proc.exitValue() != 0) {
- // os command problem, throw exception
- throw new IOException(
- "Command line returned OS error code '" + proc.exitValue() +
- "' for command " + Arrays.asList(cmdAttribs));
- }
- if (lines.size() == 0) {
- // unknown problem, throw exception
- throw new IOException(
- "Command line did not return any info " +
- "for command " + Arrays.asList(cmdAttribs));
- }
- return lines;
-
- } catch (InterruptedException ex) {
- throw new IOException(
- "Command line threw an InterruptedException '" + ex.getMessage() +
- "' for command " + Arrays.asList(cmdAttribs));
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- IOUtils.closeQuietly(err);
- IOUtils.closeQuietly(inr);
- if (proc != null) {
- proc.destroy();
- }
- }
- }
-
- /**
- * Opens the process to the operating system.
- *
- * @param cmdAttribs the command line parameters
- * @return the process
- * @throws IOException if an error occurs
- */
- Process openProcess(String[] cmdAttribs) throws IOException {
- return Runtime.getRuntime().exec(cmdAttribs);
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * General File System utilities.
+ *
+ *
+ *
+ * @author Frank W. Zammetti
+ * @author Stephen Colebourne
+ * @author Thomas Ledoux
+ * @author James Urie
+ * @author Magnus Grimsell
+ * @author Thomas Ledoux
+ * @version $Id: FileSystemUtils.java 453889 2006-10-07 11:56:25Z scolebourne $
+ * @since Commons IO 1.1
+ */
+public class FileSystemUtils {
+
+ /** Singleton instance, used mainly for testing. */
+ private static final FileSystemUtils INSTANCE = new FileSystemUtils();
+
+ /** Operating system state flag for error. */
+ private static final int INIT_PROBLEM = -1;
+ /** Operating system state flag for neither Unix nor Windows. */
+ private static final int OTHER = 0;
+ /** Operating system state flag for Windows. */
+ private static final int WINDOWS = 1;
+ /** Operating system state flag for Unix. */
+ private static final int UNIX = 2;
+ /** Operating system state flag for Posix flavour Unix. */
+ private static final int POSIX_UNIX = 3;
+
+ /** The operating system flag. */
+ private static final int OS;
+ static {
+ int os = OTHER;
+ try {
+ String osName = System.getProperty("os.name");
+ if (osName == null) {
+ throw new IOException("os.name not found");
+ }
+ osName = osName.toLowerCase();
+ // match
+ if (osName.indexOf("windows") != -1) {
+ os = WINDOWS;
+ } else if (osName.indexOf("linux") != -1 ||
+ osName.indexOf("sun os") != -1 ||
+ osName.indexOf("sunos") != -1 ||
+ osName.indexOf("solaris") != -1 ||
+ osName.indexOf("mpe/ix") != -1 ||
+ osName.indexOf("freebsd") != -1 ||
+ osName.indexOf("irix") != -1 ||
+ osName.indexOf("digital unix") != -1 ||
+ osName.indexOf("unix") != -1 ||
+ osName.indexOf("mac os x") != -1) {
+ os = UNIX;
+ } else if (osName.indexOf("hp-ux") != -1 ||
+ osName.indexOf("aix") != -1) {
+ os = POSIX_UNIX;
+ } else {
+ os = OTHER;
+ }
+
+ } catch (Exception ex) {
+ os = INIT_PROBLEM;
+ }
+ OS = os;
+ }
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public FileSystemUtils() {
+ super();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the free space on a drive or volume by invoking
+ * the command line.
+ * This method does not normalize the result, and typically returns
+ * bytes on Windows, 512 byte units on OS X and kilobytes on Unix.
+ * As this is not very useful, this method is deprecated in favour
+ * of {@link #freeSpaceKb(String)} which returns a result in kilobytes.
+ * freeSpaceKb
.)
+ *
+ * FileSystemUtils.freeSpace("C:"); // Windows
+ * FileSystemUtils.freeSpace("/volume"); // *nix
+ *
+ * The free space is calculated via the command line.
+ * It uses 'dir /-c' on Windows and 'df' on *nix.
+ *
+ * @param path the path to get free space for, not null, not empty on Unix
+ * @return the amount of free drive space on the drive or volume
+ * @throws IllegalArgumentException if the path is invalid
+ * @throws IllegalStateException if an error occurred in initialisation
+ * @throws IOException if an error occurs when finding the free space
+ * @since Commons IO 1.1, enhanced OS support in 1.2 and 1.3
+ * @deprecated Use freeSpaceKb(String)
+ * Deprecated from 1.3, may be removed in 2.0
+ */
+ public static long freeSpace(String path) throws IOException {
+ return INSTANCE.freeSpaceOS(path, OS, false);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the free space on a drive or volume in kilobytes by invoking
+ * the command line.
+ *
+ * FileSystemUtils.freeSpaceKb("C:"); // Windows
+ * FileSystemUtils.freeSpaceKb("/volume"); // *nix
+ *
+ * The free space is calculated via the command line.
+ * It uses 'dir /-c' on Windows, 'df -kP' on AIX/HP-UX and 'df -k' on other Unix.
+ *
+ * FileSystemUtils.freeSpace("C:"); // Windows
+ * FileSystemUtils.freeSpace("/volume"); // *nix
+ *
+ * The free space is calculated via the command line.
+ * It uses 'dir /-c' on Windows and 'df' on *nix.
+ *
+ * @param path the path to get free space for, not null, not empty on Unix
+ * @param os the operating system code
+ * @param kb whether to normalize to kilobytes
+ * @return the amount of free drive space on the drive or volume
+ * @throws IllegalArgumentException if the path is invalid
+ * @throws IllegalStateException if an error occurred in initialisation
+ * @throws IOException if an error occurs when finding the free space
+ */
+ long freeSpaceOS(String path, int os, boolean kb) throws IOException {
+ if (path == null) {
+ throw new IllegalArgumentException("Path must not be empty");
+ }
+ switch (os) {
+ case WINDOWS:
+ return (kb ? freeSpaceWindows(path) / 1024 : freeSpaceWindows(path));
+ case UNIX:
+ return freeSpaceUnix(path, kb, false);
+ case POSIX_UNIX:
+ return freeSpaceUnix(path, kb, true);
+ case OTHER:
+ throw new IllegalStateException("Unsupported operating system");
+ default:
+ throw new IllegalStateException(
+ "Exception caught when determining operating system");
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Find free space on the Windows platform using the 'dir' command.
+ *
+ * @param path the path to get free space for, including the colon
+ * @return the amount of free drive space on the drive
+ * @throws IOException if an error occurs
+ */
+ long freeSpaceWindows(String path) throws IOException {
+ path = FilenameUtils.normalize(path);
+ if (path.length() > 2 && path.charAt(1) == ':') {
+ path = path.substring(0, 2); // seems to make it work
+ }
+
+ // build and run the 'dir' command
+ String[] cmdAttribs = new String[] {"cmd.exe", "/C", "dir /-c " + path};
+
+ // read in the output of the command to an ArrayList
+ List lines = performCommand(cmdAttribs, Integer.MAX_VALUE);
+
+ // now iterate over the lines we just read and find the LAST
+ // non-empty line (the free space bytes should be in the last element
+ // of the ArrayList anyway, but this will ensure it works even if it's
+ // not, still assuming it is on the last non-blank line)
+ for (int i = lines.size() - 1; i >= 0; i--) {
+ String line = (String) lines.get(i);
+ if (line.length() > 0) {
+ return parseDir(line, path);
+ }
+ }
+ // all lines are blank
+ throw new IOException(
+ "Command line 'dir /-c' did not return any info " +
+ "for path '" + path + "'");
+ }
+
+ /**
+ * Parses the Windows dir response last line
+ *
+ * @param line the line to parse
+ * @param path the path that was sent
+ * @return the number of bytes
+ * @throws IOException if an error occurs
+ */
+ long parseDir(String line, String path) throws IOException {
+ // read from the end of the line to find the last numeric
+ // character on the line, then continue until we find the first
+ // non-numeric character, and everything between that and the last
+ // numeric character inclusive is our free space bytes count
+ int bytesStart = 0;
+ int bytesEnd = 0;
+ int j = line.length() - 1;
+ innerLoop1: while (j >= 0) {
+ char c = line.charAt(j);
+ if (Character.isDigit(c)) {
+ // found the last numeric character, this is the end of
+ // the free space bytes count
+ bytesEnd = j + 1;
+ break innerLoop1;
+ }
+ j--;
+ }
+ innerLoop2: while (j >= 0) {
+ char c = line.charAt(j);
+ if (!Character.isDigit(c) && c != ',' && c != '.') {
+ // found the next non-numeric character, this is the
+ // beginning of the free space bytes count
+ bytesStart = j + 1;
+ break innerLoop2;
+ }
+ j--;
+ }
+ if (j < 0) {
+ throw new IOException(
+ "Command line 'dir /-c' did not return valid info " +
+ "for path '" + path + "'");
+ }
+
+ // remove commas and dots in the bytes count
+ StringBuffer buf = new StringBuffer(line.substring(bytesStart, bytesEnd));
+ for (int k = 0; k < buf.length(); k++) {
+ if (buf.charAt(k) == ',' || buf.charAt(k) == '.') {
+ buf.deleteCharAt(k--);
+ }
+ }
+ return parseBytes(buf.toString(), path);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Find free space on the *nix platform using the 'df' command.
+ *
+ * @param path the path to get free space for
+ * @param kb whether to normalize to kilobytes
+ * @param posix whether to use the posix standard format flag
+ * @return the amount of free drive space on the volume
+ * @throws IOException if an error occurs
+ */
+ long freeSpaceUnix(String path, boolean kb, boolean posix) throws IOException {
+ if (path.length() == 0) {
+ throw new IllegalArgumentException("Path must not be empty");
+ }
+ path = FilenameUtils.normalize(path);
+
+ // build and run the 'dir' command
+ String flags = "-";
+ if (kb) {
+ flags += "k";
+ }
+ if (posix) {
+ flags += "P";
+ }
+ String[] cmdAttribs =
+ (flags.length() > 1 ? new String[] {"df", flags, path} : new String[] {"df", path});
+
+ // perform the command, asking for up to 3 lines (header, interesting, overflow)
+ List lines = performCommand(cmdAttribs, 3);
+ if (lines.size() < 2) {
+ // unknown problem, throw exception
+ throw new IOException(
+ "Command line 'df' did not return info as expected " +
+ "for path '" + path + "'- response was " + lines);
+ }
+ String line2 = (String) lines.get(1); // the line we're interested in
+
+ // Now, we tokenize the string. The fourth element is what we want.
+ StringTokenizer tok = new StringTokenizer(line2, " ");
+ if (tok.countTokens() < 4) {
+ // could be long Filesystem, thus data on third line
+ if (tok.countTokens() == 1 && lines.size() >= 3) {
+ String line3 = (String) lines.get(2); // the line may be interested in
+ tok = new StringTokenizer(line3, " ");
+ } else {
+ throw new IOException(
+ "Command line 'df' did not return data as expected " +
+ "for path '" + path + "'- check path is valid");
+ }
+ } else {
+ tok.nextToken(); // Ignore Filesystem
+ }
+ tok.nextToken(); // Ignore 1K-blocks
+ tok.nextToken(); // Ignore Used
+ String freeSpace = tok.nextToken();
+ return parseBytes(freeSpace, path);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Parses the bytes from a string.
+ *
+ * @param freeSpace the free space string
+ * @param path the path
+ * @return the number of bytes
+ * @throws IOException if an error occurs
+ */
+ long parseBytes(String freeSpace, String path) throws IOException {
+ try {
+ long bytes = Long.parseLong(freeSpace);
+ if (bytes < 0) {
+ throw new IOException(
+ "Command line 'df' did not find free space in response " +
+ "for path '" + path + "'- check path is valid");
+ }
+ return bytes;
+
+ } catch (NumberFormatException ex) {
+ throw new IOException(
+ "Command line 'df' did not return numeric data as expected " +
+ "for path '" + path + "'- check path is valid");
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Performs the os command.
+ *
+ * @param cmdAttribs the command line parameters
+ * @param max The maximum limit for the lines returned
+ * @return the parsed data
+ * @throws IOException if an error occurs
+ */
+ List performCommand(String[] cmdAttribs, int max) throws IOException {
+ // this method does what it can to avoid the 'Too many open files' error
+ // based on trial and error and these links:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4784692
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027
+ // http://forum.java.sun.com/thread.jspa?threadID=533029&messageID=2572018
+ // however, its still not perfect as the JDK support is so poor
+ // (see commond-exec or ant for a better multi-threaded multi-os solution)
+
+ List lines = new ArrayList(20);
+ Process proc = null;
+ InputStream in = null;
+ OutputStream out = null;
+ InputStream err = null;
+ BufferedReader inr = null;
+ try {
+ proc = openProcess(cmdAttribs);
+ in = proc.getInputStream();
+ out = proc.getOutputStream();
+ err = proc.getErrorStream();
+ inr = new BufferedReader(new InputStreamReader(in));
+ String line = inr.readLine();
+ while (line != null && lines.size() < max) {
+ line = line.toLowerCase().trim();
+ lines.add(line);
+ line = inr.readLine();
+ }
+
+ proc.waitFor();
+ if (proc.exitValue() != 0) {
+ // os command problem, throw exception
+ throw new IOException(
+ "Command line returned OS error code '" + proc.exitValue() +
+ "' for command " + Arrays.asList(cmdAttribs));
+ }
+ if (lines.size() == 0) {
+ // unknown problem, throw exception
+ throw new IOException(
+ "Command line did not return any info " +
+ "for command " + Arrays.asList(cmdAttribs));
+ }
+ return lines;
+
+ } catch (InterruptedException ex) {
+ throw new IOException(
+ "Command line threw an InterruptedException '" + ex.getMessage() +
+ "' for command " + Arrays.asList(cmdAttribs));
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ IOUtils.closeQuietly(err);
+ IOUtils.closeQuietly(inr);
+ if (proc != null) {
+ proc.destroy();
+ }
+ }
+ }
+
+ /**
+ * Opens the process to the operating system.
+ *
+ * @param cmdAttribs the command line parameters
+ * @return the process
+ * @throws IOException if an error occurs
+ */
+ Process openProcess(String[] cmdAttribs) throws IOException {
+ return Runtime.getRuntime().exec(cmdAttribs);
+ }
+
+}
diff --git a/src/org/apache/commons/io/FileUtils.java b/src/org/apache/commons/io/FileUtils.java
index 254800cd1961c7f1f95670ce5f418fc1c88dd23c..cbc789f80b49c69609194bf7f824bf04a7166f44 100644
--- a/src/org/apache/commons/io/FileUtils.java
+++ b/src/org/apache/commons/io/FileUtils.java
@@ -1,1890 +1,1890 @@
-/*
- * 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.commons.io;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.zip.CRC32;
-import java.util.zip.CheckedInputStream;
-import java.util.zip.Checksum;
-
-import org.apache.commons.io.filefilter.DirectoryFileFilter;
-import org.apache.commons.io.filefilter.FalseFileFilter;
-import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.SuffixFileFilter;
-import org.apache.commons.io.filefilter.TrueFileFilter;
-import org.apache.commons.io.output.NullOutputStream;
-
-/**
- * General file manipulation utilities.
- *
- *
- * File
.
- */
- public static final File[] EMPTY_FILE_ARRAY = new File[0];
-
- //-----------------------------------------------------------------------
- /**
- * Opens a {@link FileInputStream} for the specified file, providing better
- * error messages than simply calling new FileInputStream(file)
.
- * null
- * @return a new {@link FileInputStream} for the specified file
- * @throws FileNotFoundException if the file does not exist
- * @throws IOException if the file object is a directory
- * @throws IOException if the file cannot be read
- * @since Commons IO 1.3
- */
- public static FileInputStream openInputStream(File file) throws IOException {
- if (file.exists()) {
- if (file.isDirectory()) {
- throw new IOException("File '" + file + "' exists but is a directory");
- }
- if (file.canRead() == false) {
- throw new IOException("File '" + file + "' cannot be read");
- }
- } else {
- throw new FileNotFoundException("File '" + file + "' does not exist");
- }
- return new FileInputStream(file);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Opens a {@link FileOutputStream} for the specified file, checking and
- * creating the parent directory if it does not exist.
- * null
- * @return a new {@link FileOutputStream} for the specified file
- * @throws IOException if the file object is a directory
- * @throws IOException if the file cannot be written to
- * @throws IOException if a parent directory needs creating but that fails
- * @since Commons IO 1.3
- */
- public static FileOutputStream openOutputStream(File file) throws IOException {
- if (file.exists()) {
- if (file.isDirectory()) {
- throw new IOException("File '" + file + "' exists but is a directory");
- }
- if (file.canWrite() == false) {
- throw new IOException("File '" + file + "' cannot be written to");
- }
- } else {
- File parent = file.getParentFile();
- if (parent != null && parent.exists() == false) {
- if (parent.mkdirs() == false) {
- throw new IOException("File '" + file + "' could not be created");
- }
- }
- }
- return new FileOutputStream(file);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a human-readable version of the file size, where the input
- * represents a specific number of bytes.
- *
- * @param size the number of bytes
- * @return a human-readable display value (includes units)
- */
- public static String byteCountToDisplaySize(long size) {
- String displaySize;
-
- if (size / ONE_GB > 0) {
- displaySize = String.valueOf(size / ONE_GB) + " GB";
- } else if (size / ONE_MB > 0) {
- displaySize = String.valueOf(size / ONE_MB) + " MB";
- } else if (size / ONE_KB > 0) {
- displaySize = String.valueOf(size / ONE_KB) + " KB";
- } else {
- displaySize = String.valueOf(size) + " bytes";
- }
- return displaySize;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Implements the same behaviour as the "touch" utility on Unix. It creates
- * a new file with size 0 or, if the file exists already, it is opened and
- * closed without modifying it, but updating the file date and time.
- * FileFilterUtils.NameFileFilter("temp")
- * FileFilterUtils.makeCVSAware(null)
.
- *
- * @param directory the directory to search in
- * @param fileFilter filter to apply when finding files.
- * @param dirFilter optional filter to apply when finding subdirectories.
- * If this parameter is null
, subdirectories will not be included in the
- * search. Use TrueFileFilter.INSTANCE to match all directories.
- * @return an collection of java.io.File with the matching files
- * @see org.apache.commons.io.filefilter.FileFilterUtils
- * @see org.apache.commons.io.filefilter.NameFileFilter
- */
- public static Collection listFiles(
- File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
- if (!directory.isDirectory()) {
- throw new IllegalArgumentException(
- "Parameter 'directory' is not a directory");
- }
- if (fileFilter == null) {
- throw new NullPointerException("Parameter 'fileFilter' is null");
- }
-
- //Setup effective file filter
- IOFileFilter effFileFilter = FileFilterUtils.andFileFilter(fileFilter,
- FileFilterUtils.notFileFilter(DirectoryFileFilter.INSTANCE));
-
- //Setup effective directory filter
- IOFileFilter effDirFilter;
- if (dirFilter == null) {
- effDirFilter = FalseFileFilter.INSTANCE;
- } else {
- effDirFilter = FileFilterUtils.andFileFilter(dirFilter,
- DirectoryFileFilter.INSTANCE);
- }
-
- //Find files
- Collection files = new java.util.LinkedList();
- innerListFiles(files, directory,
- FileFilterUtils.orFileFilter(effFileFilter, effDirFilter));
- return files;
- }
-
- /**
- * Allows iteration over the files in given directory (and optionally
- * its subdirectories).
- * null
, subdirectories will not be included in the
- * search. Use TrueFileFilter.INSTANCE to match all directories.
- * @return an iterator of java.io.File for the matching files
- * @see org.apache.commons.io.filefilter.FileFilterUtils
- * @see org.apache.commons.io.filefilter.NameFileFilter
- * @since Commons IO 1.2
- */
- public static Iterator iterateFiles(
- File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
- return listFiles(directory, fileFilter, dirFilter).iterator();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Converts an array of file extensions to suffixes for use
- * with IOFileFilters.
- *
- * @param extensions an array of extensions. Format: {"java", "xml"}
- * @return an array of suffixes. Format: {".java", ".xml"}
- */
- private static String[] toSuffixes(String[] extensions) {
- String[] suffixes = new String[extensions.length];
- for (int i = 0; i < extensions.length; i++) {
- suffixes[i] = "." + extensions[i];
- }
- return suffixes;
- }
-
-
- /**
- * Finds files within a given directory (and optionally its subdirectories)
- * which match an array of extensions.
- *
- * @param directory the directory to search in
- * @param extensions an array of extensions, ex. {"java","xml"}. If this
- * parameter is null
, all files are returned.
- * @param recursive if true all subdirectories are searched as well
- * @return an collection of java.io.File with the matching files
- */
- public static Collection listFiles(
- File directory, String[] extensions, boolean recursive) {
- IOFileFilter filter;
- if (extensions == null) {
- filter = TrueFileFilter.INSTANCE;
- } else {
- String[] suffixes = toSuffixes(extensions);
- filter = new SuffixFileFilter(suffixes);
- }
- return listFiles(directory, filter,
- (recursive ? TrueFileFilter.INSTANCE : FalseFileFilter.INSTANCE));
- }
-
- /**
- * Allows iteration over the files in a given directory (and optionally
- * its subdirectories) which match an array of extensions. This method
- * is based on {@link #listFiles(File, String[], boolean)}.
- *
- * @param directory the directory to search in
- * @param extensions an array of extensions, ex. {"java","xml"}. If this
- * parameter is null
, all files are returned.
- * @param recursive if true all subdirectories are searched as well
- * @return an iterator of java.io.File with the matching files
- * @since Commons IO 1.2
- */
- public static Iterator iterateFiles(
- File directory, String[] extensions, boolean recursive) {
- return listFiles(directory, extensions, recursive).iterator();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares the contents of two files to determine if they are equal or not.
- * URL
to a File
.
- * file:///my%20docs/file.txt
will be
- * correctly decoded to /my docs/file.txt
.
- *
- * @param url the file URL to convert, null
returns null
- * @return the equivalent File
object, or null
- * if the URL's protocol is not file
- * @throws IllegalArgumentException if the file is incorrectly encoded
- */
- public static File toFile(URL url) {
- if (url == null || !url.getProtocol().equals("file")) {
- return null;
- } else {
- String filename = url.getFile().replace('/', File.separatorChar);
- int pos =0;
- while ((pos = filename.indexOf('%', pos)) >= 0) {
- if (pos + 2 < filename.length()) {
- String hexStr = filename.substring(pos + 1, pos + 3);
- char ch = (char) Integer.parseInt(hexStr, 16);
- filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
- }
- }
- return new File(filename);
- }
- }
-
- /**
- * Converts each of an array of URL
to a File
.
- * null
, an empty array is returned.
- * If the input contains null
, the output array contains null
at the same
- * index.
- * file:///my%20docs/file.txt
will be
- * correctly decoded to /my docs/file.txt
.
- *
- * @param urls the file URLs to convert, null
returns empty array
- * @return a non-null
array of Files matching the input, with a null
item
- * if there was a null
at that index in the input array
- * @throws IllegalArgumentException if any file is not a URL file
- * @throws IllegalArgumentException if any file is incorrectly encoded
- * @since Commons IO 1.1
- */
- public static File[] toFiles(URL[] urls) {
- if (urls == null || urls.length == 0) {
- return EMPTY_FILE_ARRAY;
- }
- File[] files = new File[urls.length];
- for (int i = 0; i < urls.length; i++) {
- URL url = urls[i];
- if (url != null) {
- if (url.getProtocol().equals("file") == false) {
- throw new IllegalArgumentException(
- "URL could not be converted to a File: " + url);
- }
- files[i] = toFile(url);
- }
- }
- return files;
- }
-
- /**
- * Converts each of an array of File
to a URL
.
- * null
- * @param destDir the directory to place the copy in, must not be null
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @see #copyFile(File, File, boolean)
- */
- public static void copyFileToDirectory(File srcFile, File destDir) throws IOException {
- copyFileToDirectory(srcFile, destDir, true);
- }
-
- /**
- * Copies a file to a directory optionally preserving the file date.
- * null
- * @param destDir the directory to place the copy in, must not be null
- * @param preserveFileDate true if the file date of the copy
- * should be the same as the original
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @see #copyFile(File, File, boolean)
- * @since Commons IO 1.3
- */
- public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException {
- if (destDir == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (destDir.exists() && destDir.isDirectory() == false) {
- throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
- }
- copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate);
- }
-
- /**
- * Copies a file to a new location preserving the file date.
- * null
- * @param destFile the new file, must not be null
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @see #copyFileToDirectory(File, File)
- */
- public static void copyFile(File srcFile, File destFile) throws IOException {
- copyFile(srcFile, destFile, true);
- }
-
- /**
- * Copies a file to a new location.
- * null
- * @param destFile the new file, must not be null
- * @param preserveFileDate true if the file date of the copy
- * should be the same as the original
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @see #copyFileToDirectory(File, File, boolean)
- */
- public static void copyFile(File srcFile, File destFile,
- boolean preserveFileDate) throws IOException {
- if (srcFile == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destFile == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (srcFile.exists() == false) {
- throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
- }
- if (srcFile.isDirectory()) {
- throw new IOException("Source '" + srcFile + "' exists but is a directory");
- }
- if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
- throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
- }
- if (destFile.getParentFile() != null && destFile.getParentFile().exists() == false) {
- if (destFile.getParentFile().mkdirs() == false) {
- throw new IOException("Destination '" + destFile + "' directory cannot be created");
- }
- }
- if (destFile.exists() && destFile.canWrite() == false) {
- throw new IOException("Destination '" + destFile + "' exists but is read-only");
- }
- doCopyFile(srcFile, destFile, preserveFileDate);
- }
-
- /**
- * Internal copy file method.
- *
- * @param srcFile the validated source file, must not be null
- * @param destFile the validated destination file, must not be null
- * @param preserveFileDate whether to preserve the file date
- * @throws IOException if an error occurs
- */
- private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
- if (destFile.exists() && destFile.isDirectory()) {
- throw new IOException("Destination '" + destFile + "' exists but is a directory");
- }
-
- FileInputStream input = new FileInputStream(srcFile);
- try {
- FileOutputStream output = new FileOutputStream(destFile);
- try {
- IOUtils.copy(input, output);
- } finally {
- IOUtils.closeQuietly(output);
- }
- } finally {
- IOUtils.closeQuietly(input);
- }
-
- if (srcFile.length() != destFile.length()) {
- throw new IOException("Failed to copy full contents from '" +
- srcFile + "' to '" + destFile + "'");
- }
- if (preserveFileDate) {
- destFile.setLastModified(srcFile.lastModified());
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Copies a directory to within another directory preserving the file dates.
- * null
- * @param destDir the directory to place the copy in, must not be null
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @since Commons IO 1.2
- */
- public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException {
- if (srcDir == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (srcDir.exists() && srcDir.isDirectory() == false) {
- throw new IllegalArgumentException("Source '" + destDir + "' is not a directory");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (destDir.exists() && destDir.isDirectory() == false) {
- throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
- }
- copyDirectory(srcDir, new File(destDir, srcDir.getName()), true);
- }
-
- /**
- * Copies a whole directory to a new location preserving the file dates.
- * null
- * @param destDir the new directory, must not be null
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @since Commons IO 1.1
- */
- public static void copyDirectory(File srcDir, File destDir) throws IOException {
- copyDirectory(srcDir, destDir, true);
- }
-
- /**
- * Copies a whole directory to a new location.
- * null
- * @param destDir the new directory, must not be null
- * @param preserveFileDate true if the file date of the copy
- * should be the same as the original
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @since Commons IO 1.1
- */
- public static void copyDirectory(File srcDir, File destDir,
- boolean preserveFileDate) throws IOException {
- copyDirectory(srcDir, destDir, null, preserveFileDate);
- }
-
- /**
- * Copies a filtered directory to a new location preserving the file dates.
- * Example: Copy directories only
- *
- * // only copy the directory structure
- * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
- *
- *
- * Example: Copy directories and txt files
- *
- * // Create a filter for ".txt" files
- * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
- * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
- *
- * // Create a filter for either directories or ".txt" files
- * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
- *
- * // Copy using the filter
- * FileUtils.copyDirectory(srcDir, destDir, filter);
- *
- *
- * @param srcDir an existing directory to copy, must not be null
- * @param destDir the new directory, must not be null
- * @param filter the filter to apply, null means copy all directories and files
- * should be the same as the original
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @since Commons IO 1.4
- */
- public static void copyDirectory(File srcDir, File destDir,
- FileFilter filter) throws IOException {
- copyDirectory(srcDir, destDir, filter, true);
- }
-
- /**
- * Copies a filtered directory to a new location.
- * Example: Copy directories only
- *
- * // only copy the directory structure
- * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
- *
- *
- * Example: Copy directories and txt files
- *
- * // Create a filter for ".txt" files
- * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
- * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
- *
- * // Create a filter for either directories or ".txt" files
- * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
- *
- * // Copy using the filter
- * FileUtils.copyDirectory(srcDir, destDir, filter, false);
- *
- *
- * @param srcDir an existing directory to copy, must not be null
- * @param destDir the new directory, must not be null
- * @param filter the filter to apply, null means copy all directories and files
- * @param preserveFileDate true if the file date of the copy
- * should be the same as the original
- *
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs during copying
- * @since Commons IO 1.4
- */
- public static void copyDirectory(File srcDir, File destDir,
- FileFilter filter, boolean preserveFileDate) throws IOException {
- if (srcDir == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (srcDir.exists() == false) {
- throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
- }
- if (srcDir.isDirectory() == false) {
- throw new IOException("Source '" + srcDir + "' exists but is not a directory");
- }
- if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) {
- throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
- }
-
- // Cater for destination being directory within the source directory (see IO-141)
- List exclusionList = null;
- if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
- File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
- if (srcFiles != null && srcFiles.length > 0) {
- exclusionList = new ArrayList(srcFiles.length);
- for (int i = 0; i < srcFiles.length; i++) {
- File copiedFile = new File(destDir, srcFiles[i].getName());
- exclusionList.add(copiedFile.getCanonicalPath());
- }
- }
- }
- doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
- }
-
- /**
- * Internal copy directory method.
- *
- * @param srcDir the validated source directory, must not be null
- * @param destDir the validated destination directory, must not be null
- * @param filter the filter to apply, null means copy all directories and files
- * @param preserveFileDate whether to preserve the file date
- * @param exclusionList List of files and directories to exclude from the copy, may be null
- * @throws IOException if an error occurs
- * @since Commons IO 1.1
- */
- private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter,
- boolean preserveFileDate, List exclusionList) throws IOException {
- if (destDir.exists()) {
- if (destDir.isDirectory() == false) {
- throw new IOException("Destination '" + destDir + "' exists but is not a directory");
- }
- } else {
- if (destDir.mkdirs() == false) {
- throw new IOException("Destination '" + destDir + "' directory cannot be created");
- }
- if (preserveFileDate) {
- destDir.setLastModified(srcDir.lastModified());
- }
- }
- if (destDir.canWrite() == false) {
- throw new IOException("Destination '" + destDir + "' cannot be written to");
- }
- // recurse
- File[] files = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
- if (files == null) { // null if security restricted
- throw new IOException("Failed to list contents of " + srcDir);
- }
- for (int i = 0; i < files.length; i++) {
- File copiedFile = new File(destDir, files[i].getName());
- if (exclusionList == null || !exclusionList.contains(files[i].getCanonicalPath())) {
- if (files[i].isDirectory()) {
- doCopyDirectory(files[i], copiedFile, filter, preserveFileDate, exclusionList);
- } else {
- doCopyFile(files[i], copiedFile, preserveFileDate);
- }
- }
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Copies bytes from the URL source
to a file
- * destination
. The directories up to destination
- * will be created if they don't already exist. destination
- * will be overwritten if it already exists.
- *
- * @param source the URL
to copy bytes from, must not be null
- * @param destination the non-directory File
to write bytes to
- * (possibly overwriting), must not be null
- * @throws IOException if source
URL cannot be opened
- * @throws IOException if destination
is a directory
- * @throws IOException if destination
cannot be written
- * @throws IOException if destination
needs creating but can't be
- * @throws IOException if an IO error occurs during copying
- */
- public static void copyURLToFile(URL source, File destination) throws IOException {
- InputStream input = source.openStream();
- try {
- FileOutputStream output = openOutputStream(destination);
- try {
- IOUtils.copy(input, output);
- } finally {
- IOUtils.closeQuietly(output);
- }
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Deletes a directory recursively.
- *
- * @param directory directory to delete
- * @throws IOException in case deletion is unsuccessful
- */
- public static void deleteDirectory(File directory) throws IOException {
- if (!directory.exists()) {
- return;
- }
-
- cleanDirectory(directory);
- if (!directory.delete()) {
- String message =
- "Unable to delete directory " + directory + ".";
- throw new IOException(message);
- }
- }
-
- /**
- * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
- *
- *
- *
- * @param file file or directory to delete, can be null
- * @return true
if the file or directory was deleted, otherwise
- * false
- *
- * @since Commons IO 1.4
- */
- public static boolean deleteQuietly(File file) {
- if (file == null) {
- return false;
- }
- try {
- if (file.isDirectory()) {
- cleanDirectory(file);
- }
- } catch (Exception e) {
- }
-
- try {
- return file.delete();
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
- * Cleans a directory without deleting it.
- *
- * @param directory directory to clean
- * @throws IOException in case cleaning is unsuccessful
- */
- public static void cleanDirectory(File directory) throws IOException {
- if (!directory.exists()) {
- String message = directory + " does not exist";
- throw new IllegalArgumentException(message);
- }
-
- if (!directory.isDirectory()) {
- String message = directory + " is not a directory";
- throw new IllegalArgumentException(message);
- }
-
- File[] files = directory.listFiles();
- if (files == null) { // null if security restricted
- throw new IOException("Failed to list contents of " + directory);
- }
-
- IOException exception = null;
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- try {
- forceDelete(file);
- } catch (IOException ioe) {
- exception = ioe;
- }
- }
-
- if (null != exception) {
- throw exception;
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Waits for NFS to propagate a file creation, imposing a timeout.
- * null
- * @param seconds the maximum time in seconds to wait
- * @return true if file exists
- * @throws NullPointerException if the file is null
- */
- public static boolean waitFor(File file, int seconds) {
- int timeout = 0;
- int tick = 0;
- while (!file.exists()) {
- if (tick++ >= 10) {
- tick = 0;
- if (timeout++ > seconds) {
- return false;
- }
- }
- try {
- Thread.sleep(100);
- } catch (InterruptedException ignore) {
- // ignore exception
- } catch (Exception ex) {
- break;
- }
- }
- return true;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Reads the contents of a file into a String.
- * The file is always closed.
- *
- * @param file the file to read, must not be null
- * @param encoding the encoding to use, null
means platform default
- * @return the file contents, never null
- * @throws IOException in case of an I/O error
- * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
- */
- public static String readFileToString(File file, String encoding) throws IOException {
- InputStream in = null;
- try {
- in = openInputStream(file);
- return IOUtils.toString(in, encoding);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
-
- /**
- * Reads the contents of a file into a String using the default encoding for the VM.
- * The file is always closed.
- *
- * @param file the file to read, must not be null
- * @return the file contents, never null
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.3.1
- */
- public static String readFileToString(File file) throws IOException {
- return readFileToString(file, null);
- }
-
- /**
- * Reads the contents of a file into a byte array.
- * The file is always closed.
- *
- * @param file the file to read, must not be null
- * @return the file contents, never null
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.1
- */
- public static byte[] readFileToByteArray(File file) throws IOException {
- InputStream in = null;
- try {
- in = openInputStream(file);
- return IOUtils.toByteArray(in);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- /**
- * Reads the contents of a file line by line to a List of Strings.
- * The file is always closed.
- *
- * @param file the file to read, must not be null
- * @param encoding the encoding to use, null
means platform default
- * @return the list of Strings representing each line in the file, never null
- * @throws IOException in case of an I/O error
- * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
- * @since Commons IO 1.1
- */
- public static List readLines(File file, String encoding) throws IOException {
- InputStream in = null;
- try {
- in = openInputStream(file);
- return IOUtils.readLines(in, encoding);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- /**
- * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM.
- * The file is always closed.
- *
- * @param file the file to read, must not be null
- * @return the list of Strings representing each line in the file, never null
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.3
- */
- public static List readLines(File file) throws IOException {
- return readLines(file, null);
- }
-
- /**
- * Returns an Iterator for the lines in a File
.
- * InputStream
for the file.
- * When you have finished with the iterator you should close the stream
- * to free internal resources. This can be done by calling the
- * {@link LineIterator#close()} or
- * {@link LineIterator#closeQuietly(LineIterator)} method.
- *
- * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
- * try {
- * while (it.hasNext()) {
- * String line = it.nextLine();
- * /// do something with line
- * }
- * } finally {
- * LineIterator.closeQuietly(iterator);
- * }
- *
- * null
- * @param encoding the encoding to use, null
means platform default
- * @return an Iterator of the lines in the file, never null
- * @throws IOException in case of an I/O error (file closed)
- * @since Commons IO 1.2
- */
- public static LineIterator lineIterator(File file, String encoding) throws IOException {
- InputStream in = null;
- try {
- in = openInputStream(file);
- return IOUtils.lineIterator(in, encoding);
- } catch (IOException ex) {
- IOUtils.closeQuietly(in);
- throw ex;
- } catch (RuntimeException ex) {
- IOUtils.closeQuietly(in);
- throw ex;
- }
- }
-
- /**
- * Returns an Iterator for the lines in a File
using the default encoding for the VM.
- *
- * @param file the file to open for input, must not be null
- * @return an Iterator of the lines in the file, never null
- * @throws IOException in case of an I/O error (file closed)
- * @since Commons IO 1.3
- * @see #lineIterator(File, String)
- */
- public static LineIterator lineIterator(File file) throws IOException {
- return lineIterator(file, null);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Writes a String to a file creating the file if it does not exist.
- *
- * NOTE: As from v1.3, the parent directories of the file will be created
- * if they do not exist.
- *
- * @param file the file to write
- * @param data the content to write to the file
- * @param encoding the encoding to use, null
means platform default
- * @throws IOException in case of an I/O error
- * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
- */
- public static void writeStringToFile(File file, String data, String encoding) throws IOException {
- OutputStream out = null;
- try {
- out = openOutputStream(file);
- IOUtils.write(data, out, encoding);
- } finally {
- IOUtils.closeQuietly(out);
- }
- }
-
- /**
- * Writes a String to a file creating the file if it does not exist using the default encoding for the VM.
- *
- * @param file the file to write
- * @param data the content to write to the file
- * @throws IOException in case of an I/O error
- */
- public static void writeStringToFile(File file, String data) throws IOException {
- writeStringToFile(file, data, null);
- }
-
- /**
- * Writes a byte array to a file creating the file if it does not exist.
- * toString()
value of each item in a collection to
- * the specified File
line by line.
- * The specified character encoding and the default line ending will be used.
- * null
means platform default
- * @param lines the lines to write, null
entries produce blank lines
- * @throws IOException in case of an I/O error
- * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
- * @since Commons IO 1.1
- */
- public static void writeLines(File file, String encoding, Collection lines) throws IOException {
- writeLines(file, encoding, lines, null);
- }
-
- /**
- * Writes the toString()
value of each item in a collection to
- * the specified File
line by line.
- * The default VM encoding and the default line ending will be used.
- *
- * @param file the file to write to
- * @param lines the lines to write, null
entries produce blank lines
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.3
- */
- public static void writeLines(File file, Collection lines) throws IOException {
- writeLines(file, null, lines, null);
- }
-
- /**
- * Writes the toString()
value of each item in a collection to
- * the specified File
line by line.
- * The specified character encoding and the line ending will be used.
- * null
means platform default
- * @param lines the lines to write, null
entries produce blank lines
- * @param lineEnding the line separator to use, null
is system default
- * @throws IOException in case of an I/O error
- * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
- * @since Commons IO 1.1
- */
- public static void writeLines(File file, String encoding, Collection lines, String lineEnding) throws IOException {
- OutputStream out = null;
- try {
- out = openOutputStream(file);
- IOUtils.writeLines(lines, lineEnding, out, encoding);
- } finally {
- IOUtils.closeQuietly(out);
- }
- }
-
- /**
- * Writes the toString()
value of each item in a collection to
- * the specified File
line by line.
- * The default VM encoding and the specified line ending will be used.
- *
- * @param file the file to write to
- * @param lines the lines to write, null
entries produce blank lines
- * @param lineEnding the line separator to use, null
is system default
- * @throws IOException in case of an I/O error
- * @since Commons IO 1.3
- */
- public static void writeLines(File file, Collection lines, String lineEnding) throws IOException {
- writeLines(file, null, lines, lineEnding);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Deletes a file. If file is a directory, delete it and all sub-directories.
- *
- *
- *
- * @param file file or directory to delete, must not be null
- * @throws NullPointerException if the directory is null
- * @throws FileNotFoundException if the file was not found
- * @throws IOException in case deletion is unsuccessful
- */
- public static void forceDelete(File file) throws IOException {
- if (file.isDirectory()) {
- deleteDirectory(file);
- } else {
- boolean filePresent = file.exists();
- if (!file.delete()) {
- if (!filePresent){
- throw new FileNotFoundException("File does not exist: " + file);
- }
- String message =
- "Unable to delete file: " + file;
- throw new IOException(message);
- }
- }
- }
-
- /**
- * Schedules a file to be deleted when JVM exits.
- * If file is directory delete it and all sub-directories.
- *
- * @param file file or directory to delete, must not be null
- * @throws NullPointerException if the file is null
- * @throws IOException in case deletion is unsuccessful
- */
- public static void forceDeleteOnExit(File file) throws IOException {
- if (file.isDirectory()) {
- deleteDirectoryOnExit(file);
- } else {
- file.deleteOnExit();
- }
- }
-
- /**
- * Schedules a directory recursively for deletion on JVM exit.
- *
- * @param directory directory to delete, must not be null
- * @throws NullPointerException if the directory is null
- * @throws IOException in case deletion is unsuccessful
- */
- private static void deleteDirectoryOnExit(File directory) throws IOException {
- if (!directory.exists()) {
- return;
- }
-
- cleanDirectoryOnExit(directory);
- directory.deleteOnExit();
- }
-
- /**
- * Cleans a directory without deleting it.
- *
- * @param directory directory to clean, must not be null
- * @throws NullPointerException if the directory is null
- * @throws IOException in case cleaning is unsuccessful
- */
- private static void cleanDirectoryOnExit(File directory) throws IOException {
- if (!directory.exists()) {
- String message = directory + " does not exist";
- throw new IllegalArgumentException(message);
- }
-
- if (!directory.isDirectory()) {
- String message = directory + " is not a directory";
- throw new IllegalArgumentException(message);
- }
-
- File[] files = directory.listFiles();
- if (files == null) { // null if security restricted
- throw new IOException("Failed to list contents of " + directory);
- }
-
- IOException exception = null;
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- try {
- forceDeleteOnExit(file);
- } catch (IOException ioe) {
- exception = ioe;
- }
- }
-
- if (null != exception) {
- throw exception;
- }
- }
-
- /**
- * Makes a directory, including any necessary but nonexistent parent
- * directories. If there already exists a file with specified name or
- * the directory cannot be created then an exception is thrown.
- *
- * @param directory directory to create, must not be null
- * @throws NullPointerException if the directory is null
- * @throws IOException if the directory cannot be created
- */
- public static void forceMkdir(File directory) throws IOException {
- if (directory.exists()) {
- if (directory.isFile()) {
- String message =
- "File "
- + directory
- + " exists and is "
- + "not a directory. Unable to create directory.";
- throw new IOException(message);
- }
- } else {
- if (!directory.mkdirs()) {
- String message =
- "Unable to create directory " + directory;
- throw new IOException(message);
- }
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Counts the size of a directory recursively (sum of the length of all files).
- *
- * @param directory directory to inspect, must not be null
- * @return size of directory in bytes, 0 if directory is security restricted
- * @throws NullPointerException if the directory is null
- */
- public static long sizeOfDirectory(File directory) {
- if (!directory.exists()) {
- String message = directory + " does not exist";
- throw new IllegalArgumentException(message);
- }
-
- if (!directory.isDirectory()) {
- String message = directory + " is not a directory";
- throw new IllegalArgumentException(message);
- }
-
- long size = 0;
-
- File[] files = directory.listFiles();
- if (files == null) { // null if security restricted
- return 0L;
- }
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
-
- if (file.isDirectory()) {
- size += sizeOfDirectory(file);
- } else {
- size += file.length();
- }
- }
-
- return size;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Tests if the specified File
is newer than the reference
- * File
.
- *
- * @param file the File
of which the modification date must
- * be compared, must not be null
- * @param reference the File
of which the modification date
- * is used, must not be null
- * @return true if the File
exists and has been modified more
- * recently than the reference File
- * @throws IllegalArgumentException if the file is null
- * @throws IllegalArgumentException if the reference file is null
or doesn't exist
- */
- public static boolean isFileNewer(File file, File reference) {
- if (reference == null) {
- throw new IllegalArgumentException("No specified reference file");
- }
- if (!reference.exists()) {
- throw new IllegalArgumentException("The reference file '"
- + file + "' doesn't exist");
- }
- return isFileNewer(file, reference.lastModified());
- }
-
- /**
- * Tests if the specified File
is newer than the specified
- * Date
.
- *
- * @param file the File
of which the modification date
- * must be compared, must not be null
- * @param date the date reference, must not be null
- * @return true if the File
exists and has been modified
- * after the given Date
.
- * @throws IllegalArgumentException if the file is null
- * @throws IllegalArgumentException if the date is null
- */
- public static boolean isFileNewer(File file, Date date) {
- if (date == null) {
- throw new IllegalArgumentException("No specified date");
- }
- return isFileNewer(file, date.getTime());
- }
-
- /**
- * Tests if the specified File
is newer than the specified
- * time reference.
- *
- * @param file the File
of which the modification date must
- * be compared, must not be null
- * @param timeMillis the time reference measured in milliseconds since the
- * epoch (00:00:00 GMT, January 1, 1970)
- * @return true if the File
exists and has been modified after
- * the given time reference.
- * @throws IllegalArgumentException if the file is null
- */
- public static boolean isFileNewer(File file, long timeMillis) {
- if (file == null) {
- throw new IllegalArgumentException("No specified file");
- }
- if (!file.exists()) {
- return false;
- }
- return file.lastModified() > timeMillis;
- }
-
-
- //-----------------------------------------------------------------------
- /**
- * Tests if the specified File
is older than the reference
- * File
.
- *
- * @param file the File
of which the modification date must
- * be compared, must not be null
- * @param reference the File
of which the modification date
- * is used, must not be null
- * @return true if the File
exists and has been modified before
- * the reference File
- * @throws IllegalArgumentException if the file is null
- * @throws IllegalArgumentException if the reference file is null
or doesn't exist
- */
- public static boolean isFileOlder(File file, File reference) {
- if (reference == null) {
- throw new IllegalArgumentException("No specified reference file");
- }
- if (!reference.exists()) {
- throw new IllegalArgumentException("The reference file '"
- + file + "' doesn't exist");
- }
- return isFileOlder(file, reference.lastModified());
- }
-
- /**
- * Tests if the specified File
is older than the specified
- * Date
.
- *
- * @param file the File
of which the modification date
- * must be compared, must not be null
- * @param date the date reference, must not be null
- * @return true if the File
exists and has been modified
- * before the given Date
.
- * @throws IllegalArgumentException if the file is null
- * @throws IllegalArgumentException if the date is null
- */
- public static boolean isFileOlder(File file, Date date) {
- if (date == null) {
- throw new IllegalArgumentException("No specified date");
- }
- return isFileOlder(file, date.getTime());
- }
-
- /**
- * Tests if the specified File
is older than the specified
- * time reference.
- *
- * @param file the File
of which the modification date must
- * be compared, must not be null
- * @param timeMillis the time reference measured in milliseconds since the
- * epoch (00:00:00 GMT, January 1, 1970)
- * @return true if the File
exists and has been modified before
- * the given time reference.
- * @throws IllegalArgumentException if the file is null
- */
- public static boolean isFileOlder(File file, long timeMillis) {
- if (file == null) {
- throw new IllegalArgumentException("No specified file");
- }
- if (!file.exists()) {
- return false;
- }
- return file.lastModified() < timeMillis;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Computes the checksum of a file using the CRC32 checksum routine.
- * The value of the checksum is returned.
- *
- * @param file the file to checksum, must not be null
- * @return the checksum value
- * @throws NullPointerException if the file or checksum is null
- * @throws IllegalArgumentException if the file is a directory
- * @throws IOException if an IO error occurs reading the file
- * @since Commons IO 1.3
- */
- public static long checksumCRC32(File file) throws IOException {
- CRC32 crc = new CRC32();
- checksum(file, crc);
- return crc.getValue();
- }
-
- /**
- * Computes the checksum of a file using the specified checksum object.
- * Multiple files may be checked using one Checksum
instance
- * if desired simply by reusing the same checksum object.
- * For example:
- *
- * long csum = FileUtils.checksum(file, new CRC32()).getValue();
- *
- *
- * @param file the file to checksum, must not be null
- * @param checksum the checksum object to be used, must not be null
- * @return the checksum specified, updated with the content of the file
- * @throws NullPointerException if the file or checksum is null
- * @throws IllegalArgumentException if the file is a directory
- * @throws IOException if an IO error occurs reading the file
- * @since Commons IO 1.3
- */
- public static Checksum checksum(File file, Checksum checksum) throws IOException {
- if (file.isDirectory()) {
- throw new IllegalArgumentException("Checksums can't be computed on directories");
- }
- InputStream in = null;
- try {
- in = new CheckedInputStream(new FileInputStream(file), checksum);
- IOUtils.copy(in, new NullOutputStream());
- } finally {
- IOUtils.closeQuietly(in);
- }
- return checksum;
- }
-
- /**
- * Moves a directory.
- * null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs moving the file
- * @since Commons IO 1.4
- */
- public static void moveDirectory(File srcDir, File destDir) throws IOException {
- if (srcDir == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (!srcDir.exists()) {
- throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
- }
- if (!srcDir.isDirectory()) {
- throw new IOException("Source '" + srcDir + "' is not a directory");
- }
- if (destDir.exists()) {
- throw new IOException("Destination '" + destDir + "' already exists");
- }
- boolean rename = srcDir.renameTo(destDir);
- if (!rename) {
- copyDirectory( srcDir, destDir );
- deleteDirectory( srcDir );
- if (srcDir.exists()) {
- throw new IOException("Failed to delete original directory '" + srcDir +
- "' after copy to '" + destDir + "'");
- }
- }
- }
-
- /**
- * Moves a directory to another directory.
- *
- * @param src the file to be moved
- * @param destDir the destination file
- * @param createDestDir If true
create the destination directory,
- * otherwise if false
throw an IOException
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs moving the file
- * @since Commons IO 1.4
- */
- public static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
- if (src == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination directory must not be null");
- }
- if (!destDir.exists() && createDestDir) {
- destDir.mkdirs();
- }
- if (!destDir.exists()) {
- throw new FileNotFoundException("Destination directory '" + destDir +
- "' does not exist [createDestDir=" + createDestDir +"]");
- }
- if (!destDir.isDirectory()) {
- throw new IOException("Destination '" + destDir + "' is not a directory");
- }
- moveDirectory(src, new File(destDir, src.getName()));
-
- }
-
- /**
- * Moves a file.
- * null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs moving the file
- * @since Commons IO 1.4
- */
- public static void moveFile(File srcFile, File destFile) throws IOException {
- if (srcFile == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destFile == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (!srcFile.exists()) {
- throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
- }
- if (srcFile.isDirectory()) {
- throw new IOException("Source '" + srcFile + "' is a directory");
- }
- if (destFile.exists()) {
- throw new IOException("Destination '" + destFile + "' already exists");
- }
- if (destFile.isDirectory()) {
- throw new IOException("Destination '" + destFile + "' is a directory");
- }
- boolean rename = srcFile.renameTo(destFile);
- if (!rename) {
- copyFile( srcFile, destFile );
- if (!srcFile.delete()) {
- FileUtils.deleteQuietly(destFile);
- throw new IOException("Failed to delete original file '" + srcFile +
- "' after copy to '" + destFile + "'");
- }
- }
- }
-
- /**
- * Moves a file to a directory.
- *
- * @param srcFile the file to be moved
- * @param destDir the destination file
- * @param createDestDir If true
create the destination directory,
- * otherwise if false
throw an IOException
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs moving the file
- * @since Commons IO 1.4
- */
- public static void moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) throws IOException {
- if (srcFile == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination directory must not be null");
- }
- if (!destDir.exists() && createDestDir) {
- destDir.mkdirs();
- }
- if (!destDir.exists()) {
- throw new FileNotFoundException("Destination directory '" + destDir +
- "' does not exist [createDestDir=" + createDestDir +"]");
- }
- if (!destDir.isDirectory()) {
- throw new IOException("Destination '" + destDir + "' is not a directory");
- }
- moveFile(srcFile, new File(destDir, srcFile.getName()));
- }
-
- /**
- * Moves a file or directory to the destination directory.
- * true
create the destination directory,
- * otherwise if false
throw an IOException
- * @throws NullPointerException if source or destination is null
- * @throws IOException if source or destination is invalid
- * @throws IOException if an IO error occurs moving the file
- * @since Commons IO 1.4
- */
- public static void moveToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
- if (src == null) {
- throw new NullPointerException("Source must not be null");
- }
- if (destDir == null) {
- throw new NullPointerException("Destination must not be null");
- }
- if (!src.exists()) {
- throw new FileNotFoundException("Source '" + src + "' does not exist");
- }
- if (src.isDirectory()) {
- moveDirectoryToDirectory(src, destDir, createDestDir);
- } else {
- moveFileToDirectory(src, destDir, createDestDir);
- }
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.Checksum;
+
+import org.apache.commons.io.filefilter.DirectoryFileFilter;
+import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.SuffixFileFilter;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.commons.io.output.NullOutputStream;
+
+/**
+ * General file manipulation utilities.
+ *
+ *
+ * File
.
+ */
+ public static final File[] EMPTY_FILE_ARRAY = new File[0];
+
+ //-----------------------------------------------------------------------
+ /**
+ * Opens a {@link FileInputStream} for the specified file, providing better
+ * error messages than simply calling new FileInputStream(file)
.
+ * null
+ * @return a new {@link FileInputStream} for the specified file
+ * @throws FileNotFoundException if the file does not exist
+ * @throws IOException if the file object is a directory
+ * @throws IOException if the file cannot be read
+ * @since Commons IO 1.3
+ */
+ public static FileInputStream openInputStream(File file) throws IOException {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ throw new IOException("File '" + file + "' exists but is a directory");
+ }
+ if (file.canRead() == false) {
+ throw new IOException("File '" + file + "' cannot be read");
+ }
+ } else {
+ throw new FileNotFoundException("File '" + file + "' does not exist");
+ }
+ return new FileInputStream(file);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Opens a {@link FileOutputStream} for the specified file, checking and
+ * creating the parent directory if it does not exist.
+ * null
+ * @return a new {@link FileOutputStream} for the specified file
+ * @throws IOException if the file object is a directory
+ * @throws IOException if the file cannot be written to
+ * @throws IOException if a parent directory needs creating but that fails
+ * @since Commons IO 1.3
+ */
+ public static FileOutputStream openOutputStream(File file) throws IOException {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ throw new IOException("File '" + file + "' exists but is a directory");
+ }
+ if (file.canWrite() == false) {
+ throw new IOException("File '" + file + "' cannot be written to");
+ }
+ } else {
+ File parent = file.getParentFile();
+ if (parent != null && parent.exists() == false) {
+ if (parent.mkdirs() == false) {
+ throw new IOException("File '" + file + "' could not be created");
+ }
+ }
+ }
+ return new FileOutputStream(file);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a human-readable version of the file size, where the input
+ * represents a specific number of bytes.
+ *
+ * @param size the number of bytes
+ * @return a human-readable display value (includes units)
+ */
+ public static String byteCountToDisplaySize(long size) {
+ String displaySize;
+
+ if (size / ONE_GB > 0) {
+ displaySize = String.valueOf(size / ONE_GB) + " GB";
+ } else if (size / ONE_MB > 0) {
+ displaySize = String.valueOf(size / ONE_MB) + " MB";
+ } else if (size / ONE_KB > 0) {
+ displaySize = String.valueOf(size / ONE_KB) + " KB";
+ } else {
+ displaySize = String.valueOf(size) + " bytes";
+ }
+ return displaySize;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Implements the same behaviour as the "touch" utility on Unix. It creates
+ * a new file with size 0 or, if the file exists already, it is opened and
+ * closed without modifying it, but updating the file date and time.
+ * FileFilterUtils.NameFileFilter("temp")
+ * FileFilterUtils.makeCVSAware(null)
.
+ *
+ * @param directory the directory to search in
+ * @param fileFilter filter to apply when finding files.
+ * @param dirFilter optional filter to apply when finding subdirectories.
+ * If this parameter is null
, subdirectories will not be included in the
+ * search. Use TrueFileFilter.INSTANCE to match all directories.
+ * @return an collection of java.io.File with the matching files
+ * @see org.apache.commons.io.filefilter.FileFilterUtils
+ * @see org.apache.commons.io.filefilter.NameFileFilter
+ */
+ public static Collection listFiles(
+ File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
+ if (!directory.isDirectory()) {
+ throw new IllegalArgumentException(
+ "Parameter 'directory' is not a directory");
+ }
+ if (fileFilter == null) {
+ throw new NullPointerException("Parameter 'fileFilter' is null");
+ }
+
+ //Setup effective file filter
+ IOFileFilter effFileFilter = FileFilterUtils.andFileFilter(fileFilter,
+ FileFilterUtils.notFileFilter(DirectoryFileFilter.INSTANCE));
+
+ //Setup effective directory filter
+ IOFileFilter effDirFilter;
+ if (dirFilter == null) {
+ effDirFilter = FalseFileFilter.INSTANCE;
+ } else {
+ effDirFilter = FileFilterUtils.andFileFilter(dirFilter,
+ DirectoryFileFilter.INSTANCE);
+ }
+
+ //Find files
+ Collection files = new java.util.LinkedList();
+ innerListFiles(files, directory,
+ FileFilterUtils.orFileFilter(effFileFilter, effDirFilter));
+ return files;
+ }
+
+ /**
+ * Allows iteration over the files in given directory (and optionally
+ * its subdirectories).
+ * null
, subdirectories will not be included in the
+ * search. Use TrueFileFilter.INSTANCE to match all directories.
+ * @return an iterator of java.io.File for the matching files
+ * @see org.apache.commons.io.filefilter.FileFilterUtils
+ * @see org.apache.commons.io.filefilter.NameFileFilter
+ * @since Commons IO 1.2
+ */
+ public static Iterator iterateFiles(
+ File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
+ return listFiles(directory, fileFilter, dirFilter).iterator();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts an array of file extensions to suffixes for use
+ * with IOFileFilters.
+ *
+ * @param extensions an array of extensions. Format: {"java", "xml"}
+ * @return an array of suffixes. Format: {".java", ".xml"}
+ */
+ private static String[] toSuffixes(String[] extensions) {
+ String[] suffixes = new String[extensions.length];
+ for (int i = 0; i < extensions.length; i++) {
+ suffixes[i] = "." + extensions[i];
+ }
+ return suffixes;
+ }
+
+
+ /**
+ * Finds files within a given directory (and optionally its subdirectories)
+ * which match an array of extensions.
+ *
+ * @param directory the directory to search in
+ * @param extensions an array of extensions, ex. {"java","xml"}. If this
+ * parameter is null
, all files are returned.
+ * @param recursive if true all subdirectories are searched as well
+ * @return an collection of java.io.File with the matching files
+ */
+ public static Collection listFiles(
+ File directory, String[] extensions, boolean recursive) {
+ IOFileFilter filter;
+ if (extensions == null) {
+ filter = TrueFileFilter.INSTANCE;
+ } else {
+ String[] suffixes = toSuffixes(extensions);
+ filter = new SuffixFileFilter(suffixes);
+ }
+ return listFiles(directory, filter,
+ (recursive ? TrueFileFilter.INSTANCE : FalseFileFilter.INSTANCE));
+ }
+
+ /**
+ * Allows iteration over the files in a given directory (and optionally
+ * its subdirectories) which match an array of extensions. This method
+ * is based on {@link #listFiles(File, String[], boolean)}.
+ *
+ * @param directory the directory to search in
+ * @param extensions an array of extensions, ex. {"java","xml"}. If this
+ * parameter is null
, all files are returned.
+ * @param recursive if true all subdirectories are searched as well
+ * @return an iterator of java.io.File with the matching files
+ * @since Commons IO 1.2
+ */
+ public static Iterator iterateFiles(
+ File directory, String[] extensions, boolean recursive) {
+ return listFiles(directory, extensions, recursive).iterator();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Compares the contents of two files to determine if they are equal or not.
+ * URL
to a File
.
+ * file:///my%20docs/file.txt
will be
+ * correctly decoded to /my docs/file.txt
.
+ *
+ * @param url the file URL to convert, null
returns null
+ * @return the equivalent File
object, or null
+ * if the URL's protocol is not file
+ * @throws IllegalArgumentException if the file is incorrectly encoded
+ */
+ public static File toFile(URL url) {
+ if (url == null || !url.getProtocol().equals("file")) {
+ return null;
+ } else {
+ String filename = url.getFile().replace('/', File.separatorChar);
+ int pos =0;
+ while ((pos = filename.indexOf('%', pos)) >= 0) {
+ if (pos + 2 < filename.length()) {
+ String hexStr = filename.substring(pos + 1, pos + 3);
+ char ch = (char) Integer.parseInt(hexStr, 16);
+ filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
+ }
+ }
+ return new File(filename);
+ }
+ }
+
+ /**
+ * Converts each of an array of URL
to a File
.
+ * null
, an empty array is returned.
+ * If the input contains null
, the output array contains null
at the same
+ * index.
+ * file:///my%20docs/file.txt
will be
+ * correctly decoded to /my docs/file.txt
.
+ *
+ * @param urls the file URLs to convert, null
returns empty array
+ * @return a non-null
array of Files matching the input, with a null
item
+ * if there was a null
at that index in the input array
+ * @throws IllegalArgumentException if any file is not a URL file
+ * @throws IllegalArgumentException if any file is incorrectly encoded
+ * @since Commons IO 1.1
+ */
+ public static File[] toFiles(URL[] urls) {
+ if (urls == null || urls.length == 0) {
+ return EMPTY_FILE_ARRAY;
+ }
+ File[] files = new File[urls.length];
+ for (int i = 0; i < urls.length; i++) {
+ URL url = urls[i];
+ if (url != null) {
+ if (url.getProtocol().equals("file") == false) {
+ throw new IllegalArgumentException(
+ "URL could not be converted to a File: " + url);
+ }
+ files[i] = toFile(url);
+ }
+ }
+ return files;
+ }
+
+ /**
+ * Converts each of an array of File
to a URL
.
+ * null
+ * @param destDir the directory to place the copy in, must not be null
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFile(File, File, boolean)
+ */
+ public static void copyFileToDirectory(File srcFile, File destDir) throws IOException {
+ copyFileToDirectory(srcFile, destDir, true);
+ }
+
+ /**
+ * Copies a file to a directory optionally preserving the file date.
+ * null
+ * @param destDir the directory to place the copy in, must not be null
+ * @param preserveFileDate true if the file date of the copy
+ * should be the same as the original
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFile(File, File, boolean)
+ * @since Commons IO 1.3
+ */
+ public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException {
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (destDir.exists() && destDir.isDirectory() == false) {
+ throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
+ }
+ copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate);
+ }
+
+ /**
+ * Copies a file to a new location preserving the file date.
+ * null
+ * @param destFile the new file, must not be null
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFileToDirectory(File, File)
+ */
+ public static void copyFile(File srcFile, File destFile) throws IOException {
+ copyFile(srcFile, destFile, true);
+ }
+
+ /**
+ * Copies a file to a new location.
+ * null
+ * @param destFile the new file, must not be null
+ * @param preserveFileDate true if the file date of the copy
+ * should be the same as the original
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFileToDirectory(File, File, boolean)
+ */
+ public static void copyFile(File srcFile, File destFile,
+ boolean preserveFileDate) throws IOException {
+ if (srcFile == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destFile == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (srcFile.exists() == false) {
+ throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
+ }
+ if (srcFile.isDirectory()) {
+ throw new IOException("Source '" + srcFile + "' exists but is a directory");
+ }
+ if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
+ throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
+ }
+ if (destFile.getParentFile() != null && destFile.getParentFile().exists() == false) {
+ if (destFile.getParentFile().mkdirs() == false) {
+ throw new IOException("Destination '" + destFile + "' directory cannot be created");
+ }
+ }
+ if (destFile.exists() && destFile.canWrite() == false) {
+ throw new IOException("Destination '" + destFile + "' exists but is read-only");
+ }
+ doCopyFile(srcFile, destFile, preserveFileDate);
+ }
+
+ /**
+ * Internal copy file method.
+ *
+ * @param srcFile the validated source file, must not be null
+ * @param destFile the validated destination file, must not be null
+ * @param preserveFileDate whether to preserve the file date
+ * @throws IOException if an error occurs
+ */
+ private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
+ if (destFile.exists() && destFile.isDirectory()) {
+ throw new IOException("Destination '" + destFile + "' exists but is a directory");
+ }
+
+ FileInputStream input = new FileInputStream(srcFile);
+ try {
+ FileOutputStream output = new FileOutputStream(destFile);
+ try {
+ IOUtils.copy(input, output);
+ } finally {
+ IOUtils.closeQuietly(output);
+ }
+ } finally {
+ IOUtils.closeQuietly(input);
+ }
+
+ if (srcFile.length() != destFile.length()) {
+ throw new IOException("Failed to copy full contents from '" +
+ srcFile + "' to '" + destFile + "'");
+ }
+ if (preserveFileDate) {
+ destFile.setLastModified(srcFile.lastModified());
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Copies a directory to within another directory preserving the file dates.
+ * null
+ * @param destDir the directory to place the copy in, must not be null
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @since Commons IO 1.2
+ */
+ public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException {
+ if (srcDir == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (srcDir.exists() && srcDir.isDirectory() == false) {
+ throw new IllegalArgumentException("Source '" + destDir + "' is not a directory");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (destDir.exists() && destDir.isDirectory() == false) {
+ throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
+ }
+ copyDirectory(srcDir, new File(destDir, srcDir.getName()), true);
+ }
+
+ /**
+ * Copies a whole directory to a new location preserving the file dates.
+ * null
+ * @param destDir the new directory, must not be null
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @since Commons IO 1.1
+ */
+ public static void copyDirectory(File srcDir, File destDir) throws IOException {
+ copyDirectory(srcDir, destDir, true);
+ }
+
+ /**
+ * Copies a whole directory to a new location.
+ * null
+ * @param destDir the new directory, must not be null
+ * @param preserveFileDate true if the file date of the copy
+ * should be the same as the original
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @since Commons IO 1.1
+ */
+ public static void copyDirectory(File srcDir, File destDir,
+ boolean preserveFileDate) throws IOException {
+ copyDirectory(srcDir, destDir, null, preserveFileDate);
+ }
+
+ /**
+ * Copies a filtered directory to a new location preserving the file dates.
+ * Example: Copy directories only
+ *
+ * // only copy the directory structure
+ * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
+ *
+ *
+ * Example: Copy directories and txt files
+ *
+ * // Create a filter for ".txt" files
+ * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+ * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+ *
+ * // Create a filter for either directories or ".txt" files
+ * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+ *
+ * // Copy using the filter
+ * FileUtils.copyDirectory(srcDir, destDir, filter);
+ *
+ *
+ * @param srcDir an existing directory to copy, must not be null
+ * @param destDir the new directory, must not be null
+ * @param filter the filter to apply, null means copy all directories and files
+ * should be the same as the original
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @since Commons IO 1.4
+ */
+ public static void copyDirectory(File srcDir, File destDir,
+ FileFilter filter) throws IOException {
+ copyDirectory(srcDir, destDir, filter, true);
+ }
+
+ /**
+ * Copies a filtered directory to a new location.
+ * Example: Copy directories only
+ *
+ * // only copy the directory structure
+ * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
+ *
+ *
+ * Example: Copy directories and txt files
+ *
+ * // Create a filter for ".txt" files
+ * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+ * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+ *
+ * // Create a filter for either directories or ".txt" files
+ * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+ *
+ * // Copy using the filter
+ * FileUtils.copyDirectory(srcDir, destDir, filter, false);
+ *
+ *
+ * @param srcDir an existing directory to copy, must not be null
+ * @param destDir the new directory, must not be null
+ * @param filter the filter to apply, null means copy all directories and files
+ * @param preserveFileDate true if the file date of the copy
+ * should be the same as the original
+ *
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @since Commons IO 1.4
+ */
+ public static void copyDirectory(File srcDir, File destDir,
+ FileFilter filter, boolean preserveFileDate) throws IOException {
+ if (srcDir == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (srcDir.exists() == false) {
+ throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
+ }
+ if (srcDir.isDirectory() == false) {
+ throw new IOException("Source '" + srcDir + "' exists but is not a directory");
+ }
+ if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) {
+ throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
+ }
+
+ // Cater for destination being directory within the source directory (see IO-141)
+ List exclusionList = null;
+ if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
+ File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
+ if (srcFiles != null && srcFiles.length > 0) {
+ exclusionList = new ArrayList(srcFiles.length);
+ for (int i = 0; i < srcFiles.length; i++) {
+ File copiedFile = new File(destDir, srcFiles[i].getName());
+ exclusionList.add(copiedFile.getCanonicalPath());
+ }
+ }
+ }
+ doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
+ }
+
+ /**
+ * Internal copy directory method.
+ *
+ * @param srcDir the validated source directory, must not be null
+ * @param destDir the validated destination directory, must not be null
+ * @param filter the filter to apply, null means copy all directories and files
+ * @param preserveFileDate whether to preserve the file date
+ * @param exclusionList List of files and directories to exclude from the copy, may be null
+ * @throws IOException if an error occurs
+ * @since Commons IO 1.1
+ */
+ private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter,
+ boolean preserveFileDate, List exclusionList) throws IOException {
+ if (destDir.exists()) {
+ if (destDir.isDirectory() == false) {
+ throw new IOException("Destination '" + destDir + "' exists but is not a directory");
+ }
+ } else {
+ if (destDir.mkdirs() == false) {
+ throw new IOException("Destination '" + destDir + "' directory cannot be created");
+ }
+ if (preserveFileDate) {
+ destDir.setLastModified(srcDir.lastModified());
+ }
+ }
+ if (destDir.canWrite() == false) {
+ throw new IOException("Destination '" + destDir + "' cannot be written to");
+ }
+ // recurse
+ File[] files = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + srcDir);
+ }
+ for (int i = 0; i < files.length; i++) {
+ File copiedFile = new File(destDir, files[i].getName());
+ if (exclusionList == null || !exclusionList.contains(files[i].getCanonicalPath())) {
+ if (files[i].isDirectory()) {
+ doCopyDirectory(files[i], copiedFile, filter, preserveFileDate, exclusionList);
+ } else {
+ doCopyFile(files[i], copiedFile, preserveFileDate);
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Copies bytes from the URL source
to a file
+ * destination
. The directories up to destination
+ * will be created if they don't already exist. destination
+ * will be overwritten if it already exists.
+ *
+ * @param source the URL
to copy bytes from, must not be null
+ * @param destination the non-directory File
to write bytes to
+ * (possibly overwriting), must not be null
+ * @throws IOException if source
URL cannot be opened
+ * @throws IOException if destination
is a directory
+ * @throws IOException if destination
cannot be written
+ * @throws IOException if destination
needs creating but can't be
+ * @throws IOException if an IO error occurs during copying
+ */
+ public static void copyURLToFile(URL source, File destination) throws IOException {
+ InputStream input = source.openStream();
+ try {
+ FileOutputStream output = openOutputStream(destination);
+ try {
+ IOUtils.copy(input, output);
+ } finally {
+ IOUtils.closeQuietly(output);
+ }
+ } finally {
+ IOUtils.closeQuietly(input);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Deletes a directory recursively.
+ *
+ * @param directory directory to delete
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void deleteDirectory(File directory) throws IOException {
+ if (!directory.exists()) {
+ return;
+ }
+
+ cleanDirectory(directory);
+ if (!directory.delete()) {
+ String message =
+ "Unable to delete directory " + directory + ".";
+ throw new IOException(message);
+ }
+ }
+
+ /**
+ * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
+ *
+ *
+ *
+ * @param file file or directory to delete, can be null
+ * @return true
if the file or directory was deleted, otherwise
+ * false
+ *
+ * @since Commons IO 1.4
+ */
+ public static boolean deleteQuietly(File file) {
+ if (file == null) {
+ return false;
+ }
+ try {
+ if (file.isDirectory()) {
+ cleanDirectory(file);
+ }
+ } catch (Exception e) {
+ }
+
+ try {
+ return file.delete();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Cleans a directory without deleting it.
+ *
+ * @param directory directory to clean
+ * @throws IOException in case cleaning is unsuccessful
+ */
+ public static void cleanDirectory(File directory) throws IOException {
+ if (!directory.exists()) {
+ String message = directory + " does not exist";
+ throw new IllegalArgumentException(message);
+ }
+
+ if (!directory.isDirectory()) {
+ String message = directory + " is not a directory";
+ throw new IllegalArgumentException(message);
+ }
+
+ File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + directory);
+ }
+
+ IOException exception = null;
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ try {
+ forceDelete(file);
+ } catch (IOException ioe) {
+ exception = ioe;
+ }
+ }
+
+ if (null != exception) {
+ throw exception;
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Waits for NFS to propagate a file creation, imposing a timeout.
+ * null
+ * @param seconds the maximum time in seconds to wait
+ * @return true if file exists
+ * @throws NullPointerException if the file is null
+ */
+ public static boolean waitFor(File file, int seconds) {
+ int timeout = 0;
+ int tick = 0;
+ while (!file.exists()) {
+ if (tick++ >= 10) {
+ tick = 0;
+ if (timeout++ > seconds) {
+ return false;
+ }
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ignore) {
+ // ignore exception
+ } catch (Exception ex) {
+ break;
+ }
+ }
+ return true;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Reads the contents of a file into a String.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be null
+ * @param encoding the encoding to use, null
means platform default
+ * @return the file contents, never null
+ * @throws IOException in case of an I/O error
+ * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+ */
+ public static String readFileToString(File file, String encoding) throws IOException {
+ InputStream in = null;
+ try {
+ in = openInputStream(file);
+ return IOUtils.toString(in, encoding);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+
+ /**
+ * Reads the contents of a file into a String using the default encoding for the VM.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be null
+ * @return the file contents, never null
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.3.1
+ */
+ public static String readFileToString(File file) throws IOException {
+ return readFileToString(file, null);
+ }
+
+ /**
+ * Reads the contents of a file into a byte array.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be null
+ * @return the file contents, never null
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.1
+ */
+ public static byte[] readFileToByteArray(File file) throws IOException {
+ InputStream in = null;
+ try {
+ in = openInputStream(file);
+ return IOUtils.toByteArray(in);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /**
+ * Reads the contents of a file line by line to a List of Strings.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be null
+ * @param encoding the encoding to use, null
means platform default
+ * @return the list of Strings representing each line in the file, never null
+ * @throws IOException in case of an I/O error
+ * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+ * @since Commons IO 1.1
+ */
+ public static List readLines(File file, String encoding) throws IOException {
+ InputStream in = null;
+ try {
+ in = openInputStream(file);
+ return IOUtils.readLines(in, encoding);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /**
+ * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be null
+ * @return the list of Strings representing each line in the file, never null
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.3
+ */
+ public static List readLines(File file) throws IOException {
+ return readLines(file, null);
+ }
+
+ /**
+ * Returns an Iterator for the lines in a File
.
+ * InputStream
for the file.
+ * When you have finished with the iterator you should close the stream
+ * to free internal resources. This can be done by calling the
+ * {@link LineIterator#close()} or
+ * {@link LineIterator#closeQuietly(LineIterator)} method.
+ *
+ * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
+ * try {
+ * while (it.hasNext()) {
+ * String line = it.nextLine();
+ * /// do something with line
+ * }
+ * } finally {
+ * LineIterator.closeQuietly(iterator);
+ * }
+ *
+ * null
+ * @param encoding the encoding to use, null
means platform default
+ * @return an Iterator of the lines in the file, never null
+ * @throws IOException in case of an I/O error (file closed)
+ * @since Commons IO 1.2
+ */
+ public static LineIterator lineIterator(File file, String encoding) throws IOException {
+ InputStream in = null;
+ try {
+ in = openInputStream(file);
+ return IOUtils.lineIterator(in, encoding);
+ } catch (IOException ex) {
+ IOUtils.closeQuietly(in);
+ throw ex;
+ } catch (RuntimeException ex) {
+ IOUtils.closeQuietly(in);
+ throw ex;
+ }
+ }
+
+ /**
+ * Returns an Iterator for the lines in a File
using the default encoding for the VM.
+ *
+ * @param file the file to open for input, must not be null
+ * @return an Iterator of the lines in the file, never null
+ * @throws IOException in case of an I/O error (file closed)
+ * @since Commons IO 1.3
+ * @see #lineIterator(File, String)
+ */
+ public static LineIterator lineIterator(File file) throws IOException {
+ return lineIterator(file, null);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Writes a String to a file creating the file if it does not exist.
+ *
+ * NOTE: As from v1.3, the parent directories of the file will be created
+ * if they do not exist.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ * @param encoding the encoding to use, null
means platform default
+ * @throws IOException in case of an I/O error
+ * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+ */
+ public static void writeStringToFile(File file, String data, String encoding) throws IOException {
+ OutputStream out = null;
+ try {
+ out = openOutputStream(file);
+ IOUtils.write(data, out, encoding);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * Writes a String to a file creating the file if it does not exist using the default encoding for the VM.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ * @throws IOException in case of an I/O error
+ */
+ public static void writeStringToFile(File file, String data) throws IOException {
+ writeStringToFile(file, data, null);
+ }
+
+ /**
+ * Writes a byte array to a file creating the file if it does not exist.
+ * toString()
value of each item in a collection to
+ * the specified File
line by line.
+ * The specified character encoding and the default line ending will be used.
+ * null
means platform default
+ * @param lines the lines to write, null
entries produce blank lines
+ * @throws IOException in case of an I/O error
+ * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+ * @since Commons IO 1.1
+ */
+ public static void writeLines(File file, String encoding, Collection lines) throws IOException {
+ writeLines(file, encoding, lines, null);
+ }
+
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * the specified File
line by line.
+ * The default VM encoding and the default line ending will be used.
+ *
+ * @param file the file to write to
+ * @param lines the lines to write, null
entries produce blank lines
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.3
+ */
+ public static void writeLines(File file, Collection lines) throws IOException {
+ writeLines(file, null, lines, null);
+ }
+
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * the specified File
line by line.
+ * The specified character encoding and the line ending will be used.
+ * null
means platform default
+ * @param lines the lines to write, null
entries produce blank lines
+ * @param lineEnding the line separator to use, null
is system default
+ * @throws IOException in case of an I/O error
+ * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+ * @since Commons IO 1.1
+ */
+ public static void writeLines(File file, String encoding, Collection lines, String lineEnding) throws IOException {
+ OutputStream out = null;
+ try {
+ out = openOutputStream(file);
+ IOUtils.writeLines(lines, lineEnding, out, encoding);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * the specified File
line by line.
+ * The default VM encoding and the specified line ending will be used.
+ *
+ * @param file the file to write to
+ * @param lines the lines to write, null
entries produce blank lines
+ * @param lineEnding the line separator to use, null
is system default
+ * @throws IOException in case of an I/O error
+ * @since Commons IO 1.3
+ */
+ public static void writeLines(File file, Collection lines, String lineEnding) throws IOException {
+ writeLines(file, null, lines, lineEnding);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Deletes a file. If file is a directory, delete it and all sub-directories.
+ *
+ *
+ *
+ * @param file file or directory to delete, must not be null
+ * @throws NullPointerException if the directory is null
+ * @throws FileNotFoundException if the file was not found
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void forceDelete(File file) throws IOException {
+ if (file.isDirectory()) {
+ deleteDirectory(file);
+ } else {
+ boolean filePresent = file.exists();
+ if (!file.delete()) {
+ if (!filePresent){
+ throw new FileNotFoundException("File does not exist: " + file);
+ }
+ String message =
+ "Unable to delete file: " + file;
+ throw new IOException(message);
+ }
+ }
+ }
+
+ /**
+ * Schedules a file to be deleted when JVM exits.
+ * If file is directory delete it and all sub-directories.
+ *
+ * @param file file or directory to delete, must not be null
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void forceDeleteOnExit(File file) throws IOException {
+ if (file.isDirectory()) {
+ deleteDirectoryOnExit(file);
+ } else {
+ file.deleteOnExit();
+ }
+ }
+
+ /**
+ * Schedules a directory recursively for deletion on JVM exit.
+ *
+ * @param directory directory to delete, must not be null
+ * @throws NullPointerException if the directory is null
+ * @throws IOException in case deletion is unsuccessful
+ */
+ private static void deleteDirectoryOnExit(File directory) throws IOException {
+ if (!directory.exists()) {
+ return;
+ }
+
+ cleanDirectoryOnExit(directory);
+ directory.deleteOnExit();
+ }
+
+ /**
+ * Cleans a directory without deleting it.
+ *
+ * @param directory directory to clean, must not be null
+ * @throws NullPointerException if the directory is null
+ * @throws IOException in case cleaning is unsuccessful
+ */
+ private static void cleanDirectoryOnExit(File directory) throws IOException {
+ if (!directory.exists()) {
+ String message = directory + " does not exist";
+ throw new IllegalArgumentException(message);
+ }
+
+ if (!directory.isDirectory()) {
+ String message = directory + " is not a directory";
+ throw new IllegalArgumentException(message);
+ }
+
+ File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + directory);
+ }
+
+ IOException exception = null;
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ try {
+ forceDeleteOnExit(file);
+ } catch (IOException ioe) {
+ exception = ioe;
+ }
+ }
+
+ if (null != exception) {
+ throw exception;
+ }
+ }
+
+ /**
+ * Makes a directory, including any necessary but nonexistent parent
+ * directories. If there already exists a file with specified name or
+ * the directory cannot be created then an exception is thrown.
+ *
+ * @param directory directory to create, must not be null
+ * @throws NullPointerException if the directory is null
+ * @throws IOException if the directory cannot be created
+ */
+ public static void forceMkdir(File directory) throws IOException {
+ if (directory.exists()) {
+ if (directory.isFile()) {
+ String message =
+ "File "
+ + directory
+ + " exists and is "
+ + "not a directory. Unable to create directory.";
+ throw new IOException(message);
+ }
+ } else {
+ if (!directory.mkdirs()) {
+ String message =
+ "Unable to create directory " + directory;
+ throw new IOException(message);
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Counts the size of a directory recursively (sum of the length of all files).
+ *
+ * @param directory directory to inspect, must not be null
+ * @return size of directory in bytes, 0 if directory is security restricted
+ * @throws NullPointerException if the directory is null
+ */
+ public static long sizeOfDirectory(File directory) {
+ if (!directory.exists()) {
+ String message = directory + " does not exist";
+ throw new IllegalArgumentException(message);
+ }
+
+ if (!directory.isDirectory()) {
+ String message = directory + " is not a directory";
+ throw new IllegalArgumentException(message);
+ }
+
+ long size = 0;
+
+ File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ return 0L;
+ }
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+
+ if (file.isDirectory()) {
+ size += sizeOfDirectory(file);
+ } else {
+ size += file.length();
+ }
+ }
+
+ return size;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Tests if the specified File
is newer than the reference
+ * File
.
+ *
+ * @param file the File
of which the modification date must
+ * be compared, must not be null
+ * @param reference the File
of which the modification date
+ * is used, must not be null
+ * @return true if the File
exists and has been modified more
+ * recently than the reference File
+ * @throws IllegalArgumentException if the file is null
+ * @throws IllegalArgumentException if the reference file is null
or doesn't exist
+ */
+ public static boolean isFileNewer(File file, File reference) {
+ if (reference == null) {
+ throw new IllegalArgumentException("No specified reference file");
+ }
+ if (!reference.exists()) {
+ throw new IllegalArgumentException("The reference file '"
+ + file + "' doesn't exist");
+ }
+ return isFileNewer(file, reference.lastModified());
+ }
+
+ /**
+ * Tests if the specified File
is newer than the specified
+ * Date
.
+ *
+ * @param file the File
of which the modification date
+ * must be compared, must not be null
+ * @param date the date reference, must not be null
+ * @return true if the File
exists and has been modified
+ * after the given Date
.
+ * @throws IllegalArgumentException if the file is null
+ * @throws IllegalArgumentException if the date is null
+ */
+ public static boolean isFileNewer(File file, Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("No specified date");
+ }
+ return isFileNewer(file, date.getTime());
+ }
+
+ /**
+ * Tests if the specified File
is newer than the specified
+ * time reference.
+ *
+ * @param file the File
of which the modification date must
+ * be compared, must not be null
+ * @param timeMillis the time reference measured in milliseconds since the
+ * epoch (00:00:00 GMT, January 1, 1970)
+ * @return true if the File
exists and has been modified after
+ * the given time reference.
+ * @throws IllegalArgumentException if the file is null
+ */
+ public static boolean isFileNewer(File file, long timeMillis) {
+ if (file == null) {
+ throw new IllegalArgumentException("No specified file");
+ }
+ if (!file.exists()) {
+ return false;
+ }
+ return file.lastModified() > timeMillis;
+ }
+
+
+ //-----------------------------------------------------------------------
+ /**
+ * Tests if the specified File
is older than the reference
+ * File
.
+ *
+ * @param file the File
of which the modification date must
+ * be compared, must not be null
+ * @param reference the File
of which the modification date
+ * is used, must not be null
+ * @return true if the File
exists and has been modified before
+ * the reference File
+ * @throws IllegalArgumentException if the file is null
+ * @throws IllegalArgumentException if the reference file is null
or doesn't exist
+ */
+ public static boolean isFileOlder(File file, File reference) {
+ if (reference == null) {
+ throw new IllegalArgumentException("No specified reference file");
+ }
+ if (!reference.exists()) {
+ throw new IllegalArgumentException("The reference file '"
+ + file + "' doesn't exist");
+ }
+ return isFileOlder(file, reference.lastModified());
+ }
+
+ /**
+ * Tests if the specified File
is older than the specified
+ * Date
.
+ *
+ * @param file the File
of which the modification date
+ * must be compared, must not be null
+ * @param date the date reference, must not be null
+ * @return true if the File
exists and has been modified
+ * before the given Date
.
+ * @throws IllegalArgumentException if the file is null
+ * @throws IllegalArgumentException if the date is null
+ */
+ public static boolean isFileOlder(File file, Date date) {
+ if (date == null) {
+ throw new IllegalArgumentException("No specified date");
+ }
+ return isFileOlder(file, date.getTime());
+ }
+
+ /**
+ * Tests if the specified File
is older than the specified
+ * time reference.
+ *
+ * @param file the File
of which the modification date must
+ * be compared, must not be null
+ * @param timeMillis the time reference measured in milliseconds since the
+ * epoch (00:00:00 GMT, January 1, 1970)
+ * @return true if the File
exists and has been modified before
+ * the given time reference.
+ * @throws IllegalArgumentException if the file is null
+ */
+ public static boolean isFileOlder(File file, long timeMillis) {
+ if (file == null) {
+ throw new IllegalArgumentException("No specified file");
+ }
+ if (!file.exists()) {
+ return false;
+ }
+ return file.lastModified() < timeMillis;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Computes the checksum of a file using the CRC32 checksum routine.
+ * The value of the checksum is returned.
+ *
+ * @param file the file to checksum, must not be null
+ * @return the checksum value
+ * @throws NullPointerException if the file or checksum is null
+ * @throws IllegalArgumentException if the file is a directory
+ * @throws IOException if an IO error occurs reading the file
+ * @since Commons IO 1.3
+ */
+ public static long checksumCRC32(File file) throws IOException {
+ CRC32 crc = new CRC32();
+ checksum(file, crc);
+ return crc.getValue();
+ }
+
+ /**
+ * Computes the checksum of a file using the specified checksum object.
+ * Multiple files may be checked using one Checksum
instance
+ * if desired simply by reusing the same checksum object.
+ * For example:
+ *
+ * long csum = FileUtils.checksum(file, new CRC32()).getValue();
+ *
+ *
+ * @param file the file to checksum, must not be null
+ * @param checksum the checksum object to be used, must not be null
+ * @return the checksum specified, updated with the content of the file
+ * @throws NullPointerException if the file or checksum is null
+ * @throws IllegalArgumentException if the file is a directory
+ * @throws IOException if an IO error occurs reading the file
+ * @since Commons IO 1.3
+ */
+ public static Checksum checksum(File file, Checksum checksum) throws IOException {
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException("Checksums can't be computed on directories");
+ }
+ InputStream in = null;
+ try {
+ in = new CheckedInputStream(new FileInputStream(file), checksum);
+ IOUtils.copy(in, new NullOutputStream());
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ return checksum;
+ }
+
+ /**
+ * Moves a directory.
+ * null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ * @since Commons IO 1.4
+ */
+ public static void moveDirectory(File srcDir, File destDir) throws IOException {
+ if (srcDir == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (!srcDir.exists()) {
+ throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
+ }
+ if (!srcDir.isDirectory()) {
+ throw new IOException("Source '" + srcDir + "' is not a directory");
+ }
+ if (destDir.exists()) {
+ throw new IOException("Destination '" + destDir + "' already exists");
+ }
+ boolean rename = srcDir.renameTo(destDir);
+ if (!rename) {
+ copyDirectory( srcDir, destDir );
+ deleteDirectory( srcDir );
+ if (srcDir.exists()) {
+ throw new IOException("Failed to delete original directory '" + srcDir +
+ "' after copy to '" + destDir + "'");
+ }
+ }
+ }
+
+ /**
+ * Moves a directory to another directory.
+ *
+ * @param src the file to be moved
+ * @param destDir the destination file
+ * @param createDestDir If true
create the destination directory,
+ * otherwise if false
throw an IOException
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ * @since Commons IO 1.4
+ */
+ public static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
+ if (src == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination directory must not be null");
+ }
+ if (!destDir.exists() && createDestDir) {
+ destDir.mkdirs();
+ }
+ if (!destDir.exists()) {
+ throw new FileNotFoundException("Destination directory '" + destDir +
+ "' does not exist [createDestDir=" + createDestDir +"]");
+ }
+ if (!destDir.isDirectory()) {
+ throw new IOException("Destination '" + destDir + "' is not a directory");
+ }
+ moveDirectory(src, new File(destDir, src.getName()));
+
+ }
+
+ /**
+ * Moves a file.
+ * null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ * @since Commons IO 1.4
+ */
+ public static void moveFile(File srcFile, File destFile) throws IOException {
+ if (srcFile == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destFile == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (!srcFile.exists()) {
+ throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
+ }
+ if (srcFile.isDirectory()) {
+ throw new IOException("Source '" + srcFile + "' is a directory");
+ }
+ if (destFile.exists()) {
+ throw new IOException("Destination '" + destFile + "' already exists");
+ }
+ if (destFile.isDirectory()) {
+ throw new IOException("Destination '" + destFile + "' is a directory");
+ }
+ boolean rename = srcFile.renameTo(destFile);
+ if (!rename) {
+ copyFile( srcFile, destFile );
+ if (!srcFile.delete()) {
+ FileUtils.deleteQuietly(destFile);
+ throw new IOException("Failed to delete original file '" + srcFile +
+ "' after copy to '" + destFile + "'");
+ }
+ }
+ }
+
+ /**
+ * Moves a file to a directory.
+ *
+ * @param srcFile the file to be moved
+ * @param destDir the destination file
+ * @param createDestDir If true
create the destination directory,
+ * otherwise if false
throw an IOException
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ * @since Commons IO 1.4
+ */
+ public static void moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) throws IOException {
+ if (srcFile == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination directory must not be null");
+ }
+ if (!destDir.exists() && createDestDir) {
+ destDir.mkdirs();
+ }
+ if (!destDir.exists()) {
+ throw new FileNotFoundException("Destination directory '" + destDir +
+ "' does not exist [createDestDir=" + createDestDir +"]");
+ }
+ if (!destDir.isDirectory()) {
+ throw new IOException("Destination '" + destDir + "' is not a directory");
+ }
+ moveFile(srcFile, new File(destDir, srcFile.getName()));
+ }
+
+ /**
+ * Moves a file or directory to the destination directory.
+ * true
create the destination directory,
+ * otherwise if false
throw an IOException
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ * @since Commons IO 1.4
+ */
+ public static void moveToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
+ if (src == null) {
+ throw new NullPointerException("Source must not be null");
+ }
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (!src.exists()) {
+ throw new FileNotFoundException("Source '" + src + "' does not exist");
+ }
+ if (src.isDirectory()) {
+ moveDirectoryToDirectory(src, destDir, createDestDir);
+ } else {
+ moveFileToDirectory(src, destDir, createDestDir);
+ }
+ }
+
+}
diff --git a/src/org/apache/commons/io/FilenameUtils.java b/src/org/apache/commons/io/FilenameUtils.java
index 8e170b14709ff9d62f29df49d7f33f94b7b6baaf..2f16ad0b25cd625d17a04a183242b33d0b56150d 100644
--- a/src/org/apache/commons/io/FilenameUtils.java
+++ b/src/org/apache/commons/io/FilenameUtils.java
@@ -1,1260 +1,1260 @@
-/*
- * 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.commons.io;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Stack;
-
-/**
- * General filename and filepath manipulation utilities.
- *
- *
- * Note that this class works best if directory filenames end with a separator.
- * If you omit the last separator, it is impossible to determine if the filename
- * corresponds to a file or a directory. As a result, we have chosen to say
- * it corresponds to a file.
- *
- * Windows:
- * a\b\c.txt --> "" --> relative
- * \a\b\c.txt --> "\" --> current drive absolute
- * C:a\b\c.txt --> "C:" --> drive relative
- * C:\a\b\c.txt --> "C:\" --> absolute
- * \\server\a\b\c.txt --> "\\server\" --> UNC
- *
- * Unix:
- * a/b/c.txt --> "" --> relative
- * /a/b/c.txt --> "/" --> absolute
- * ~/a/b/c.txt --> "~/" --> current user
- * ~ --> "~/" --> current user (slash added)
- * ~user/a/b/c.txt --> "~user/" --> named user
- * ~user --> "~user/" --> named user (slash added)
- *
- * Both prefix styles are matched always, irrespective of the machine that you are
- * currently running on.
- * null
- * is returned.
- *
- * /foo// --> /foo/
- * /foo/./ --> /foo/
- * /foo/../bar --> /bar
- * /foo/../bar/ --> /bar/
- * /foo/../bar/../baz --> /baz
- * //foo//./bar --> /foo/bar
- * /../ --> null
- * ../foo --> null
- * foo/bar/.. --> foo/
- * foo/../../bar --> null
- * foo/../bar --> bar
- * //server/foo/../bar --> //server/bar
- * //server/../bar --> null
- * C:\foo\..\bar --> C:\bar
- * C:\..\bar --> null
- * ~/foo/../bar/ --> ~/bar/
- * ~/../bar --> null
- *
- * (Note the file separator returned will be correct for Windows/Unix)
- *
- * @param filename the filename to normalize, null returns null
- * @return the normalized filename, or null if invalid
- */
- public static String normalize(String filename) {
- return doNormalize(filename, true);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Normalizes a path, removing double and single dot path steps,
- * and removing any final directory separator.
- * null
- * is returned.
- *
- * /foo// --> /foo
- * /foo/./ --> /foo
- * /foo/../bar --> /bar
- * /foo/../bar/ --> /bar
- * /foo/../bar/../baz --> /baz
- * //foo//./bar --> /foo/bar
- * /../ --> null
- * ../foo --> null
- * foo/bar/.. --> foo
- * foo/../../bar --> null
- * foo/../bar --> bar
- * //server/foo/../bar --> //server/bar
- * //server/../bar --> null
- * C:\foo\..\bar --> C:\bar
- * C:\..\bar --> null
- * ~/foo/../bar/ --> ~/bar
- * ~/../bar --> null
- *
- * (Note the file separator returned will be correct for Windows/Unix)
- *
- * @param filename the filename to normalize, null returns null
- * @return the normalized filename, or null if invalid
- */
- public static String normalizeNoEndSeparator(String filename) {
- return doNormalize(filename, false);
- }
-
- /**
- * Internal method to perform the normalization.
- *
- * @param filename the filename
- * @param keepSeparator true to keep the final separator
- * @return the normalized filename
- */
- private static String doNormalize(String filename, boolean keepSeparator) {
- if (filename == null) {
- return null;
- }
- int size = filename.length();
- if (size == 0) {
- return filename;
- }
- int prefix = getPrefixLength(filename);
- if (prefix < 0) {
- return null;
- }
-
- char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy
- filename.getChars(0, filename.length(), array, 0);
-
- // fix separators throughout
- for (int i = 0; i < array.length; i++) {
- if (array[i] == OTHER_SEPARATOR) {
- array[i] = SYSTEM_SEPARATOR;
- }
- }
-
- // add extra separator on the end to simplify code below
- boolean lastIsDirectory = true;
- if (array[size - 1] != SYSTEM_SEPARATOR) {
- array[size++] = SYSTEM_SEPARATOR;
- lastIsDirectory = false;
- }
-
- // adjoining slashes
- for (int i = prefix + 1; i < size; i++) {
- if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == SYSTEM_SEPARATOR) {
- System.arraycopy(array, i, array, i - 1, size - i);
- size--;
- i--;
- }
- }
-
- // dot slash
- for (int i = prefix + 1; i < size; i++) {
- if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
- (i == prefix + 1 || array[i - 2] == SYSTEM_SEPARATOR)) {
- if (i == size - 1) {
- lastIsDirectory = true;
- }
- System.arraycopy(array, i + 1, array, i - 1, size - i);
- size -=2;
- i--;
- }
- }
-
- // double dot slash
- outer:
- for (int i = prefix + 2; i < size; i++) {
- if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' && array[i - 2] == '.' &&
- (i == prefix + 2 || array[i - 3] == SYSTEM_SEPARATOR)) {
- if (i == prefix + 2) {
- return null;
- }
- if (i == size - 1) {
- lastIsDirectory = true;
- }
- int j;
- for (j = i - 4 ; j >= prefix; j--) {
- if (array[j] == SYSTEM_SEPARATOR) {
- // remove b/../ from a/b/../c
- System.arraycopy(array, i + 1, array, j + 1, size - i);
- size -= (i - j);
- i = j + 1;
- continue outer;
- }
- }
- // remove a/../ from a/../c
- System.arraycopy(array, i + 1, array, prefix, size - i);
- size -= (i + 1 - prefix);
- i = prefix + 1;
- }
- }
-
- if (size <= 0) { // should never be less than 0
- return "";
- }
- if (size <= prefix) { // should never be less than prefix
- return new String(array, 0, size);
- }
- if (lastIsDirectory && keepSeparator) {
- return new String(array, 0, size); // keep trailing separator
- }
- return new String(array, 0, size - 1); // lose trailing separator
- }
-
- //-----------------------------------------------------------------------
- /**
- * Concatenates a filename to a base path using normal command line style rules.
- * ..
is handled.
- * pathToAdd
is absolute (has an absolute prefix), then
- * it will be normalized and returned.
- * Otherwise, the paths will be joined, normalized and returned.
- *
- * /foo/ + bar --> /foo/bar
- * /foo + bar --> /foo/bar
- * /foo + /bar --> /bar
- * /foo + C:/bar --> C:/bar
- * /foo + C:bar --> C:bar (*)
- * /foo/a/ + ../bar --> foo/bar
- * /foo/ + ../../bar --> null
- * /foo/ + /bar --> /bar
- * /foo/.. + /bar --> /bar
- * /foo + bar/c.txt --> /foo/bar/c.txt
- * /foo/c.txt + bar --> /foo/c.txt/bar (!)
- *
- * (*) Note that the Windows relative drive prefix is unreliable when
- * used with this method.
- * (!) Note that the first parameter must be a path. If it ends with a name, then
- * the name will be built into the concatenated path. If this might be a problem,
- * use {@link #getFullPath(String)} on the base path argument.
- *
- * @param basePath the base path to attach to, always treated as a path
- * @param fullFilenameToAdd the filename (or path) to attach to the base
- * @return the concatenated path, or null if invalid
- */
- public static String concat(String basePath, String fullFilenameToAdd) {
- int prefix = getPrefixLength(fullFilenameToAdd);
- if (prefix < 0) {
- return null;
- }
- if (prefix > 0) {
- return normalize(fullFilenameToAdd);
- }
- if (basePath == null) {
- return null;
- }
- int len = basePath.length();
- if (len == 0) {
- return normalize(fullFilenameToAdd);
- }
- char ch = basePath.charAt(len - 1);
- if (isSeparator(ch)) {
- return normalize(basePath + fullFilenameToAdd);
- } else {
- return normalize(basePath + '/' + fullFilenameToAdd);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Converts all separators to the Unix separator of forward slash.
- *
- * @param path the path to be changed, null ignored
- * @return the updated path
- */
- public static String separatorsToUnix(String path) {
- if (path == null || path.indexOf(WINDOWS_SEPARATOR) == -1) {
- return path;
- }
- return path.replace(WINDOWS_SEPARATOR, UNIX_SEPARATOR);
- }
-
- /**
- * Converts all separators to the Windows separator of backslash.
- *
- * @param path the path to be changed, null ignored
- * @return the updated path
- */
- public static String separatorsToWindows(String path) {
- if (path == null || path.indexOf(UNIX_SEPARATOR) == -1) {
- return path;
- }
- return path.replace(UNIX_SEPARATOR, WINDOWS_SEPARATOR);
- }
-
- /**
- * Converts all separators to the system separator.
- *
- * @param path the path to be changed, null ignored
- * @return the updated path
- */
- public static String separatorsToSystem(String path) {
- if (path == null) {
- return null;
- }
- if (isSystemWindows()) {
- return separatorsToWindows(path);
- } else {
- return separatorsToUnix(path);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns the length of the filename prefix, such as C:/
or ~/
.
- *
- * Windows:
- * a\b\c.txt --> "" --> relative
- * \a\b\c.txt --> "\" --> current drive absolute
- * C:a\b\c.txt --> "C:" --> drive relative
- * C:\a\b\c.txt --> "C:\" --> absolute
- * \\server\a\b\c.txt --> "\\server\" --> UNC
- *
- * Unix:
- * a/b/c.txt --> "" --> relative
- * /a/b/c.txt --> "/" --> absolute
- * ~/a/b/c.txt --> "~/" --> current user
- * ~ --> "~/" --> current user (slash added)
- * ~user/a/b/c.txt --> "~user/" --> named user
- * ~user --> "~user/" --> named user (slash added)
- *
- * C:/
- * or ~/
.
- *
- * Windows:
- * a\b\c.txt --> "" --> relative
- * \a\b\c.txt --> "\" --> current drive absolute
- * C:a\b\c.txt --> "C:" --> drive relative
- * C:\a\b\c.txt --> "C:\" --> absolute
- * \\server\a\b\c.txt --> "\\server\" --> UNC
- *
- * Unix:
- * a/b/c.txt --> "" --> relative
- * /a/b/c.txt --> "/" --> absolute
- * ~/a/b/c.txt --> "~/" --> current user
- * ~ --> "~/" --> current user (slash added)
- * ~user/a/b/c.txt --> "~user/" --> named user
- * ~user --> "~user/" --> named user (slash added)
- *
- *
- * C:\a\b\c.txt --> a\b\
- * ~/a/b/c.txt --> a/b/
- * a.txt --> ""
- * a/b/c --> a/b/
- * a/b/c/ --> a/b/c/
- *
- *
- * C:\a\b\c.txt --> a\b
- * ~/a/b/c.txt --> a/b
- * a.txt --> ""
- * a/b/c --> a/b
- * a/b/c/ --> a/b/c
- *
- *
- * C:\a\b\c.txt --> C:\a\b\
- * ~/a/b/c.txt --> ~/a/b/
- * a.txt --> ""
- * a/b/c --> a/b/
- * a/b/c/ --> a/b/c/
- * C: --> C:
- * C:\ --> C:\
- * ~ --> ~/
- * ~/ --> ~/
- * ~user --> ~user/
- * ~user/ --> ~user/
- *
- *
- * C:\a\b\c.txt --> C:\a\b
- * ~/a/b/c.txt --> ~/a/b
- * a.txt --> ""
- * a/b/c --> a/b
- * a/b/c/ --> a/b/c
- * C: --> C:
- * C:\ --> C:\
- * ~ --> ~
- * ~/ --> ~
- * ~user --> ~user
- * ~user/ --> ~user
- *
- *
- * a/b/c.txt --> c.txt
- * a.txt --> a.txt
- * a/b/c --> c
- * a/b/c/ --> ""
- *
- *
- * a/b/c.txt --> c
- * a.txt --> a
- * a/b/c --> c
- * a/b/c/ --> ""
- *
- *
- * foo.txt --> "txt"
- * a/b/c.jpg --> "jpg"
- * a/b.txt/c --> ""
- * a/b/c --> ""
- *
- *
- * foo.txt --> foo
- * a\b\c.jpg --> a\b\c
- * a\b\c --> a\b\c
- * a.b\c --> a.b\c
- *
- *
- * wildcardMatch("c.txt", "*.txt") --> true
- * wildcardMatch("c.txt", "*.jpg") --> false
- * wildcardMatch("a/b/c.txt", "a/b/*") --> true
- * wildcardMatch("c.txt", "*.???") --> true
- * wildcardMatch("c.txt", "*.????") --> false
- *
- *
- * @param filename the filename to match on
- * @param wildcardMatcher the wildcard string to match against
- * @return true if the filename matches the wilcard string
- * @see IOCase#SENSITIVE
- */
- public static boolean wildcardMatch(String filename, String wildcardMatcher) {
- return wildcardMatch(filename, wildcardMatcher, IOCase.SENSITIVE);
- }
-
- /**
- * Checks a filename to see if it matches the specified wildcard matcher
- * using the case rules of the system.
- *
- * wildcardMatch("c.txt", "*.txt") --> true
- * wildcardMatch("c.txt", "*.jpg") --> false
- * wildcardMatch("a/b/c.txt", "a/b/*") --> true
- * wildcardMatch("c.txt", "*.???") --> true
- * wildcardMatch("c.txt", "*.????") --> false
- *
- *
- * @param filename the filename to match on
- * @param wildcardMatcher the wildcard string to match against
- * @return true if the filename matches the wilcard string
- * @see IOCase#SYSTEM
- */
- public static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher) {
- return wildcardMatch(filename, wildcardMatcher, IOCase.SYSTEM);
- }
-
- /**
- * Checks a filename to see if it matches the specified wildcard matcher
- * allowing control over case-sensitivity.
- *
+ *
+ * Note that this class works best if directory filenames end with a separator.
+ * If you omit the last separator, it is impossible to determine if the filename
+ * corresponds to a file or a directory. As a result, we have chosen to say
+ * it corresponds to a file.
+ *
+ * Windows:
+ * a\b\c.txt --> "" --> relative
+ * \a\b\c.txt --> "\" --> current drive absolute
+ * C:a\b\c.txt --> "C:" --> drive relative
+ * C:\a\b\c.txt --> "C:\" --> absolute
+ * \\server\a\b\c.txt --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt --> "" --> relative
+ * /a/b/c.txt --> "/" --> absolute
+ * ~/a/b/c.txt --> "~/" --> current user
+ * ~ --> "~/" --> current user (slash added)
+ * ~user/a/b/c.txt --> "~user/" --> named user
+ * ~user --> "~user/" --> named user (slash added)
+ *
+ * Both prefix styles are matched always, irrespective of the machine that you are
+ * currently running on.
+ * null
+ * is returned.
+ *
+ * /foo// --> /foo/
+ * /foo/./ --> /foo/
+ * /foo/../bar --> /bar
+ * /foo/../bar/ --> /bar/
+ * /foo/../bar/../baz --> /baz
+ * //foo//./bar --> /foo/bar
+ * /../ --> null
+ * ../foo --> null
+ * foo/bar/.. --> foo/
+ * foo/../../bar --> null
+ * foo/../bar --> bar
+ * //server/foo/../bar --> //server/bar
+ * //server/../bar --> null
+ * C:\foo\..\bar --> C:\bar
+ * C:\..\bar --> null
+ * ~/foo/../bar/ --> ~/bar/
+ * ~/../bar --> null
+ *
+ * (Note the file separator returned will be correct for Windows/Unix)
+ *
+ * @param filename the filename to normalize, null returns null
+ * @return the normalized filename, or null if invalid
+ */
+ public static String normalize(String filename) {
+ return doNormalize(filename, true);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Normalizes a path, removing double and single dot path steps,
+ * and removing any final directory separator.
+ * null
+ * is returned.
+ *
+ * /foo// --> /foo
+ * /foo/./ --> /foo
+ * /foo/../bar --> /bar
+ * /foo/../bar/ --> /bar
+ * /foo/../bar/../baz --> /baz
+ * //foo//./bar --> /foo/bar
+ * /../ --> null
+ * ../foo --> null
+ * foo/bar/.. --> foo
+ * foo/../../bar --> null
+ * foo/../bar --> bar
+ * //server/foo/../bar --> //server/bar
+ * //server/../bar --> null
+ * C:\foo\..\bar --> C:\bar
+ * C:\..\bar --> null
+ * ~/foo/../bar/ --> ~/bar
+ * ~/../bar --> null
+ *
+ * (Note the file separator returned will be correct for Windows/Unix)
+ *
+ * @param filename the filename to normalize, null returns null
+ * @return the normalized filename, or null if invalid
+ */
+ public static String normalizeNoEndSeparator(String filename) {
+ return doNormalize(filename, false);
+ }
+
+ /**
+ * Internal method to perform the normalization.
+ *
+ * @param filename the filename
+ * @param keepSeparator true to keep the final separator
+ * @return the normalized filename
+ */
+ private static String doNormalize(String filename, boolean keepSeparator) {
+ if (filename == null) {
+ return null;
+ }
+ int size = filename.length();
+ if (size == 0) {
+ return filename;
+ }
+ int prefix = getPrefixLength(filename);
+ if (prefix < 0) {
+ return null;
+ }
+
+ char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy
+ filename.getChars(0, filename.length(), array, 0);
+
+ // fix separators throughout
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == OTHER_SEPARATOR) {
+ array[i] = SYSTEM_SEPARATOR;
+ }
+ }
+
+ // add extra separator on the end to simplify code below
+ boolean lastIsDirectory = true;
+ if (array[size - 1] != SYSTEM_SEPARATOR) {
+ array[size++] = SYSTEM_SEPARATOR;
+ lastIsDirectory = false;
+ }
+
+ // adjoining slashes
+ for (int i = prefix + 1; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == SYSTEM_SEPARATOR) {
+ System.arraycopy(array, i, array, i - 1, size - i);
+ size--;
+ i--;
+ }
+ }
+
+ // dot slash
+ for (int i = prefix + 1; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
+ (i == prefix + 1 || array[i - 2] == SYSTEM_SEPARATOR)) {
+ if (i == size - 1) {
+ lastIsDirectory = true;
+ }
+ System.arraycopy(array, i + 1, array, i - 1, size - i);
+ size -=2;
+ i--;
+ }
+ }
+
+ // double dot slash
+ outer:
+ for (int i = prefix + 2; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' && array[i - 2] == '.' &&
+ (i == prefix + 2 || array[i - 3] == SYSTEM_SEPARATOR)) {
+ if (i == prefix + 2) {
+ return null;
+ }
+ if (i == size - 1) {
+ lastIsDirectory = true;
+ }
+ int j;
+ for (j = i - 4 ; j >= prefix; j--) {
+ if (array[j] == SYSTEM_SEPARATOR) {
+ // remove b/../ from a/b/../c
+ System.arraycopy(array, i + 1, array, j + 1, size - i);
+ size -= (i - j);
+ i = j + 1;
+ continue outer;
+ }
+ }
+ // remove a/../ from a/../c
+ System.arraycopy(array, i + 1, array, prefix, size - i);
+ size -= (i + 1 - prefix);
+ i = prefix + 1;
+ }
+ }
+
+ if (size <= 0) { // should never be less than 0
+ return "";
+ }
+ if (size <= prefix) { // should never be less than prefix
+ return new String(array, 0, size);
+ }
+ if (lastIsDirectory && keepSeparator) {
+ return new String(array, 0, size); // keep trailing separator
+ }
+ return new String(array, 0, size - 1); // lose trailing separator
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Concatenates a filename to a base path using normal command line style rules.
+ * ..
is handled.
+ * pathToAdd
is absolute (has an absolute prefix), then
+ * it will be normalized and returned.
+ * Otherwise, the paths will be joined, normalized and returned.
+ *
+ * /foo/ + bar --> /foo/bar
+ * /foo + bar --> /foo/bar
+ * /foo + /bar --> /bar
+ * /foo + C:/bar --> C:/bar
+ * /foo + C:bar --> C:bar (*)
+ * /foo/a/ + ../bar --> foo/bar
+ * /foo/ + ../../bar --> null
+ * /foo/ + /bar --> /bar
+ * /foo/.. + /bar --> /bar
+ * /foo + bar/c.txt --> /foo/bar/c.txt
+ * /foo/c.txt + bar --> /foo/c.txt/bar (!)
+ *
+ * (*) Note that the Windows relative drive prefix is unreliable when
+ * used with this method.
+ * (!) Note that the first parameter must be a path. If it ends with a name, then
+ * the name will be built into the concatenated path. If this might be a problem,
+ * use {@link #getFullPath(String)} on the base path argument.
+ *
+ * @param basePath the base path to attach to, always treated as a path
+ * @param fullFilenameToAdd the filename (or path) to attach to the base
+ * @return the concatenated path, or null if invalid
+ */
+ public static String concat(String basePath, String fullFilenameToAdd) {
+ int prefix = getPrefixLength(fullFilenameToAdd);
+ if (prefix < 0) {
+ return null;
+ }
+ if (prefix > 0) {
+ return normalize(fullFilenameToAdd);
+ }
+ if (basePath == null) {
+ return null;
+ }
+ int len = basePath.length();
+ if (len == 0) {
+ return normalize(fullFilenameToAdd);
+ }
+ char ch = basePath.charAt(len - 1);
+ if (isSeparator(ch)) {
+ return normalize(basePath + fullFilenameToAdd);
+ } else {
+ return normalize(basePath + '/' + fullFilenameToAdd);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts all separators to the Unix separator of forward slash.
+ *
+ * @param path the path to be changed, null ignored
+ * @return the updated path
+ */
+ public static String separatorsToUnix(String path) {
+ if (path == null || path.indexOf(WINDOWS_SEPARATOR) == -1) {
+ return path;
+ }
+ return path.replace(WINDOWS_SEPARATOR, UNIX_SEPARATOR);
+ }
+
+ /**
+ * Converts all separators to the Windows separator of backslash.
+ *
+ * @param path the path to be changed, null ignored
+ * @return the updated path
+ */
+ public static String separatorsToWindows(String path) {
+ if (path == null || path.indexOf(UNIX_SEPARATOR) == -1) {
+ return path;
+ }
+ return path.replace(UNIX_SEPARATOR, WINDOWS_SEPARATOR);
+ }
+
+ /**
+ * Converts all separators to the system separator.
+ *
+ * @param path the path to be changed, null ignored
+ * @return the updated path
+ */
+ public static String separatorsToSystem(String path) {
+ if (path == null) {
+ return null;
+ }
+ if (isSystemWindows()) {
+ return separatorsToWindows(path);
+ } else {
+ return separatorsToUnix(path);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the length of the filename prefix, such as C:/
or ~/
.
+ *
+ * Windows:
+ * a\b\c.txt --> "" --> relative
+ * \a\b\c.txt --> "\" --> current drive absolute
+ * C:a\b\c.txt --> "C:" --> drive relative
+ * C:\a\b\c.txt --> "C:\" --> absolute
+ * \\server\a\b\c.txt --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt --> "" --> relative
+ * /a/b/c.txt --> "/" --> absolute
+ * ~/a/b/c.txt --> "~/" --> current user
+ * ~ --> "~/" --> current user (slash added)
+ * ~user/a/b/c.txt --> "~user/" --> named user
+ * ~user --> "~user/" --> named user (slash added)
+ *
+ * C:/
+ * or ~/
.
+ *
+ * Windows:
+ * a\b\c.txt --> "" --> relative
+ * \a\b\c.txt --> "\" --> current drive absolute
+ * C:a\b\c.txt --> "C:" --> drive relative
+ * C:\a\b\c.txt --> "C:\" --> absolute
+ * \\server\a\b\c.txt --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt --> "" --> relative
+ * /a/b/c.txt --> "/" --> absolute
+ * ~/a/b/c.txt --> "~/" --> current user
+ * ~ --> "~/" --> current user (slash added)
+ * ~user/a/b/c.txt --> "~user/" --> named user
+ * ~user --> "~user/" --> named user (slash added)
+ *
+ *
+ * C:\a\b\c.txt --> a\b\
+ * ~/a/b/c.txt --> a/b/
+ * a.txt --> ""
+ * a/b/c --> a/b/
+ * a/b/c/ --> a/b/c/
+ *
+ *
+ * C:\a\b\c.txt --> a\b
+ * ~/a/b/c.txt --> a/b
+ * a.txt --> ""
+ * a/b/c --> a/b
+ * a/b/c/ --> a/b/c
+ *
+ *
+ * C:\a\b\c.txt --> C:\a\b\
+ * ~/a/b/c.txt --> ~/a/b/
+ * a.txt --> ""
+ * a/b/c --> a/b/
+ * a/b/c/ --> a/b/c/
+ * C: --> C:
+ * C:\ --> C:\
+ * ~ --> ~/
+ * ~/ --> ~/
+ * ~user --> ~user/
+ * ~user/ --> ~user/
+ *
+ *
+ * C:\a\b\c.txt --> C:\a\b
+ * ~/a/b/c.txt --> ~/a/b
+ * a.txt --> ""
+ * a/b/c --> a/b
+ * a/b/c/ --> a/b/c
+ * C: --> C:
+ * C:\ --> C:\
+ * ~ --> ~
+ * ~/ --> ~
+ * ~user --> ~user
+ * ~user/ --> ~user
+ *
+ *
+ * a/b/c.txt --> c.txt
+ * a.txt --> a.txt
+ * a/b/c --> c
+ * a/b/c/ --> ""
+ *
+ *
+ * a/b/c.txt --> c
+ * a.txt --> a
+ * a/b/c --> c
+ * a/b/c/ --> ""
+ *
+ *
+ * foo.txt --> "txt"
+ * a/b/c.jpg --> "jpg"
+ * a/b.txt/c --> ""
+ * a/b/c --> ""
+ *
+ *
+ * foo.txt --> foo
+ * a\b\c.jpg --> a\b\c
+ * a\b\c --> a\b\c
+ * a.b\c --> a.b\c
+ *
+ *
+ * wildcardMatch("c.txt", "*.txt") --> true
+ * wildcardMatch("c.txt", "*.jpg") --> false
+ * wildcardMatch("a/b/c.txt", "a/b/*") --> true
+ * wildcardMatch("c.txt", "*.???") --> true
+ * wildcardMatch("c.txt", "*.????") --> false
+ *
+ *
+ * @param filename the filename to match on
+ * @param wildcardMatcher the wildcard string to match against
+ * @return true if the filename matches the wilcard string
+ * @see IOCase#SENSITIVE
+ */
+ public static boolean wildcardMatch(String filename, String wildcardMatcher) {
+ return wildcardMatch(filename, wildcardMatcher, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Checks a filename to see if it matches the specified wildcard matcher
+ * using the case rules of the system.
+ *
+ * wildcardMatch("c.txt", "*.txt") --> true
+ * wildcardMatch("c.txt", "*.jpg") --> false
+ * wildcardMatch("a/b/c.txt", "a/b/*") --> true
+ * wildcardMatch("c.txt", "*.???") --> true
+ * wildcardMatch("c.txt", "*.????") --> false
+ *
+ *
+ * @param filename the filename to match on
+ * @param wildcardMatcher the wildcard string to match against
+ * @return true if the filename matches the wilcard string
+ * @see IOCase#SYSTEM
+ */
+ public static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher) {
+ return wildcardMatch(filename, wildcardMatcher, IOCase.SYSTEM);
+ }
+
+ /**
+ * Checks a filename to see if it matches the specified wildcard matcher
+ * allowing control over case-sensitivity.
+ * check
methods in this
- * class to compare filenames.
- *
- * @author Stephen Colebourne
- * @version $Id: IOCase.java 606345 2007-12-21 23:43:01Z ggregory $
- * @since Commons IO 1.3
- */
-public final class IOCase implements Serializable {
-
- /**
- * The constant for case sensitive regardless of operating system.
- */
- public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
-
- /**
- * The constant for case insensitive regardless of operating system.
- */
- public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
-
- /**
- * The constant for case sensitivity determined by the current operating system.
- * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
- * check
methods in this
+ * class to compare filenames.
+ *
+ * @author Stephen Colebourne
+ * @version $Id: IOCase.java 606345 2007-12-21 23:43:01Z ggregory $
+ * @since Commons IO 1.3
+ */
+public final class IOCase implements Serializable {
+
+ /**
+ * The constant for case sensitive regardless of operating system.
+ */
+ public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
+
+ /**
+ * The constant for case insensitive regardless of operating system.
+ */
+ public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
+
+ /**
+ * The constant for case sensitivity determined by the current operating system.
+ * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
+ * cause
is not used in this instance's
- * message.
- * null
value is allowed.
- */
- public IOExceptionWithCause(String message, Throwable cause) {
- super(message);
- this.initCause(cause);
- }
-
- /**
- * Constructs a new instance with the given cause.
- * cause==null ? null : cause.toString()
, which by default contains the class
- * and message of cause
. This constructor is useful for call sites that just wrap another throwable.
- * null
value is allowed.
- */
- public IOExceptionWithCause(Throwable cause) {
- super(cause == null ? null : cause.toString());
- this.initCause(cause);
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.IOException;
+
+/**
+ * Subclasses IOException with the {@link Throwable} constructors missing before Java 6. If you are using Java 6,
+ * consider this class deprecated and use {@link IOException}.
+ *
+ * @author Apache Commons IO
+ * @version $Id$
+ * @since Commons IO 1.4
+ */
+public class IOExceptionWithCause extends IOException {
+
+ /**
+ * Defines the serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new instance with the given message and cause.
+ * cause
is not used in this instance's
+ * message.
+ * null
value is allowed.
+ */
+ public IOExceptionWithCause(String message, Throwable cause) {
+ super(message);
+ this.initCause(cause);
+ }
+
+ /**
+ * Constructs a new instance with the given cause.
+ * cause==null ? null : cause.toString()
, which by default contains the class
+ * and message of cause
. This constructor is useful for call sites that just wrap another throwable.
+ * null
value is allowed.
+ */
+ public IOExceptionWithCause(Throwable cause) {
+ super(cause == null ? null : cause.toString());
+ this.initCause(cause);
+ }
+
+}
diff --git a/src/org/apache/commons/io/IOUtils.java b/src/org/apache/commons/io/IOUtils.java
index 1f91e25627a2fc56147040d6ab233e68ea644004..dfbd465f7ecf941468251991f484bc047c54c87e 100644
--- a/src/org/apache/commons/io/IOUtils.java
+++ b/src/org/apache/commons/io/IOUtils.java
@@ -1,1274 +1,1274 @@
-/*
- * 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.commons.io;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.commons.io.output.ByteArrayOutputStream;
-
-/**
- * General IO stream manipulation utilities.
- *
- *
- * BufferedInputStream
- * or BufferedReader
. The default buffer size of 4K has been shown
- * to be efficient in tests.
- * Reader
.
- * Writer
.
- * InputStream
.
- * OutputStream
.
- * InputStream
as a byte[]
.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from
- * @return the requested byte array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- */
- public static byte[] toByteArray(InputStream input) throws IOException {
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- copy(input, output);
- return output.toByteArray();
- }
-
- /**
- * Get the contents of a Reader
as a byte[]
- * using the default character encoding of the platform.
- * BufferedReader
.
- *
- * @param input the Reader
to read from
- * @return the requested byte array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- */
- public static byte[] toByteArray(Reader input) throws IOException {
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- copy(input, output);
- return output.toByteArray();
- }
-
- /**
- * Get the contents of a Reader
as a byte[]
- * using the specified character encoding.
- * BufferedReader
.
- *
- * @param input the Reader
to read from
- * @param encoding the encoding to use, null means platform default
- * @return the requested byte array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static byte[] toByteArray(Reader input, String encoding)
- throws IOException {
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- copy(input, output, encoding);
- return output.toByteArray();
- }
-
- /**
- * Get the contents of a String
as a byte[]
- * using the default character encoding of the platform.
- * String
to convert
- * @return the requested byte array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs (never occurs)
- * @deprecated Use {@link String#getBytes()}
- */
- public static byte[] toByteArray(String input) throws IOException {
- return input.getBytes();
- }
-
- // read char[]
- //-----------------------------------------------------------------------
- /**
- * Get the contents of an InputStream
as a character array
- * using the default character encoding of the platform.
- * BufferedInputStream
.
- *
- * @param is the InputStream
to read from
- * @return the requested character array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static char[] toCharArray(InputStream is) throws IOException {
- CharArrayWriter output = new CharArrayWriter();
- copy(is, output);
- return output.toCharArray();
- }
-
- /**
- * Get the contents of an InputStream
as a character array
- * using the specified character encoding.
- * BufferedInputStream
.
- *
- * @param is the InputStream
to read from
- * @param encoding the encoding to use, null means platform default
- * @return the requested character array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static char[] toCharArray(InputStream is, String encoding)
- throws IOException {
- CharArrayWriter output = new CharArrayWriter();
- copy(is, output, encoding);
- return output.toCharArray();
- }
-
- /**
- * Get the contents of a Reader
as a character array.
- * BufferedReader
.
- *
- * @param input the Reader
to read from
- * @return the requested character array
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static char[] toCharArray(Reader input) throws IOException {
- CharArrayWriter sw = new CharArrayWriter();
- copy(input, sw);
- return sw.toCharArray();
- }
-
- // read toString
- //-----------------------------------------------------------------------
- /**
- * Get the contents of an InputStream
as a String
- * using the default character encoding of the platform.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from
- * @return the requested String
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- */
- public static String toString(InputStream input) throws IOException {
- StringWriter sw = new StringWriter();
- copy(input, sw);
- return sw.toString();
- }
-
- /**
- * Get the contents of an InputStream
as a String
- * using the specified character encoding.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from
- * @param encoding the encoding to use, null means platform default
- * @return the requested String
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- */
- public static String toString(InputStream input, String encoding)
- throws IOException {
- StringWriter sw = new StringWriter();
- copy(input, sw, encoding);
- return sw.toString();
- }
-
- /**
- * Get the contents of a Reader
as a String.
- * BufferedReader
.
- *
- * @param input the Reader
to read from
- * @return the requested String
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- */
- public static String toString(Reader input) throws IOException {
- StringWriter sw = new StringWriter();
- copy(input, sw);
- return sw.toString();
- }
-
- /**
- * Get the contents of a byte[]
as a String
- * using the default character encoding of the platform.
- *
- * @param input the byte array to read from
- * @return the requested String
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs (never occurs)
- * @deprecated Use {@link String#String(byte[])}
- */
- public static String toString(byte[] input) throws IOException {
- return new String(input);
- }
-
- /**
- * Get the contents of a byte[]
as a String
- * using the specified character encoding.
- * InputStream
as a list of Strings,
- * one entry per line, using the default character encoding of the platform.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from, not null
- * @return the list of Strings, never null
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static List readLines(InputStream input) throws IOException {
- InputStreamReader reader = new InputStreamReader(input);
- return readLines(reader);
- }
-
- /**
- * Get the contents of an InputStream
as a list of Strings,
- * one entry per line, using the specified character encoding.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from, not null
- * @param encoding the encoding to use, null means platform default
- * @return the list of Strings, never null
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static List readLines(InputStream input, String encoding) throws IOException {
- if (encoding == null) {
- return readLines(input);
- } else {
- InputStreamReader reader = new InputStreamReader(input, encoding);
- return readLines(reader);
- }
- }
-
- /**
- * Get the contents of a Reader
as a list of Strings,
- * one entry per line.
- * BufferedReader
.
- *
- * @param input the Reader
to read from, not null
- * @return the list of Strings, never null
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static List readLines(Reader input) throws IOException {
- BufferedReader reader = new BufferedReader(input);
- List list = new ArrayList();
- String line = reader.readLine();
- while (line != null) {
- list.add(line);
- line = reader.readLine();
- }
- return list;
- }
-
- // lineIterator
- //-----------------------------------------------------------------------
- /**
- * Return an Iterator for the lines in a Reader
.
- * LineIterator
holds a reference to the open
- * Reader
specified here. When you have finished with the
- * iterator you should close the reader to free internal resources.
- * This can be done by closing the reader directly, or by calling
- * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
- *
- * try {
- * LineIterator it = IOUtils.lineIterator(reader);
- * while (it.hasNext()) {
- * String line = it.nextLine();
- * /// do something with line
- * }
- * } finally {
- * IOUtils.closeQuietly(reader);
- * }
- *
- *
- * @param reader the Reader
to read from, not null
- * @return an Iterator of the lines in the reader, never null
- * @throws IllegalArgumentException if the reader is null
- * @since Commons IO 1.2
- */
- public static LineIterator lineIterator(Reader reader) {
- return new LineIterator(reader);
- }
-
- /**
- * Return an Iterator for the lines in an InputStream
, using
- * the character encoding specified (or default encoding if null).
- * LineIterator
holds a reference to the open
- * InputStream
specified here. When you have finished with
- * the iterator you should close the stream to free internal resources.
- * This can be done by closing the stream directly, or by calling
- * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
- *
- * try {
- * LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
- * while (it.hasNext()) {
- * String line = it.nextLine();
- * /// do something with line
- * }
- * } finally {
- * IOUtils.closeQuietly(stream);
- * }
- *
- *
- * @param input the InputStream
to read from, not null
- * @param encoding the encoding to use, null means platform default
- * @return an Iterator of the lines in the reader, never null
- * @throws IllegalArgumentException if the input is null
- * @throws IOException if an I/O error occurs, such as if the encoding is invalid
- * @since Commons IO 1.2
- */
- public static LineIterator lineIterator(InputStream input, String encoding)
- throws IOException {
- Reader reader = null;
- if (encoding == null) {
- reader = new InputStreamReader(input);
- } else {
- reader = new InputStreamReader(input, encoding);
- }
- return new LineIterator(reader);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Convert the specified string to an input stream, encoded as bytes
- * using the default character encoding of the platform.
- *
- * @param input the string to convert
- * @return an input stream
- * @since Commons IO 1.1
- */
- public static InputStream toInputStream(String input) {
- byte[] bytes = input.getBytes();
- return new ByteArrayInputStream(bytes);
- }
-
- /**
- * Convert the specified string to an input stream, encoded as bytes
- * using the specified character encoding.
- * byte[]
to an OutputStream
.
- *
- * @param data the byte array to write, do not modify during output,
- * null ignored
- * @param output the OutputStream
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(byte[] data, OutputStream output)
- throws IOException {
- if (data != null) {
- output.write(data);
- }
- }
-
- /**
- * Writes bytes from a byte[]
to chars on a Writer
- * using the default character encoding of the platform.
- * Writer
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(byte[] data, Writer output) throws IOException {
- if (data != null) {
- output.write(new String(data));
- }
- }
-
- /**
- * Writes bytes from a byte[]
to chars on a Writer
- * using the specified character encoding.
- * Writer
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(byte[] data, Writer output, String encoding)
- throws IOException {
- if (data != null) {
- if (encoding == null) {
- write(data, output);
- } else {
- output.write(new String(data, encoding));
- }
- }
- }
-
- // write char[]
- //-----------------------------------------------------------------------
- /**
- * Writes chars from a char[]
to a Writer
- * using the default character encoding of the platform.
- *
- * @param data the char array to write, do not modify during output,
- * null ignored
- * @param output the Writer
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(char[] data, Writer output) throws IOException {
- if (data != null) {
- output.write(data);
- }
- }
-
- /**
- * Writes chars from a char[]
to bytes on an
- * OutputStream
.
- * OutputStream
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(char[] data, OutputStream output)
- throws IOException {
- if (data != null) {
- output.write(new String(data).getBytes());
- }
- }
-
- /**
- * Writes chars from a char[]
to bytes on an
- * OutputStream
using the specified character encoding.
- * OutputStream
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(char[] data, OutputStream output, String encoding)
- throws IOException {
- if (data != null) {
- if (encoding == null) {
- write(data, output);
- } else {
- output.write(new String(data).getBytes(encoding));
- }
- }
- }
-
- // write String
- //-----------------------------------------------------------------------
- /**
- * Writes chars from a String
to a Writer
.
- *
- * @param data the String
to write, null ignored
- * @param output the Writer
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(String data, Writer output) throws IOException {
- if (data != null) {
- output.write(data);
- }
- }
-
- /**
- * Writes chars from a String
to bytes on an
- * OutputStream
using the default character encoding of the
- * platform.
- * String
to write, null ignored
- * @param output the OutputStream
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(String data, OutputStream output)
- throws IOException {
- if (data != null) {
- output.write(data.getBytes());
- }
- }
-
- /**
- * Writes chars from a String
to bytes on an
- * OutputStream
using the specified character encoding.
- * String
to write, null ignored
- * @param output the OutputStream
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(String data, OutputStream output, String encoding)
- throws IOException {
- if (data != null) {
- if (encoding == null) {
- write(data, output);
- } else {
- output.write(data.getBytes(encoding));
- }
- }
- }
-
- // write StringBuffer
- //-----------------------------------------------------------------------
- /**
- * Writes chars from a StringBuffer
to a Writer
.
- *
- * @param data the StringBuffer
to write, null ignored
- * @param output the Writer
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(StringBuffer data, Writer output)
- throws IOException {
- if (data != null) {
- output.write(data.toString());
- }
- }
-
- /**
- * Writes chars from a StringBuffer
to bytes on an
- * OutputStream
using the default character encoding of the
- * platform.
- * StringBuffer
to write, null ignored
- * @param output the OutputStream
to write to
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(StringBuffer data, OutputStream output)
- throws IOException {
- if (data != null) {
- output.write(data.toString().getBytes());
- }
- }
-
- /**
- * Writes chars from a StringBuffer
to bytes on an
- * OutputStream
using the specified character encoding.
- * StringBuffer
to write, null ignored
- * @param output the OutputStream
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void write(StringBuffer data, OutputStream output,
- String encoding) throws IOException {
- if (data != null) {
- if (encoding == null) {
- write(data, output);
- } else {
- output.write(data.toString().getBytes(encoding));
- }
- }
- }
-
- // writeLines
- //-----------------------------------------------------------------------
- /**
- * Writes the toString()
value of each item in a collection to
- * an OutputStream
line by line, using the default character
- * encoding of the platform and the specified line ending.
- *
- * @param lines the lines to write, null entries produce blank lines
- * @param lineEnding the line separator to use, null is system default
- * @param output the OutputStream
to write to, not null, not closed
- * @throws NullPointerException if the output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void writeLines(Collection lines, String lineEnding,
- OutputStream output) throws IOException {
- if (lines == null) {
- return;
- }
- if (lineEnding == null) {
- lineEnding = LINE_SEPARATOR;
- }
- for (Iterator it = lines.iterator(); it.hasNext(); ) {
- Object line = it.next();
- if (line != null) {
- output.write(line.toString().getBytes());
- }
- output.write(lineEnding.getBytes());
- }
- }
-
- /**
- * Writes the toString()
value of each item in a collection to
- * an OutputStream
line by line, using the specified character
- * encoding and the specified line ending.
- * OutputStream
to write to, not null, not closed
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if the output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void writeLines(Collection lines, String lineEnding,
- OutputStream output, String encoding) throws IOException {
- if (encoding == null) {
- writeLines(lines, lineEnding, output);
- } else {
- if (lines == null) {
- return;
- }
- if (lineEnding == null) {
- lineEnding = LINE_SEPARATOR;
- }
- for (Iterator it = lines.iterator(); it.hasNext(); ) {
- Object line = it.next();
- if (line != null) {
- output.write(line.toString().getBytes(encoding));
- }
- output.write(lineEnding.getBytes(encoding));
- }
- }
- }
-
- /**
- * Writes the toString()
value of each item in a collection to
- * a Writer
line by line, using the specified line ending.
- *
- * @param lines the lines to write, null entries produce blank lines
- * @param lineEnding the line separator to use, null is system default
- * @param writer the Writer
to write to, not null, not closed
- * @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void writeLines(Collection lines, String lineEnding,
- Writer writer) throws IOException {
- if (lines == null) {
- return;
- }
- if (lineEnding == null) {
- lineEnding = LINE_SEPARATOR;
- }
- for (Iterator it = lines.iterator(); it.hasNext(); ) {
- Object line = it.next();
- if (line != null) {
- writer.write(line.toString());
- }
- writer.write(lineEnding);
- }
- }
-
- // copy from InputStream
- //-----------------------------------------------------------------------
- /**
- * Copy bytes from an InputStream
to an
- * OutputStream
.
- * BufferedInputStream
.
- * -1
after the copy has completed since the correct
- * number of bytes cannot be returned as an int. For large streams
- * use the copyLarge(InputStream, OutputStream)
method.
- *
- * @param input the InputStream
to read from
- * @param output the OutputStream
to write to
- * @return the number of bytes copied
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @throws ArithmeticException if the byte count is too large
- * @since Commons IO 1.1
- */
- public static int copy(InputStream input, OutputStream output) throws IOException {
- long count = copyLarge(input, output);
- if (count > Integer.MAX_VALUE) {
- return -1;
- }
- return (int) count;
- }
-
- /**
- * Copy bytes from a large (over 2GB) InputStream
to an
- * OutputStream
.
- * BufferedInputStream
.
- *
- * @param input the InputStream
to read from
- * @param output the OutputStream
to write to
- * @return the number of bytes copied
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.3
- */
- public static long copyLarge(InputStream input, OutputStream output)
- throws IOException {
- byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- long count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- /**
- * Copy bytes from an InputStream
to chars on a
- * Writer
using the default character encoding of the platform.
- * BufferedInputStream
.
- * InputStream
to read from
- * @param output the Writer
to write to
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void copy(InputStream input, Writer output)
- throws IOException {
- InputStreamReader in = new InputStreamReader(input);
- copy(in, output);
- }
-
- /**
- * Copy bytes from an InputStream
to chars on a
- * Writer
using the specified character encoding.
- * BufferedInputStream
.
- * InputStream
to read from
- * @param output the Writer
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void copy(InputStream input, Writer output, String encoding)
- throws IOException {
- if (encoding == null) {
- copy(input, output);
- } else {
- InputStreamReader in = new InputStreamReader(input, encoding);
- copy(in, output);
- }
- }
-
- // copy from Reader
- //-----------------------------------------------------------------------
- /**
- * Copy chars from a Reader
to a Writer
.
- * BufferedReader
.
- * -1
after the copy has completed since the correct
- * number of chars cannot be returned as an int. For large streams
- * use the copyLarge(Reader, Writer)
method.
- *
- * @param input the Reader
to read from
- * @param output the Writer
to write to
- * @return the number of characters copied
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @throws ArithmeticException if the character count is too large
- * @since Commons IO 1.1
- */
- public static int copy(Reader input, Writer output) throws IOException {
- long count = copyLarge(input, output);
- if (count > Integer.MAX_VALUE) {
- return -1;
- }
- return (int) count;
- }
-
- /**
- * Copy chars from a large (over 2GB) Reader
to a Writer
.
- * BufferedReader
.
- *
- * @param input the Reader
to read from
- * @param output the Writer
to write to
- * @return the number of characters copied
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.3
- */
- public static long copyLarge(Reader input, Writer output) throws IOException {
- char[] buffer = new char[DEFAULT_BUFFER_SIZE];
- long count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- /**
- * Copy chars from a Reader
to bytes on an
- * OutputStream
using the default character encoding of the
- * platform, and calling flush.
- * BufferedReader
.
- * Reader
to read from
- * @param output the OutputStream
to write to
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void copy(Reader input, OutputStream output)
- throws IOException {
- OutputStreamWriter out = new OutputStreamWriter(output);
- copy(input, out);
- // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
- // have to flush here.
- out.flush();
- }
-
- /**
- * Copy chars from a Reader
to bytes on an
- * OutputStream
using the specified character encoding, and
- * calling flush.
- * BufferedReader
.
- * Reader
to read from
- * @param output the OutputStream
to write to
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if the input or output is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static void copy(Reader input, OutputStream output, String encoding)
- throws IOException {
- if (encoding == null) {
- copy(input, output);
- } else {
- OutputStreamWriter out = new OutputStreamWriter(output, encoding);
- copy(input, out);
- // XXX Unless anyone is planning on rewriting OutputStreamWriter,
- // we have to flush here.
- out.flush();
- }
- }
-
- // content equals
- //-----------------------------------------------------------------------
- /**
- * Compare the contents of two Streams to determine if they are equal or
- * not.
- * BufferedInputStream
if they are not already buffered.
- *
- * @param input1 the first stream
- * @param input2 the second stream
- * @return true if the content of the streams are equal or they both don't
- * exist, false otherwise
- * @throws NullPointerException if either input is null
- * @throws IOException if an I/O error occurs
- */
- public static boolean contentEquals(InputStream input1, InputStream input2)
- throws IOException {
- if (!(input1 instanceof BufferedInputStream)) {
- input1 = new BufferedInputStream(input1);
- }
- if (!(input2 instanceof BufferedInputStream)) {
- input2 = new BufferedInputStream(input2);
- }
-
- int ch = input1.read();
- while (-1 != ch) {
- int ch2 = input2.read();
- if (ch != ch2) {
- return false;
- }
- ch = input1.read();
- }
-
- int ch2 = input2.read();
- return (ch2 == -1);
- }
-
- /**
- * Compare the contents of two Readers to determine if they are equal or
- * not.
- * BufferedReader
if they are not already buffered.
- *
- * @param input1 the first reader
- * @param input2 the second reader
- * @return true if the content of the readers are equal or they both don't
- * exist, false otherwise
- * @throws NullPointerException if either input is null
- * @throws IOException if an I/O error occurs
- * @since Commons IO 1.1
- */
- public static boolean contentEquals(Reader input1, Reader input2)
- throws IOException {
- if (!(input1 instanceof BufferedReader)) {
- input1 = new BufferedReader(input1);
- }
- if (!(input2 instanceof BufferedReader)) {
- input2 = new BufferedReader(input2);
- }
-
- int ch = input1.read();
- while (-1 != ch) {
- int ch2 = input2.read();
- if (ch != ch2) {
- return false;
- }
- ch = input1.read();
- }
-
- int ch2 = input2.read();
- return (ch2 == -1);
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+
+/**
+ * General IO stream manipulation utilities.
+ *
+ *
+ * BufferedInputStream
+ * or BufferedReader
. The default buffer size of 4K has been shown
+ * to be efficient in tests.
+ * Reader
.
+ * Writer
.
+ * InputStream
.
+ * OutputStream
.
+ * InputStream
as a byte[]
.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @return the requested byte array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static byte[] toByteArray(InputStream input) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ copy(input, output);
+ return output.toByteArray();
+ }
+
+ /**
+ * Get the contents of a Reader
as a byte[]
+ * using the default character encoding of the platform.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @return the requested byte array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static byte[] toByteArray(Reader input) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ copy(input, output);
+ return output.toByteArray();
+ }
+
+ /**
+ * Get the contents of a Reader
as a byte[]
+ * using the specified character encoding.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @param encoding the encoding to use, null means platform default
+ * @return the requested byte array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static byte[] toByteArray(Reader input, String encoding)
+ throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ copy(input, output, encoding);
+ return output.toByteArray();
+ }
+
+ /**
+ * Get the contents of a String
as a byte[]
+ * using the default character encoding of the platform.
+ * String
to convert
+ * @return the requested byte array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs (never occurs)
+ * @deprecated Use {@link String#getBytes()}
+ */
+ public static byte[] toByteArray(String input) throws IOException {
+ return input.getBytes();
+ }
+
+ // read char[]
+ //-----------------------------------------------------------------------
+ /**
+ * Get the contents of an InputStream
as a character array
+ * using the default character encoding of the platform.
+ * BufferedInputStream
.
+ *
+ * @param is the InputStream
to read from
+ * @return the requested character array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static char[] toCharArray(InputStream is) throws IOException {
+ CharArrayWriter output = new CharArrayWriter();
+ copy(is, output);
+ return output.toCharArray();
+ }
+
+ /**
+ * Get the contents of an InputStream
as a character array
+ * using the specified character encoding.
+ * BufferedInputStream
.
+ *
+ * @param is the InputStream
to read from
+ * @param encoding the encoding to use, null means platform default
+ * @return the requested character array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static char[] toCharArray(InputStream is, String encoding)
+ throws IOException {
+ CharArrayWriter output = new CharArrayWriter();
+ copy(is, output, encoding);
+ return output.toCharArray();
+ }
+
+ /**
+ * Get the contents of a Reader
as a character array.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @return the requested character array
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static char[] toCharArray(Reader input) throws IOException {
+ CharArrayWriter sw = new CharArrayWriter();
+ copy(input, sw);
+ return sw.toCharArray();
+ }
+
+ // read toString
+ //-----------------------------------------------------------------------
+ /**
+ * Get the contents of an InputStream
as a String
+ * using the default character encoding of the platform.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static String toString(InputStream input) throws IOException {
+ StringWriter sw = new StringWriter();
+ copy(input, sw);
+ return sw.toString();
+ }
+
+ /**
+ * Get the contents of an InputStream
as a String
+ * using the specified character encoding.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @param encoding the encoding to use, null means platform default
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static String toString(InputStream input, String encoding)
+ throws IOException {
+ StringWriter sw = new StringWriter();
+ copy(input, sw, encoding);
+ return sw.toString();
+ }
+
+ /**
+ * Get the contents of a Reader
as a String.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static String toString(Reader input) throws IOException {
+ StringWriter sw = new StringWriter();
+ copy(input, sw);
+ return sw.toString();
+ }
+
+ /**
+ * Get the contents of a byte[]
as a String
+ * using the default character encoding of the platform.
+ *
+ * @param input the byte array to read from
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs (never occurs)
+ * @deprecated Use {@link String#String(byte[])}
+ */
+ public static String toString(byte[] input) throws IOException {
+ return new String(input);
+ }
+
+ /**
+ * Get the contents of a byte[]
as a String
+ * using the specified character encoding.
+ * InputStream
as a list of Strings,
+ * one entry per line, using the default character encoding of the platform.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from, not null
+ * @return the list of Strings, never null
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static List readLines(InputStream input) throws IOException {
+ InputStreamReader reader = new InputStreamReader(input);
+ return readLines(reader);
+ }
+
+ /**
+ * Get the contents of an InputStream
as a list of Strings,
+ * one entry per line, using the specified character encoding.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from, not null
+ * @param encoding the encoding to use, null means platform default
+ * @return the list of Strings, never null
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static List readLines(InputStream input, String encoding) throws IOException {
+ if (encoding == null) {
+ return readLines(input);
+ } else {
+ InputStreamReader reader = new InputStreamReader(input, encoding);
+ return readLines(reader);
+ }
+ }
+
+ /**
+ * Get the contents of a Reader
as a list of Strings,
+ * one entry per line.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from, not null
+ * @return the list of Strings, never null
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static List readLines(Reader input) throws IOException {
+ BufferedReader reader = new BufferedReader(input);
+ List list = new ArrayList();
+ String line = reader.readLine();
+ while (line != null) {
+ list.add(line);
+ line = reader.readLine();
+ }
+ return list;
+ }
+
+ // lineIterator
+ //-----------------------------------------------------------------------
+ /**
+ * Return an Iterator for the lines in a Reader
.
+ * LineIterator
holds a reference to the open
+ * Reader
specified here. When you have finished with the
+ * iterator you should close the reader to free internal resources.
+ * This can be done by closing the reader directly, or by calling
+ * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
+ *
+ * try {
+ * LineIterator it = IOUtils.lineIterator(reader);
+ * while (it.hasNext()) {
+ * String line = it.nextLine();
+ * /// do something with line
+ * }
+ * } finally {
+ * IOUtils.closeQuietly(reader);
+ * }
+ *
+ *
+ * @param reader the Reader
to read from, not null
+ * @return an Iterator of the lines in the reader, never null
+ * @throws IllegalArgumentException if the reader is null
+ * @since Commons IO 1.2
+ */
+ public static LineIterator lineIterator(Reader reader) {
+ return new LineIterator(reader);
+ }
+
+ /**
+ * Return an Iterator for the lines in an InputStream
, using
+ * the character encoding specified (or default encoding if null).
+ * LineIterator
holds a reference to the open
+ * InputStream
specified here. When you have finished with
+ * the iterator you should close the stream to free internal resources.
+ * This can be done by closing the stream directly, or by calling
+ * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
+ *
+ * try {
+ * LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
+ * while (it.hasNext()) {
+ * String line = it.nextLine();
+ * /// do something with line
+ * }
+ * } finally {
+ * IOUtils.closeQuietly(stream);
+ * }
+ *
+ *
+ * @param input the InputStream
to read from, not null
+ * @param encoding the encoding to use, null means platform default
+ * @return an Iterator of the lines in the reader, never null
+ * @throws IllegalArgumentException if the input is null
+ * @throws IOException if an I/O error occurs, such as if the encoding is invalid
+ * @since Commons IO 1.2
+ */
+ public static LineIterator lineIterator(InputStream input, String encoding)
+ throws IOException {
+ Reader reader = null;
+ if (encoding == null) {
+ reader = new InputStreamReader(input);
+ } else {
+ reader = new InputStreamReader(input, encoding);
+ }
+ return new LineIterator(reader);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Convert the specified string to an input stream, encoded as bytes
+ * using the default character encoding of the platform.
+ *
+ * @param input the string to convert
+ * @return an input stream
+ * @since Commons IO 1.1
+ */
+ public static InputStream toInputStream(String input) {
+ byte[] bytes = input.getBytes();
+ return new ByteArrayInputStream(bytes);
+ }
+
+ /**
+ * Convert the specified string to an input stream, encoded as bytes
+ * using the specified character encoding.
+ * byte[]
to an OutputStream
.
+ *
+ * @param data the byte array to write, do not modify during output,
+ * null ignored
+ * @param output the OutputStream
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(byte[] data, OutputStream output)
+ throws IOException {
+ if (data != null) {
+ output.write(data);
+ }
+ }
+
+ /**
+ * Writes bytes from a byte[]
to chars on a Writer
+ * using the default character encoding of the platform.
+ * Writer
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(byte[] data, Writer output) throws IOException {
+ if (data != null) {
+ output.write(new String(data));
+ }
+ }
+
+ /**
+ * Writes bytes from a byte[]
to chars on a Writer
+ * using the specified character encoding.
+ * Writer
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(byte[] data, Writer output, String encoding)
+ throws IOException {
+ if (data != null) {
+ if (encoding == null) {
+ write(data, output);
+ } else {
+ output.write(new String(data, encoding));
+ }
+ }
+ }
+
+ // write char[]
+ //-----------------------------------------------------------------------
+ /**
+ * Writes chars from a char[]
to a Writer
+ * using the default character encoding of the platform.
+ *
+ * @param data the char array to write, do not modify during output,
+ * null ignored
+ * @param output the Writer
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(char[] data, Writer output) throws IOException {
+ if (data != null) {
+ output.write(data);
+ }
+ }
+
+ /**
+ * Writes chars from a char[]
to bytes on an
+ * OutputStream
.
+ * OutputStream
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(char[] data, OutputStream output)
+ throws IOException {
+ if (data != null) {
+ output.write(new String(data).getBytes());
+ }
+ }
+
+ /**
+ * Writes chars from a char[]
to bytes on an
+ * OutputStream
using the specified character encoding.
+ * OutputStream
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(char[] data, OutputStream output, String encoding)
+ throws IOException {
+ if (data != null) {
+ if (encoding == null) {
+ write(data, output);
+ } else {
+ output.write(new String(data).getBytes(encoding));
+ }
+ }
+ }
+
+ // write String
+ //-----------------------------------------------------------------------
+ /**
+ * Writes chars from a String
to a Writer
.
+ *
+ * @param data the String
to write, null ignored
+ * @param output the Writer
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(String data, Writer output) throws IOException {
+ if (data != null) {
+ output.write(data);
+ }
+ }
+
+ /**
+ * Writes chars from a String
to bytes on an
+ * OutputStream
using the default character encoding of the
+ * platform.
+ * String
to write, null ignored
+ * @param output the OutputStream
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(String data, OutputStream output)
+ throws IOException {
+ if (data != null) {
+ output.write(data.getBytes());
+ }
+ }
+
+ /**
+ * Writes chars from a String
to bytes on an
+ * OutputStream
using the specified character encoding.
+ * String
to write, null ignored
+ * @param output the OutputStream
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(String data, OutputStream output, String encoding)
+ throws IOException {
+ if (data != null) {
+ if (encoding == null) {
+ write(data, output);
+ } else {
+ output.write(data.getBytes(encoding));
+ }
+ }
+ }
+
+ // write StringBuffer
+ //-----------------------------------------------------------------------
+ /**
+ * Writes chars from a StringBuffer
to a Writer
.
+ *
+ * @param data the StringBuffer
to write, null ignored
+ * @param output the Writer
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(StringBuffer data, Writer output)
+ throws IOException {
+ if (data != null) {
+ output.write(data.toString());
+ }
+ }
+
+ /**
+ * Writes chars from a StringBuffer
to bytes on an
+ * OutputStream
using the default character encoding of the
+ * platform.
+ * StringBuffer
to write, null ignored
+ * @param output the OutputStream
to write to
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(StringBuffer data, OutputStream output)
+ throws IOException {
+ if (data != null) {
+ output.write(data.toString().getBytes());
+ }
+ }
+
+ /**
+ * Writes chars from a StringBuffer
to bytes on an
+ * OutputStream
using the specified character encoding.
+ * StringBuffer
to write, null ignored
+ * @param output the OutputStream
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void write(StringBuffer data, OutputStream output,
+ String encoding) throws IOException {
+ if (data != null) {
+ if (encoding == null) {
+ write(data, output);
+ } else {
+ output.write(data.toString().getBytes(encoding));
+ }
+ }
+ }
+
+ // writeLines
+ //-----------------------------------------------------------------------
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * an OutputStream
line by line, using the default character
+ * encoding of the platform and the specified line ending.
+ *
+ * @param lines the lines to write, null entries produce blank lines
+ * @param lineEnding the line separator to use, null is system default
+ * @param output the OutputStream
to write to, not null, not closed
+ * @throws NullPointerException if the output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void writeLines(Collection lines, String lineEnding,
+ OutputStream output) throws IOException {
+ if (lines == null) {
+ return;
+ }
+ if (lineEnding == null) {
+ lineEnding = LINE_SEPARATOR;
+ }
+ for (Iterator it = lines.iterator(); it.hasNext(); ) {
+ Object line = it.next();
+ if (line != null) {
+ output.write(line.toString().getBytes());
+ }
+ output.write(lineEnding.getBytes());
+ }
+ }
+
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * an OutputStream
line by line, using the specified character
+ * encoding and the specified line ending.
+ * OutputStream
to write to, not null, not closed
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if the output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void writeLines(Collection lines, String lineEnding,
+ OutputStream output, String encoding) throws IOException {
+ if (encoding == null) {
+ writeLines(lines, lineEnding, output);
+ } else {
+ if (lines == null) {
+ return;
+ }
+ if (lineEnding == null) {
+ lineEnding = LINE_SEPARATOR;
+ }
+ for (Iterator it = lines.iterator(); it.hasNext(); ) {
+ Object line = it.next();
+ if (line != null) {
+ output.write(line.toString().getBytes(encoding));
+ }
+ output.write(lineEnding.getBytes(encoding));
+ }
+ }
+ }
+
+ /**
+ * Writes the toString()
value of each item in a collection to
+ * a Writer
line by line, using the specified line ending.
+ *
+ * @param lines the lines to write, null entries produce blank lines
+ * @param lineEnding the line separator to use, null is system default
+ * @param writer the Writer
to write to, not null, not closed
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void writeLines(Collection lines, String lineEnding,
+ Writer writer) throws IOException {
+ if (lines == null) {
+ return;
+ }
+ if (lineEnding == null) {
+ lineEnding = LINE_SEPARATOR;
+ }
+ for (Iterator it = lines.iterator(); it.hasNext(); ) {
+ Object line = it.next();
+ if (line != null) {
+ writer.write(line.toString());
+ }
+ writer.write(lineEnding);
+ }
+ }
+
+ // copy from InputStream
+ //-----------------------------------------------------------------------
+ /**
+ * Copy bytes from an InputStream
to an
+ * OutputStream
.
+ * BufferedInputStream
.
+ * -1
after the copy has completed since the correct
+ * number of bytes cannot be returned as an int. For large streams
+ * use the copyLarge(InputStream, OutputStream)
method.
+ *
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @throws ArithmeticException if the byte count is too large
+ * @since Commons IO 1.1
+ */
+ public static int copy(InputStream input, OutputStream output) throws IOException {
+ long count = copyLarge(input, output);
+ if (count > Integer.MAX_VALUE) {
+ return -1;
+ }
+ return (int) count;
+ }
+
+ /**
+ * Copy bytes from a large (over 2GB) InputStream
to an
+ * OutputStream
.
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.3
+ */
+ public static long copyLarge(InputStream input, OutputStream output)
+ throws IOException {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ long count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
+ * Copy bytes from an InputStream
to chars on a
+ * Writer
using the default character encoding of the platform.
+ * BufferedInputStream
.
+ * InputStream
to read from
+ * @param output the Writer
to write to
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void copy(InputStream input, Writer output)
+ throws IOException {
+ InputStreamReader in = new InputStreamReader(input);
+ copy(in, output);
+ }
+
+ /**
+ * Copy bytes from an InputStream
to chars on a
+ * Writer
using the specified character encoding.
+ * BufferedInputStream
.
+ * InputStream
to read from
+ * @param output the Writer
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void copy(InputStream input, Writer output, String encoding)
+ throws IOException {
+ if (encoding == null) {
+ copy(input, output);
+ } else {
+ InputStreamReader in = new InputStreamReader(input, encoding);
+ copy(in, output);
+ }
+ }
+
+ // copy from Reader
+ //-----------------------------------------------------------------------
+ /**
+ * Copy chars from a Reader
to a Writer
.
+ * BufferedReader
.
+ * -1
after the copy has completed since the correct
+ * number of chars cannot be returned as an int. For large streams
+ * use the copyLarge(Reader, Writer)
method.
+ *
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @return the number of characters copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @throws ArithmeticException if the character count is too large
+ * @since Commons IO 1.1
+ */
+ public static int copy(Reader input, Writer output) throws IOException {
+ long count = copyLarge(input, output);
+ if (count > Integer.MAX_VALUE) {
+ return -1;
+ }
+ return (int) count;
+ }
+
+ /**
+ * Copy chars from a large (over 2GB) Reader
to a Writer
.
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @return the number of characters copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.3
+ */
+ public static long copyLarge(Reader input, Writer output) throws IOException {
+ char[] buffer = new char[DEFAULT_BUFFER_SIZE];
+ long count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
+ * Copy chars from a Reader
to bytes on an
+ * OutputStream
using the default character encoding of the
+ * platform, and calling flush.
+ * BufferedReader
.
+ * Reader
to read from
+ * @param output the OutputStream
to write to
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void copy(Reader input, OutputStream output)
+ throws IOException {
+ OutputStreamWriter out = new OutputStreamWriter(output);
+ copy(input, out);
+ // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
+ // have to flush here.
+ out.flush();
+ }
+
+ /**
+ * Copy chars from a Reader
to bytes on an
+ * OutputStream
using the specified character encoding, and
+ * calling flush.
+ * BufferedReader
.
+ * Reader
to read from
+ * @param output the OutputStream
to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static void copy(Reader input, OutputStream output, String encoding)
+ throws IOException {
+ if (encoding == null) {
+ copy(input, output);
+ } else {
+ OutputStreamWriter out = new OutputStreamWriter(output, encoding);
+ copy(input, out);
+ // XXX Unless anyone is planning on rewriting OutputStreamWriter,
+ // we have to flush here.
+ out.flush();
+ }
+ }
+
+ // content equals
+ //-----------------------------------------------------------------------
+ /**
+ * Compare the contents of two Streams to determine if they are equal or
+ * not.
+ * BufferedInputStream
if they are not already buffered.
+ *
+ * @param input1 the first stream
+ * @param input2 the second stream
+ * @return true if the content of the streams are equal or they both don't
+ * exist, false otherwise
+ * @throws NullPointerException if either input is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static boolean contentEquals(InputStream input1, InputStream input2)
+ throws IOException {
+ if (!(input1 instanceof BufferedInputStream)) {
+ input1 = new BufferedInputStream(input1);
+ }
+ if (!(input2 instanceof BufferedInputStream)) {
+ input2 = new BufferedInputStream(input2);
+ }
+
+ int ch = input1.read();
+ while (-1 != ch) {
+ int ch2 = input2.read();
+ if (ch != ch2) {
+ return false;
+ }
+ ch = input1.read();
+ }
+
+ int ch2 = input2.read();
+ return (ch2 == -1);
+ }
+
+ /**
+ * Compare the contents of two Readers to determine if they are equal or
+ * not.
+ * BufferedReader
if they are not already buffered.
+ *
+ * @param input1 the first reader
+ * @param input2 the second reader
+ * @return true if the content of the readers are equal or they both don't
+ * exist, false otherwise
+ * @throws NullPointerException if either input is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static boolean contentEquals(Reader input1, Reader input2)
+ throws IOException {
+ if (!(input1 instanceof BufferedReader)) {
+ input1 = new BufferedReader(input1);
+ }
+ if (!(input2 instanceof BufferedReader)) {
+ input2 = new BufferedReader(input2);
+ }
+
+ int ch = input1.read();
+ while (-1 != ch) {
+ int ch2 = input2.read();
+ if (ch != ch2) {
+ return false;
+ }
+ ch = input1.read();
+ }
+
+ int ch2 = input2.read();
+ return (ch2 == -1);
+ }
+
+}
diff --git a/src/org/apache/commons/io/LineIterator.java b/src/org/apache/commons/io/LineIterator.java
index eac47d23a3e82088002d51702f78c3d4c4c5352b..2bec43b9774395fdb28df4e39285f76cc277ced9 100644
--- a/src/org/apache/commons/io/LineIterator.java
+++ b/src/org/apache/commons/io/LineIterator.java
@@ -1,181 +1,181 @@
-/*
- * 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.commons.io;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * An Iterator over the lines in a Reader
.
- * LineIterator
holds a reference to an open Reader
.
- * When you have finished with the iterator you should close the reader
- * to free internal resources. This can be done by closing the reader directly,
- * or by calling the {@link #close()} or {@link #closeQuietly(LineIterator)}
- * method on the iterator.
- *
- * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
- * try {
- * while (it.hasNext()) {
- * String line = it.nextLine();
- * /// do something with line
- * }
- * } finally {
- * LineIterator.closeQuietly(iterator);
- * }
- *
- *
- * @author Niall Pemberton
- * @author Stephen Colebourne
- * @author Sandy McArthur
- * @version $Id: LineIterator.java 437567 2006-08-28 06:39:07Z bayard $
- * @since Commons IO 1.2
- */
-public class LineIterator implements Iterator {
-
- /** The reader that is being read. */
- private final BufferedReader bufferedReader;
- /** The current line. */
- private String cachedLine;
- /** A flag indicating if the iterator has been fully read. */
- private boolean finished = false;
-
- /**
- * Constructs an iterator of the lines for a Reader
.
- *
- * @param reader the Reader
to read from, not null
- * @throws IllegalArgumentException if the reader is null
- */
- public LineIterator(final Reader reader) throws IllegalArgumentException {
- if (reader == null) {
- throw new IllegalArgumentException("Reader must not be null");
- }
- if (reader instanceof BufferedReader) {
- bufferedReader = (BufferedReader) reader;
- } else {
- bufferedReader = new BufferedReader(reader);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Indicates whether the Reader
has more lines.
- * If there is an IOException
then {@link #close()} will
- * be called on this instance.
- *
- * @return true
if the Reader has more lines
- * @throws IllegalStateException if an IO exception occurs
- */
- public boolean hasNext() {
- if (cachedLine != null) {
- return true;
- } else if (finished) {
- return false;
- } else {
- try {
- while (true) {
- String line = bufferedReader.readLine();
- if (line == null) {
- finished = true;
- return false;
- } else if (isValidLine(line)) {
- cachedLine = line;
- return true;
- }
- }
- } catch(IOException ioe) {
- close();
- throw new IllegalStateException(ioe.toString());
- }
- }
- }
-
- /**
- * Overridable method to validate each line that is returned.
- *
- * @param line the line that is to be validated
- * @return true if valid, false to remove from the iterator
- */
- protected boolean isValidLine(String line) {
- return true;
- }
-
- /**
- * Returns the next line in the wrapped Reader
.
- *
- * @return the next line from the input
- * @throws NoSuchElementException if there is no line to return
- */
- public Object next() {
- return nextLine();
- }
-
- /**
- * Returns the next line in the wrapped Reader
.
- *
- * @return the next line from the input
- * @throws NoSuchElementException if there is no line to return
- */
- public String nextLine() {
- if (!hasNext()) {
- throw new NoSuchElementException("No more lines");
- }
- String currentLine = cachedLine;
- cachedLine = null;
- return currentLine;
- }
-
- /**
- * Closes the underlying Reader
quietly.
- * This method is useful if you only want to process the first few
- * lines of a larger file. If you do not close the iterator
- * then the Reader
remains open.
- * This method can safely be called multiple times.
- */
- public void close() {
- finished = true;
- IOUtils.closeQuietly(bufferedReader);
- cachedLine = null;
- }
-
- /**
- * Unsupported.
- *
- * @throws UnsupportedOperationException always
- */
- public void remove() {
- throw new UnsupportedOperationException("Remove unsupported on LineIterator");
- }
-
- //-----------------------------------------------------------------------
- /**
- * Closes the iterator, handling null and ignoring exceptions.
- *
- * @param iterator the iterator to close
- */
- public static void closeQuietly(LineIterator iterator) {
- if (iterator != null) {
- iterator.close();
- }
- }
-
-}
+/*
+ * 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.commons.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An Iterator over the lines in a Reader
.
+ * LineIterator
holds a reference to an open Reader
.
+ * When you have finished with the iterator you should close the reader
+ * to free internal resources. This can be done by closing the reader directly,
+ * or by calling the {@link #close()} or {@link #closeQuietly(LineIterator)}
+ * method on the iterator.
+ *
+ * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
+ * try {
+ * while (it.hasNext()) {
+ * String line = it.nextLine();
+ * /// do something with line
+ * }
+ * } finally {
+ * LineIterator.closeQuietly(iterator);
+ * }
+ *
+ *
+ * @author Niall Pemberton
+ * @author Stephen Colebourne
+ * @author Sandy McArthur
+ * @version $Id: LineIterator.java 437567 2006-08-28 06:39:07Z bayard $
+ * @since Commons IO 1.2
+ */
+public class LineIterator implements Iterator {
+
+ /** The reader that is being read. */
+ private final BufferedReader bufferedReader;
+ /** The current line. */
+ private String cachedLine;
+ /** A flag indicating if the iterator has been fully read. */
+ private boolean finished = false;
+
+ /**
+ * Constructs an iterator of the lines for a Reader
.
+ *
+ * @param reader the Reader
to read from, not null
+ * @throws IllegalArgumentException if the reader is null
+ */
+ public LineIterator(final Reader reader) throws IllegalArgumentException {
+ if (reader == null) {
+ throw new IllegalArgumentException("Reader must not be null");
+ }
+ if (reader instanceof BufferedReader) {
+ bufferedReader = (BufferedReader) reader;
+ } else {
+ bufferedReader = new BufferedReader(reader);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Indicates whether the Reader
has more lines.
+ * If there is an IOException
then {@link #close()} will
+ * be called on this instance.
+ *
+ * @return true
if the Reader has more lines
+ * @throws IllegalStateException if an IO exception occurs
+ */
+ public boolean hasNext() {
+ if (cachedLine != null) {
+ return true;
+ } else if (finished) {
+ return false;
+ } else {
+ try {
+ while (true) {
+ String line = bufferedReader.readLine();
+ if (line == null) {
+ finished = true;
+ return false;
+ } else if (isValidLine(line)) {
+ cachedLine = line;
+ return true;
+ }
+ }
+ } catch(IOException ioe) {
+ close();
+ throw new IllegalStateException(ioe.toString());
+ }
+ }
+ }
+
+ /**
+ * Overridable method to validate each line that is returned.
+ *
+ * @param line the line that is to be validated
+ * @return true if valid, false to remove from the iterator
+ */
+ protected boolean isValidLine(String line) {
+ return true;
+ }
+
+ /**
+ * Returns the next line in the wrapped Reader
.
+ *
+ * @return the next line from the input
+ * @throws NoSuchElementException if there is no line to return
+ */
+ public Object next() {
+ return nextLine();
+ }
+
+ /**
+ * Returns the next line in the wrapped Reader
.
+ *
+ * @return the next line from the input
+ * @throws NoSuchElementException if there is no line to return
+ */
+ public String nextLine() {
+ if (!hasNext()) {
+ throw new NoSuchElementException("No more lines");
+ }
+ String currentLine = cachedLine;
+ cachedLine = null;
+ return currentLine;
+ }
+
+ /**
+ * Closes the underlying Reader
quietly.
+ * This method is useful if you only want to process the first few
+ * lines of a larger file. If you do not close the iterator
+ * then the Reader
remains open.
+ * This method can safely be called multiple times.
+ */
+ public void close() {
+ finished = true;
+ IOUtils.closeQuietly(bufferedReader);
+ cachedLine = null;
+ }
+
+ /**
+ * Unsupported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("Remove unsupported on LineIterator");
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Closes the iterator, handling null and ignoring exceptions.
+ *
+ * @param iterator the iterator to close
+ */
+ public static void closeQuietly(LineIterator iterator) {
+ if (iterator != null) {
+ iterator.close();
+ }
+ }
+
+}
diff --git a/src/org/apache/commons/io/comparator/DefaultFileComparator.java b/src/org/apache/commons/io/comparator/DefaultFileComparator.java
index d36076288c09e28a9d0362d39c183b899877c097..851817d0b46ad28fabb467b6dd25da0be613f8a4 100644
--- a/src/org/apache/commons/io/comparator/DefaultFileComparator.java
+++ b/src/org/apache/commons/io/comparator/DefaultFileComparator.java
@@ -1,68 +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.commons.io.comparator;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Comparator;
-
-/**
- * Compare two files using the default {@link File#compareTo(File)} method.
- *
- * List<File> list = ...
- * Collections.sort(list, DefaultFileComparator.DEFAULT_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, DefaultFileComparator.DEFAULT_REVERSE);
- *
- *
+ * List<File> list = ...
+ * Collections.sort(list, DefaultFileComparator.DEFAULT_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, DefaultFileComparator.DEFAULT_REVERSE);
+ *
+ *
- * List<File> list = ...
- * Collections.sort(list, ExtensionFileComparator.EXTENSION_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, ExtensionFileComparator.EXTENSION_INSENSITIVE_REVERSE);
- *
- *
+ * List<File> list = ...
+ * Collections.sort(list, ExtensionFileComparator.EXTENSION_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, ExtensionFileComparator.EXTENSION_INSENSITIVE_REVERSE);
+ *
+ *
- * List<File> list = ...
- * Collections.sort(list, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
- *
- *
+ * List<File> list = ...
+ * Collections.sort(list, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
+ *
+ *
- * List<File> list = ...
- * Collections.sort(list, NameFileComparator.NAME_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, NameFileComparator.NAME_INSENSITIVE_REVERSE);
- *
- *
+ * List<File> list = ...
+ * Collections.sort(list, NameFileComparator.NAME_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, NameFileComparator.NAME_INSENSITIVE_REVERSE);
+ *
+ *
- * List<File> list = ...
- * Collections.sort(list, PathFileComparator.PATH_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, PathFileComparator.PATH_INSENSITIVE_REVERSE);
- *
- *
+ * List<File> list = ...
+ * Collections.sort(list, PathFileComparator.PATH_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, PathFileComparator.PATH_INSENSITIVE_REVERSE);
+ *
+ *
- * List<File> list = ...
- * Collections.sort(list, LengthFileComparator.LENGTH_COMPARATOR);
- *
- *
- * File[] array = ...
- * Arrays.sort(array, LengthFileComparator.LENGTH_REVERSE);
- *
- * sumDirectoryContents
is true
.
- *
- * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
- * @since Commons IO 1.4
- */
-public class SizeFileComparator implements Comparator, Serializable {
-
- /** Size comparator instance - directories are treated as zero size */
- public static final Comparator SIZE_COMPARATOR = new SizeFileComparator();
-
- /** Reverse size comparator instance - directories are treated as zero size */
- public static final Comparator SIZE_REVERSE = new ReverseComparator(SIZE_COMPARATOR);
-
- /**
- * Size comparator instance which sums the size of a directory's contents
- * using {@link FileUtils#sizeOfDirectory(File)}
- */
- public static final Comparator SIZE_SUMDIR_COMPARATOR = new SizeFileComparator(true);
-
- /**
- * Reverse size comparator instance which sums the size of a directory's contents
- * using {@link FileUtils#sizeOfDirectory(File)}
- */
- public static final Comparator SIZE_SUMDIR_REVERSE = new ReverseComparator(SIZE_SUMDIR_COMPARATOR);
-
- /** Whether the sum of the directory's contents should be calculated. */
- private final boolean sumDirectoryContents;
-
- /**
- * Construct a file size comparator instance (directories treated as zero size).
- */
- public SizeFileComparator() {
- this.sumDirectoryContents = false;
- }
-
- /**
- * Construct a file size comparator instance specifying whether the size of
- * the directory contents should be aggregated.
- * sumDirectoryContents
is true
The size of
- * directories is calculated using {@link FileUtils#sizeOfDirectory(File)}.
- *
- * @param sumDirectoryContents true
if the sum of the directoryies contents
- * should be calculated, otherwise false
if directories should be treated
- * as size zero (see {@link FileUtils#sizeOfDirectory(File)}).
- */
- public SizeFileComparator(boolean sumDirectoryContents) {
- this.sumDirectoryContents = sumDirectoryContents;
- }
-
- /**
- * Compare the length of two files.
- *
- * @param obj1 The first file to compare
- * @param obj2 The second file to compare
- * @return a negative value if the first file's length
- * is less than the second, zero if the lengths are the
- * same and a positive value if the first files length
- * is greater than the second file.
- *
- */
- public int compare(Object obj1, Object obj2) {
- File file1 = (File)obj1;
- File file2 = (File)obj2;
- long size1 = 0;
- if (file1.isDirectory()) {
- size1 = sumDirectoryContents && file1.exists() ? FileUtils.sizeOfDirectory(file1) : 0;
- } else {
- size1 = file1.length();
- }
- long size2 = 0;
- if (file2.isDirectory()) {
- size2 = sumDirectoryContents && file2.exists() ? FileUtils.sizeOfDirectory(file2) : 0;
- } else {
- size2 = file2.length();
- }
- long result = size1 - size2;
- if (result < 0) {
- return -1;
- } else if (result > 0) {
- return 1;
- } else {
- return 0;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.comparator;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.io.FileUtils;
+
+/**
+ * Compare the length/size of two files for order (see
+ * {@link File#length()} and {@link FileUtils#sizeOfDirectory(File)}).
+ *
+ * List<File> list = ...
+ * Collections.sort(list, LengthFileComparator.LENGTH_COMPARATOR);
+ *
+ *
+ * File[] array = ...
+ * Arrays.sort(array, LengthFileComparator.LENGTH_REVERSE);
+ *
+ * sumDirectoryContents
is true
.
+ *
+ * @version $Revision: 609243 $ $Date: 2008-01-06 00:30:42 +0000 (Sun, 06 Jan 2008) $
+ * @since Commons IO 1.4
+ */
+public class SizeFileComparator implements Comparator, Serializable {
+
+ /** Size comparator instance - directories are treated as zero size */
+ public static final Comparator SIZE_COMPARATOR = new SizeFileComparator();
+
+ /** Reverse size comparator instance - directories are treated as zero size */
+ public static final Comparator SIZE_REVERSE = new ReverseComparator(SIZE_COMPARATOR);
+
+ /**
+ * Size comparator instance which sums the size of a directory's contents
+ * using {@link FileUtils#sizeOfDirectory(File)}
+ */
+ public static final Comparator SIZE_SUMDIR_COMPARATOR = new SizeFileComparator(true);
+
+ /**
+ * Reverse size comparator instance which sums the size of a directory's contents
+ * using {@link FileUtils#sizeOfDirectory(File)}
+ */
+ public static final Comparator SIZE_SUMDIR_REVERSE = new ReverseComparator(SIZE_SUMDIR_COMPARATOR);
+
+ /** Whether the sum of the directory's contents should be calculated. */
+ private final boolean sumDirectoryContents;
+
+ /**
+ * Construct a file size comparator instance (directories treated as zero size).
+ */
+ public SizeFileComparator() {
+ this.sumDirectoryContents = false;
+ }
+
+ /**
+ * Construct a file size comparator instance specifying whether the size of
+ * the directory contents should be aggregated.
+ * sumDirectoryContents
is true
The size of
+ * directories is calculated using {@link FileUtils#sizeOfDirectory(File)}.
+ *
+ * @param sumDirectoryContents true
if the sum of the directoryies contents
+ * should be calculated, otherwise false
if directories should be treated
+ * as size zero (see {@link FileUtils#sizeOfDirectory(File)}).
+ */
+ public SizeFileComparator(boolean sumDirectoryContents) {
+ this.sumDirectoryContents = sumDirectoryContents;
+ }
+
+ /**
+ * Compare the length of two files.
+ *
+ * @param obj1 The first file to compare
+ * @param obj2 The second file to compare
+ * @return a negative value if the first file's length
+ * is less than the second, zero if the lengths are the
+ * same and a positive value if the first files length
+ * is greater than the second file.
+ *
+ */
+ public int compare(Object obj1, Object obj2) {
+ File file1 = (File)obj1;
+ File file2 = (File)obj2;
+ long size1 = 0;
+ if (file1.isDirectory()) {
+ size1 = sumDirectoryContents && file1.exists() ? FileUtils.sizeOfDirectory(file1) : 0;
+ } else {
+ size1 = file1.length();
+ }
+ long size2 = 0;
+ if (file2.isDirectory()) {
+ size2 = sumDirectoryContents && file2.exists() ? FileUtils.sizeOfDirectory(file2) : 0;
+ } else {
+ size2 = file2.length();
+ }
+ long result = size1 - size2;
+ if (result < 0) {
+ return -1;
+ } else if (result > 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/src/org/apache/commons/io/comparator/package.html b/src/org/apache/commons/io/comparator/package.html
index a2f756f183a41254259c91f749f713d8504c9d82..fe81e2fa9f0a2d514955797333701ec8c5ccf4e3 100644
--- a/src/org/apache/commons/io/comparator/package.html
+++ b/src/org/apache/commons/io/comparator/package.html
@@ -1,25 +1,25 @@
-
-
-
-
- * File dir = new File(".");
- * // We are interested in files older than one day
- * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
- * String[] files = dir.list( new AgeFileFilter(cutoff) );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @author Rahul Akolkar
- * @version $Id: AgeFileFilter.java 606381 2007-12-22 02:03:16Z ggregory $
- * @since Commons IO 1.2
- */
-public class AgeFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The cutoff time threshold. */
- private final long cutoff;
- /** Whether the files accepted will be older or newer. */
- private final boolean acceptOlder;
-
- /**
- * Constructs a new age file filter for files equal to or older than
- * a certain cutoff
- *
- * @param cutoff the threshold age of the files
- */
- public AgeFileFilter(long cutoff) {
- this(cutoff, true);
- }
-
- /**
- * Constructs a new age file filter for files on any one side
- * of a certain cutoff.
- *
- * @param cutoff the threshold age of the files
- * @param acceptOlder if true, older files (at or before the cutoff)
- * are accepted, else newer ones (after the cutoff).
- */
- public AgeFileFilter(long cutoff, boolean acceptOlder) {
- this.acceptOlder = acceptOlder;
- this.cutoff = cutoff;
- }
-
- /**
- * Constructs a new age file filter for files older than (at or before)
- * a certain cutoff date.
- *
- * @param cutoffDate the threshold age of the files
- */
- public AgeFileFilter(Date cutoffDate) {
- this(cutoffDate, true);
- }
-
- /**
- * Constructs a new age file filter for files on any one side
- * of a certain cutoff date.
- *
- * @param cutoffDate the threshold age of the files
- * @param acceptOlder if true, older files (at or before the cutoff)
- * are accepted, else newer ones (after the cutoff).
- */
- public AgeFileFilter(Date cutoffDate, boolean acceptOlder) {
- this(cutoffDate.getTime(), acceptOlder);
- }
-
- /**
- * Constructs a new age file filter for files older than (at or before)
- * a certain File (whose last modification time will be used as reference).
- *
- * @param cutoffReference the file whose last modification
- * time is usesd as the threshold age of the files
- */
- public AgeFileFilter(File cutoffReference) {
- this(cutoffReference, true);
- }
-
- /**
- * Constructs a new age file filter for files on any one side
- * of a certain File (whose last modification time will be used as
- * reference).
- *
- * @param cutoffReference the file whose last modification
- * time is usesd as the threshold age of the files
- * @param acceptOlder if true, older files (at or before the cutoff)
- * are accepted, else newer ones (after the cutoff).
- */
- public AgeFileFilter(File cutoffReference, boolean acceptOlder) {
- this(cutoffReference.lastModified(), acceptOlder);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks to see if the last modification of the file matches cutoff
- * favorably.
- *
+ * File dir = new File(".");
+ * // We are interested in files older than one day
+ * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * String[] files = dir.list( new AgeFileFilter(cutoff) );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @author Rahul Akolkar
+ * @version $Id: AgeFileFilter.java 606381 2007-12-22 02:03:16Z ggregory $
+ * @since Commons IO 1.2
+ */
+public class AgeFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The cutoff time threshold. */
+ private final long cutoff;
+ /** Whether the files accepted will be older or newer. */
+ private final boolean acceptOlder;
+
+ /**
+ * Constructs a new age file filter for files equal to or older than
+ * a certain cutoff
+ *
+ * @param cutoff the threshold age of the files
+ */
+ public AgeFileFilter(long cutoff) {
+ this(cutoff, true);
+ }
+
+ /**
+ * Constructs a new age file filter for files on any one side
+ * of a certain cutoff.
+ *
+ * @param cutoff the threshold age of the files
+ * @param acceptOlder if true, older files (at or before the cutoff)
+ * are accepted, else newer ones (after the cutoff).
+ */
+ public AgeFileFilter(long cutoff, boolean acceptOlder) {
+ this.acceptOlder = acceptOlder;
+ this.cutoff = cutoff;
+ }
+
+ /**
+ * Constructs a new age file filter for files older than (at or before)
+ * a certain cutoff date.
+ *
+ * @param cutoffDate the threshold age of the files
+ */
+ public AgeFileFilter(Date cutoffDate) {
+ this(cutoffDate, true);
+ }
+
+ /**
+ * Constructs a new age file filter for files on any one side
+ * of a certain cutoff date.
+ *
+ * @param cutoffDate the threshold age of the files
+ * @param acceptOlder if true, older files (at or before the cutoff)
+ * are accepted, else newer ones (after the cutoff).
+ */
+ public AgeFileFilter(Date cutoffDate, boolean acceptOlder) {
+ this(cutoffDate.getTime(), acceptOlder);
+ }
+
+ /**
+ * Constructs a new age file filter for files older than (at or before)
+ * a certain File (whose last modification time will be used as reference).
+ *
+ * @param cutoffReference the file whose last modification
+ * time is usesd as the threshold age of the files
+ */
+ public AgeFileFilter(File cutoffReference) {
+ this(cutoffReference, true);
+ }
+
+ /**
+ * Constructs a new age file filter for files on any one side
+ * of a certain File (whose last modification time will be used as
+ * reference).
+ *
+ * @param cutoffReference the file whose last modification
+ * time is usesd as the threshold age of the files
+ * @param acceptOlder if true, older files (at or before the cutoff)
+ * are accepted, else newer ones (after the cutoff).
+ */
+ public AgeFileFilter(File cutoffReference, boolean acceptOlder) {
+ this(cutoffReference.lastModified(), acceptOlder);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks to see if the last modification of the file matches cutoff
+ * favorably.
+ * true
if all filters in the
- * list return true
. Otherwise, it returns false
.
- * Checking of the file filter list stops when the first filter returns
- * false
.
- *
- * @since Commons IO 1.0
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- *
- * @author Steven Caswell
- */
-public class AndFileFilter
- extends AbstractFileFilter
- implements ConditionalFileFilter, Serializable {
-
- /** The list of file filters. */
- private List fileFilters;
-
- /**
- * Constructs a new instance of AndFileFilter
.
- *
- * @since Commons IO 1.1
- */
- public AndFileFilter() {
- this.fileFilters = new ArrayList();
- }
-
- /**
- * Constructs a new instance of AndFileFilter
- * with the specified list of filters.
- *
- * @param fileFilters a List of IOFileFilter instances, copied, null ignored
- * @since Commons IO 1.1
- */
- public AndFileFilter(final List fileFilters) {
- if (fileFilters == null) {
- this.fileFilters = new ArrayList();
- } else {
- this.fileFilters = new ArrayList(fileFilters);
- }
- }
-
- /**
- * Constructs a new file filter that ANDs the result of two other filters.
- *
- * @param filter1 the first filter, must not be null
- * @param filter2 the second filter, must not be null
- * @throws IllegalArgumentException if either filter is null
- */
- public AndFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
- if (filter1 == null || filter2 == null) {
- throw new IllegalArgumentException("The filters must not be null");
- }
- this.fileFilters = new ArrayList();
- addFileFilter(filter1);
- addFileFilter(filter2);
- }
-
- /**
- * {@inheritDoc}
- */
- public void addFileFilter(final IOFileFilter ioFileFilter) {
- this.fileFilters.add(ioFileFilter);
- }
-
- /**
- * {@inheritDoc}
- */
- public List getFileFilters() {
- return Collections.unmodifiableList(this.fileFilters);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean removeFileFilter(final IOFileFilter ioFileFilter) {
- return this.fileFilters.remove(ioFileFilter);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFileFilters(final List fileFilters) {
- this.fileFilters = new ArrayList(fileFilters);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean accept(final File file) {
- if (this.fileFilters.size() == 0) {
- return false;
- }
- for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
- IOFileFilter fileFilter = (IOFileFilter) iter.next();
- if (!fileFilter.accept(file)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean accept(final File file, final String name) {
- if (this.fileFilters.size() == 0) {
- return false;
- }
- for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
- IOFileFilter fileFilter = (IOFileFilter) iter.next();
- if (!fileFilter.accept(file, name)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (fileFilters != null) {
- for (int i = 0; i < fileFilters.size(); i++) {
- if (i > 0) {
- buffer.append(",");
- }
- Object filter = fileFilters.get(i);
- buffer.append(filter == null ? "null" : filter.toString());
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A {@link java.io.FileFilter} providing conditional AND logic across a list of
+ * file filters. This filter returns true
if all filters in the
+ * list return true
. Otherwise, it returns false
.
+ * Checking of the file filter list stops when the first filter returns
+ * false
.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ *
+ * @author Steven Caswell
+ */
+public class AndFileFilter
+ extends AbstractFileFilter
+ implements ConditionalFileFilter, Serializable {
+
+ /** The list of file filters. */
+ private List fileFilters;
+
+ /**
+ * Constructs a new instance of AndFileFilter
.
+ *
+ * @since Commons IO 1.1
+ */
+ public AndFileFilter() {
+ this.fileFilters = new ArrayList();
+ }
+
+ /**
+ * Constructs a new instance of AndFileFilter
+ * with the specified list of filters.
+ *
+ * @param fileFilters a List of IOFileFilter instances, copied, null ignored
+ * @since Commons IO 1.1
+ */
+ public AndFileFilter(final List fileFilters) {
+ if (fileFilters == null) {
+ this.fileFilters = new ArrayList();
+ } else {
+ this.fileFilters = new ArrayList(fileFilters);
+ }
+ }
+
+ /**
+ * Constructs a new file filter that ANDs the result of two other filters.
+ *
+ * @param filter1 the first filter, must not be null
+ * @param filter2 the second filter, must not be null
+ * @throws IllegalArgumentException if either filter is null
+ */
+ public AndFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
+ if (filter1 == null || filter2 == null) {
+ throw new IllegalArgumentException("The filters must not be null");
+ }
+ this.fileFilters = new ArrayList();
+ addFileFilter(filter1);
+ addFileFilter(filter2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addFileFilter(final IOFileFilter ioFileFilter) {
+ this.fileFilters.add(ioFileFilter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getFileFilters() {
+ return Collections.unmodifiableList(this.fileFilters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean removeFileFilter(final IOFileFilter ioFileFilter) {
+ return this.fileFilters.remove(ioFileFilter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFileFilters(final List fileFilters) {
+ this.fileFilters = new ArrayList(fileFilters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean accept(final File file) {
+ if (this.fileFilters.size() == 0) {
+ return false;
+ }
+ for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
+ IOFileFilter fileFilter = (IOFileFilter) iter.next();
+ if (!fileFilter.accept(file)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean accept(final File file, final String name) {
+ if (this.fileFilters.size() == 0) {
+ return false;
+ }
+ for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
+ IOFileFilter fileFilter = (IOFileFilter) iter.next();
+ if (!fileFilter.accept(file, name)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (fileFilters != null) {
+ for (int i = 0; i < fileFilters.size(); i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ Object filter = fileFilters.get(i);
+ buffer.append(filter == null ? "null" : filter.toString());
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/CanReadFileFilter.java b/src/org/apache/commons/io/filefilter/CanReadFileFilter.java
index a9c132570c878abbec5d6d11e91eb7326797f601..1744af0e3de1d4495b35de46af82ceaf7818c064 100644
--- a/src/org/apache/commons/io/filefilter/CanReadFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/CanReadFileFilter.java
@@ -1,92 +1,92 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts File
s that can be read.
- *
- * File dir = new File(".");
- * String[] files = dir.list( CanReadFileFilter.CAN_READ );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( CanReadFileFilter.CANNOT_READ );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( CanReadFileFilter.READ_ONLY );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 587916 $
- */
-public class CanReadFileFilter extends AbstractFileFilter implements Serializable {
-
- /** Singleton instance of readable filter */
- public static final IOFileFilter CAN_READ = new CanReadFileFilter();
-
- /** Singleton instance of not readable filter */
- public static final IOFileFilter CANNOT_READ = new NotFileFilter(CAN_READ);
-
- /** Singleton instance of read-only filter */
- public static final IOFileFilter READ_ONLY = new AndFileFilter(CAN_READ,
- CanWriteFileFilter.CANNOT_WRITE);
-
- /**
- * Restrictive consructor.
- */
- protected CanReadFileFilter() {
- }
-
- /**
- * Checks to see if the file can be read.
- *
- * @param file the File to check.
- * @return true
if the file can be
- * read, otherwise false
.
- */
- public boolean accept(File file) {
- return file.canRead();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts File
s that can be read.
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.CAN_READ );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.CANNOT_READ );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.READ_ONLY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 587916 $
+ */
+public class CanReadFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** Singleton instance of readable filter */
+ public static final IOFileFilter CAN_READ = new CanReadFileFilter();
+
+ /** Singleton instance of not readable filter */
+ public static final IOFileFilter CANNOT_READ = new NotFileFilter(CAN_READ);
+
+ /** Singleton instance of read-only filter */
+ public static final IOFileFilter READ_ONLY = new AndFileFilter(CAN_READ,
+ CanWriteFileFilter.CANNOT_WRITE);
+
+ /**
+ * Restrictive consructor.
+ */
+ protected CanReadFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file can be read.
+ *
+ * @param file the File to check.
+ * @return true
if the file can be
+ * read, otherwise false
.
+ */
+ public boolean accept(File file) {
+ return file.canRead();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/CanWriteFileFilter.java b/src/org/apache/commons/io/filefilter/CanWriteFileFilter.java
index da664f25ca21c43e63af078bbbcd1bd5f25c3d9d..b91eccae3360e496d008cf40a71deba451cd4248 100644
--- a/src/org/apache/commons/io/filefilter/CanWriteFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/CanWriteFileFilter.java
@@ -1,80 +1,80 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts File
s that can be written to.
- *
- * File dir = new File(".");
- * String[] files = dir.list( CanWriteFileFilter.CAN_WRITE );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( CanWriteFileFilter.CANNOT_WRITE );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * CanReadFileFilter.READ_ONLY
.
- *
- * @since Commons IO 1.3
- * @version $Revision: 587916 $
- */
-public class CanWriteFileFilter extends AbstractFileFilter implements Serializable {
-
- /** Singleton instance of writable filter */
- public static final IOFileFilter CAN_WRITE = new CanWriteFileFilter();
-
- /** Singleton instance of not writable filter */
- public static final IOFileFilter CANNOT_WRITE = new NotFileFilter(CAN_WRITE);
-
- /**
- * Restrictive consructor.
- */
- protected CanWriteFileFilter() {
- }
-
- /**
- * Checks to see if the file can be written to.
- *
- * @param file the File to check
- * @return true
if the file can be
- * written to, otherwise false
.
- */
- public boolean accept(File file) {
- return file.canWrite();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts File
s that can be written to.
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( CanWriteFileFilter.CAN_WRITE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( CanWriteFileFilter.CANNOT_WRITE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * CanReadFileFilter.READ_ONLY
.
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 587916 $
+ */
+public class CanWriteFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** Singleton instance of writable filter */
+ public static final IOFileFilter CAN_WRITE = new CanWriteFileFilter();
+
+ /** Singleton instance of not writable filter */
+ public static final IOFileFilter CANNOT_WRITE = new NotFileFilter(CAN_WRITE);
+
+ /**
+ * Restrictive consructor.
+ */
+ protected CanWriteFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file can be written to.
+ *
+ * @param file the File to check
+ * @return true
if the file can be
+ * written to, otherwise false
.
+ */
+ public boolean accept(File file) {
+ return file.canWrite();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/ConditionalFileFilter.java b/src/org/apache/commons/io/filefilter/ConditionalFileFilter.java
index ce1419ee82aaa4dc7dfe48ddc72d1f31a53360a4..5faf0075dfd43c3966343136201050d07cbab3a5 100644
--- a/src/org/apache/commons/io/filefilter/ConditionalFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/ConditionalFileFilter.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.io.filefilter;
-
-import java.util.List;
-
-/**
- * Defines operations for conditional file filters.
- *
- * @since Commons IO 1.1
- * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
- *
- * @author Steven Caswell
- */
-public interface ConditionalFileFilter {
-
- /**
- * Adds the specified file filter to the list of file filters at the end of
- * the list.
- *
- * @param ioFileFilter the filter to be added
- * @since Commons IO 1.1
- */
- public void addFileFilter(IOFileFilter ioFileFilter);
-
- /**
- * Returns this conditional file filter's list of file filters.
- *
- * @return the file filter list
- * @since Commons IO 1.1
- */
- public List getFileFilters();
-
- /**
- * Removes the specified file filter.
- *
- * @param ioFileFilter filter to be removed
- * @return true
if the filter was found in the list,
- * false
otherwise
- * @since Commons IO 1.1
- */
- public boolean removeFileFilter(IOFileFilter ioFileFilter);
-
- /**
- * Sets the list of file filters, replacing any previously configured
- * file filters on this filter.
- *
- * @param fileFilters the list of filters
- * @since Commons IO 1.1
- */
- public void setFileFilters(List fileFilters);
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.util.List;
+
+/**
+ * Defines operations for conditional file filters.
+ *
+ * @since Commons IO 1.1
+ * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
+ *
+ * @author Steven Caswell
+ */
+public interface ConditionalFileFilter {
+
+ /**
+ * Adds the specified file filter to the list of file filters at the end of
+ * the list.
+ *
+ * @param ioFileFilter the filter to be added
+ * @since Commons IO 1.1
+ */
+ public void addFileFilter(IOFileFilter ioFileFilter);
+
+ /**
+ * Returns this conditional file filter's list of file filters.
+ *
+ * @return the file filter list
+ * @since Commons IO 1.1
+ */
+ public List getFileFilters();
+
+ /**
+ * Removes the specified file filter.
+ *
+ * @param ioFileFilter filter to be removed
+ * @return true
if the filter was found in the list,
+ * false
otherwise
+ * @since Commons IO 1.1
+ */
+ public boolean removeFileFilter(IOFileFilter ioFileFilter);
+
+ /**
+ * Sets the list of file filters, replacing any previously configured
+ * file filters on this filter.
+ *
+ * @param fileFilters the list of filters
+ * @since Commons IO 1.1
+ */
+ public void setFileFilters(List fileFilters);
+
+}
diff --git a/src/org/apache/commons/io/filefilter/DelegateFileFilter.java b/src/org/apache/commons/io/filefilter/DelegateFileFilter.java
index c2d67c4691f9d55beb7482c45c30195f033147bb..1c86d7e5016fc71efc0ac5f62232a395d7e932fa 100644
--- a/src/org/apache/commons/io/filefilter/DelegateFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/DelegateFileFilter.java
@@ -1,104 +1,104 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.io.Serializable;
-
-/**
- * This class turns a Java FileFilter or FilenameFilter into an IO FileFilter.
- *
- * @since Commons IO 1.0
- * @version $Revision: 591058 $ $Date: 2007-11-01 15:47:05 +0000 (Thu, 01 Nov 2007) $
- *
- * @author Stephen Colebourne
- */
-public class DelegateFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The Filename filter */
- private final FilenameFilter filenameFilter;
- /** The File filter */
- private final FileFilter fileFilter;
-
- /**
- * Constructs a delegate file filter around an existing FilenameFilter.
- *
- * @param filter the filter to decorate
- */
- public DelegateFileFilter(FilenameFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("The FilenameFilter must not be null");
- }
- this.filenameFilter = filter;
- this.fileFilter = null;
- }
-
- /**
- * Constructs a delegate file filter around an existing FileFilter.
- *
- * @param filter the filter to decorate
- */
- public DelegateFileFilter(FileFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("The FileFilter must not be null");
- }
- this.fileFilter = filter;
- this.filenameFilter = null;
- }
-
- /**
- * Checks the filter.
- *
- * @param file the file to check
- * @return true if the filter matches
- */
- public boolean accept(File file) {
- if (fileFilter != null) {
- return fileFilter.accept(file);
- } else {
- return super.accept(file);
- }
- }
-
- /**
- * Checks the filter.
- *
- * @param dir the directory
- * @param name the filename in the directory
- * @return true if the filter matches
- */
- public boolean accept(File dir, String name) {
- if (filenameFilter != null) {
- return filenameFilter.accept(dir, name);
- } else {
- return super.accept(dir, name);
- }
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- String delegate = (fileFilter != null ? fileFilter.toString() : filenameFilter.toString());
- return super.toString() + "(" + delegate + ")";
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.io.Serializable;
+
+/**
+ * This class turns a Java FileFilter or FilenameFilter into an IO FileFilter.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 591058 $ $Date: 2007-11-01 15:47:05 +0000 (Thu, 01 Nov 2007) $
+ *
+ * @author Stephen Colebourne
+ */
+public class DelegateFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The Filename filter */
+ private final FilenameFilter filenameFilter;
+ /** The File filter */
+ private final FileFilter fileFilter;
+
+ /**
+ * Constructs a delegate file filter around an existing FilenameFilter.
+ *
+ * @param filter the filter to decorate
+ */
+ public DelegateFileFilter(FilenameFilter filter) {
+ if (filter == null) {
+ throw new IllegalArgumentException("The FilenameFilter must not be null");
+ }
+ this.filenameFilter = filter;
+ this.fileFilter = null;
+ }
+
+ /**
+ * Constructs a delegate file filter around an existing FileFilter.
+ *
+ * @param filter the filter to decorate
+ */
+ public DelegateFileFilter(FileFilter filter) {
+ if (filter == null) {
+ throw new IllegalArgumentException("The FileFilter must not be null");
+ }
+ this.fileFilter = filter;
+ this.filenameFilter = null;
+ }
+
+ /**
+ * Checks the filter.
+ *
+ * @param file the file to check
+ * @return true if the filter matches
+ */
+ public boolean accept(File file) {
+ if (fileFilter != null) {
+ return fileFilter.accept(file);
+ } else {
+ return super.accept(file);
+ }
+ }
+
+ /**
+ * Checks the filter.
+ *
+ * @param dir the directory
+ * @param name the filename in the directory
+ * @return true if the filter matches
+ */
+ public boolean accept(File dir, String name) {
+ if (filenameFilter != null) {
+ return filenameFilter.accept(dir, name);
+ } else {
+ return super.accept(dir, name);
+ }
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ String delegate = (fileFilter != null ? fileFilter.toString() : filenameFilter.toString());
+ return super.toString() + "(" + delegate + ")";
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/DirectoryFileFilter.java b/src/org/apache/commons/io/filefilter/DirectoryFileFilter.java
index 3412e7beffb7bf6f04f2b5a26c7fec23c4bf2f1c..a1a44f522e4b62b74dd083d350f6ee4e7c39108f 100644
--- a/src/org/apache/commons/io/filefilter/DirectoryFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/DirectoryFileFilter.java
@@ -1,73 +1,73 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts File
s that are directories.
- *
- * File dir = new File(".");
- * String[] files = dir.list( DirectoryFileFilter.INSTANCE );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.0
- * @version $Revision: 587916 $ $Date: 2007-10-24 16:53:07 +0100 (Wed, 24 Oct 2007) $
- *
- * @author Stephen Colebourne
- * @author Peter Donald
- */
-public class DirectoryFileFilter extends AbstractFileFilter implements Serializable {
-
- /**
- * Singleton instance of directory filter.
- * @since Commons IO 1.3
- */
- public static final IOFileFilter DIRECTORY = new DirectoryFileFilter();
- /**
- * Singleton instance of directory filter.
- * Please use the identical DirectoryFileFilter.DIRECTORY constant.
- * The new name is more JDK 1.5 friendly as it doesn't clash with other
- * values when using static imports.
- */
- public static final IOFileFilter INSTANCE = DIRECTORY;
-
- /**
- * Restrictive consructor.
- */
- protected DirectoryFileFilter() {
- }
-
- /**
- * Checks to see if the file is a directory.
- *
- * @param file the File to check
- * @return true if the file is a directory
- */
- public boolean accept(File file) {
- return file.isDirectory();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts File
s that are directories.
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( DirectoryFileFilter.INSTANCE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 587916 $ $Date: 2007-10-24 16:53:07 +0100 (Wed, 24 Oct 2007) $
+ *
+ * @author Stephen Colebourne
+ * @author Peter Donald
+ */
+public class DirectoryFileFilter extends AbstractFileFilter implements Serializable {
+
+ /**
+ * Singleton instance of directory filter.
+ * @since Commons IO 1.3
+ */
+ public static final IOFileFilter DIRECTORY = new DirectoryFileFilter();
+ /**
+ * Singleton instance of directory filter.
+ * Please use the identical DirectoryFileFilter.DIRECTORY constant.
+ * The new name is more JDK 1.5 friendly as it doesn't clash with other
+ * values when using static imports.
+ */
+ public static final IOFileFilter INSTANCE = DIRECTORY;
+
+ /**
+ * Restrictive consructor.
+ */
+ protected DirectoryFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file is a directory.
+ *
+ * @param file the File to check
+ * @return true if the file is a directory
+ */
+ public boolean accept(File file) {
+ return file.isDirectory();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/EmptyFileFilter.java b/src/org/apache/commons/io/filefilter/EmptyFileFilter.java
index e88a862d48f9a36274338530a0434a5972a04dc8..f5219f420b7f22e658872cf379c9a8b520b57b65 100644
--- a/src/org/apache/commons/io/filefilter/EmptyFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/EmptyFileFilter.java
@@ -1,84 +1,84 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts files or directories that are empty.
- * File
is a directory it checks that
- * it contains no files.
- *
- * File dir = new File(".");
- * String[] files = dir.list( EmptyFileFilter.EMPTY );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( EmptyFileFilter.NOT_EMPTY );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 587916 $
- */
-public class EmptyFileFilter extends AbstractFileFilter implements Serializable {
-
- /** Singleton instance of empty filter */
- public static final IOFileFilter EMPTY = new EmptyFileFilter();
-
- /** Singleton instance of not-empty filter */
- public static final IOFileFilter NOT_EMPTY = new NotFileFilter(EMPTY);
-
- /**
- * Restrictive consructor.
- */
- protected EmptyFileFilter() {
- }
-
- /**
- * Checks to see if the file is empty.
- *
- * @param file the file or directory to check
- * @return true
if the file or directory
- * is empty, otherwise false
.
- */
- public boolean accept(File file) {
- if (file.isDirectory()) {
- File[] files = file.listFiles();
- return (files == null || files.length == 0);
- } else {
- return (file.length() == 0);
- }
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts files or directories that are empty.
+ * File
is a directory it checks that
+ * it contains no files.
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( EmptyFileFilter.EMPTY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( EmptyFileFilter.NOT_EMPTY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 587916 $
+ */
+public class EmptyFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** Singleton instance of empty filter */
+ public static final IOFileFilter EMPTY = new EmptyFileFilter();
+
+ /** Singleton instance of not-empty filter */
+ public static final IOFileFilter NOT_EMPTY = new NotFileFilter(EMPTY);
+
+ /**
+ * Restrictive consructor.
+ */
+ protected EmptyFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file is empty.
+ *
+ * @param file the file or directory to check
+ * @return true
if the file or directory
+ * is empty, otherwise false
.
+ */
+ public boolean accept(File file) {
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ return (files == null || files.length == 0);
+ } else {
+ return (file.length() == 0);
+ }
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/FalseFileFilter.java b/src/org/apache/commons/io/filefilter/FalseFileFilter.java
index 8a87d4092178149a32a582192c966b167fab8da6..5a24c6a0f2a241e02160e5cb7fbb9f0dea56251a 100644
--- a/src/org/apache/commons/io/filefilter/FalseFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/FalseFileFilter.java
@@ -1,72 +1,72 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * A file filter that always returns false.
- *
- * @since Commons IO 1.0
- * @version $Revision: 587978 $ $Date: 2007-10-24 20:36:51 +0100 (Wed, 24 Oct 2007) $
- *
- * @author Stephen Colebourne
- */
-public class FalseFileFilter implements IOFileFilter, Serializable {
-
- /**
- * Singleton instance of false filter.
- * @since Commons IO 1.3
- */
- public static final IOFileFilter FALSE = new FalseFileFilter();
- /**
- * Singleton instance of false filter.
- * Please use the identical FalseFileFilter.FALSE constant.
- * The new name is more JDK 1.5 friendly as it doesn't clash with other
- * values when using static imports.
- */
- public static final IOFileFilter INSTANCE = FALSE;
-
- /**
- * Restrictive consructor.
- */
- protected FalseFileFilter() {
- }
-
- /**
- * Returns false.
- *
- * @param file the file to check
- * @return false
- */
- public boolean accept(File file) {
- return false;
- }
-
- /**
- * Returns false.
- *
- * @param dir the directory to check
- * @param name the filename
- * @return false
- */
- public boolean accept(File dir, String name) {
- return false;
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * A file filter that always returns false.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 587978 $ $Date: 2007-10-24 20:36:51 +0100 (Wed, 24 Oct 2007) $
+ *
+ * @author Stephen Colebourne
+ */
+public class FalseFileFilter implements IOFileFilter, Serializable {
+
+ /**
+ * Singleton instance of false filter.
+ * @since Commons IO 1.3
+ */
+ public static final IOFileFilter FALSE = new FalseFileFilter();
+ /**
+ * Singleton instance of false filter.
+ * Please use the identical FalseFileFilter.FALSE constant.
+ * The new name is more JDK 1.5 friendly as it doesn't clash with other
+ * values when using static imports.
+ */
+ public static final IOFileFilter INSTANCE = FALSE;
+
+ /**
+ * Restrictive consructor.
+ */
+ protected FalseFileFilter() {
+ }
+
+ /**
+ * Returns false.
+ *
+ * @param file the file to check
+ * @return false
+ */
+ public boolean accept(File file) {
+ return false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @param dir the directory to check
+ * @param name the filename
+ * @return false
+ */
+ public boolean accept(File dir, String name) {
+ return false;
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/FileFileFilter.java b/src/org/apache/commons/io/filefilter/FileFileFilter.java
index 0d49eddd4447c12773a81c805a8d881a00887bc0..7547f4e9c55cd3609450ad746d3ad9f890958511 100644
--- a/src/org/apache/commons/io/filefilter/FileFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/FileFileFilter.java
@@ -1,60 +1,60 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts File
s that are files (not directories).
- *
- * File dir = new File(".");
- * String[] files = dir.list( FileFileFilter.FILE );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 155419 $ $Date: 2007-10-24 16:53:07 +0100 (Wed, 24 Oct 2007) $
- */
-public class FileFileFilter extends AbstractFileFilter implements Serializable {
-
- /** Singleton instance of file filter */
- public static final IOFileFilter FILE = new FileFileFilter();
-
- /**
- * Restrictive consructor.
- */
- protected FileFileFilter() {
- }
-
- /**
- * Checks to see if the file is a file.
- *
- * @param file the File to check
- * @return true if the file is a file
- */
- public boolean accept(File file) {
- return file.isFile();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts File
s that are files (not directories).
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( FileFileFilter.FILE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 155419 $ $Date: 2007-10-24 16:53:07 +0100 (Wed, 24 Oct 2007) $
+ */
+public class FileFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** Singleton instance of file filter */
+ public static final IOFileFilter FILE = new FileFileFilter();
+
+ /**
+ * Restrictive consructor.
+ */
+ protected FileFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file is a file.
+ *
+ * @param file the File to check
+ * @return true if the file is a file
+ */
+ public boolean accept(File file) {
+ return file.isFile();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/FileFilterUtils.java b/src/org/apache/commons/io/filefilter/FileFilterUtils.java
index 71c37b1d287cc913edee9897f2d5e23042ed6fe9..e09e28bb999ad6c18f6a60c4d763a5976161e18c 100644
--- a/src/org/apache/commons/io/filefilter/FileFilterUtils.java
+++ b/src/org/apache/commons/io/filefilter/FileFilterUtils.java
@@ -1,361 +1,361 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.util.Date;
-
-/**
- * Useful utilities for working with file filters. It provides access to all
- * file filter implementations in this package so you don't have to import
- * every class you use.
- *
- * @since Commons IO 1.0
- * @version $Id: FileFilterUtils.java 609286 2008-01-06 10:01:26Z scolebourne $
- *
- * @author Stephen Colebourne
- * @author Jeremias Maerki
- * @author Masato Tezuka
- * @author Rahul Akolkar
- */
-public class FileFilterUtils {
-
- /**
- * FileFilterUtils is not normally instantiated.
- */
- public FileFilterUtils() {
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a filter that returns true if the filename starts with the specified text.
- *
- * @param prefix the filename prefix
- * @return a prefix checking filter
- */
- public static IOFileFilter prefixFileFilter(String prefix) {
- return new PrefixFileFilter(prefix);
- }
-
- /**
- * Returns a filter that returns true if the filename ends with the specified text.
- *
- * @param suffix the filename suffix
- * @return a suffix checking filter
- */
- public static IOFileFilter suffixFileFilter(String suffix) {
- return new SuffixFileFilter(suffix);
- }
-
- /**
- * Returns a filter that returns true if the filename matches the specified text.
- *
- * @param name the filename
- * @return a name checking filter
- */
- public static IOFileFilter nameFileFilter(String name) {
- return new NameFileFilter(name);
- }
-
- /**
- * Returns a filter that checks if the file is a directory.
- *
- * @return file filter that accepts only directories and not files
- */
- public static IOFileFilter directoryFileFilter() {
- return DirectoryFileFilter.DIRECTORY;
- }
-
- /**
- * Returns a filter that checks if the file is a file (and not a directory).
- *
- * @return file filter that accepts only files and not directories
- */
- public static IOFileFilter fileFileFilter() {
- return FileFileFilter.FILE;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a filter that ANDs the two specified filters.
- *
- * @param filter1 the first filter
- * @param filter2 the second filter
- * @return a filter that ANDs the two specified filters
- */
- public static IOFileFilter andFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
- return new AndFileFilter(filter1, filter2);
- }
-
- /**
- * Returns a filter that ORs the two specified filters.
- *
- * @param filter1 the first filter
- * @param filter2 the second filter
- * @return a filter that ORs the two specified filters
- */
- public static IOFileFilter orFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
- return new OrFileFilter(filter1, filter2);
- }
-
- /**
- * Returns a filter that NOTs the specified filter.
- *
- * @param filter the filter to invert
- * @return a filter that NOTs the specified filter
- */
- public static IOFileFilter notFileFilter(IOFileFilter filter) {
- return new NotFileFilter(filter);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a filter that always returns true.
- *
- * @return a true filter
- */
- public static IOFileFilter trueFileFilter() {
- return TrueFileFilter.TRUE;
- }
-
- /**
- * Returns a filter that always returns false.
- *
- * @return a false filter
- */
- public static IOFileFilter falseFileFilter() {
- return FalseFileFilter.FALSE;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns an IOFileFilter
that wraps the
- * FileFilter
instance.
- *
- * @param filter the filter to be wrapped
- * @return a new filter that implements IOFileFilter
- */
- public static IOFileFilter asFileFilter(FileFilter filter) {
- return new DelegateFileFilter(filter);
- }
-
- /**
- * Returns an IOFileFilter
that wraps the
- * FilenameFilter
instance.
- *
- * @param filter the filter to be wrapped
- * @return a new filter that implements IOFileFilter
- */
- public static IOFileFilter asFileFilter(FilenameFilter filter) {
- return new DelegateFileFilter(filter);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a filter that returns true if the file was last modified after
- * the specified cutoff time.
- *
- * @param cutoff the time threshold
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(long cutoff) {
- return new AgeFileFilter(cutoff);
- }
-
- /**
- * Returns a filter that filters files based on a cutoff time.
- *
- * @param cutoff the time threshold
- * @param acceptOlder if true, older files get accepted, if false, newer
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(long cutoff, boolean acceptOlder) {
- return new AgeFileFilter(cutoff, acceptOlder);
- }
-
- /**
- * Returns a filter that returns true if the file was last modified after
- * the specified cutoff date.
- *
- * @param cutoffDate the time threshold
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(Date cutoffDate) {
- return new AgeFileFilter(cutoffDate);
- }
-
- /**
- * Returns a filter that filters files based on a cutoff date.
- *
- * @param cutoffDate the time threshold
- * @param acceptOlder if true, older files get accepted, if false, newer
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(Date cutoffDate, boolean acceptOlder) {
- return new AgeFileFilter(cutoffDate, acceptOlder);
- }
-
- /**
- * Returns a filter that returns true if the file was last modified after
- * the specified reference file.
- *
- * @param cutoffReference the file whose last modification
- * time is usesd as the threshold age of the files
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(File cutoffReference) {
- return new AgeFileFilter(cutoffReference);
- }
-
- /**
- * Returns a filter that filters files based on a cutoff reference file.
- *
- * @param cutoffReference the file whose last modification
- * time is usesd as the threshold age of the files
- * @param acceptOlder if true, older files get accepted, if false, newer
- * @return an appropriately configured age file filter
- * @since Commons IO 1.2
- */
- public static IOFileFilter ageFileFilter(File cutoffReference, boolean acceptOlder) {
- return new AgeFileFilter(cutoffReference, acceptOlder);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a filter that returns true if the file is bigger than a certain size.
- *
- * @param threshold the file size threshold
- * @return an appropriately configured SizeFileFilter
- * @since Commons IO 1.2
- */
- public static IOFileFilter sizeFileFilter(long threshold) {
- return new SizeFileFilter(threshold);
- }
-
- /**
- * Returns a filter that filters based on file size.
- *
- * @param threshold the file size threshold
- * @param acceptLarger if true, larger files get accepted, if false, smaller
- * @return an appropriately configured SizeFileFilter
- * @since Commons IO 1.2
- */
- public static IOFileFilter sizeFileFilter(long threshold, boolean acceptLarger) {
- return new SizeFileFilter(threshold, acceptLarger);
- }
-
- /**
- * Returns a filter that accepts files whose size is >= minimum size
- * and <= maximum size.
- *
- * @param minSizeInclusive the minimum file size (inclusive)
- * @param maxSizeInclusive the maximum file size (inclusive)
- * @return an appropriately configured IOFileFilter
- * @since Commons IO 1.3
- */
- public static IOFileFilter sizeRangeFileFilter(long minSizeInclusive, long maxSizeInclusive ) {
- IOFileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true);
- IOFileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false);
- return new AndFileFilter(minimumFilter, maximumFilter);
- }
-
- //-----------------------------------------------------------------------
- /* Constructed on demand and then cached */
- private static IOFileFilter cvsFilter;
-
- /* Constructed on demand and then cached */
- private static IOFileFilter svnFilter;
-
- /**
- * Decorates a filter to make it ignore CVS directories.
- * Passing in null
will return a filter that accepts everything
- * except CVS directories.
- *
- * @param filter the filter to decorate, null means an unrestricted filter
- * @return the decorated filter, never null
- * @since Commons IO 1.1 (method existed but had bug in 1.0)
- */
- public static IOFileFilter makeCVSAware(IOFileFilter filter) {
- if (cvsFilter == null) {
- cvsFilter = notFileFilter(
- andFileFilter(directoryFileFilter(), nameFileFilter("CVS")));
- }
- if (filter == null) {
- return cvsFilter;
- } else {
- return andFileFilter(filter, cvsFilter);
- }
- }
-
- /**
- * Decorates a filter to make it ignore SVN directories.
- * Passing in null
will return a filter that accepts everything
- * except SVN directories.
- *
- * @param filter the filter to decorate, null means an unrestricted filter
- * @return the decorated filter, never null
- * @since Commons IO 1.1
- */
- public static IOFileFilter makeSVNAware(IOFileFilter filter) {
- if (svnFilter == null) {
- svnFilter = notFileFilter(
- andFileFilter(directoryFileFilter(), nameFileFilter(".svn")));
- }
- if (filter == null) {
- return svnFilter;
- } else {
- return andFileFilter(filter, svnFilter);
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Decorates a filter so that it only applies to directories and not to files.
- *
- * @param filter the filter to decorate, null means an unrestricted filter
- * @return the decorated filter, never null
- * @since Commons IO 1.3
- */
- public static IOFileFilter makeDirectoryOnly(IOFileFilter filter) {
- if (filter == null) {
- return DirectoryFileFilter.DIRECTORY;
- }
- return new AndFileFilter(DirectoryFileFilter.DIRECTORY, filter);
- }
-
- /**
- * Decorates a filter so that it only applies to files and not to directories.
- *
- * @param filter the filter to decorate, null means an unrestricted filter
- * @return the decorated filter, never null
- * @since Commons IO 1.3
- */
- public static IOFileFilter makeFileOnly(IOFileFilter filter) {
- if (filter == null) {
- return FileFileFilter.FILE;
- }
- return new AndFileFilter(FileFileFilter.FILE, filter);
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.util.Date;
+
+/**
+ * Useful utilities for working with file filters. It provides access to all
+ * file filter implementations in this package so you don't have to import
+ * every class you use.
+ *
+ * @since Commons IO 1.0
+ * @version $Id: FileFilterUtils.java 609286 2008-01-06 10:01:26Z scolebourne $
+ *
+ * @author Stephen Colebourne
+ * @author Jeremias Maerki
+ * @author Masato Tezuka
+ * @author Rahul Akolkar
+ */
+public class FileFilterUtils {
+
+ /**
+ * FileFilterUtils is not normally instantiated.
+ */
+ public FileFilterUtils() {
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a filter that returns true if the filename starts with the specified text.
+ *
+ * @param prefix the filename prefix
+ * @return a prefix checking filter
+ */
+ public static IOFileFilter prefixFileFilter(String prefix) {
+ return new PrefixFileFilter(prefix);
+ }
+
+ /**
+ * Returns a filter that returns true if the filename ends with the specified text.
+ *
+ * @param suffix the filename suffix
+ * @return a suffix checking filter
+ */
+ public static IOFileFilter suffixFileFilter(String suffix) {
+ return new SuffixFileFilter(suffix);
+ }
+
+ /**
+ * Returns a filter that returns true if the filename matches the specified text.
+ *
+ * @param name the filename
+ * @return a name checking filter
+ */
+ public static IOFileFilter nameFileFilter(String name) {
+ return new NameFileFilter(name);
+ }
+
+ /**
+ * Returns a filter that checks if the file is a directory.
+ *
+ * @return file filter that accepts only directories and not files
+ */
+ public static IOFileFilter directoryFileFilter() {
+ return DirectoryFileFilter.DIRECTORY;
+ }
+
+ /**
+ * Returns a filter that checks if the file is a file (and not a directory).
+ *
+ * @return file filter that accepts only files and not directories
+ */
+ public static IOFileFilter fileFileFilter() {
+ return FileFileFilter.FILE;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a filter that ANDs the two specified filters.
+ *
+ * @param filter1 the first filter
+ * @param filter2 the second filter
+ * @return a filter that ANDs the two specified filters
+ */
+ public static IOFileFilter andFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
+ return new AndFileFilter(filter1, filter2);
+ }
+
+ /**
+ * Returns a filter that ORs the two specified filters.
+ *
+ * @param filter1 the first filter
+ * @param filter2 the second filter
+ * @return a filter that ORs the two specified filters
+ */
+ public static IOFileFilter orFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
+ return new OrFileFilter(filter1, filter2);
+ }
+
+ /**
+ * Returns a filter that NOTs the specified filter.
+ *
+ * @param filter the filter to invert
+ * @return a filter that NOTs the specified filter
+ */
+ public static IOFileFilter notFileFilter(IOFileFilter filter) {
+ return new NotFileFilter(filter);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a filter that always returns true.
+ *
+ * @return a true filter
+ */
+ public static IOFileFilter trueFileFilter() {
+ return TrueFileFilter.TRUE;
+ }
+
+ /**
+ * Returns a filter that always returns false.
+ *
+ * @return a false filter
+ */
+ public static IOFileFilter falseFileFilter() {
+ return FalseFileFilter.FALSE;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns an IOFileFilter
that wraps the
+ * FileFilter
instance.
+ *
+ * @param filter the filter to be wrapped
+ * @return a new filter that implements IOFileFilter
+ */
+ public static IOFileFilter asFileFilter(FileFilter filter) {
+ return new DelegateFileFilter(filter);
+ }
+
+ /**
+ * Returns an IOFileFilter
that wraps the
+ * FilenameFilter
instance.
+ *
+ * @param filter the filter to be wrapped
+ * @return a new filter that implements IOFileFilter
+ */
+ public static IOFileFilter asFileFilter(FilenameFilter filter) {
+ return new DelegateFileFilter(filter);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a filter that returns true if the file was last modified after
+ * the specified cutoff time.
+ *
+ * @param cutoff the time threshold
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(long cutoff) {
+ return new AgeFileFilter(cutoff);
+ }
+
+ /**
+ * Returns a filter that filters files based on a cutoff time.
+ *
+ * @param cutoff the time threshold
+ * @param acceptOlder if true, older files get accepted, if false, newer
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(long cutoff, boolean acceptOlder) {
+ return new AgeFileFilter(cutoff, acceptOlder);
+ }
+
+ /**
+ * Returns a filter that returns true if the file was last modified after
+ * the specified cutoff date.
+ *
+ * @param cutoffDate the time threshold
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(Date cutoffDate) {
+ return new AgeFileFilter(cutoffDate);
+ }
+
+ /**
+ * Returns a filter that filters files based on a cutoff date.
+ *
+ * @param cutoffDate the time threshold
+ * @param acceptOlder if true, older files get accepted, if false, newer
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(Date cutoffDate, boolean acceptOlder) {
+ return new AgeFileFilter(cutoffDate, acceptOlder);
+ }
+
+ /**
+ * Returns a filter that returns true if the file was last modified after
+ * the specified reference file.
+ *
+ * @param cutoffReference the file whose last modification
+ * time is usesd as the threshold age of the files
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(File cutoffReference) {
+ return new AgeFileFilter(cutoffReference);
+ }
+
+ /**
+ * Returns a filter that filters files based on a cutoff reference file.
+ *
+ * @param cutoffReference the file whose last modification
+ * time is usesd as the threshold age of the files
+ * @param acceptOlder if true, older files get accepted, if false, newer
+ * @return an appropriately configured age file filter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter ageFileFilter(File cutoffReference, boolean acceptOlder) {
+ return new AgeFileFilter(cutoffReference, acceptOlder);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a filter that returns true if the file is bigger than a certain size.
+ *
+ * @param threshold the file size threshold
+ * @return an appropriately configured SizeFileFilter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter sizeFileFilter(long threshold) {
+ return new SizeFileFilter(threshold);
+ }
+
+ /**
+ * Returns a filter that filters based on file size.
+ *
+ * @param threshold the file size threshold
+ * @param acceptLarger if true, larger files get accepted, if false, smaller
+ * @return an appropriately configured SizeFileFilter
+ * @since Commons IO 1.2
+ */
+ public static IOFileFilter sizeFileFilter(long threshold, boolean acceptLarger) {
+ return new SizeFileFilter(threshold, acceptLarger);
+ }
+
+ /**
+ * Returns a filter that accepts files whose size is >= minimum size
+ * and <= maximum size.
+ *
+ * @param minSizeInclusive the minimum file size (inclusive)
+ * @param maxSizeInclusive the maximum file size (inclusive)
+ * @return an appropriately configured IOFileFilter
+ * @since Commons IO 1.3
+ */
+ public static IOFileFilter sizeRangeFileFilter(long minSizeInclusive, long maxSizeInclusive ) {
+ IOFileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true);
+ IOFileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false);
+ return new AndFileFilter(minimumFilter, maximumFilter);
+ }
+
+ //-----------------------------------------------------------------------
+ /* Constructed on demand and then cached */
+ private static IOFileFilter cvsFilter;
+
+ /* Constructed on demand and then cached */
+ private static IOFileFilter svnFilter;
+
+ /**
+ * Decorates a filter to make it ignore CVS directories.
+ * Passing in null
will return a filter that accepts everything
+ * except CVS directories.
+ *
+ * @param filter the filter to decorate, null means an unrestricted filter
+ * @return the decorated filter, never null
+ * @since Commons IO 1.1 (method existed but had bug in 1.0)
+ */
+ public static IOFileFilter makeCVSAware(IOFileFilter filter) {
+ if (cvsFilter == null) {
+ cvsFilter = notFileFilter(
+ andFileFilter(directoryFileFilter(), nameFileFilter("CVS")));
+ }
+ if (filter == null) {
+ return cvsFilter;
+ } else {
+ return andFileFilter(filter, cvsFilter);
+ }
+ }
+
+ /**
+ * Decorates a filter to make it ignore SVN directories.
+ * Passing in null
will return a filter that accepts everything
+ * except SVN directories.
+ *
+ * @param filter the filter to decorate, null means an unrestricted filter
+ * @return the decorated filter, never null
+ * @since Commons IO 1.1
+ */
+ public static IOFileFilter makeSVNAware(IOFileFilter filter) {
+ if (svnFilter == null) {
+ svnFilter = notFileFilter(
+ andFileFilter(directoryFileFilter(), nameFileFilter(".svn")));
+ }
+ if (filter == null) {
+ return svnFilter;
+ } else {
+ return andFileFilter(filter, svnFilter);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Decorates a filter so that it only applies to directories and not to files.
+ *
+ * @param filter the filter to decorate, null means an unrestricted filter
+ * @return the decorated filter, never null
+ * @since Commons IO 1.3
+ */
+ public static IOFileFilter makeDirectoryOnly(IOFileFilter filter) {
+ if (filter == null) {
+ return DirectoryFileFilter.DIRECTORY;
+ }
+ return new AndFileFilter(DirectoryFileFilter.DIRECTORY, filter);
+ }
+
+ /**
+ * Decorates a filter so that it only applies to files and not to directories.
+ *
+ * @param filter the filter to decorate, null means an unrestricted filter
+ * @return the decorated filter, never null
+ * @since Commons IO 1.3
+ */
+ public static IOFileFilter makeFileOnly(IOFileFilter filter) {
+ if (filter == null) {
+ return FileFileFilter.FILE;
+ }
+ return new AndFileFilter(FileFileFilter.FILE, filter);
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/HiddenFileFilter.java b/src/org/apache/commons/io/filefilter/HiddenFileFilter.java
index 244153d5e36e7509a778ba51f5c4150fda97235d..9d90aa7f4aa6351071243d862000fe06709d808b 100644
--- a/src/org/apache/commons/io/filefilter/HiddenFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/HiddenFileFilter.java
@@ -1,76 +1,76 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * This filter accepts File
s that are hidden.
- *
- * File dir = new File(".");
- * String[] files = dir.list( HiddenFileFilter.HIDDEN );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( HiddenFileFilter.VISIBLE );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 587916 $
- */
-public class HiddenFileFilter extends AbstractFileFilter implements Serializable {
-
- /** Singleton instance of hidden filter */
- public static final IOFileFilter HIDDEN = new HiddenFileFilter();
-
- /** Singleton instance of visible filter */
- public static final IOFileFilter VISIBLE = new NotFileFilter(HIDDEN);
-
- /**
- * Restrictive consructor.
- */
- protected HiddenFileFilter() {
- }
-
- /**
- * Checks to see if the file is hidden.
- *
- * @param file the File to check
- * @return true
if the file is
- * hidden, otherwise false
.
- */
- public boolean accept(File file) {
- return file.isHidden();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This filter accepts File
s that are hidden.
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( HiddenFileFilter.HIDDEN );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( HiddenFileFilter.VISIBLE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 587916 $
+ */
+public class HiddenFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** Singleton instance of hidden filter */
+ public static final IOFileFilter HIDDEN = new HiddenFileFilter();
+
+ /** Singleton instance of visible filter */
+ public static final IOFileFilter VISIBLE = new NotFileFilter(HIDDEN);
+
+ /**
+ * Restrictive consructor.
+ */
+ protected HiddenFileFilter() {
+ }
+
+ /**
+ * Checks to see if the file is hidden.
+ *
+ * @param file the File to check
+ * @return true
if the file is
+ * hidden, otherwise false
.
+ */
+ public boolean accept(File file) {
+ return file.isHidden();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/IOFileFilter.java b/src/org/apache/commons/io/filefilter/IOFileFilter.java
index 5ebd8275103525e078a3fe868547ddd5df33117b..cd650c17dc8b4415a6e15f4b8dd40bb5933cf402 100644
--- a/src/org/apache/commons/io/filefilter/IOFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/IOFileFilter.java
@@ -1,55 +1,55 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-
-/**
- * An interface which brings the FileFilter and FilenameFilter
- * interfaces together.
- *
- * @since Commons IO 1.0
- * @version $Revision: 471628 $ $Date: 2006-11-06 04:06:45 +0000 (Mon, 06 Nov 2006) $
- *
- * @author Stephen Colebourne
- */
-public interface IOFileFilter extends FileFilter, FilenameFilter {
-
- /**
- * Checks to see if the File should be accepted by this filter.
- * Test
:
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( new NameFileFilter("Test") );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.0
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- *
- * @author Stephen Colebourne
- * @author Federico Barbieri
- * @author Serge Knystautas
- * @author Peter Donald
- */
-public class NameFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The filenames to search for */
- private final String[] names;
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Constructs a new case-sensitive name file filter for a single name.
- *
- * @param name the name to allow, must not be null
- * @throws IllegalArgumentException if the name is null
- */
- public NameFileFilter(String name) {
- this(name, null);
- }
-
- /**
- * Construct a new name file filter specifying case-sensitivity.
- *
- * @param name the name to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the name is null
- */
- public NameFileFilter(String name, IOCase caseSensitivity) {
- if (name == null) {
- throw new IllegalArgumentException("The wildcard must not be null");
- }
- this.names = new String[] {name};
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new case-sensitive name file filter for an array of names.
- * Test
:
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( new NameFileFilter("Test") );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ *
+ * @author Stephen Colebourne
+ * @author Federico Barbieri
+ * @author Serge Knystautas
+ * @author Peter Donald
+ */
+public class NameFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The filenames to search for */
+ private final String[] names;
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Constructs a new case-sensitive name file filter for a single name.
+ *
+ * @param name the name to allow, must not be null
+ * @throws IllegalArgumentException if the name is null
+ */
+ public NameFileFilter(String name) {
+ this(name, null);
+ }
+
+ /**
+ * Construct a new name file filter specifying case-sensitivity.
+ *
+ * @param name the name to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the name is null
+ */
+ public NameFileFilter(String name, IOCase caseSensitivity) {
+ if (name == null) {
+ throw new IllegalArgumentException("The wildcard must not be null");
+ }
+ this.names = new String[] {name};
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new case-sensitive name file filter for an array of names.
+ * true
if any filters in the
- * list return true
. Otherwise, it returns false
.
- * Checking of the file filter list stops when the first filter returns
- * true
.
- *
- * @since Commons IO 1.0
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- *
- * @author Steven Caswell
- */
-public class OrFileFilter
- extends AbstractFileFilter
- implements ConditionalFileFilter, Serializable {
-
- /** The list of file filters. */
- private List fileFilters;
-
- /**
- * Constructs a new instance of OrFileFilter
.
- *
- * @since Commons IO 1.1
- */
- public OrFileFilter() {
- this.fileFilters = new ArrayList();
- }
-
- /**
- * Constructs a new instance of OrFileFilter
- * with the specified filters.
- *
- * @param fileFilters the file filters for this filter, copied, null ignored
- * @since Commons IO 1.1
- */
- public OrFileFilter(final List fileFilters) {
- if (fileFilters == null) {
- this.fileFilters = new ArrayList();
- } else {
- this.fileFilters = new ArrayList(fileFilters);
- }
- }
-
- /**
- * Constructs a new file filter that ORs the result of two other filters.
- *
- * @param filter1 the first filter, must not be null
- * @param filter2 the second filter, must not be null
- * @throws IllegalArgumentException if either filter is null
- */
- public OrFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
- if (filter1 == null || filter2 == null) {
- throw new IllegalArgumentException("The filters must not be null");
- }
- this.fileFilters = new ArrayList();
- addFileFilter(filter1);
- addFileFilter(filter2);
- }
-
- /**
- * {@inheritDoc}
- */
- public void addFileFilter(final IOFileFilter ioFileFilter) {
- this.fileFilters.add(ioFileFilter);
- }
-
- /**
- * {@inheritDoc}
- */
- public List getFileFilters() {
- return Collections.unmodifiableList(this.fileFilters);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean removeFileFilter(IOFileFilter ioFileFilter) {
- return this.fileFilters.remove(ioFileFilter);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFileFilters(final List fileFilters) {
- this.fileFilters = fileFilters;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean accept(final File file) {
- for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
- IOFileFilter fileFilter = (IOFileFilter) iter.next();
- if (fileFilter.accept(file)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean accept(final File file, final String name) {
- for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
- IOFileFilter fileFilter = (IOFileFilter) iter.next();
- if (fileFilter.accept(file, name)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Provide a String representaion of this file filter.
- *
- * @return a String representaion
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(super.toString());
- buffer.append("(");
- if (fileFilters != null) {
- for (int i = 0; i < fileFilters.size(); i++) {
- if (i > 0) {
- buffer.append(",");
- }
- Object filter = fileFilters.get(i);
- buffer.append(filter == null ? "null" : filter.toString());
- }
- }
- buffer.append(")");
- return buffer.toString();
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A {@link java.io.FileFilter} providing conditional OR logic across a list of
+ * file filters. This filter returns true
if any filters in the
+ * list return true
. Otherwise, it returns false
.
+ * Checking of the file filter list stops when the first filter returns
+ * true
.
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ *
+ * @author Steven Caswell
+ */
+public class OrFileFilter
+ extends AbstractFileFilter
+ implements ConditionalFileFilter, Serializable {
+
+ /** The list of file filters. */
+ private List fileFilters;
+
+ /**
+ * Constructs a new instance of OrFileFilter
.
+ *
+ * @since Commons IO 1.1
+ */
+ public OrFileFilter() {
+ this.fileFilters = new ArrayList();
+ }
+
+ /**
+ * Constructs a new instance of OrFileFilter
+ * with the specified filters.
+ *
+ * @param fileFilters the file filters for this filter, copied, null ignored
+ * @since Commons IO 1.1
+ */
+ public OrFileFilter(final List fileFilters) {
+ if (fileFilters == null) {
+ this.fileFilters = new ArrayList();
+ } else {
+ this.fileFilters = new ArrayList(fileFilters);
+ }
+ }
+
+ /**
+ * Constructs a new file filter that ORs the result of two other filters.
+ *
+ * @param filter1 the first filter, must not be null
+ * @param filter2 the second filter, must not be null
+ * @throws IllegalArgumentException if either filter is null
+ */
+ public OrFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
+ if (filter1 == null || filter2 == null) {
+ throw new IllegalArgumentException("The filters must not be null");
+ }
+ this.fileFilters = new ArrayList();
+ addFileFilter(filter1);
+ addFileFilter(filter2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addFileFilter(final IOFileFilter ioFileFilter) {
+ this.fileFilters.add(ioFileFilter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getFileFilters() {
+ return Collections.unmodifiableList(this.fileFilters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean removeFileFilter(IOFileFilter ioFileFilter) {
+ return this.fileFilters.remove(ioFileFilter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFileFilters(final List fileFilters) {
+ this.fileFilters = fileFilters;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean accept(final File file) {
+ for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
+ IOFileFilter fileFilter = (IOFileFilter) iter.next();
+ if (fileFilter.accept(file)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean accept(final File file, final String name) {
+ for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) {
+ IOFileFilter fileFilter = (IOFileFilter) iter.next();
+ if (fileFilter.accept(file, name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Provide a String representaion of this file filter.
+ *
+ * @return a String representaion
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(super.toString());
+ buffer.append("(");
+ if (fileFilters != null) {
+ for (int i = 0; i < fileFilters.size(); i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ Object filter = fileFilters.get(i);
+ buffer.append(filter == null ? "null" : filter.toString());
+ }
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/PrefixFileFilter.java b/src/org/apache/commons/io/filefilter/PrefixFileFilter.java
index 0b6fcb96135b4e1873f5a6a46291fb85d234f387..15826bcea08e2aef35e33dfe61b3ab0252e7c380 100644
--- a/src/org/apache/commons/io/filefilter/PrefixFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/PrefixFileFilter.java
@@ -1,197 +1,197 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.commons.io.IOCase;
-
-/**
- * Filters filenames for a certain prefix.
- * Test
:
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( new PrefixFileFilter("Test") );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.0
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- *
- * @author Stephen Colebourne
- * @author Federico Barbieri
- * @author Serge Knystautas
- * @author Peter Donald
- */
-public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The filename prefixes to search for */
- private final String[] prefixes;
-
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Constructs a new Prefix file filter for a single prefix.
- *
- * @param prefix the prefix to allow, must not be null
- * @throws IllegalArgumentException if the prefix is null
- */
- public PrefixFileFilter(String prefix) {
- this(prefix, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Prefix file filter for a single prefix
- * specifying case-sensitivity.
- *
- * @param prefix the prefix to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the prefix is null
- * @since Commons IO 1.4
- */
- public PrefixFileFilter(String prefix, IOCase caseSensitivity) {
- if (prefix == null) {
- throw new IllegalArgumentException("The prefix must not be null");
- }
- this.prefixes = new String[] {prefix};
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new Prefix file filter for any of an array of prefixes.
- * Test
:
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( new PrefixFileFilter("Test") );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ *
+ * @author Stephen Colebourne
+ * @author Federico Barbieri
+ * @author Serge Knystautas
+ * @author Peter Donald
+ */
+public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The filename prefixes to search for */
+ private final String[] prefixes;
+
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Constructs a new Prefix file filter for a single prefix.
+ *
+ * @param prefix the prefix to allow, must not be null
+ * @throws IllegalArgumentException if the prefix is null
+ */
+ public PrefixFileFilter(String prefix) {
+ this(prefix, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Prefix file filter for a single prefix
+ * specifying case-sensitivity.
+ *
+ * @param prefix the prefix to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the prefix is null
+ * @since Commons IO 1.4
+ */
+ public PrefixFileFilter(String prefix, IOCase caseSensitivity) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("The prefix must not be null");
+ }
+ this.prefixes = new String[] {prefix};
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new Prefix file filter for any of an array of prefixes.
+ *
- * File dir = new File(".");
- * FileFilter fileFilter = new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$");
- * File[] files = dir.listFiles(fileFilter);
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @author Oliver Siegmar
- * @version $Revision: 606381 $
- * @since Commons IO 1.4
- */
-public class RegexFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The regular expression pattern that will be used to match filenames */
- private final Pattern pattern;
-
- /**
- * Construct a new regular expression filter.
- *
- * @param pattern regular string expression to match
- * @throws IllegalArgumentException if the pattern is null
- */
- public RegexFileFilter(String pattern) {
- if (pattern == null) {
- throw new IllegalArgumentException("Pattern is missing");
- }
-
- this.pattern = Pattern.compile(pattern);
- }
-
- /**
- * Construct a new regular expression filter with the specified flags case sensitivity.
- *
- * @param pattern regular string expression to match
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the pattern is null
- */
- public RegexFileFilter(String pattern, IOCase caseSensitivity) {
- if (pattern == null) {
- throw new IllegalArgumentException("Pattern is missing");
- }
- int flags = 0;
- if (caseSensitivity != null && !caseSensitivity.isCaseSensitive()) {
- flags = Pattern.CASE_INSENSITIVE;
- }
- this.pattern = Pattern.compile(pattern, flags);
- }
-
- /**
- * Construct a new regular expression filter with the specified flags.
- *
- * @param pattern regular string expression to match
- * @param flags pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE}
- * @throws IllegalArgumentException if the pattern is null
- */
- public RegexFileFilter(String pattern, int flags) {
- if (pattern == null) {
- throw new IllegalArgumentException("Pattern is missing");
- }
- this.pattern = Pattern.compile(pattern, flags);
- }
-
- /**
- * Construct a new regular expression filter for a compiled regular expression
- *
- * @param pattern regular expression to match
- * @throws IllegalArgumentException if the pattern is null
- */
- public RegexFileFilter(Pattern pattern) {
- if (pattern == null) {
- throw new IllegalArgumentException("Pattern is missing");
- }
-
- this.pattern = pattern;
- }
-
- /**
- * Checks to see if the filename matches one of the regular expressions.
- *
- * @param dir the file directory
- * @param name the filename
- * @return true if the filename matches one of the regular expressions
- */
- public boolean accept(File dir, String name) {
- return (pattern.matcher(name).matches());
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOCase;
+
+/**
+ * Filters files using supplied regular expression(s).
+ *
+ * See java.util.regex.Pattern for regex matching rules
+ *
+ *
+ *
+ * e.g.
+ *
+ * File dir = new File(".");
+ * FileFilter fileFilter = new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @author Oliver Siegmar
+ * @version $Revision: 606381 $
+ * @since Commons IO 1.4
+ */
+public class RegexFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The regular expression pattern that will be used to match filenames */
+ private final Pattern pattern;
+
+ /**
+ * Construct a new regular expression filter.
+ *
+ * @param pattern regular string expression to match
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public RegexFileFilter(String pattern) {
+ if (pattern == null) {
+ throw new IllegalArgumentException("Pattern is missing");
+ }
+
+ this.pattern = Pattern.compile(pattern);
+ }
+
+ /**
+ * Construct a new regular expression filter with the specified flags case sensitivity.
+ *
+ * @param pattern regular string expression to match
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public RegexFileFilter(String pattern, IOCase caseSensitivity) {
+ if (pattern == null) {
+ throw new IllegalArgumentException("Pattern is missing");
+ }
+ int flags = 0;
+ if (caseSensitivity != null && !caseSensitivity.isCaseSensitive()) {
+ flags = Pattern.CASE_INSENSITIVE;
+ }
+ this.pattern = Pattern.compile(pattern, flags);
+ }
+
+ /**
+ * Construct a new regular expression filter with the specified flags.
+ *
+ * @param pattern regular string expression to match
+ * @param flags pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE}
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public RegexFileFilter(String pattern, int flags) {
+ if (pattern == null) {
+ throw new IllegalArgumentException("Pattern is missing");
+ }
+ this.pattern = Pattern.compile(pattern, flags);
+ }
+
+ /**
+ * Construct a new regular expression filter for a compiled regular expression
+ *
+ * @param pattern regular expression to match
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public RegexFileFilter(Pattern pattern) {
+ if (pattern == null) {
+ throw new IllegalArgumentException("Pattern is missing");
+ }
+
+ this.pattern = pattern;
+ }
+
+ /**
+ * Checks to see if the filename matches one of the regular expressions.
+ *
+ * @param dir the file directory
+ * @param name the filename
+ * @return true if the filename matches one of the regular expressions
+ */
+ public boolean accept(File dir, String name) {
+ return (pattern.matcher(name).matches());
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/SizeFileFilter.java b/src/org/apache/commons/io/filefilter/SizeFileFilter.java
index 614e4243f111dffa5ec832fe1808ce32c160f37e..1e97a42155b346281071a0b5a0635a1518ac92ac 100644
--- a/src/org/apache/commons/io/filefilter/SizeFileFilter.java
+++ b/src/org/apache/commons/io/filefilter/SizeFileFilter.java
@@ -1,103 +1,103 @@
-/*
- * 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.commons.io.filefilter;
-
-import java.io.File;
-import java.io.Serializable;
-
-/**
- * Filters files based on size, can filter either smaller files or
- * files equal to or larger than a given threshold.
- *
- * File dir = new File(".");
- * String[] files = dir.list( new SizeFileFilter(1024 * 1024) );
- * for ( int i = 0; i < files.length; i++ ) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @author Rahul Akolkar
- * @version $Id: SizeFileFilter.java 591058 2007-11-01 15:47:05Z niallp $
- * @since Commons IO 1.2
- */
-public class SizeFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The size threshold. */
- private final long size;
- /** Whether the files accepted will be larger or smaller. */
- private final boolean acceptLarger;
-
- /**
- * Constructs a new size file filter for files equal to or
- * larger than a certain size.
- *
- * @param size the threshold size of the files
- * @throws IllegalArgumentException if the size is negative
- */
- public SizeFileFilter(long size) {
- this(size, true);
- }
-
- /**
- * Constructs a new size file filter for files based on a certain size
- * threshold.
- *
- * @param size the threshold size of the files
- * @param acceptLarger if true, files equal to or larger are accepted,
- * otherwise smaller ones (but not equal to)
- * @throws IllegalArgumentException if the size is negative
- */
- public SizeFileFilter(long size, boolean acceptLarger) {
- if (size < 0) {
- throw new IllegalArgumentException("The size must be non-negative");
- }
- this.size = size;
- this.acceptLarger = acceptLarger;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks to see if the size of the file is favorable.
- *
+ * File dir = new File(".");
+ * String[] files = dir.list( new SizeFileFilter(1024 * 1024) );
+ * for ( int i = 0; i < files.length; i++ ) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @author Rahul Akolkar
+ * @version $Id: SizeFileFilter.java 591058 2007-11-01 15:47:05Z niallp $
+ * @since Commons IO 1.2
+ */
+public class SizeFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The size threshold. */
+ private final long size;
+ /** Whether the files accepted will be larger or smaller. */
+ private final boolean acceptLarger;
+
+ /**
+ * Constructs a new size file filter for files equal to or
+ * larger than a certain size.
+ *
+ * @param size the threshold size of the files
+ * @throws IllegalArgumentException if the size is negative
+ */
+ public SizeFileFilter(long size) {
+ this(size, true);
+ }
+
+ /**
+ * Constructs a new size file filter for files based on a certain size
+ * threshold.
+ *
+ * @param size the threshold size of the files
+ * @param acceptLarger if true, files equal to or larger are accepted,
+ * otherwise smaller ones (but not equal to)
+ * @throws IllegalArgumentException if the size is negative
+ */
+ public SizeFileFilter(long size, boolean acceptLarger) {
+ if (size < 0) {
+ throw new IllegalArgumentException("The size must be non-negative");
+ }
+ this.size = size;
+ this.acceptLarger = acceptLarger;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks to see if the size of the file is favorable.
+ * *.java
files
- * in the current directory:
- *
- *
- * File dir = new File(".");
- * String[] files = dir.list( new SuffixFileFilter(".java") );
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @since Commons IO 1.0
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- *
- * @author Stephen Colebourne
- * @author Federico Barbieri
- * @author Serge Knystautas
- * @author Peter Donald
- */
-public class SuffixFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The filename suffixes to search for */
- private final String[] suffixes;
-
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Constructs a new Suffix file filter for a single extension.
- *
- * @param suffix the suffix to allow, must not be null
- * @throws IllegalArgumentException if the suffix is null
- */
- public SuffixFileFilter(String suffix) {
- this(suffix, IOCase.SENSITIVE);
- }
-
- /**
- * Constructs a new Suffix file filter for a single extension
- * specifying case-sensitivity.
- *
- * @param suffix the suffix to allow, must not be null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the suffix is null
- * @since Commons IO 1.4
- */
- public SuffixFileFilter(String suffix, IOCase caseSensitivity) {
- if (suffix == null) {
- throw new IllegalArgumentException("The suffix must not be null");
- }
- this.suffixes = new String[] {suffix};
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Constructs a new Suffix file filter for an array of suffixs.
- * *.java
files
+ * in the current directory:
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list( new SuffixFileFilter(".java") );
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @since Commons IO 1.0
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ *
+ * @author Stephen Colebourne
+ * @author Federico Barbieri
+ * @author Serge Knystautas
+ * @author Peter Donald
+ */
+public class SuffixFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The filename suffixes to search for */
+ private final String[] suffixes;
+
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Constructs a new Suffix file filter for a single extension.
+ *
+ * @param suffix the suffix to allow, must not be null
+ * @throws IllegalArgumentException if the suffix is null
+ */
+ public SuffixFileFilter(String suffix) {
+ this(suffix, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Constructs a new Suffix file filter for a single extension
+ * specifying case-sensitivity.
+ *
+ * @param suffix the suffix to allow, must not be null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the suffix is null
+ * @since Commons IO 1.4
+ */
+ public SuffixFileFilter(String suffix, IOCase caseSensitivity) {
+ if (suffix == null) {
+ throw new IllegalArgumentException("The suffix must not be null");
+ }
+ this.suffixes = new String[] {suffix};
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Constructs a new Suffix file filter for an array of suffixs.
+ *
- * File dir = new File(".");
- * FileFilter fileFilter = new WildcardFileFilter("*test*.java~*~");
- * File[] files = dir.listFiles(fileFilter);
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @author Jason Anderson
- * @version $Revision: 155419 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- * @since Commons IO 1.3
- */
-public class WildcardFileFilter extends AbstractFileFilter implements Serializable {
-
- /** The wildcards that will be used to match filenames. */
- private final String[] wildcards;
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
-
- /**
- * Construct a new case-sensitive wildcard filter for a single wildcard.
- *
- * @param wildcard the wildcard to match
- * @throws IllegalArgumentException if the pattern is null
- */
- public WildcardFileFilter(String wildcard) {
- this(wildcard, null);
- }
-
- /**
- * Construct a new wildcard filter for a single wildcard specifying case-sensitivity.
- *
- * @param wildcard the wildcard to match, not null
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
- * @throws IllegalArgumentException if the pattern is null
- */
- public WildcardFileFilter(String wildcard, IOCase caseSensitivity) {
- if (wildcard == null) {
- throw new IllegalArgumentException("The wildcard must not be null");
- }
- this.wildcards = new String[] { wildcard };
- this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
- }
-
- /**
- * Construct a new case-sensitive wildcard filter for an array of wildcards.
- *
+ * File dir = new File(".");
+ * FileFilter fileFilter = new WildcardFileFilter("*test*.java~*~");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @author Jason Anderson
+ * @version $Revision: 155419 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ * @since Commons IO 1.3
+ */
+public class WildcardFileFilter extends AbstractFileFilter implements Serializable {
+
+ /** The wildcards that will be used to match filenames. */
+ private final String[] wildcards;
+ /** Whether the comparison is case sensitive. */
+ private final IOCase caseSensitivity;
+
+ /**
+ * Construct a new case-sensitive wildcard filter for a single wildcard.
+ *
+ * @param wildcard the wildcard to match
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public WildcardFileFilter(String wildcard) {
+ this(wildcard, null);
+ }
+
+ /**
+ * Construct a new wildcard filter for a single wildcard specifying case-sensitivity.
+ *
+ * @param wildcard the wildcard to match, not null
+ * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public WildcardFileFilter(String wildcard, IOCase caseSensitivity) {
+ if (wildcard == null) {
+ throw new IllegalArgumentException("The wildcard must not be null");
+ }
+ this.wildcards = new String[] { wildcard };
+ this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
+ }
+
+ /**
+ * Construct a new case-sensitive wildcard filter for an array of wildcards.
+ *
- * File dir = new File(".");
- * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
- * File[] files = dir.listFiles(fileFilter);
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- *
- *
- * @author Jason Anderson
- * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
- * @since Commons IO 1.1
- * @deprecated Use WilcardFileFilter. Deprecated as this class performs directory
- * filtering which it shouldn't do, but that can't be removed due to compatability.
- */
-public class WildcardFilter extends AbstractFileFilter implements Serializable {
-
- /** The wildcards that will be used to match filenames. */
- private final String[] wildcards;
-
- /**
- * Construct a new case-sensitive wildcard filter for a single wildcard.
- *
- * @param wildcard the wildcard to match
- * @throws IllegalArgumentException if the pattern is null
- */
- public WildcardFilter(String wildcard) {
- if (wildcard == null) {
- throw new IllegalArgumentException("The wildcard must not be null");
- }
- this.wildcards = new String[] { wildcard };
- }
-
- /**
- * Construct a new case-sensitive wildcard filter for an array of wildcards.
- *
- * @param wildcards the array of wildcards to match
- * @throws IllegalArgumentException if the pattern array is null
- */
- public WildcardFilter(String[] wildcards) {
- if (wildcards == null) {
- throw new IllegalArgumentException("The wildcard array must not be null");
- }
- this.wildcards = wildcards;
- }
-
- /**
- * Construct a new case-sensitive wildcard filter for a list of wildcards.
- *
- * @param wildcards the list of wildcards to match
- * @throws IllegalArgumentException if the pattern list is null
- * @throws ClassCastException if the list does not contain Strings
- */
- public WildcardFilter(List wildcards) {
- if (wildcards == null) {
- throw new IllegalArgumentException("The wildcard list must not be null");
- }
- this.wildcards = (String[]) wildcards.toArray(new String[wildcards.size()]);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Checks to see if the filename matches one of the wildcards.
- *
- * @param dir the file directory
- * @param name the filename
- * @return true if the filename matches one of the wildcards
- */
- public boolean accept(File dir, String name) {
- if (dir != null && new File(dir, name).isDirectory()) {
- return false;
- }
-
- for (int i = 0; i < wildcards.length; i++) {
- if (FilenameUtils.wildcardMatch(name, wildcards[i])) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Checks to see if the filename matches one of the wildcards.
- *
- * @param file the file to check
- * @return true if the filename matches one of the wildcards
- */
- public boolean accept(File file) {
- if (file.isDirectory()) {
- return false;
- }
-
- for (int i = 0; i < wildcards.length; i++) {
- if (FilenameUtils.wildcardMatch(file.getName(), wildcards[i])) {
- return true;
- }
- }
-
- return false;
- }
-
-}
+/*
+ * 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.commons.io.filefilter;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.commons.io.FilenameUtils;
+
+/**
+ * Filters files using the supplied wildcards.
+ *
+ * File dir = new File(".");
+ * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * @author Jason Anderson
+ * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
+ * @since Commons IO 1.1
+ * @deprecated Use WilcardFileFilter. Deprecated as this class performs directory
+ * filtering which it shouldn't do, but that can't be removed due to compatability.
+ */
+public class WildcardFilter extends AbstractFileFilter implements Serializable {
+
+ /** The wildcards that will be used to match filenames. */
+ private final String[] wildcards;
+
+ /**
+ * Construct a new case-sensitive wildcard filter for a single wildcard.
+ *
+ * @param wildcard the wildcard to match
+ * @throws IllegalArgumentException if the pattern is null
+ */
+ public WildcardFilter(String wildcard) {
+ if (wildcard == null) {
+ throw new IllegalArgumentException("The wildcard must not be null");
+ }
+ this.wildcards = new String[] { wildcard };
+ }
+
+ /**
+ * Construct a new case-sensitive wildcard filter for an array of wildcards.
+ *
+ * @param wildcards the array of wildcards to match
+ * @throws IllegalArgumentException if the pattern array is null
+ */
+ public WildcardFilter(String[] wildcards) {
+ if (wildcards == null) {
+ throw new IllegalArgumentException("The wildcard array must not be null");
+ }
+ this.wildcards = wildcards;
+ }
+
+ /**
+ * Construct a new case-sensitive wildcard filter for a list of wildcards.
+ *
+ * @param wildcards the list of wildcards to match
+ * @throws IllegalArgumentException if the pattern list is null
+ * @throws ClassCastException if the list does not contain Strings
+ */
+ public WildcardFilter(List wildcards) {
+ if (wildcards == null) {
+ throw new IllegalArgumentException("The wildcard list must not be null");
+ }
+ this.wildcards = (String[]) wildcards.toArray(new String[wildcards.size()]);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks to see if the filename matches one of the wildcards.
+ *
+ * @param dir the file directory
+ * @param name the filename
+ * @return true if the filename matches one of the wildcards
+ */
+ public boolean accept(File dir, String name) {
+ if (dir != null && new File(dir, name).isDirectory()) {
+ return false;
+ }
+
+ for (int i = 0; i < wildcards.length; i++) {
+ if (FilenameUtils.wildcardMatch(name, wildcards[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks to see if the filename matches one of the wildcards.
+ *
+ * @param file the file to check
+ * @return true if the filename matches one of the wildcards
+ */
+ public boolean accept(File file) {
+ if (file.isDirectory()) {
+ return false;
+ }
+
+ for (int i = 0; i < wildcards.length; i++) {
+ if (FilenameUtils.wildcardMatch(file.getName(), wildcards[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/org/apache/commons/io/filefilter/package.html b/src/org/apache/commons/io/filefilter/package.html
index 7a45f251dedbecf0d69b02093560a1b73651d615..e495e9521399b04ab0241dc8eb2675a33a2bf37c 100644
--- a/src/org/apache/commons/io/filefilter/package.html
+++ b/src/org/apache/commons/io/filefilter/package.html
@@ -1,143 +1,143 @@
-
-
-
-
-
-
-
-
-
-
- DirectoryFilter
- Only accept directories
-
-
- PrefixFileFilter
- Filter based on a prefix
-
-
- SuffixFileFilter
- Filter based on a suffix
-
-
- NameFileFilter
- Filter based on a filename
-
-
- WildcardFileFilter
- Filter based on wildcards
-
-
- AgeFileFilter
- Filter based on last modified time of file
-
-
-
-SizeFileFilter
- Filter based on file size
-
-
-
-
-
-
- TrueFileFilter
- Accept all files
-
-
- FalseFileFilter
- Accept no files
-
-
- NotFileFilter
- Applies a logical NOT to an existing filter
-
-
- AndFileFilter
- Combines two filters using a logical AND
-
-
-
-
-OrFileFilter
- Combines two filter using a logical OR
-
- File dir = new File(".");
- String[] files = dir.list(
- new AndFileFilter(
- new AndFileFilter(
- new PrefixFileFilter("A"),
- new OrFileFilter(
- new SuffixFileFilter(".class"),
- new SuffixFileFilter(".java")
- )
- ),
- new NotFileFilter(
- new DirectoryFileFilter()
- )
- )
- );
- for ( int i=0; i<files.length; i++ ) {
- System.out.println(files[i]);
- }
-
-
-
- File dir = new File(".");
- String[] files = dir.list(
- FileFilterUtils.andFileFilter(
- FileFilterUtils.andFileFilter(
- FileFilterUtils.prefixFileFilter("A"),
- FileFilterUtils.orFileFilter(
- FileFilterUtils.suffixFileFilter(".class"),
- FileFilterUtils.suffixFileFilter(".java")
- )
- ),
- FileFilterUtils.notFileFilter(
- FileFilterUtils.directoryFileFilter()
- )
- )
- );
- for ( int i=0; i<files.length; i++ ) {
- System.out.println(files[i]);
- }
-
-
+
+
+
+
+
+ DirectoryFilter
+ Only accept directories
+
+
+ PrefixFileFilter
+ Filter based on a prefix
+
+
+ SuffixFileFilter
+ Filter based on a suffix
+
+
+ NameFileFilter
+ Filter based on a filename
+
+
+ WildcardFileFilter
+ Filter based on wildcards
+
+
+ AgeFileFilter
+ Filter based on last modified time of file
+
+
+
+SizeFileFilter
+ Filter based on file size
+
+
+
+
+
+
+ TrueFileFilter
+ Accept all files
+
+
+ FalseFileFilter
+ Accept no files
+
+
+ NotFileFilter
+ Applies a logical NOT to an existing filter
+
+
+ AndFileFilter
+ Combines two filters using a logical AND
+
+
+
+
+OrFileFilter
+ Combines two filter using a logical OR
+
+ File dir = new File(".");
+ String[] files = dir.list(
+ new AndFileFilter(
+ new AndFileFilter(
+ new PrefixFileFilter("A"),
+ new OrFileFilter(
+ new SuffixFileFilter(".class"),
+ new SuffixFileFilter(".java")
+ )
+ ),
+ new NotFileFilter(
+ new DirectoryFileFilter()
+ )
+ )
+ );
+ for ( int i=0; i<files.length; i++ ) {
+ System.out.println(files[i]);
+ }
+
+
+
+ File dir = new File(".");
+ String[] files = dir.list(
+ FileFilterUtils.andFileFilter(
+ FileFilterUtils.andFileFilter(
+ FileFilterUtils.prefixFileFilter("A"),
+ FileFilterUtils.orFileFilter(
+ FileFilterUtils.suffixFileFilter(".class"),
+ FileFilterUtils.suffixFileFilter(".java")
+ )
+ ),
+ FileFilterUtils.notFileFilter(
+ FileFilterUtils.directoryFileFilter()
+ )
+ )
+ );
+ for ( int i=0; i<files.length; i++ ) {
+ System.out.println(files[i]);
+ }
+
+null
- */
- public CharSequenceReader(CharSequence charSequence) {
- this.charSequence = (charSequence != null ? charSequence : "");
- }
-
- /**
- * Close resets the file back to the start and removes any marked position.
- */
- public void close() {
- idx = 0;
- mark = 0;
- }
-
- /**
- * Mark the current position.
- *
- * @param readAheadLimit ignored
- */
- public void mark(int readAheadLimit) {
- mark = idx;
- }
-
- /**
- * Mark is supported (returns true).
- *
- * @return true
- */
- public boolean markSupported() {
- return true;
- }
-
- /**
- * Read a single character.
- *
- * @return the next character from the character sequence
- * or -1 if the end has been reached.
- */
- public int read() {
- if (idx >= charSequence.length()) {
- return -1;
- } else {
- return charSequence.charAt(idx++);
- }
- }
-
- /**
- * Read the sepcified number of characters into the array.
- *
- * @param array The array to store the characters in
- * @param offset The starting position in the array to store
- * @param length The maximum number of characters to read
- * @return The number of characters read or -1 if there are
- * no more
- */
- public int read(char[] array, int offset, int length) {
- if (idx >= charSequence.length()) {
- return -1;
- }
- if (array == null) {
- throw new NullPointerException("Character array is missing");
- }
- if (length < 0 || (offset + length) > array.length) {
- throw new IndexOutOfBoundsException("Array Size=" + array.length +
- ", offset=" + offset + ", length=" + length);
- }
- int count = 0;
- for (int i = 0; i < length; i++) {
- int c = read();
- if (c == -1) {
- return count;
- }
- array[offset + i] = (char)c;
- count++;
- }
- return count;
- }
-
- /**
- * Reset the reader to the last marked position (or the beginning if
- * mark has not been called).
- */
- public void reset() {
- idx = mark;
- }
-
- /**
- * Skip the specified number of characters.
- *
- * @param n The number of characters to skip
- * @return The actual number of characters skipped
- */
- public long skip(long n) {
- if (n < 0) {
- throw new IllegalArgumentException(
- "Number of characters to skip is less than zero: " + n);
- }
- if (idx >= charSequence.length()) {
- return -1;
- }
- int dest = (int)Math.min(charSequence.length(), (idx + n));
- int count = dest - idx;
- idx = dest;
- return count;
- }
-
- /**
- * Return a String representation of the underlying
- * character sequence.
- *
- * @return The contents of the character sequence
- */
- public String toString() {
- return charSequence.toString();
- }
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.Reader;
+import java.io.Serializable;
+
+/**
+ * {@link Reader} implementation that can read from String, StringBuffer,
+ * StringBuilder or CharBuffer.
+ * null
+ */
+ public CharSequenceReader(CharSequence charSequence) {
+ this.charSequence = (charSequence != null ? charSequence : "");
+ }
+
+ /**
+ * Close resets the file back to the start and removes any marked position.
+ */
+ public void close() {
+ idx = 0;
+ mark = 0;
+ }
+
+ /**
+ * Mark the current position.
+ *
+ * @param readAheadLimit ignored
+ */
+ public void mark(int readAheadLimit) {
+ mark = idx;
+ }
+
+ /**
+ * Mark is supported (returns true).
+ *
+ * @return true
+ */
+ public boolean markSupported() {
+ return true;
+ }
+
+ /**
+ * Read a single character.
+ *
+ * @return the next character from the character sequence
+ * or -1 if the end has been reached.
+ */
+ public int read() {
+ if (idx >= charSequence.length()) {
+ return -1;
+ } else {
+ return charSequence.charAt(idx++);
+ }
+ }
+
+ /**
+ * Read the sepcified number of characters into the array.
+ *
+ * @param array The array to store the characters in
+ * @param offset The starting position in the array to store
+ * @param length The maximum number of characters to read
+ * @return The number of characters read or -1 if there are
+ * no more
+ */
+ public int read(char[] array, int offset, int length) {
+ if (idx >= charSequence.length()) {
+ return -1;
+ }
+ if (array == null) {
+ throw new NullPointerException("Character array is missing");
+ }
+ if (length < 0 || (offset + length) > array.length) {
+ throw new IndexOutOfBoundsException("Array Size=" + array.length +
+ ", offset=" + offset + ", length=" + length);
+ }
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ int c = read();
+ if (c == -1) {
+ return count;
+ }
+ array[offset + i] = (char)c;
+ count++;
+ }
+ return count;
+ }
+
+ /**
+ * Reset the reader to the last marked position (or the beginning if
+ * mark has not been called).
+ */
+ public void reset() {
+ idx = mark;
+ }
+
+ /**
+ * Skip the specified number of characters.
+ *
+ * @param n The number of characters to skip
+ * @return The actual number of characters skipped
+ */
+ public long skip(long n) {
+ if (n < 0) {
+ throw new IllegalArgumentException(
+ "Number of characters to skip is less than zero: " + n);
+ }
+ if (idx >= charSequence.length()) {
+ return -1;
+ }
+ int dest = (int)Math.min(charSequence.length(), (idx + n));
+ int count = dest - idx;
+ idx = dest;
+ return count;
+ }
+
+ /**
+ * Return a String representation of the underlying
+ * character sequence.
+ *
+ * @return The contents of the character sequence
+ */
+ public String toString() {
+ return charSequence.toString();
+ }
+}
diff --git a/src/org/apache/commons/io/input/ClassLoaderObjectInputStream.java b/src/org/apache/commons/io/input/ClassLoaderObjectInputStream.java
index 13d048946561492c76698231027f3a0ada28a5d1..334ff895f976d87814194295c744cacb39214cb8 100644
--- a/src/org/apache/commons/io/input/ClassLoaderObjectInputStream.java
+++ b/src/org/apache/commons/io/input/ClassLoaderObjectInputStream.java
@@ -1,77 +1,77 @@
-/*
- * 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.commons.io.input;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.io.StreamCorruptedException;
-
-/**
- * A special ObjectInputStream that loads a class based on a specified
- * ClassLoader
rather than the system default.
- * ClassLoader
rather than the system default.
+ * null
input stream.
- *
- * @version $Id: ClosedInputStream.java 601751 2007-12-06 14:55:45Z niallp $
- * @since Commons IO 1.4
- */
-public class ClosedInputStream extends InputStream {
-
- /**
- * A singleton.
- */
- public static final ClosedInputStream CLOSED_INPUT_STREAM = new ClosedInputStream();
-
- /**
- * Returns -1 to indicate that the stream is closed.
- *
- * @return always -1
- */
- public int read() {
- return -1;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.input;
+
+import java.io.InputStream;
+
+/**
+ * Closed input stream. This stream returns -1 to all attempts to read
+ * something from the stream.
+ * null
input stream.
+ *
+ * @version $Id: ClosedInputStream.java 601751 2007-12-06 14:55:45Z niallp $
+ * @since Commons IO 1.4
+ */
+public class ClosedInputStream extends InputStream {
+
+ /**
+ * A singleton.
+ */
+ public static final ClosedInputStream CLOSED_INPUT_STREAM = new ClosedInputStream();
+
+ /**
+ * Returns -1 to indicate that the stream is closed.
+ *
+ * @return always -1
+ */
+ public int read() {
+ return -1;
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/CountingInputStream.java b/src/org/apache/commons/io/input/CountingInputStream.java
index 2782276c88f4c8893a37c18db44bb89ccabda7f4..2e5da27875acef4f807166ea8213aba8836f4d81 100644
--- a/src/org/apache/commons/io/input/CountingInputStream.java
+++ b/src/org/apache/commons/io/input/CountingInputStream.java
@@ -1,175 +1,175 @@
-/*
- * 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.commons.io.input;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A decorating input stream that counts the number of bytes that have passed
- * through the stream so far.
- * int
.
- * See {@link #getByteCount()} for a method using a long
.
- *
- * @return the number of bytes accumulated
- * @throws ArithmeticException if the byte count is too large
- */
- public synchronized int getCount() {
- long result = getByteCount();
- if (result > Integer.MAX_VALUE) {
- throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
- }
- return (int) result;
- }
-
- /**
- * Set the byte count back to 0.
- * int
.
- * See {@link #resetByteCount()} for a method using a long
.
- *
- * @return the count previous to resetting
- * @throws ArithmeticException if the byte count is too large
- */
- public synchronized int resetCount() {
- long result = resetByteCount();
- if (result > Integer.MAX_VALUE) {
- throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
- }
- return (int) result;
- }
-
- /**
- * The number of bytes that have passed through this stream.
- * getCount()
- * and was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
- *
- * @return the number of bytes accumulated
- * @since Commons IO 1.3
- */
- public synchronized long getByteCount() {
- return this.count;
- }
-
- /**
- * Set the byte count back to 0.
- * resetCount()
- * and was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
- *
- * @return the count previous to resetting
- * @since Commons IO 1.3
- */
- public synchronized long resetByteCount() {
- long tmp = this.count;
- this.count = 0;
- return tmp;
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A decorating input stream that counts the number of bytes that have passed
+ * through the stream so far.
+ * int
.
+ * See {@link #getByteCount()} for a method using a long
.
+ *
+ * @return the number of bytes accumulated
+ * @throws ArithmeticException if the byte count is too large
+ */
+ public synchronized int getCount() {
+ long result = getByteCount();
+ if (result > Integer.MAX_VALUE) {
+ throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
+ }
+ return (int) result;
+ }
+
+ /**
+ * Set the byte count back to 0.
+ * int
.
+ * See {@link #resetByteCount()} for a method using a long
.
+ *
+ * @return the count previous to resetting
+ * @throws ArithmeticException if the byte count is too large
+ */
+ public synchronized int resetCount() {
+ long result = resetByteCount();
+ if (result > Integer.MAX_VALUE) {
+ throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
+ }
+ return (int) result;
+ }
+
+ /**
+ * The number of bytes that have passed through this stream.
+ * getCount()
+ * and was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the number of bytes accumulated
+ * @since Commons IO 1.3
+ */
+ public synchronized long getByteCount() {
+ return this.count;
+ }
+
+ /**
+ * Set the byte count back to 0.
+ * resetCount()
+ * and was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the count previous to resetting
+ * @since Commons IO 1.3
+ */
+ public synchronized long resetByteCount() {
+ long tmp = this.count;
+ this.count = 0;
+ return tmp;
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/DemuxInputStream.java b/src/org/apache/commons/io/input/DemuxInputStream.java
index 1ae8889169a4166142c071411e8953c5ef2d9dc1..7ef592cf9306e6a346a608a226dd9386f87293cd 100644
--- a/src/org/apache/commons/io/input/DemuxInputStream.java
+++ b/src/org/apache/commons/io/input/DemuxInputStream.java
@@ -1,91 +1,91 @@
-/*
- * 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.commons.io.input;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Data written to this stream is forwarded to a stream that has been associated
- * with this thread.
- *
- * @author Peter Donald
- * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
- */
-public class DemuxInputStream
- extends InputStream
-{
- private InheritableThreadLocal m_streams = new InheritableThreadLocal();
-
- /**
- * Bind the specified stream to the current thread.
- *
- * @param input the stream to bind
- * @return the InputStream that was previously active
- */
- public InputStream bindStream( InputStream input )
- {
- InputStream oldValue = getStream();
- m_streams.set( input );
- return oldValue;
- }
-
- /**
- * Closes stream associated with current thread.
- *
- * @throws IOException if an error occurs
- */
- public void close()
- throws IOException
- {
- InputStream input = getStream();
- if( null != input )
- {
- input.close();
- }
- }
-
- /**
- * Read byte from stream associated with current thread.
- *
- * @return the byte read from stream
- * @throws IOException if an error occurs
- */
- public int read()
- throws IOException
- {
- InputStream input = getStream();
- if( null != input )
- {
- return input.read();
- }
- else
- {
- return -1;
- }
- }
-
- /**
- * Utility method to retrieve stream bound to current thread (if any).
- *
- * @return the input stream
- */
- private InputStream getStream()
- {
- return (InputStream)m_streams.get();
- }
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Data written to this stream is forwarded to a stream that has been associated
+ * with this thread.
+ *
+ * @author Peter Donald
+ * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
+ */
+public class DemuxInputStream
+ extends InputStream
+{
+ private InheritableThreadLocal m_streams = new InheritableThreadLocal();
+
+ /**
+ * Bind the specified stream to the current thread.
+ *
+ * @param input the stream to bind
+ * @return the InputStream that was previously active
+ */
+ public InputStream bindStream( InputStream input )
+ {
+ InputStream oldValue = getStream();
+ m_streams.set( input );
+ return oldValue;
+ }
+
+ /**
+ * Closes stream associated with current thread.
+ *
+ * @throws IOException if an error occurs
+ */
+ public void close()
+ throws IOException
+ {
+ InputStream input = getStream();
+ if( null != input )
+ {
+ input.close();
+ }
+ }
+
+ /**
+ * Read byte from stream associated with current thread.
+ *
+ * @return the byte read from stream
+ * @throws IOException if an error occurs
+ */
+ public int read()
+ throws IOException
+ {
+ InputStream input = getStream();
+ if( null != input )
+ {
+ return input.read();
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Utility method to retrieve stream bound to current thread (if any).
+ *
+ * @return the input stream
+ */
+ private InputStream getStream()
+ {
+ return (InputStream)m_streams.get();
+ }
+}
diff --git a/src/org/apache/commons/io/input/NullInputStream.java b/src/org/apache/commons/io/input/NullInputStream.java
index 7cee2c6d091b149f1b703d4ed95d6920781813b1..96cc6c42da01b75dc5ca41fea9b6d9741fe90da9 100644
--- a/src/org/apache/commons/io/input/NullInputStream.java
+++ b/src/org/apache/commons/io/input/NullInputStream.java
@@ -1,329 +1,329 @@
-/*
- * 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.commons.io.input;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A functional, light weight {@link InputStream} that emulates
- * a stream of a specified size.
- * processByte()
and
- * processBytes()
methods can be implemented to generate
- * data, for example:
- *
- *
- * public class TestInputStream extends NullInputStream {
- * public TestInputStream(int size) {
- * super(size);
- * }
- * protected int processByte() {
- * return ... // return required value here
- * }
- * protected void processBytes(byte[] bytes, int offset, int length) {
- * for (int i = offset; i < length; i++) {
- * bytes[i] = ... // set array value here
- * }
- * }
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 463529 $
- */
-public class NullInputStream extends InputStream {
-
- private long size;
- private long position;
- private long mark = -1;
- private long readlimit;
- private boolean eof;
- private boolean throwEofException;
- private boolean markSupported;
-
- /**
- * Create an {@link InputStream} that emulates a specified size
- * which supports marking and does not throw EOFException.
- *
- * @param size The size of the input stream to emulate.
- */
- public NullInputStream(long size) {
- this(size, true, false);
- }
-
- /**
- * Create an {@link InputStream} that emulates a specified
- * size with option settings.
- *
- * @param size The size of the input stream to emulate.
- * @param markSupported Whether this instance will support
- * the mark()
functionality.
- * @param throwEofException Whether this implementation
- * will throw an {@link EOFException} or return -1 when the
- * end of file is reached.
- */
- public NullInputStream(long size, boolean markSupported, boolean throwEofException) {
- this.size = size;
- this.markSupported = markSupported;
- this.throwEofException = throwEofException;
- }
-
- /**
- * Return the current position.
- *
- * @return the current position.
- */
- public long getPosition() {
- return position;
- }
-
- /**
- * Return the size this {@link InputStream} emulates.
- *
- * @return The size of the input stream to emulate.
- */
- public long getSize() {
- return size;
- }
-
- /**
- * Return the number of bytes that can be read.
- *
- * @return The number of bytes that can be read.
- */
- public int available() {
- long avail = size - position;
- if (avail <= 0) {
- return 0;
- } else if (avail > Integer.MAX_VALUE) {
- return Integer.MAX_VALUE;
- } else {
- return (int)avail;
- }
- }
-
- /**
- * Close this input stream - resets the internal state to
- * the initial values.
- *
- * @throws IOException If an error occurs.
- */
- public void close() throws IOException {
- eof = false;
- position = 0;
- mark = -1;
- }
-
- /**
- * Mark the current position.
- *
- * @param readlimit The number of bytes before this marked position
- * is invalid.
- * @throws UnsupportedOperationException if mark is not supported.
- */
- public synchronized void mark(int readlimit) {
- if (!markSupported) {
- throw new UnsupportedOperationException("Mark not supported");
- }
- mark = position;
- this.readlimit = readlimit;
- }
-
- /**
- * Indicates whether mark is supported.
- *
- * @return Whether mark is supported or not.
- */
- public boolean markSupported() {
- return markSupported;
- }
-
- /**
- * Read a byte.
- *
- * @return Either The byte value returned by processByte()
- * or -1
if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read() throws IOException {
- if (eof) {
- throw new IOException("Read after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position++;
- return processByte();
- }
-
- /**
- * Read some bytes into the specified array.
- *
- * @param bytes The byte array to read into
- * @return The number of bytes read or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read(byte[] bytes) throws IOException {
- return read(bytes, 0, bytes.length);
- }
-
- /**
- * Read the specified number bytes into an array.
- *
- * @param bytes The byte array to read into.
- * @param offset The offset to start reading bytes into.
- * @param length The number of bytes to read.
- * @return The number of bytes read or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read(byte[] bytes, int offset, int length) throws IOException {
- if (eof) {
- throw new IOException("Read after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position += length;
- int returnLength = length;
- if (position > size) {
- returnLength = length - (int)(position - size);
- position = size;
- }
- processBytes(bytes, offset, returnLength);
- return returnLength;
- }
-
- /**
- * Reset the stream to the point when mark was last called.
- *
- * @throws UnsupportedOperationException if mark is not supported.
- * @throws IOException If no position has been marked
- * or the read limit has been exceed since the last position was
- * marked.
- */
- public synchronized void reset() throws IOException {
- if (!markSupported) {
- throw new UnsupportedOperationException("Mark not supported");
- }
- if (mark < 0) {
- throw new IOException("No position has been marked");
- }
- if (position > (mark + readlimit)) {
- throw new IOException("Marked position [" + mark +
- "] is no longer valid - passed the read limit [" +
- readlimit + "]");
- }
- position = mark;
- eof = false;
- }
-
- /**
- * Skip a specified number of bytes.
- *
- * @param numberOfBytes The number of bytes to skip.
- * @return The number of bytes skipped or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public long skip(long numberOfBytes) throws IOException {
- if (eof) {
- throw new IOException("Skip after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position += numberOfBytes;
- long returnLength = numberOfBytes;
- if (position > size) {
- returnLength = numberOfBytes - (position - size);
- position = size;
- }
- return returnLength;
- }
-
- /**
- * Return a byte value for the read()
method.
- * read(byte[], offset, length)
- * method.
- * -1
if throwEofException
is
- * set to false
- * @throws EOFException if throwEofException
is set
- * to true
.
- */
- private int doEndOfFile() throws EOFException {
- eof = true;
- if (throwEofException) {
- throw new EOFException();
- }
- return -1;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.input;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A functional, light weight {@link InputStream} that emulates
+ * a stream of a specified size.
+ * processByte()
and
+ * processBytes()
methods can be implemented to generate
+ * data, for example:
+ *
+ *
+ * public class TestInputStream extends NullInputStream {
+ * public TestInputStream(int size) {
+ * super(size);
+ * }
+ * protected int processByte() {
+ * return ... // return required value here
+ * }
+ * protected void processBytes(byte[] bytes, int offset, int length) {
+ * for (int i = offset; i < length; i++) {
+ * bytes[i] = ... // set array value here
+ * }
+ * }
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 463529 $
+ */
+public class NullInputStream extends InputStream {
+
+ private long size;
+ private long position;
+ private long mark = -1;
+ private long readlimit;
+ private boolean eof;
+ private boolean throwEofException;
+ private boolean markSupported;
+
+ /**
+ * Create an {@link InputStream} that emulates a specified size
+ * which supports marking and does not throw EOFException.
+ *
+ * @param size The size of the input stream to emulate.
+ */
+ public NullInputStream(long size) {
+ this(size, true, false);
+ }
+
+ /**
+ * Create an {@link InputStream} that emulates a specified
+ * size with option settings.
+ *
+ * @param size The size of the input stream to emulate.
+ * @param markSupported Whether this instance will support
+ * the mark()
functionality.
+ * @param throwEofException Whether this implementation
+ * will throw an {@link EOFException} or return -1 when the
+ * end of file is reached.
+ */
+ public NullInputStream(long size, boolean markSupported, boolean throwEofException) {
+ this.size = size;
+ this.markSupported = markSupported;
+ this.throwEofException = throwEofException;
+ }
+
+ /**
+ * Return the current position.
+ *
+ * @return the current position.
+ */
+ public long getPosition() {
+ return position;
+ }
+
+ /**
+ * Return the size this {@link InputStream} emulates.
+ *
+ * @return The size of the input stream to emulate.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Return the number of bytes that can be read.
+ *
+ * @return The number of bytes that can be read.
+ */
+ public int available() {
+ long avail = size - position;
+ if (avail <= 0) {
+ return 0;
+ } else if (avail > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ } else {
+ return (int)avail;
+ }
+ }
+
+ /**
+ * Close this input stream - resets the internal state to
+ * the initial values.
+ *
+ * @throws IOException If an error occurs.
+ */
+ public void close() throws IOException {
+ eof = false;
+ position = 0;
+ mark = -1;
+ }
+
+ /**
+ * Mark the current position.
+ *
+ * @param readlimit The number of bytes before this marked position
+ * is invalid.
+ * @throws UnsupportedOperationException if mark is not supported.
+ */
+ public synchronized void mark(int readlimit) {
+ if (!markSupported) {
+ throw new UnsupportedOperationException("Mark not supported");
+ }
+ mark = position;
+ this.readlimit = readlimit;
+ }
+
+ /**
+ * Indicates whether mark is supported.
+ *
+ * @return Whether mark is supported or not.
+ */
+ public boolean markSupported() {
+ return markSupported;
+ }
+
+ /**
+ * Read a byte.
+ *
+ * @return Either The byte value returned by processByte()
+ * or -1
if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read() throws IOException {
+ if (eof) {
+ throw new IOException("Read after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position++;
+ return processByte();
+ }
+
+ /**
+ * Read some bytes into the specified array.
+ *
+ * @param bytes The byte array to read into
+ * @return The number of bytes read or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read(byte[] bytes) throws IOException {
+ return read(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Read the specified number bytes into an array.
+ *
+ * @param bytes The byte array to read into.
+ * @param offset The offset to start reading bytes into.
+ * @param length The number of bytes to read.
+ * @return The number of bytes read or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read(byte[] bytes, int offset, int length) throws IOException {
+ if (eof) {
+ throw new IOException("Read after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position += length;
+ int returnLength = length;
+ if (position > size) {
+ returnLength = length - (int)(position - size);
+ position = size;
+ }
+ processBytes(bytes, offset, returnLength);
+ return returnLength;
+ }
+
+ /**
+ * Reset the stream to the point when mark was last called.
+ *
+ * @throws UnsupportedOperationException if mark is not supported.
+ * @throws IOException If no position has been marked
+ * or the read limit has been exceed since the last position was
+ * marked.
+ */
+ public synchronized void reset() throws IOException {
+ if (!markSupported) {
+ throw new UnsupportedOperationException("Mark not supported");
+ }
+ if (mark < 0) {
+ throw new IOException("No position has been marked");
+ }
+ if (position > (mark + readlimit)) {
+ throw new IOException("Marked position [" + mark +
+ "] is no longer valid - passed the read limit [" +
+ readlimit + "]");
+ }
+ position = mark;
+ eof = false;
+ }
+
+ /**
+ * Skip a specified number of bytes.
+ *
+ * @param numberOfBytes The number of bytes to skip.
+ * @return The number of bytes skipped or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public long skip(long numberOfBytes) throws IOException {
+ if (eof) {
+ throw new IOException("Skip after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position += numberOfBytes;
+ long returnLength = numberOfBytes;
+ if (position > size) {
+ returnLength = numberOfBytes - (position - size);
+ position = size;
+ }
+ return returnLength;
+ }
+
+ /**
+ * Return a byte value for the read()
method.
+ * read(byte[], offset, length)
+ * method.
+ * -1
if throwEofException
is
+ * set to false
+ * @throws EOFException if throwEofException
is set
+ * to true
.
+ */
+ private int doEndOfFile() throws EOFException {
+ eof = true;
+ if (throwEofException) {
+ throw new EOFException();
+ }
+ return -1;
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/NullReader.java b/src/org/apache/commons/io/input/NullReader.java
index 159e390216d87238e4edbb2a1a1bf7fa40b9703e..95f7400f2c1d82acd133170adc6467d87954614a 100644
--- a/src/org/apache/commons/io/input/NullReader.java
+++ b/src/org/apache/commons/io/input/NullReader.java
@@ -1,313 +1,313 @@
-/*
- * 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.commons.io.input;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * A functional, light weight {@link Reader} that emulates
- * a reader of a specified size.
- * processChar()
and
- * processChars()
methods can be implemented to generate
- * data, for example:
- *
- *
- * public class TestReader extends NullReader {
- * public TestReader(int size) {
- * super(size);
- * }
- * protected char processChar() {
- * return ... // return required value here
- * }
- * protected void processChars(char[] chars, int offset, int length) {
- * for (int i = offset; i < length; i++) {
- * chars[i] = ... // set array value here
- * }
- * }
- * }
- *
- *
- * @since Commons IO 1.3
- * @version $Revision: 463529 $
- */
-public class NullReader extends Reader {
-
- private long size;
- private long position;
- private long mark = -1;
- private long readlimit;
- private boolean eof;
- private boolean throwEofException;
- private boolean markSupported;
-
- /**
- * Create a {@link Reader} that emulates a specified size
- * which supports marking and does not throw EOFException.
- *
- * @param size The size of the reader to emulate.
- */
- public NullReader(long size) {
- this(size, true, false);
- }
-
- /**
- * Create a {@link Reader} that emulates a specified
- * size with option settings.
- *
- * @param size The size of the reader to emulate.
- * @param markSupported Whether this instance will support
- * the mark()
functionality.
- * @param throwEofException Whether this implementation
- * will throw an {@link EOFException} or return -1 when the
- * end of file is reached.
- */
- public NullReader(long size, boolean markSupported, boolean throwEofException) {
- this.size = size;
- this.markSupported = markSupported;
- this.throwEofException = throwEofException;
- }
-
- /**
- * Return the current position.
- *
- * @return the current position.
- */
- public long getPosition() {
- return position;
- }
-
- /**
- * Return the size this {@link Reader} emulates.
- *
- * @return The size of the reader to emulate.
- */
- public long getSize() {
- return size;
- }
-
- /**
- * Close this Reader - resets the internal state to
- * the initial values.
- *
- * @throws IOException If an error occurs.
- */
- public void close() throws IOException {
- eof = false;
- position = 0;
- mark = -1;
- }
-
- /**
- * Mark the current position.
- *
- * @param readlimit The number of characters before this marked position
- * is invalid.
- * @throws UnsupportedOperationException if mark is not supported.
- */
- public synchronized void mark(int readlimit) {
- if (!markSupported) {
- throw new UnsupportedOperationException("Mark not supported");
- }
- mark = position;
- this.readlimit = readlimit;
- }
-
- /**
- * Indicates whether mark is supported.
- *
- * @return Whether mark is supported or not.
- */
- public boolean markSupported() {
- return markSupported;
- }
-
- /**
- * Read a character.
- *
- * @return Either The character value returned by processChar()
- * or -1
if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read() throws IOException {
- if (eof) {
- throw new IOException("Read after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position++;
- return processChar();
- }
-
- /**
- * Read some characters into the specified array.
- *
- * @param chars The character array to read into
- * @return The number of characters read or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read(char[] chars) throws IOException {
- return read(chars, 0, chars.length);
- }
-
- /**
- * Read the specified number characters into an array.
- *
- * @param chars The character array to read into.
- * @param offset The offset to start reading characters into.
- * @param length The number of characters to read.
- * @return The number of characters read or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public int read(char[] chars, int offset, int length) throws IOException {
- if (eof) {
- throw new IOException("Read after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position += length;
- int returnLength = length;
- if (position > size) {
- returnLength = length - (int)(position - size);
- position = size;
- }
- processChars(chars, offset, returnLength);
- return returnLength;
- }
-
- /**
- * Reset the stream to the point when mark was last called.
- *
- * @throws UnsupportedOperationException if mark is not supported.
- * @throws IOException If no position has been marked
- * or the read limit has been exceed since the last position was
- * marked.
- */
- public synchronized void reset() throws IOException {
- if (!markSupported) {
- throw new UnsupportedOperationException("Mark not supported");
- }
- if (mark < 0) {
- throw new IOException("No position has been marked");
- }
- if (position > (mark + readlimit)) {
- throw new IOException("Marked position [" + mark +
- "] is no longer valid - passed the read limit [" +
- readlimit + "]");
- }
- position = mark;
- eof = false;
- }
-
- /**
- * Skip a specified number of characters.
- *
- * @param numberOfChars The number of characters to skip.
- * @return The number of characters skipped or -1
- * if the end of file has been reached and
- * throwEofException
is set to false
.
- * @throws EOFException if the end of file is reached and
- * throwEofException
is set to true
.
- * @throws IOException if trying to read past the end of file.
- */
- public long skip(long numberOfChars) throws IOException {
- if (eof) {
- throw new IOException("Skip after end of file");
- }
- if (position == size) {
- return doEndOfFile();
- }
- position += numberOfChars;
- long returnLength = numberOfChars;
- if (position > size) {
- returnLength = numberOfChars - (position - size);
- position = size;
- }
- return returnLength;
- }
-
- /**
- * Return a character value for the read()
method.
- * read(char[], offset, length)
- * method.
- * -1
if throwEofException
is
- * set to false
- * @throws EOFException if throwEofException
is set
- * to true
.
- */
- private int doEndOfFile() throws EOFException {
- eof = true;
- if (throwEofException) {
- throw new EOFException();
- }
- return -1;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.input;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * A functional, light weight {@link Reader} that emulates
+ * a reader of a specified size.
+ * processChar()
and
+ * processChars()
methods can be implemented to generate
+ * data, for example:
+ *
+ *
+ * public class TestReader extends NullReader {
+ * public TestReader(int size) {
+ * super(size);
+ * }
+ * protected char processChar() {
+ * return ... // return required value here
+ * }
+ * protected void processChars(char[] chars, int offset, int length) {
+ * for (int i = offset; i < length; i++) {
+ * chars[i] = ... // set array value here
+ * }
+ * }
+ * }
+ *
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 463529 $
+ */
+public class NullReader extends Reader {
+
+ private long size;
+ private long position;
+ private long mark = -1;
+ private long readlimit;
+ private boolean eof;
+ private boolean throwEofException;
+ private boolean markSupported;
+
+ /**
+ * Create a {@link Reader} that emulates a specified size
+ * which supports marking and does not throw EOFException.
+ *
+ * @param size The size of the reader to emulate.
+ */
+ public NullReader(long size) {
+ this(size, true, false);
+ }
+
+ /**
+ * Create a {@link Reader} that emulates a specified
+ * size with option settings.
+ *
+ * @param size The size of the reader to emulate.
+ * @param markSupported Whether this instance will support
+ * the mark()
functionality.
+ * @param throwEofException Whether this implementation
+ * will throw an {@link EOFException} or return -1 when the
+ * end of file is reached.
+ */
+ public NullReader(long size, boolean markSupported, boolean throwEofException) {
+ this.size = size;
+ this.markSupported = markSupported;
+ this.throwEofException = throwEofException;
+ }
+
+ /**
+ * Return the current position.
+ *
+ * @return the current position.
+ */
+ public long getPosition() {
+ return position;
+ }
+
+ /**
+ * Return the size this {@link Reader} emulates.
+ *
+ * @return The size of the reader to emulate.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Close this Reader - resets the internal state to
+ * the initial values.
+ *
+ * @throws IOException If an error occurs.
+ */
+ public void close() throws IOException {
+ eof = false;
+ position = 0;
+ mark = -1;
+ }
+
+ /**
+ * Mark the current position.
+ *
+ * @param readlimit The number of characters before this marked position
+ * is invalid.
+ * @throws UnsupportedOperationException if mark is not supported.
+ */
+ public synchronized void mark(int readlimit) {
+ if (!markSupported) {
+ throw new UnsupportedOperationException("Mark not supported");
+ }
+ mark = position;
+ this.readlimit = readlimit;
+ }
+
+ /**
+ * Indicates whether mark is supported.
+ *
+ * @return Whether mark is supported or not.
+ */
+ public boolean markSupported() {
+ return markSupported;
+ }
+
+ /**
+ * Read a character.
+ *
+ * @return Either The character value returned by processChar()
+ * or -1
if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read() throws IOException {
+ if (eof) {
+ throw new IOException("Read after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position++;
+ return processChar();
+ }
+
+ /**
+ * Read some characters into the specified array.
+ *
+ * @param chars The character array to read into
+ * @return The number of characters read or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read(char[] chars) throws IOException {
+ return read(chars, 0, chars.length);
+ }
+
+ /**
+ * Read the specified number characters into an array.
+ *
+ * @param chars The character array to read into.
+ * @param offset The offset to start reading characters into.
+ * @param length The number of characters to read.
+ * @return The number of characters read or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public int read(char[] chars, int offset, int length) throws IOException {
+ if (eof) {
+ throw new IOException("Read after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position += length;
+ int returnLength = length;
+ if (position > size) {
+ returnLength = length - (int)(position - size);
+ position = size;
+ }
+ processChars(chars, offset, returnLength);
+ return returnLength;
+ }
+
+ /**
+ * Reset the stream to the point when mark was last called.
+ *
+ * @throws UnsupportedOperationException if mark is not supported.
+ * @throws IOException If no position has been marked
+ * or the read limit has been exceed since the last position was
+ * marked.
+ */
+ public synchronized void reset() throws IOException {
+ if (!markSupported) {
+ throw new UnsupportedOperationException("Mark not supported");
+ }
+ if (mark < 0) {
+ throw new IOException("No position has been marked");
+ }
+ if (position > (mark + readlimit)) {
+ throw new IOException("Marked position [" + mark +
+ "] is no longer valid - passed the read limit [" +
+ readlimit + "]");
+ }
+ position = mark;
+ eof = false;
+ }
+
+ /**
+ * Skip a specified number of characters.
+ *
+ * @param numberOfChars The number of characters to skip.
+ * @return The number of characters skipped or -1
+ * if the end of file has been reached and
+ * throwEofException
is set to false
.
+ * @throws EOFException if the end of file is reached and
+ * throwEofException
is set to true
.
+ * @throws IOException if trying to read past the end of file.
+ */
+ public long skip(long numberOfChars) throws IOException {
+ if (eof) {
+ throw new IOException("Skip after end of file");
+ }
+ if (position == size) {
+ return doEndOfFile();
+ }
+ position += numberOfChars;
+ long returnLength = numberOfChars;
+ if (position > size) {
+ returnLength = numberOfChars - (position - size);
+ position = size;
+ }
+ return returnLength;
+ }
+
+ /**
+ * Return a character value for the read()
method.
+ * read(char[], offset, length)
+ * method.
+ * -1
if throwEofException
is
+ * set to false
+ * @throws EOFException if throwEofException
is set
+ * to true
.
+ */
+ private int doEndOfFile() throws EOFException {
+ eof = true;
+ if (throwEofException) {
+ throw new EOFException();
+ }
+ return -1;
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/ProxyInputStream.java b/src/org/apache/commons/io/input/ProxyInputStream.java
index a08ad92d04206e87e992c09cf04bb46be648db95..5b2edd5820580d549dba66849e9bd1adb6231fbe 100644
--- a/src/org/apache/commons/io/input/ProxyInputStream.java
+++ b/src/org/apache/commons/io/input/ProxyInputStream.java
@@ -1,129 +1,129 @@
-/*
- * 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.commons.io.input;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A Proxy stream which acts as expected, that is it passes the method
- * calls on to the proxied stream and doesn't change which methods are
- * being called.
- * read()
method.
- * @return the byte read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read() throws IOException {
- return in.read();
- }
-
- /**
- * Invokes the delegate's read(byte[])
method.
- * @param bts the buffer to read the bytes into
- * @return the number of bytes read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read(byte[] bts) throws IOException {
- return in.read(bts);
- }
-
- /**
- * Invokes the delegate's read(byte[], int, int)
method.
- * @param bts the buffer to read the bytes into
- * @param st The start offset
- * @param end The number of bytes to read
- * @return the number of bytes read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read(byte[] bts, int st, int end) throws IOException {
- return in.read(bts, st, end);
- }
-
- /**
- * Invokes the delegate's skip(long)
method.
- * @param ln the number of bytes to skip
- * @return the number of bytes to skipped or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public long skip(long ln) throws IOException {
- return in.skip(ln);
- }
-
- /**
- * Invokes the delegate's available()
method.
- * @return the number of available bytes
- * @throws IOException if an I/O error occurs
- */
- public int available() throws IOException {
- return in.available();
- }
-
- /**
- * Invokes the delegate's close()
method.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- in.close();
- }
-
- /**
- * Invokes the delegate's mark(int)
method.
- * @param idx read ahead limit
- */
- public synchronized void mark(int idx) {
- in.mark(idx);
- }
-
- /**
- * Invokes the delegate's reset()
method.
- * @throws IOException if an I/O error occurs
- */
- public synchronized void reset() throws IOException {
- in.reset();
- }
-
- /**
- * Invokes the delegate's markSupported()
method.
- * @return true if mark is supported, otherwise false
- */
- public boolean markSupported() {
- return in.markSupported();
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A Proxy stream which acts as expected, that is it passes the method
+ * calls on to the proxied stream and doesn't change which methods are
+ * being called.
+ * read()
method.
+ * @return the byte read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read() throws IOException {
+ return in.read();
+ }
+
+ /**
+ * Invokes the delegate's read(byte[])
method.
+ * @param bts the buffer to read the bytes into
+ * @return the number of bytes read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read(byte[] bts) throws IOException {
+ return in.read(bts);
+ }
+
+ /**
+ * Invokes the delegate's read(byte[], int, int)
method.
+ * @param bts the buffer to read the bytes into
+ * @param st The start offset
+ * @param end The number of bytes to read
+ * @return the number of bytes read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read(byte[] bts, int st, int end) throws IOException {
+ return in.read(bts, st, end);
+ }
+
+ /**
+ * Invokes the delegate's skip(long)
method.
+ * @param ln the number of bytes to skip
+ * @return the number of bytes to skipped or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public long skip(long ln) throws IOException {
+ return in.skip(ln);
+ }
+
+ /**
+ * Invokes the delegate's available()
method.
+ * @return the number of available bytes
+ * @throws IOException if an I/O error occurs
+ */
+ public int available() throws IOException {
+ return in.available();
+ }
+
+ /**
+ * Invokes the delegate's close()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ in.close();
+ }
+
+ /**
+ * Invokes the delegate's mark(int)
method.
+ * @param idx read ahead limit
+ */
+ public synchronized void mark(int idx) {
+ in.mark(idx);
+ }
+
+ /**
+ * Invokes the delegate's reset()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void reset() throws IOException {
+ in.reset();
+ }
+
+ /**
+ * Invokes the delegate's markSupported()
method.
+ * @return true if mark is supported, otherwise false
+ */
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/ProxyReader.java b/src/org/apache/commons/io/input/ProxyReader.java
index d55290f5a436f7e9fcd9005b3f3ad9e86b246f2d..81e113cccbedd4ad1ffa929c8268266e6c7dd4a7 100644
--- a/src/org/apache/commons/io/input/ProxyReader.java
+++ b/src/org/apache/commons/io/input/ProxyReader.java
@@ -1,130 +1,130 @@
-/*
- * 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.commons.io.input;
-
-import java.io.FilterReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * A Proxy stream which acts as expected, that is it passes the method
- * calls on to the proxied stream and doesn't change which methods are
- * being called.
- * read()
method.
- * @return the character read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read() throws IOException {
- return in.read();
- }
-
- /**
- * Invokes the delegate's read(char[])
method.
- * @param chr the buffer to read the characters into
- * @return the number of characters read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read(char[] chr) throws IOException {
- return in.read(chr);
- }
-
- /**
- * Invokes the delegate's read(char[], int, int)
method.
- * @param chr the buffer to read the characters into
- * @param st The start offset
- * @param end The number of bytes to read
- * @return the number of characters read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public int read(char[] chr, int st, int end) throws IOException {
- return in.read(chr, st, end);
- }
-
- /**
- * Invokes the delegate's skip(long)
method.
- * @param ln the number of bytes to skip
- * @return the number of bytes to skipped or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- */
- public long skip(long ln) throws IOException {
- return in.skip(ln);
- }
-
- /**
- * Invokes the delegate's ready()
method.
- * @return true if the stream is ready to be read
- * @throws IOException if an I/O error occurs
- */
- public boolean ready() throws IOException {
- return in.ready();
- }
-
- /**
- * Invokes the delegate's close()
method.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- in.close();
- }
-
- /**
- * Invokes the delegate's mark(int)
method.
- * @param idx read ahead limit
- * @throws IOException if an I/O error occurs
- */
- public synchronized void mark(int idx) throws IOException {
- in.mark(idx);
- }
-
- /**
- * Invokes the delegate's reset()
method.
- * @throws IOException if an I/O error occurs
- */
- public synchronized void reset() throws IOException {
- in.reset();
- }
-
- /**
- * Invokes the delegate's markSupported()
method.
- * @return true if mark is supported, otherwise false
- */
- public boolean markSupported() {
- return in.markSupported();
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * A Proxy stream which acts as expected, that is it passes the method
+ * calls on to the proxied stream and doesn't change which methods are
+ * being called.
+ * read()
method.
+ * @return the character read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read() throws IOException {
+ return in.read();
+ }
+
+ /**
+ * Invokes the delegate's read(char[])
method.
+ * @param chr the buffer to read the characters into
+ * @return the number of characters read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read(char[] chr) throws IOException {
+ return in.read(chr);
+ }
+
+ /**
+ * Invokes the delegate's read(char[], int, int)
method.
+ * @param chr the buffer to read the characters into
+ * @param st The start offset
+ * @param end The number of bytes to read
+ * @return the number of characters read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public int read(char[] chr, int st, int end) throws IOException {
+ return in.read(chr, st, end);
+ }
+
+ /**
+ * Invokes the delegate's skip(long)
method.
+ * @param ln the number of bytes to skip
+ * @return the number of bytes to skipped or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ */
+ public long skip(long ln) throws IOException {
+ return in.skip(ln);
+ }
+
+ /**
+ * Invokes the delegate's ready()
method.
+ * @return true if the stream is ready to be read
+ * @throws IOException if an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ return in.ready();
+ }
+
+ /**
+ * Invokes the delegate's close()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ in.close();
+ }
+
+ /**
+ * Invokes the delegate's mark(int)
method.
+ * @param idx read ahead limit
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void mark(int idx) throws IOException {
+ in.mark(idx);
+ }
+
+ /**
+ * Invokes the delegate's reset()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void reset() throws IOException {
+ in.reset();
+ }
+
+ /**
+ * Invokes the delegate's markSupported()
method.
+ * @return true if mark is supported, otherwise false
+ */
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/SwappedDataInputStream.java b/src/org/apache/commons/io/input/SwappedDataInputStream.java
index 5b65b1eee378fd4b083ac5e7cf73d8896def14c6..fe2f97eb703e1575751108a60f81f2c03310678e 100644
--- a/src/org/apache/commons/io/input/SwappedDataInputStream.java
+++ b/src/org/apache/commons/io/input/SwappedDataInputStream.java
@@ -1,251 +1,251 @@
-/*
- * 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.commons.io.input;
-
-import java.io.DataInput;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.io.EndianUtils;
-
-/**
- * DataInput for systems relying on little endian data formats.
- * When read, values will be changed from little endian to big
- * endian formats for internal usage.
- * {@link #readByte()} == 0
- * @return the true if the byte read is zero, otherwise false
- * @throws IOException if an I/O error occurs
- * @throws EOFException if an end of file is reached unexpectedly
- */
- public boolean readBoolean()
- throws IOException, EOFException
- {
- return ( 0 == readByte() );
- }
-
- /**
- * Invokes the delegate's read()
method.
- * @return the byte read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- * @throws EOFException if an end of file is reached unexpectedly
- */
- public byte readByte()
- throws IOException, EOFException
- {
- return (byte)in.read();
- }
-
- /**
- * Reads a character delegating to {@link #readShort()}.
- * @return the byte read or -1 if the end of stream
- * @throws IOException if an I/O error occurs
- * @throws EOFException if an end of file is reached unexpectedly
- */
- public char readChar()
- throws IOException, EOFException
- {
- return (char)readShort();
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}.
- * @return the read long
- * @throws IOException if an I/O error occurs
- * @throws EOFException if an end of file is reached unexpectedly
- */
- public double readDouble()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedDouble( in );
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}.
- * @return the read long
- * @throws IOException if an I/O error occurs
- * @throws EOFException if an end of file is reached unexpectedly
- */
- public float readFloat()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedFloat( in );
- }
-
- /**
- * Invokes the delegate's read(byte[] data, int, int)
method.
- *
- * @param data the buffer to read the bytes into
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public void readFully( byte[] data )
- throws IOException, EOFException
- {
- readFully( data, 0, data.length );
- }
-
-
- /**
- * Invokes the delegate's read(byte[] data, int, int)
method.
- *
- * @param data the buffer to read the bytes into
- * @param offset The start offset
- * @param length The number of bytes to read
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public void readFully( byte[] data, int offset, int length )
- throws IOException, EOFException
- {
- int remaining = length;
-
- while( remaining > 0 )
- {
- int location = offset + ( length - remaining );
- int count = read( data, location, remaining );
-
- if( -1 == count )
- {
- throw new EOFException();
- }
-
- remaining -= count;
- }
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}.
- * @return the read long
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public int readInt()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedInteger( in );
- }
-
- /**
- * Not currently supported - throws {@link UnsupportedOperationException}.
- * @return the line read
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public String readLine()
- throws IOException, EOFException
- {
- throw new UnsupportedOperationException(
- "Operation not supported: readLine()" );
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}.
- * @return the read long
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public long readLong()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedLong( in );
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}.
- * @return the read long
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public short readShort()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedShort( in );
- }
-
- /**
- * Invokes the delegate's read()
method.
- * @return the byte read or -1 if the end of stream
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public int readUnsignedByte()
- throws IOException, EOFException
- {
- return in.read();
- }
-
- /**
- * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}.
- * @return the read long
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public int readUnsignedShort()
- throws IOException, EOFException
- {
- return EndianUtils.readSwappedUnsignedShort( in );
- }
-
- /**
- * Not currently supported - throws {@link UnsupportedOperationException}.
- * @return UTF String read
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public String readUTF()
- throws IOException, EOFException
- {
- throw new UnsupportedOperationException(
- "Operation not supported: readUTF()" );
- }
-
- /**
- * Invokes the delegate's skip(int)
method.
- * @param count the number of bytes to skip
- * @return the number of bytes to skipped or -1 if the end of stream
- * @throws EOFException if an end of file is reached unexpectedly
- * @throws IOException if an I/O error occurs
- */
- public int skipBytes( int count )
- throws IOException, EOFException
- {
- return (int)in.skip( count );
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.DataInput;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.EndianUtils;
+
+/**
+ * DataInput for systems relying on little endian data formats.
+ * When read, values will be changed from little endian to big
+ * endian formats for internal usage.
+ * {@link #readByte()} == 0
+ * @return the true if the byte read is zero, otherwise false
+ * @throws IOException if an I/O error occurs
+ * @throws EOFException if an end of file is reached unexpectedly
+ */
+ public boolean readBoolean()
+ throws IOException, EOFException
+ {
+ return ( 0 == readByte() );
+ }
+
+ /**
+ * Invokes the delegate's read()
method.
+ * @return the byte read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ * @throws EOFException if an end of file is reached unexpectedly
+ */
+ public byte readByte()
+ throws IOException, EOFException
+ {
+ return (byte)in.read();
+ }
+
+ /**
+ * Reads a character delegating to {@link #readShort()}.
+ * @return the byte read or -1 if the end of stream
+ * @throws IOException if an I/O error occurs
+ * @throws EOFException if an end of file is reached unexpectedly
+ */
+ public char readChar()
+ throws IOException, EOFException
+ {
+ return (char)readShort();
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}.
+ * @return the read long
+ * @throws IOException if an I/O error occurs
+ * @throws EOFException if an end of file is reached unexpectedly
+ */
+ public double readDouble()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedDouble( in );
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}.
+ * @return the read long
+ * @throws IOException if an I/O error occurs
+ * @throws EOFException if an end of file is reached unexpectedly
+ */
+ public float readFloat()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedFloat( in );
+ }
+
+ /**
+ * Invokes the delegate's read(byte[] data, int, int)
method.
+ *
+ * @param data the buffer to read the bytes into
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public void readFully( byte[] data )
+ throws IOException, EOFException
+ {
+ readFully( data, 0, data.length );
+ }
+
+
+ /**
+ * Invokes the delegate's read(byte[] data, int, int)
method.
+ *
+ * @param data the buffer to read the bytes into
+ * @param offset The start offset
+ * @param length The number of bytes to read
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public void readFully( byte[] data, int offset, int length )
+ throws IOException, EOFException
+ {
+ int remaining = length;
+
+ while( remaining > 0 )
+ {
+ int location = offset + ( length - remaining );
+ int count = read( data, location, remaining );
+
+ if( -1 == count )
+ {
+ throw new EOFException();
+ }
+
+ remaining -= count;
+ }
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}.
+ * @return the read long
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public int readInt()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedInteger( in );
+ }
+
+ /**
+ * Not currently supported - throws {@link UnsupportedOperationException}.
+ * @return the line read
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public String readLine()
+ throws IOException, EOFException
+ {
+ throw new UnsupportedOperationException(
+ "Operation not supported: readLine()" );
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}.
+ * @return the read long
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public long readLong()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedLong( in );
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}.
+ * @return the read long
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public short readShort()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedShort( in );
+ }
+
+ /**
+ * Invokes the delegate's read()
method.
+ * @return the byte read or -1 if the end of stream
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public int readUnsignedByte()
+ throws IOException, EOFException
+ {
+ return in.read();
+ }
+
+ /**
+ * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}.
+ * @return the read long
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public int readUnsignedShort()
+ throws IOException, EOFException
+ {
+ return EndianUtils.readSwappedUnsignedShort( in );
+ }
+
+ /**
+ * Not currently supported - throws {@link UnsupportedOperationException}.
+ * @return UTF String read
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public String readUTF()
+ throws IOException, EOFException
+ {
+ throw new UnsupportedOperationException(
+ "Operation not supported: readUTF()" );
+ }
+
+ /**
+ * Invokes the delegate's skip(int)
method.
+ * @param count the number of bytes to skip
+ * @return the number of bytes to skipped or -1 if the end of stream
+ * @throws EOFException if an end of file is reached unexpectedly
+ * @throws IOException if an I/O error occurs
+ */
+ public int skipBytes( int count )
+ throws IOException, EOFException
+ {
+ return (int)in.skip( count );
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/TeeInputStream.java b/src/org/apache/commons/io/input/TeeInputStream.java
index fed000ed6870aedb2ee1b83e39b4005236c5f472..acc4649ae0b4a2ac57cb381ed6084c1b15358431 100644
--- a/src/org/apache/commons/io/input/TeeInputStream.java
+++ b/src/org/apache/commons/io/input/TeeInputStream.java
@@ -1,147 +1,147 @@
-/*
- * 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.commons.io.input;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * InputStream proxy that transparently writes a copy of all bytes read
- * from the proxied stream to a given OutputStream. Using {@link #skip(long)}
- * or {@link #mark(int)}/{@link #reset()} on the stream will result on some
- * bytes from the input stream being skipped or duplicated in the output
- * stream.
- * true
.
- *
- * @param input input stream to be proxied
- * @param branch output stream that will receive a copy of all bytes read
- * @param closeBranch flag for closing also the output stream when this
- * stream is closed
- */
- public TeeInputStream(
- InputStream input, OutputStream branch, boolean closeBranch) {
- super(input);
- this.branch = branch;
- this.closeBranch = closeBranch;
- }
-
- /**
- * Closes the proxied input stream and, if so configured, the associated
- * output stream. An exception thrown from one stream will not prevent
- * closing of the other stream.
- *
- * @throws IOException if either of the streams could not be closed
- */
- public void close() throws IOException {
- try {
- super.close();
- } finally {
- if (closeBranch) {
- branch.close();
- }
- }
- }
-
- /**
- * Reads a single byte from the proxied input stream and writes it to
- * the associated output stream.
- *
- * @return next byte from the stream, or -1 if the stream has ended
- * @throws IOException if the stream could not be read (or written)
- */
- public int read() throws IOException {
- int ch = super.read();
- if (ch != -1) {
- branch.write(ch);
- }
- return ch;
- }
-
- /**
- * Reads bytes from the proxied input stream and writes the read bytes
- * to the associated output stream.
- *
- * @param bts byte buffer
- * @param st start offset within the buffer
- * @param end maximum number of bytes to read
- * @return number of bytes read, or -1 if the stream has ended
- * @throws IOException if the stream could not be read (or written)
- */
- public int read(byte[] bts, int st, int end) throws IOException {
- int n = super.read(bts, st, end);
- if (n != -1) {
- branch.write(bts, st, n);
- }
- return n;
- }
-
- /**
- * Reads bytes from the proxied input stream and writes the read bytes
- * to the associated output stream.
- *
- * @param bts byte buffer
- * @return number of bytes read, or -1 if the stream has ended
- * @throws IOException if the stream could not be read (or written)
- */
- public int read(byte[] bts) throws IOException {
- int n = super.read(bts);
- if (n != -1) {
- branch.write(bts, 0, n);
- }
- return n;
- }
-
-}
+/*
+ * 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.commons.io.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * InputStream proxy that transparently writes a copy of all bytes read
+ * from the proxied stream to a given OutputStream. Using {@link #skip(long)}
+ * or {@link #mark(int)}/{@link #reset()} on the stream will result on some
+ * bytes from the input stream being skipped or duplicated in the output
+ * stream.
+ * true
.
+ *
+ * @param input input stream to be proxied
+ * @param branch output stream that will receive a copy of all bytes read
+ * @param closeBranch flag for closing also the output stream when this
+ * stream is closed
+ */
+ public TeeInputStream(
+ InputStream input, OutputStream branch, boolean closeBranch) {
+ super(input);
+ this.branch = branch;
+ this.closeBranch = closeBranch;
+ }
+
+ /**
+ * Closes the proxied input stream and, if so configured, the associated
+ * output stream. An exception thrown from one stream will not prevent
+ * closing of the other stream.
+ *
+ * @throws IOException if either of the streams could not be closed
+ */
+ public void close() throws IOException {
+ try {
+ super.close();
+ } finally {
+ if (closeBranch) {
+ branch.close();
+ }
+ }
+ }
+
+ /**
+ * Reads a single byte from the proxied input stream and writes it to
+ * the associated output stream.
+ *
+ * @return next byte from the stream, or -1 if the stream has ended
+ * @throws IOException if the stream could not be read (or written)
+ */
+ public int read() throws IOException {
+ int ch = super.read();
+ if (ch != -1) {
+ branch.write(ch);
+ }
+ return ch;
+ }
+
+ /**
+ * Reads bytes from the proxied input stream and writes the read bytes
+ * to the associated output stream.
+ *
+ * @param bts byte buffer
+ * @param st start offset within the buffer
+ * @param end maximum number of bytes to read
+ * @return number of bytes read, or -1 if the stream has ended
+ * @throws IOException if the stream could not be read (or written)
+ */
+ public int read(byte[] bts, int st, int end) throws IOException {
+ int n = super.read(bts, st, end);
+ if (n != -1) {
+ branch.write(bts, st, n);
+ }
+ return n;
+ }
+
+ /**
+ * Reads bytes from the proxied input stream and writes the read bytes
+ * to the associated output stream.
+ *
+ * @param bts byte buffer
+ * @return number of bytes read, or -1 if the stream has ended
+ * @throws IOException if the stream could not be read (or written)
+ */
+ public int read(byte[] bts) throws IOException {
+ int n = super.read(bts);
+ if (n != -1) {
+ branch.write(bts, 0, n);
+ }
+ return n;
+ }
+
+}
diff --git a/src/org/apache/commons/io/input/package.html b/src/org/apache/commons/io/input/package.html
index 9aa8b15bad36a113d2c449f3528730790449e17a..440fa0f7ee52a73adc66a0d95aadb56cc3ebea7c 100644
--- a/src/org/apache/commons/io/input/package.html
+++ b/src/org/apache/commons/io/input/package.html
@@ -1,25 +1,25 @@
-
-
-
-InputStream
and Reader
.
-InputStream
and Reader
.
+toByteArray()
and
- * toString()
.
- * byte[]
buffer
- * specified by index.
- *
- * @param index the index of the buffer required
- * @return the buffer
- */
- private byte[] getBuffer(int index) {
- return (byte[]) buffers.get(index);
- }
-
- /**
- * Makes a new buffer available either by allocating
- * a new one or re-cycling an existing one.
- *
- * @param newcount the size of the buffer if one is created
- */
- private void needNewBuffer(int newcount) {
- if (currentBufferIndex < buffers.size() - 1) {
- //Recycling old buffer
- filledBufferSum += currentBuffer.length;
-
- currentBufferIndex++;
- currentBuffer = getBuffer(currentBufferIndex);
- } else {
- //Creating new buffer
- int newBufferSize;
- if (currentBuffer == null) {
- newBufferSize = newcount;
- filledBufferSum = 0;
- } else {
- newBufferSize = Math.max(
- currentBuffer.length << 1,
- newcount - filledBufferSum);
- filledBufferSum += currentBuffer.length;
- }
-
- currentBufferIndex++;
- currentBuffer = new byte[newBufferSize];
- buffers.add(currentBuffer);
- }
- }
-
- /**
- * Write the bytes to byte array.
- * @param b the bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
- */
- public void write(byte[] b, int off, int len) {
- if ((off < 0)
- || (off > b.length)
- || (len < 0)
- || ((off + len) > b.length)
- || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
- }
- synchronized (this) {
- int newcount = count + len;
- int remaining = len;
- int inBufferPos = count - filledBufferSum;
- while (remaining > 0) {
- int part = Math.min(remaining, currentBuffer.length - inBufferPos);
- System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
- remaining -= part;
- if (remaining > 0) {
- needNewBuffer(newcount);
- inBufferPos = 0;
- }
- }
- count = newcount;
- }
- }
-
- /**
- * Write a byte to byte array.
- * @param b the byte to write
- */
- public synchronized void write(int b) {
- int inBufferPos = count - filledBufferSum;
- if (inBufferPos == currentBuffer.length) {
- needNewBuffer(count + 1);
- inBufferPos = 0;
- }
- currentBuffer[inBufferPos] = (byte) b;
- count++;
- }
-
- /**
- * Writes the entire contents of the specified input stream to this
- * byte stream. Bytes from the input stream are read directly into the
- * internal buffers of this streams.
- *
- * @param in the input stream to read from
- * @return total number of bytes read from the input stream
- * (and written to this stream)
- * @throws IOException if an I/O error occurs while reading the input stream
- * @since Commons IO 1.4
- */
- public synchronized int write(InputStream in) throws IOException {
- int readCount = 0;
- int inBufferPos = count - filledBufferSum;
- int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
- while (n != -1) {
- readCount += n;
- inBufferPos += n;
- count += n;
- if (inBufferPos == currentBuffer.length) {
- needNewBuffer(currentBuffer.length);
- inBufferPos = 0;
- }
- n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
- }
- return readCount;
- }
-
- /**
- * Return the current size of the byte array.
- * @return the current size of the byte array
- */
- public synchronized int size() {
- return count;
- }
-
- /**
- * Closing a ByteArrayOutputStream has no effect. The methods in
- * this class can be called after the stream has been closed without
- * generating an IOException.
- *
- * @throws IOException never (this method should not declare this exception
- * but it has to now due to backwards compatability)
- */
- public void close() throws IOException {
- //nop
- }
-
- /**
- * @see java.io.ByteArrayOutputStream#reset()
- */
- public synchronized void reset() {
- count = 0;
- filledBufferSum = 0;
- currentBufferIndex = 0;
- currentBuffer = getBuffer(currentBufferIndex);
- }
-
- /**
- * Writes the entire contents of this byte stream to the
- * specified output stream.
- *
- * @param out the output stream to write to
- * @throws IOException if an I/O error occurs, such as if the stream is closed
- * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
- */
- public synchronized void writeTo(OutputStream out) throws IOException {
- int remaining = count;
- for (int i = 0; i < buffers.size(); i++) {
- byte[] buf = getBuffer(i);
- int c = Math.min(buf.length, remaining);
- out.write(buf, 0, c);
- remaining -= c;
- if (remaining == 0) {
- break;
- }
- }
- }
-
- /**
- * Gets the curent contents of this byte stream as a byte array.
- * The result is independent of this stream.
- *
- * @return the current contents of this output stream, as a byte array
- * @see java.io.ByteArrayOutputStream#toByteArray()
- */
- public synchronized byte[] toByteArray() {
- int remaining = count;
- if (remaining == 0) {
- return EMPTY_BYTE_ARRAY;
- }
- byte newbuf[] = new byte[remaining];
- int pos = 0;
- for (int i = 0; i < buffers.size(); i++) {
- byte[] buf = getBuffer(i);
- int c = Math.min(buf.length, remaining);
- System.arraycopy(buf, 0, newbuf, pos, c);
- pos += c;
- remaining -= c;
- if (remaining == 0) {
- break;
- }
- }
- return newbuf;
- }
-
- /**
- * Gets the curent contents of this byte stream as a string.
- * @return the contents of the byte array as a String
- * @see java.io.ByteArrayOutputStream#toString()
- */
- public String toString() {
- return new String(toByteArray());
- }
-
- /**
- * Gets the curent contents of this byte stream as a string
- * using the specified encoding.
- *
- * @param enc the name of the character encoding
- * @return the string converted from the byte array
- * @throws UnsupportedEncodingException if the encoding is not supported
- * @see java.io.ByteArrayOutputStream#toString(String)
- */
- public String toString(String enc) throws UnsupportedEncodingException {
- return new String(toByteArray(), enc);
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class implements an output stream in which the data is
+ * written into a byte array. The buffer automatically grows as data
+ * is written to it.
+ * toByteArray()
and
+ * toString()
.
+ * byte[]
buffer
+ * specified by index.
+ *
+ * @param index the index of the buffer required
+ * @return the buffer
+ */
+ private byte[] getBuffer(int index) {
+ return (byte[]) buffers.get(index);
+ }
+
+ /**
+ * Makes a new buffer available either by allocating
+ * a new one or re-cycling an existing one.
+ *
+ * @param newcount the size of the buffer if one is created
+ */
+ private void needNewBuffer(int newcount) {
+ if (currentBufferIndex < buffers.size() - 1) {
+ //Recycling old buffer
+ filledBufferSum += currentBuffer.length;
+
+ currentBufferIndex++;
+ currentBuffer = getBuffer(currentBufferIndex);
+ } else {
+ //Creating new buffer
+ int newBufferSize;
+ if (currentBuffer == null) {
+ newBufferSize = newcount;
+ filledBufferSum = 0;
+ } else {
+ newBufferSize = Math.max(
+ currentBuffer.length << 1,
+ newcount - filledBufferSum);
+ filledBufferSum += currentBuffer.length;
+ }
+
+ currentBufferIndex++;
+ currentBuffer = new byte[newBufferSize];
+ buffers.add(currentBuffer);
+ }
+ }
+
+ /**
+ * Write the bytes to byte array.
+ * @param b the bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
+ */
+ public void write(byte[] b, int off, int len) {
+ if ((off < 0)
+ || (off > b.length)
+ || (len < 0)
+ || ((off + len) > b.length)
+ || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ synchronized (this) {
+ int newcount = count + len;
+ int remaining = len;
+ int inBufferPos = count - filledBufferSum;
+ while (remaining > 0) {
+ int part = Math.min(remaining, currentBuffer.length - inBufferPos);
+ System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
+ remaining -= part;
+ if (remaining > 0) {
+ needNewBuffer(newcount);
+ inBufferPos = 0;
+ }
+ }
+ count = newcount;
+ }
+ }
+
+ /**
+ * Write a byte to byte array.
+ * @param b the byte to write
+ */
+ public synchronized void write(int b) {
+ int inBufferPos = count - filledBufferSum;
+ if (inBufferPos == currentBuffer.length) {
+ needNewBuffer(count + 1);
+ inBufferPos = 0;
+ }
+ currentBuffer[inBufferPos] = (byte) b;
+ count++;
+ }
+
+ /**
+ * Writes the entire contents of the specified input stream to this
+ * byte stream. Bytes from the input stream are read directly into the
+ * internal buffers of this streams.
+ *
+ * @param in the input stream to read from
+ * @return total number of bytes read from the input stream
+ * (and written to this stream)
+ * @throws IOException if an I/O error occurs while reading the input stream
+ * @since Commons IO 1.4
+ */
+ public synchronized int write(InputStream in) throws IOException {
+ int readCount = 0;
+ int inBufferPos = count - filledBufferSum;
+ int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
+ while (n != -1) {
+ readCount += n;
+ inBufferPos += n;
+ count += n;
+ if (inBufferPos == currentBuffer.length) {
+ needNewBuffer(currentBuffer.length);
+ inBufferPos = 0;
+ }
+ n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
+ }
+ return readCount;
+ }
+
+ /**
+ * Return the current size of the byte array.
+ * @return the current size of the byte array
+ */
+ public synchronized int size() {
+ return count;
+ }
+
+ /**
+ * Closing a ByteArrayOutputStream has no effect. The methods in
+ * this class can be called after the stream has been closed without
+ * generating an IOException.
+ *
+ * @throws IOException never (this method should not declare this exception
+ * but it has to now due to backwards compatability)
+ */
+ public void close() throws IOException {
+ //nop
+ }
+
+ /**
+ * @see java.io.ByteArrayOutputStream#reset()
+ */
+ public synchronized void reset() {
+ count = 0;
+ filledBufferSum = 0;
+ currentBufferIndex = 0;
+ currentBuffer = getBuffer(currentBufferIndex);
+ }
+
+ /**
+ * Writes the entire contents of this byte stream to the
+ * specified output stream.
+ *
+ * @param out the output stream to write to
+ * @throws IOException if an I/O error occurs, such as if the stream is closed
+ * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
+ */
+ public synchronized void writeTo(OutputStream out) throws IOException {
+ int remaining = count;
+ for (int i = 0; i < buffers.size(); i++) {
+ byte[] buf = getBuffer(i);
+ int c = Math.min(buf.length, remaining);
+ out.write(buf, 0, c);
+ remaining -= c;
+ if (remaining == 0) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Gets the curent contents of this byte stream as a byte array.
+ * The result is independent of this stream.
+ *
+ * @return the current contents of this output stream, as a byte array
+ * @see java.io.ByteArrayOutputStream#toByteArray()
+ */
+ public synchronized byte[] toByteArray() {
+ int remaining = count;
+ if (remaining == 0) {
+ return EMPTY_BYTE_ARRAY;
+ }
+ byte newbuf[] = new byte[remaining];
+ int pos = 0;
+ for (int i = 0; i < buffers.size(); i++) {
+ byte[] buf = getBuffer(i);
+ int c = Math.min(buf.length, remaining);
+ System.arraycopy(buf, 0, newbuf, pos, c);
+ pos += c;
+ remaining -= c;
+ if (remaining == 0) {
+ break;
+ }
+ }
+ return newbuf;
+ }
+
+ /**
+ * Gets the curent contents of this byte stream as a string.
+ * @return the contents of the byte array as a String
+ * @see java.io.ByteArrayOutputStream#toString()
+ */
+ public String toString() {
+ return new String(toByteArray());
+ }
+
+ /**
+ * Gets the curent contents of this byte stream as a string
+ * using the specified encoding.
+ *
+ * @param enc the name of the character encoding
+ * @return the string converted from the byte array
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ * @see java.io.ByteArrayOutputStream#toString(String)
+ */
+ public String toString(String enc) throws UnsupportedEncodingException {
+ return new String(toByteArray(), enc);
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/CloseShieldOutputStream.java b/src/org/apache/commons/io/output/CloseShieldOutputStream.java
index 63f44be405c90d8f5828a3706cda7367ec7fc7a3..58a9946024c09b001d75c8be8e9a9e11521fd024 100644
--- a/src/org/apache/commons/io/output/CloseShieldOutputStream.java
+++ b/src/org/apache/commons/io/output/CloseShieldOutputStream.java
@@ -1,52 +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.commons.io.output;
-
-import java.io.OutputStream;
-
-/**
- * Proxy stream that prevents the underlying output stream from being closed.
- * null
output stream.
- *
- * @version $Id: ClosedOutputStream.java 601751 2007-12-06 14:55:45Z niallp $
- * @since Commons IO 1.4
- */
-public class ClosedOutputStream extends OutputStream {
-
- /**
- * A singleton.
- */
- public static final ClosedOutputStream CLOSED_OUTPUT_STREAM = new ClosedOutputStream();
-
- /**
- * Throws an {@link IOException} to indicate that the stream is closed.
- *
- * @param b ignored
- * @throws IOException always thrown
- */
- public void write(int b) throws IOException {
- throw new IOException("write(" + b + ") failed: stream is closed");
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Closed output stream. This stream throws an exception on all attempts to
+ * write something to the stream.
+ * null
output stream.
+ *
+ * @version $Id: ClosedOutputStream.java 601751 2007-12-06 14:55:45Z niallp $
+ * @since Commons IO 1.4
+ */
+public class ClosedOutputStream extends OutputStream {
+
+ /**
+ * A singleton.
+ */
+ public static final ClosedOutputStream CLOSED_OUTPUT_STREAM = new ClosedOutputStream();
+
+ /**
+ * Throws an {@link IOException} to indicate that the stream is closed.
+ *
+ * @param b ignored
+ * @throws IOException always thrown
+ */
+ public void write(int b) throws IOException {
+ throw new IOException("write(" + b + ") failed: stream is closed");
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/CountingOutputStream.java b/src/org/apache/commons/io/output/CountingOutputStream.java
index 67288286078c75f08c3ff7049d9ca486030fcff7..392276a917bd2b9877fc106fc8323b15b9e09334 100644
--- a/src/org/apache/commons/io/output/CountingOutputStream.java
+++ b/src/org/apache/commons/io/output/CountingOutputStream.java
@@ -1,154 +1,154 @@
-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A decorating output stream that counts the number of bytes that have passed
- * through the stream so far.
- * int
.
- * See {@link #getByteCount()} for a method using a long
.
- *
- * @return the number of bytes accumulated
- * @throws ArithmeticException if the byte count is too large
- */
- public synchronized int getCount() {
- long result = getByteCount();
- if (result > Integer.MAX_VALUE) {
- throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
- }
- return (int) result;
- }
-
- /**
- * Set the byte count back to 0.
- * int
.
- * See {@link #resetByteCount()} for a method using a long
.
- *
- * @return the count previous to resetting
- * @throws ArithmeticException if the byte count is too large
- */
- public synchronized int resetCount() {
- long result = resetByteCount();
- if (result > Integer.MAX_VALUE) {
- throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
- }
- return (int) result;
- }
-
- /**
- * The number of bytes that have passed through this stream.
- * getCount()
.
- * It was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
- *
- * @return the number of bytes accumulated
- * @since Commons IO 1.3
- */
- public synchronized long getByteCount() {
- return this.count;
- }
-
- /**
- * Set the byte count back to 0.
- * resetCount()
.
- * It was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
- *
- * @return the count previous to resetting
- * @since Commons IO 1.3
- */
- public synchronized long resetByteCount() {
- long tmp = this.count;
- this.count = 0;
- return tmp;
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A decorating output stream that counts the number of bytes that have passed
+ * through the stream so far.
+ * int
.
+ * See {@link #getByteCount()} for a method using a long
.
+ *
+ * @return the number of bytes accumulated
+ * @throws ArithmeticException if the byte count is too large
+ */
+ public synchronized int getCount() {
+ long result = getByteCount();
+ if (result > Integer.MAX_VALUE) {
+ throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
+ }
+ return (int) result;
+ }
+
+ /**
+ * Set the byte count back to 0.
+ * int
.
+ * See {@link #resetByteCount()} for a method using a long
.
+ *
+ * @return the count previous to resetting
+ * @throws ArithmeticException if the byte count is too large
+ */
+ public synchronized int resetCount() {
+ long result = resetByteCount();
+ if (result > Integer.MAX_VALUE) {
+ throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
+ }
+ return (int) result;
+ }
+
+ /**
+ * The number of bytes that have passed through this stream.
+ * getCount()
.
+ * It was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the number of bytes accumulated
+ * @since Commons IO 1.3
+ */
+ public synchronized long getByteCount() {
+ return this.count;
+ }
+
+ /**
+ * Set the byte count back to 0.
+ * resetCount()
.
+ * It was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the count previous to resetting
+ * @since Commons IO 1.3
+ */
+ public synchronized long resetByteCount() {
+ long tmp = this.count;
+ this.count = 0;
+ return tmp;
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/DeferredFileOutputStream.java b/src/org/apache/commons/io/output/DeferredFileOutputStream.java
index b8a9e96070e3af6297a9fa64c6eab5777adde1c2..c0f223341d9754bddffb890e69bbac8ec1ddfc36 100644
--- a/src/org/apache/commons/io/output/DeferredFileOutputStream.java
+++ b/src/org/apache/commons/io/output/DeferredFileOutputStream.java
@@ -1,269 +1,269 @@
-/*
- * 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.commons.io.output;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.commons.io.IOUtils;
-
-
-/**
- * An output stream which will retain data in memory until a specified
- * threshold is reached, and only then commit it to disk. If the stream is
- * closed before the threshold is reached, the data will not be written to
- * disk at all.
- * memoryOutputStream
or
- * diskOutputStream
.
- */
- private OutputStream currentOutputStream;
-
-
- /**
- * The file to which output will be directed if the threshold is exceeded.
- */
- private File outputFile;
-
- /**
- * The temporary file prefix.
- */
- private String prefix;
-
- /**
- * The temporary file suffix.
- */
- private String suffix;
-
- /**
- * The directory to use for temporary files.
- */
- private File directory;
-
-
- /**
- * True when close() has been called successfully.
- */
- private boolean closed = false;
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Constructs an instance of this class which will trigger an event at the
- * specified threshold, and save data to a file beyond that point.
- *
- * @param threshold The number of bytes at which to trigger an event.
- * @param outputFile The file to which data is saved beyond the threshold.
- */
- public DeferredFileOutputStream(int threshold, File outputFile)
- {
- super(threshold);
- this.outputFile = outputFile;
-
- memoryOutputStream = new ByteArrayOutputStream();
- currentOutputStream = memoryOutputStream;
- }
-
-
- /**
- * Constructs an instance of this class which will trigger an event at the
- * specified threshold, and save data to a temporary file beyond that point.
- *
- * @param threshold The number of bytes at which to trigger an event.
- * @param prefix Prefix to use for the temporary file.
- * @param suffix Suffix to use for the temporary file.
- * @param directory Temporary file directory.
- *
- * @since Commons IO 1.4
- */
- public DeferredFileOutputStream(int threshold, String prefix, String suffix, File directory)
- {
- this(threshold, (File)null);
- if (prefix == null) {
- throw new IllegalArgumentException("Temporary file prefix is missing");
- }
- this.prefix = prefix;
- this.suffix = suffix;
- this.directory = directory;
- }
-
-
- // --------------------------------------- ThresholdingOutputStream methods
-
-
- /**
- * Returns the current output stream. This may be memory based or disk
- * based, depending on the current state with respect to the threshold.
- *
- * @return The underlying output stream.
- *
- * @exception IOException if an error occurs.
- */
- protected OutputStream getStream() throws IOException
- {
- return currentOutputStream;
- }
-
-
- /**
- * Switches the underlying output stream from a memory based stream to one
- * that is backed by disk. This is the point at which we realise that too
- * much data is being written to keep in memory, so we elect to switch to
- * disk-based storage.
- *
- * @exception IOException if an error occurs.
- */
- protected void thresholdReached() throws IOException
- {
- if (prefix != null) {
- outputFile = File.createTempFile(prefix, suffix, directory);
- }
- FileOutputStream fos = new FileOutputStream(outputFile);
- memoryOutputStream.writeTo(fos);
- currentOutputStream = fos;
- memoryOutputStream = null;
- }
-
-
- // --------------------------------------------------------- Public methods
-
-
- /**
- * Determines whether or not the data for this output stream has been
- * retained in memory.
- *
- * @return true
if the data is available in memory;
- * false
otherwise.
- */
- public boolean isInMemory()
- {
- return (!isThresholdExceeded());
- }
-
-
- /**
- * Returns the data for this output stream as an array of bytes, assuming
- * that the data has been retained in memory. If the data was written to
- * disk, this method returns null
.
- *
- * @return The data for this output stream, or null
if no such
- * data is available.
- */
- public byte[] getData()
- {
- if (memoryOutputStream != null)
- {
- return memoryOutputStream.toByteArray();
- }
- return null;
- }
-
-
- /**
- * Returns either the output file specified in the constructor or
- * the temporary file created or null.
- * null
is returned.
- *
- * @return The file for this output stream, or null
if no such
- * file exists.
- */
- public File getFile()
- {
- return outputFile;
- }
-
-
- /**
- * Closes underlying output stream, and mark this as closed
- *
- * @exception IOException if an error occurs.
- */
- public void close() throws IOException
- {
- super.close();
- closed = true;
- }
-
-
- /**
- * Writes the data from this output stream to the specified output stream,
- * after it has been closed.
- *
- * @param out output stream to write to.
- * @exception IOException if this stream is not yet closed or an error occurs.
- */
- public void writeTo(OutputStream out) throws IOException
- {
- // we may only need to check if this is closed if we are working with a file
- // but we should force the habit of closing wether we are working with
- // a file or memory.
- if (!closed)
- {
- throw new IOException("Stream not closed");
- }
-
- if(isInMemory())
- {
- memoryOutputStream.writeTo(out);
- }
- else
- {
- FileInputStream fis = new FileInputStream(outputFile);
- try {
- IOUtils.copy(fis, out);
- } finally {
- IOUtils.closeQuietly(fis);
- }
- }
- }
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+
+
+/**
+ * An output stream which will retain data in memory until a specified
+ * threshold is reached, and only then commit it to disk. If the stream is
+ * closed before the threshold is reached, the data will not be written to
+ * disk at all.
+ * memoryOutputStream
or
+ * diskOutputStream
.
+ */
+ private OutputStream currentOutputStream;
+
+
+ /**
+ * The file to which output will be directed if the threshold is exceeded.
+ */
+ private File outputFile;
+
+ /**
+ * The temporary file prefix.
+ */
+ private String prefix;
+
+ /**
+ * The temporary file suffix.
+ */
+ private String suffix;
+
+ /**
+ * The directory to use for temporary files.
+ */
+ private File directory;
+
+
+ /**
+ * True when close() has been called successfully.
+ */
+ private boolean closed = false;
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Constructs an instance of this class which will trigger an event at the
+ * specified threshold, and save data to a file beyond that point.
+ *
+ * @param threshold The number of bytes at which to trigger an event.
+ * @param outputFile The file to which data is saved beyond the threshold.
+ */
+ public DeferredFileOutputStream(int threshold, File outputFile)
+ {
+ super(threshold);
+ this.outputFile = outputFile;
+
+ memoryOutputStream = new ByteArrayOutputStream();
+ currentOutputStream = memoryOutputStream;
+ }
+
+
+ /**
+ * Constructs an instance of this class which will trigger an event at the
+ * specified threshold, and save data to a temporary file beyond that point.
+ *
+ * @param threshold The number of bytes at which to trigger an event.
+ * @param prefix Prefix to use for the temporary file.
+ * @param suffix Suffix to use for the temporary file.
+ * @param directory Temporary file directory.
+ *
+ * @since Commons IO 1.4
+ */
+ public DeferredFileOutputStream(int threshold, String prefix, String suffix, File directory)
+ {
+ this(threshold, (File)null);
+ if (prefix == null) {
+ throw new IllegalArgumentException("Temporary file prefix is missing");
+ }
+ this.prefix = prefix;
+ this.suffix = suffix;
+ this.directory = directory;
+ }
+
+
+ // --------------------------------------- ThresholdingOutputStream methods
+
+
+ /**
+ * Returns the current output stream. This may be memory based or disk
+ * based, depending on the current state with respect to the threshold.
+ *
+ * @return The underlying output stream.
+ *
+ * @exception IOException if an error occurs.
+ */
+ protected OutputStream getStream() throws IOException
+ {
+ return currentOutputStream;
+ }
+
+
+ /**
+ * Switches the underlying output stream from a memory based stream to one
+ * that is backed by disk. This is the point at which we realise that too
+ * much data is being written to keep in memory, so we elect to switch to
+ * disk-based storage.
+ *
+ * @exception IOException if an error occurs.
+ */
+ protected void thresholdReached() throws IOException
+ {
+ if (prefix != null) {
+ outputFile = File.createTempFile(prefix, suffix, directory);
+ }
+ FileOutputStream fos = new FileOutputStream(outputFile);
+ memoryOutputStream.writeTo(fos);
+ currentOutputStream = fos;
+ memoryOutputStream = null;
+ }
+
+
+ // --------------------------------------------------------- Public methods
+
+
+ /**
+ * Determines whether or not the data for this output stream has been
+ * retained in memory.
+ *
+ * @return true
if the data is available in memory;
+ * false
otherwise.
+ */
+ public boolean isInMemory()
+ {
+ return (!isThresholdExceeded());
+ }
+
+
+ /**
+ * Returns the data for this output stream as an array of bytes, assuming
+ * that the data has been retained in memory. If the data was written to
+ * disk, this method returns null
.
+ *
+ * @return The data for this output stream, or null
if no such
+ * data is available.
+ */
+ public byte[] getData()
+ {
+ if (memoryOutputStream != null)
+ {
+ return memoryOutputStream.toByteArray();
+ }
+ return null;
+ }
+
+
+ /**
+ * Returns either the output file specified in the constructor or
+ * the temporary file created or null.
+ * null
is returned.
+ *
+ * @return The file for this output stream, or null
if no such
+ * file exists.
+ */
+ public File getFile()
+ {
+ return outputFile;
+ }
+
+
+ /**
+ * Closes underlying output stream, and mark this as closed
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void close() throws IOException
+ {
+ super.close();
+ closed = true;
+ }
+
+
+ /**
+ * Writes the data from this output stream to the specified output stream,
+ * after it has been closed.
+ *
+ * @param out output stream to write to.
+ * @exception IOException if this stream is not yet closed or an error occurs.
+ */
+ public void writeTo(OutputStream out) throws IOException
+ {
+ // we may only need to check if this is closed if we are working with a file
+ // but we should force the habit of closing wether we are working with
+ // a file or memory.
+ if (!closed)
+ {
+ throw new IOException("Stream not closed");
+ }
+
+ if(isInMemory())
+ {
+ memoryOutputStream.writeTo(out);
+ }
+ else
+ {
+ FileInputStream fis = new FileInputStream(outputFile);
+ try {
+ IOUtils.copy(fis, out);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ }
+ }
+}
diff --git a/src/org/apache/commons/io/output/DemuxOutputStream.java b/src/org/apache/commons/io/output/DemuxOutputStream.java
index 08691111838440f4fa21c283ecff3f11cfa7fb90..36edec61dabbac35c83166a564f953f01c0f57fc 100644
--- a/src/org/apache/commons/io/output/DemuxOutputStream.java
+++ b/src/org/apache/commons/io/output/DemuxOutputStream.java
@@ -1,102 +1,102 @@
-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Data written to this stream is forwarded to a stream that has been associated
- * with this thread.
- *
- * @author Peter Donald
- * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
- */
-public class DemuxOutputStream
- extends OutputStream
-{
- private InheritableThreadLocal m_streams = new InheritableThreadLocal();
-
- /**
- * Bind the specified stream to the current thread.
- *
- * @param output the stream to bind
- * @return the OutputStream that was previously active
- */
- public OutputStream bindStream( OutputStream output )
- {
- OutputStream stream = getStream();
- m_streams.set( output );
- return stream;
- }
-
- /**
- * Closes stream associated with current thread.
- *
- * @throws IOException if an error occurs
- */
- public void close()
- throws IOException
- {
- OutputStream output = getStream();
- if( null != output )
- {
- output.close();
- }
- }
-
- /**
- * Flushes stream associated with current thread.
- *
- * @throws IOException if an error occurs
- */
- public void flush()
- throws IOException
- {
- OutputStream output = getStream();
- if( null != output )
- {
- output.flush();
- }
- }
-
- /**
- * Writes byte to stream associated with current thread.
- *
- * @param ch the byte to write to stream
- * @throws IOException if an error occurs
- */
- public void write( int ch )
- throws IOException
- {
- OutputStream output = getStream();
- if( null != output )
- {
- output.write( ch );
- }
- }
-
- /**
- * Utility method to retrieve stream bound to current thread (if any).
- *
- * @return the output stream
- */
- private OutputStream getStream()
- {
- return (OutputStream)m_streams.get();
- }
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Data written to this stream is forwarded to a stream that has been associated
+ * with this thread.
+ *
+ * @author Peter Donald
+ * @version $Revision: 437567 $ $Date: 2006-08-28 07:39:07 +0100 (Mon, 28 Aug 2006) $
+ */
+public class DemuxOutputStream
+ extends OutputStream
+{
+ private InheritableThreadLocal m_streams = new InheritableThreadLocal();
+
+ /**
+ * Bind the specified stream to the current thread.
+ *
+ * @param output the stream to bind
+ * @return the OutputStream that was previously active
+ */
+ public OutputStream bindStream( OutputStream output )
+ {
+ OutputStream stream = getStream();
+ m_streams.set( output );
+ return stream;
+ }
+
+ /**
+ * Closes stream associated with current thread.
+ *
+ * @throws IOException if an error occurs
+ */
+ public void close()
+ throws IOException
+ {
+ OutputStream output = getStream();
+ if( null != output )
+ {
+ output.close();
+ }
+ }
+
+ /**
+ * Flushes stream associated with current thread.
+ *
+ * @throws IOException if an error occurs
+ */
+ public void flush()
+ throws IOException
+ {
+ OutputStream output = getStream();
+ if( null != output )
+ {
+ output.flush();
+ }
+ }
+
+ /**
+ * Writes byte to stream associated with current thread.
+ *
+ * @param ch the byte to write to stream
+ * @throws IOException if an error occurs
+ */
+ public void write( int ch )
+ throws IOException
+ {
+ OutputStream output = getStream();
+ if( null != output )
+ {
+ output.write( ch );
+ }
+ }
+
+ /**
+ * Utility method to retrieve stream bound to current thread (if any).
+ *
+ * @return the output stream
+ */
+ private OutputStream getStream()
+ {
+ return (OutputStream)m_streams.get();
+ }
+}
diff --git a/src/org/apache/commons/io/output/FileWriterWithEncoding.java b/src/org/apache/commons/io/output/FileWriterWithEncoding.java
index a8f89334b200fc5d7e49cd2c760c69e5430445a4..d5708ad17d2e22d615f12468f12f66770d9f38fb 100644
--- a/src/org/apache/commons/io/output/FileWriterWithEncoding.java
+++ b/src/org/apache/commons/io/output/FileWriterWithEncoding.java
@@ -1,324 +1,324 @@
-/*
- * 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.commons.io.output;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-
-/**
- * Writer of files that allows the encoding to be set.
- * FileWriter
- * that allows an encoding to be set. Unfortunately, it cannot subclass
- * FileWriter
.
- * FileWriter
+ * that allows an encoding to be set. Unfortunately, it cannot subclass
+ * FileWriter
.
+ * FileWriter
- * that will use a lock file to prevent duplicate writes.
- * java.io.tmpdir
.
- * The encoding may also be specified, and defaults to the platform default.
- *
- * @author Scott Sanders
- * @author Michael Salmon
- * @author Jon S. Stevens
- * @author Daniel Rall
- * @author Stephen Colebourne
- * @author Andy Lehane
- * @version $Id: LockableFileWriter.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class LockableFileWriter extends Writer {
- // Cannot extend ProxyWriter, as requires writer to be
- // known when super() is called
-
- /** The extension for the lock file. */
- private static final String LCK = ".lck";
-
- /** The writer to decorate. */
- private final Writer out;
- /** The lock file. */
- private final File lockFile;
-
- /**
- * Constructs a LockableFileWriter.
- * If the file exists, it is overwritten.
- *
- * @param fileName the file to write to, not null
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(String fileName) throws IOException {
- this(fileName, false, null);
- }
-
- /**
- * Constructs a LockableFileWriter.
- *
- * @param fileName file to write to, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(String fileName, boolean append) throws IOException {
- this(fileName, append, null);
- }
-
- /**
- * Constructs a LockableFileWriter.
- *
- * @param fileName the file to write to, not null
- * @param append true if content should be appended, false to overwrite
- * @param lockDir the directory in which the lock file should be held
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(String fileName, boolean append, String lockDir) throws IOException {
- this(new File(fileName), append, lockDir);
- }
-
- /**
- * Constructs a LockableFileWriter.
- * If the file exists, it is overwritten.
- *
- * @param file the file to write to, not null
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(File file) throws IOException {
- this(file, false, null);
- }
-
- /**
- * Constructs a LockableFileWriter.
- *
- * @param file the file to write to, not null
- * @param append true if content should be appended, false to overwrite
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(File file, boolean append) throws IOException {
- this(file, append, null);
- }
-
- /**
- * Constructs a LockableFileWriter.
- *
- * @param file the file to write to, not null
- * @param append true if content should be appended, false to overwrite
- * @param lockDir the directory in which the lock file should be held
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(File file, boolean append, String lockDir) throws IOException {
- this(file, null, append, lockDir);
- }
-
- /**
- * Constructs a LockableFileWriter with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, null means platform default
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(File file, String encoding) throws IOException {
- this(file, encoding, false, null);
- }
-
- /**
- * Constructs a LockableFileWriter with a file encoding.
- *
- * @param file the file to write to, not null
- * @param encoding the encoding to use, null means platform default
- * @param append true if content should be appended, false to overwrite
- * @param lockDir the directory in which the lock file should be held
- * @throws NullPointerException if the file is null
- * @throws IOException in case of an I/O error
- */
- public LockableFileWriter(File file, String encoding, boolean append,
- String lockDir) throws IOException {
- super();
- // init file to create/append
- file = file.getAbsoluteFile();
- if (file.getParentFile() != null) {
- FileUtils.forceMkdir(file.getParentFile());
- }
- if (file.isDirectory()) {
- throw new IOException("File specified is a directory");
- }
-
- // init lock file
- if (lockDir == null) {
- lockDir = System.getProperty("java.io.tmpdir");
- }
- File lockDirFile = new File(lockDir);
- FileUtils.forceMkdir(lockDirFile);
- testLockDir(lockDirFile);
- lockFile = new File(lockDirFile, file.getName() + LCK);
-
- // check if locked
- createLock();
-
- // init wrapped writer
- out = initWriter(file, encoding, append);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Tests that we can write to the lock directory.
- *
- * @param lockDir the File representing the lock directory
- * @throws IOException if we cannot write to the lock directory
- * @throws IOException if we cannot find the lock file
- */
- private void testLockDir(File lockDir) throws IOException {
- if (!lockDir.exists()) {
- throw new IOException(
- "Could not find lockDir: " + lockDir.getAbsolutePath());
- }
- if (!lockDir.canWrite()) {
- throw new IOException(
- "Could not write to lockDir: " + lockDir.getAbsolutePath());
- }
- }
-
- /**
- * Creates the lock file.
- *
- * @throws IOException if we cannot create the file
- */
- private void createLock() throws IOException {
- synchronized (LockableFileWriter.class) {
- if (!lockFile.createNewFile()) {
- throw new IOException("Can't write file, lock " +
- lockFile.getAbsolutePath() + " exists");
- }
- lockFile.deleteOnExit();
- }
- }
-
- /**
- * Initialise the wrapped file writer.
- * Ensure that a cleanup occurs if the writer creation fails.
- *
- * @param file the file to be accessed
- * @param encoding the encoding to use
- * @param append true to append
- * @return The initialised writer
- * @throws IOException if an error occurs
- */
- private Writer initWriter(File file, String encoding, boolean append) throws IOException {
- boolean fileExistedAlready = file.exists();
- OutputStream stream = null;
- Writer writer = null;
- try {
- if (encoding == null) {
- writer = new FileWriter(file.getAbsolutePath(), append);
- } else {
- stream = new FileOutputStream(file.getAbsolutePath(), append);
- writer = new OutputStreamWriter(stream, encoding);
- }
- } catch (IOException ex) {
- IOUtils.closeQuietly(writer);
- IOUtils.closeQuietly(stream);
- lockFile.delete();
- if (fileExistedAlready == false) {
- file.delete();
- }
- throw ex;
- } catch (RuntimeException ex) {
- IOUtils.closeQuietly(writer);
- IOUtils.closeQuietly(stream);
- lockFile.delete();
- if (fileExistedAlready == false) {
- file.delete();
- }
- throw ex;
- }
- return writer;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Closes the file writer.
- *
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- try {
- out.close();
- } finally {
- lockFile.delete();
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Write a character.
- * @param idx the character to write
- * @throws IOException if an I/O error occurs
- */
- public void write(int idx) throws IOException {
- out.write(idx);
- }
-
- /**
- * Write the characters from an array.
- * @param chr the characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr) throws IOException {
- out.write(chr);
- }
-
- /**
- * Write the specified characters from an array.
- * @param chr the characters to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr, int st, int end) throws IOException {
- out.write(chr, st, end);
- }
-
- /**
- * Write the characters from a string.
- * @param str the string to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str) throws IOException {
- out.write(str);
- }
-
- /**
- * Write the specified characters from a string.
- * @param str the string to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str, int st, int end) throws IOException {
- out.write(str, st, end);
- }
-
- /**
- * Flush the stream.
- * @throws IOException if an I/O error occurs
- */
- public void flush() throws IOException {
- out.flush();
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * FileWriter that will create and honor lock files to allow simple
+ * cross thread file lock handling.
+ * FileWriter
+ * that will use a lock file to prevent duplicate writes.
+ * java.io.tmpdir
.
+ * The encoding may also be specified, and defaults to the platform default.
+ *
+ * @author Scott Sanders
+ * @author Michael Salmon
+ * @author Jon S. Stevens
+ * @author Daniel Rall
+ * @author Stephen Colebourne
+ * @author Andy Lehane
+ * @version $Id: LockableFileWriter.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class LockableFileWriter extends Writer {
+ // Cannot extend ProxyWriter, as requires writer to be
+ // known when super() is called
+
+ /** The extension for the lock file. */
+ private static final String LCK = ".lck";
+
+ /** The writer to decorate. */
+ private final Writer out;
+ /** The lock file. */
+ private final File lockFile;
+
+ /**
+ * Constructs a LockableFileWriter.
+ * If the file exists, it is overwritten.
+ *
+ * @param fileName the file to write to, not null
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(String fileName) throws IOException {
+ this(fileName, false, null);
+ }
+
+ /**
+ * Constructs a LockableFileWriter.
+ *
+ * @param fileName file to write to, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(String fileName, boolean append) throws IOException {
+ this(fileName, append, null);
+ }
+
+ /**
+ * Constructs a LockableFileWriter.
+ *
+ * @param fileName the file to write to, not null
+ * @param append true if content should be appended, false to overwrite
+ * @param lockDir the directory in which the lock file should be held
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(String fileName, boolean append, String lockDir) throws IOException {
+ this(new File(fileName), append, lockDir);
+ }
+
+ /**
+ * Constructs a LockableFileWriter.
+ * If the file exists, it is overwritten.
+ *
+ * @param file the file to write to, not null
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(File file) throws IOException {
+ this(file, false, null);
+ }
+
+ /**
+ * Constructs a LockableFileWriter.
+ *
+ * @param file the file to write to, not null
+ * @param append true if content should be appended, false to overwrite
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(File file, boolean append) throws IOException {
+ this(file, append, null);
+ }
+
+ /**
+ * Constructs a LockableFileWriter.
+ *
+ * @param file the file to write to, not null
+ * @param append true if content should be appended, false to overwrite
+ * @param lockDir the directory in which the lock file should be held
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(File file, boolean append, String lockDir) throws IOException {
+ this(file, null, append, lockDir);
+ }
+
+ /**
+ * Constructs a LockableFileWriter with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(File file, String encoding) throws IOException {
+ this(file, encoding, false, null);
+ }
+
+ /**
+ * Constructs a LockableFileWriter with a file encoding.
+ *
+ * @param file the file to write to, not null
+ * @param encoding the encoding to use, null means platform default
+ * @param append true if content should be appended, false to overwrite
+ * @param lockDir the directory in which the lock file should be held
+ * @throws NullPointerException if the file is null
+ * @throws IOException in case of an I/O error
+ */
+ public LockableFileWriter(File file, String encoding, boolean append,
+ String lockDir) throws IOException {
+ super();
+ // init file to create/append
+ file = file.getAbsoluteFile();
+ if (file.getParentFile() != null) {
+ FileUtils.forceMkdir(file.getParentFile());
+ }
+ if (file.isDirectory()) {
+ throw new IOException("File specified is a directory");
+ }
+
+ // init lock file
+ if (lockDir == null) {
+ lockDir = System.getProperty("java.io.tmpdir");
+ }
+ File lockDirFile = new File(lockDir);
+ FileUtils.forceMkdir(lockDirFile);
+ testLockDir(lockDirFile);
+ lockFile = new File(lockDirFile, file.getName() + LCK);
+
+ // check if locked
+ createLock();
+
+ // init wrapped writer
+ out = initWriter(file, encoding, append);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Tests that we can write to the lock directory.
+ *
+ * @param lockDir the File representing the lock directory
+ * @throws IOException if we cannot write to the lock directory
+ * @throws IOException if we cannot find the lock file
+ */
+ private void testLockDir(File lockDir) throws IOException {
+ if (!lockDir.exists()) {
+ throw new IOException(
+ "Could not find lockDir: " + lockDir.getAbsolutePath());
+ }
+ if (!lockDir.canWrite()) {
+ throw new IOException(
+ "Could not write to lockDir: " + lockDir.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Creates the lock file.
+ *
+ * @throws IOException if we cannot create the file
+ */
+ private void createLock() throws IOException {
+ synchronized (LockableFileWriter.class) {
+ if (!lockFile.createNewFile()) {
+ throw new IOException("Can't write file, lock " +
+ lockFile.getAbsolutePath() + " exists");
+ }
+ lockFile.deleteOnExit();
+ }
+ }
+
+ /**
+ * Initialise the wrapped file writer.
+ * Ensure that a cleanup occurs if the writer creation fails.
+ *
+ * @param file the file to be accessed
+ * @param encoding the encoding to use
+ * @param append true to append
+ * @return The initialised writer
+ * @throws IOException if an error occurs
+ */
+ private Writer initWriter(File file, String encoding, boolean append) throws IOException {
+ boolean fileExistedAlready = file.exists();
+ OutputStream stream = null;
+ Writer writer = null;
+ try {
+ if (encoding == null) {
+ writer = new FileWriter(file.getAbsolutePath(), append);
+ } else {
+ stream = new FileOutputStream(file.getAbsolutePath(), append);
+ writer = new OutputStreamWriter(stream, encoding);
+ }
+ } catch (IOException ex) {
+ IOUtils.closeQuietly(writer);
+ IOUtils.closeQuietly(stream);
+ lockFile.delete();
+ if (fileExistedAlready == false) {
+ file.delete();
+ }
+ throw ex;
+ } catch (RuntimeException ex) {
+ IOUtils.closeQuietly(writer);
+ IOUtils.closeQuietly(stream);
+ lockFile.delete();
+ if (fileExistedAlready == false) {
+ file.delete();
+ }
+ throw ex;
+ }
+ return writer;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Closes the file writer.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ try {
+ out.close();
+ } finally {
+ lockFile.delete();
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Write a character.
+ * @param idx the character to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(int idx) throws IOException {
+ out.write(idx);
+ }
+
+ /**
+ * Write the characters from an array.
+ * @param chr the characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr) throws IOException {
+ out.write(chr);
+ }
+
+ /**
+ * Write the specified characters from an array.
+ * @param chr the characters to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr, int st, int end) throws IOException {
+ out.write(chr, st, end);
+ }
+
+ /**
+ * Write the characters from a string.
+ * @param str the string to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str) throws IOException {
+ out.write(str);
+ }
+
+ /**
+ * Write the specified characters from a string.
+ * @param str the string to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str, int st, int end) throws IOException {
+ out.write(str, st, end);
+ }
+
+ /**
+ * Flush the stream.
+ * @throws IOException if an I/O error occurs
+ */
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/NullOutputStream.java b/src/org/apache/commons/io/output/NullOutputStream.java
index 7e3cdaf2c254dc6e2d2f059d7232eb296fe77331..5558d30d72479a5f58ed7d89c107e87ce65d3516 100644
--- a/src/org/apache/commons/io/output/NullOutputStream.java
+++ b/src/org/apache/commons/io/output/NullOutputStream.java
@@ -1,65 +1,65 @@
-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * This OutputStream writes all data to the famous /dev/null.
- * /dev/null
.
- * @param b The bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
- */
- public void write(byte[] b, int off, int len) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param b The byte to write
- */
- public void write(int b) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param b The bytes to write
- * @throws IOException never
- */
- public void write(byte[] b) throws IOException {
- //to /dev/null
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This OutputStream writes all data to the famous /dev/null.
+ * /dev/null
.
+ * @param b The bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
+ */
+ public void write(byte[] b, int off, int len) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param b The byte to write
+ */
+ public void write(int b) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param b The bytes to write
+ * @throws IOException never
+ */
+ public void write(byte[] b) throws IOException {
+ //to /dev/null
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/NullWriter.java b/src/org/apache/commons/io/output/NullWriter.java
index aed52aba89debd1d6becf3b8d98b1ba5eb012bb3..8fd2bf489c2f8a660cec9bd25b93d0c685e7e040 100644
--- a/src/org/apache/commons/io/output/NullWriter.java
+++ b/src/org/apache/commons/io/output/NullWriter.java
@@ -1,96 +1,96 @@
-/*
- * 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.commons.io.output;
-
-import java.io.Writer;
-
-/**
- * This {@link Writer} writes all data to the famous /dev/null.
- * Writer
has no destination (file/socket etc.) and all
- * characters written to it are ignored and lost.
- *
- * @version $Id: NullWriter.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class NullWriter extends Writer {
-
- /**
- * A singleton.
- */
- public static final NullWriter NULL_WRITER = new NullWriter();
-
- /**
- * Constructs a new NullWriter.
- */
- public NullWriter() {
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param idx The character to write
- */
- public void write(int idx) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param chr The characters to write
- */
- public void write(char[] chr) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param chr The characters to write
- * @param st The start offset
- * @param end The number of characters to write
- */
- public void write(char[] chr, int st, int end) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param str The string to write
- */
- public void write(String str) {
- //to /dev/null
- }
-
- /**
- * Does nothing - output to /dev/null
.
- * @param str The string to write
- * @param st The start offset
- * @param end The number of characters to write
- */
- public void write(String str, int st, int end) {
- //to /dev/null
- }
-
- /** @see java.io.Writer#flush() */
- public void flush() {
- //to /dev/null
- }
-
- /** @see java.io.Writer#close() */
- public void close() {
- //to /dev/null
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.Writer;
+
+/**
+ * This {@link Writer} writes all data to the famous /dev/null.
+ * Writer
has no destination (file/socket etc.) and all
+ * characters written to it are ignored and lost.
+ *
+ * @version $Id: NullWriter.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class NullWriter extends Writer {
+
+ /**
+ * A singleton.
+ */
+ public static final NullWriter NULL_WRITER = new NullWriter();
+
+ /**
+ * Constructs a new NullWriter.
+ */
+ public NullWriter() {
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param idx The character to write
+ */
+ public void write(int idx) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param chr The characters to write
+ */
+ public void write(char[] chr) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param chr The characters to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ */
+ public void write(char[] chr, int st, int end) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param str The string to write
+ */
+ public void write(String str) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to /dev/null
.
+ * @param str The string to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ */
+ public void write(String str, int st, int end) {
+ //to /dev/null
+ }
+
+ /** @see java.io.Writer#flush() */
+ public void flush() {
+ //to /dev/null
+ }
+
+ /** @see java.io.Writer#close() */
+ public void close() {
+ //to /dev/null
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/ProxyOutputStream.java b/src/org/apache/commons/io/output/ProxyOutputStream.java
index b63d723171edeada7e8088eadcd10191c9189928..9376d6ce4df0f7ca35fde79928ea9a4424310e79 100644
--- a/src/org/apache/commons/io/output/ProxyOutputStream.java
+++ b/src/org/apache/commons/io/output/ProxyOutputStream.java
@@ -1,89 +1,89 @@
-/*
- * 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.commons.io.output;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A Proxy stream which acts as expected, that is it passes the method
- * calls on to the proxied stream and doesn't change which methods are
- * being called. It is an alternative base class to FilterOutputStream
- * to increase reusability.
- *
- * @author Stephen Colebourne
- * @version $Id: ProxyOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class ProxyOutputStream extends FilterOutputStream {
-
- /**
- * Constructs a new ProxyOutputStream.
- *
- * @param proxy the OutputStream to delegate to
- */
- public ProxyOutputStream(OutputStream proxy) {
- super(proxy);
- // the proxy is stored in a protected superclass variable named 'out'
- }
-
- /**
- * Invokes the delegate's write(int)
method.
- * @param idx the byte to write
- * @throws IOException if an I/O error occurs
- */
- public void write(int idx) throws IOException {
- out.write(idx);
- }
-
- /**
- * Invokes the delegate's write(byte[])
method.
- * @param bts the bytes to write
- * @throws IOException if an I/O error occurs
- */
- public void write(byte[] bts) throws IOException {
- out.write(bts);
- }
-
- /**
- * Invokes the delegate's write(byte[])
method.
- * @param bts the bytes to write
- * @param st The start offset
- * @param end The number of bytes to write
- * @throws IOException if an I/O error occurs
- */
- public void write(byte[] bts, int st, int end) throws IOException {
- out.write(bts, st, end);
- }
-
- /**
- * Invokes the delegate's flush()
method.
- * @throws IOException if an I/O error occurs
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Invokes the delegate's close()
method.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- out.close();
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A Proxy stream which acts as expected, that is it passes the method
+ * calls on to the proxied stream and doesn't change which methods are
+ * being called. It is an alternative base class to FilterOutputStream
+ * to increase reusability.
+ *
+ * @author Stephen Colebourne
+ * @version $Id: ProxyOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class ProxyOutputStream extends FilterOutputStream {
+
+ /**
+ * Constructs a new ProxyOutputStream.
+ *
+ * @param proxy the OutputStream to delegate to
+ */
+ public ProxyOutputStream(OutputStream proxy) {
+ super(proxy);
+ // the proxy is stored in a protected superclass variable named 'out'
+ }
+
+ /**
+ * Invokes the delegate's write(int)
method.
+ * @param idx the byte to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(int idx) throws IOException {
+ out.write(idx);
+ }
+
+ /**
+ * Invokes the delegate's write(byte[])
method.
+ * @param bts the bytes to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(byte[] bts) throws IOException {
+ out.write(bts);
+ }
+
+ /**
+ * Invokes the delegate's write(byte[])
method.
+ * @param bts the bytes to write
+ * @param st The start offset
+ * @param end The number of bytes to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(byte[] bts, int st, int end) throws IOException {
+ out.write(bts, st, end);
+ }
+
+ /**
+ * Invokes the delegate's flush()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Invokes the delegate's close()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ out.close();
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/ProxyWriter.java b/src/org/apache/commons/io/output/ProxyWriter.java
index fbec628851501038ef5104e934b0776a67f9cb2e..8b617d85249aa9132bf48416f11464a1f64ea3d7 100644
--- a/src/org/apache/commons/io/output/ProxyWriter.java
+++ b/src/org/apache/commons/io/output/ProxyWriter.java
@@ -1,111 +1,111 @@
-/*
- * 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.commons.io.output;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * A Proxy stream which acts as expected, that is it passes the method
- * calls on to the proxied stream and doesn't change which methods are
- * being called. It is an alternative base class to FilterWriter
- * to increase reusability, because FilterWriter changes the
- * methods being called, such as write(char[]) to write(char[], int, int)
- * and write(String) to write(String, int, int).
- *
- * @author Stephen Colebourne
- * @version $Id: ProxyWriter.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class ProxyWriter extends FilterWriter {
-
- /**
- * Constructs a new ProxyWriter.
- *
- * @param proxy the Writer to delegate to
- */
- public ProxyWriter(Writer proxy) {
- super(proxy);
- // the proxy is stored in a protected superclass variable named 'out'
- }
-
- /**
- * Invokes the delegate's write(int)
method.
- * @param idx the character to write
- * @throws IOException if an I/O error occurs
- */
- public void write(int idx) throws IOException {
- out.write(idx);
- }
-
- /**
- * Invokes the delegate's write(char[])
method.
- * @param chr the characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr) throws IOException {
- out.write(chr);
- }
-
- /**
- * Invokes the delegate's write(char[], int, int)
method.
- * @param chr the characters to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(char[] chr, int st, int end) throws IOException {
- out.write(chr, st, end);
- }
-
- /**
- * Invokes the delegate's write(String)
method.
- * @param str the string to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str) throws IOException {
- out.write(str);
- }
-
- /**
- * Invokes the delegate's write(String)
method.
- * @param str the string to write
- * @param st The start offset
- * @param end The number of characters to write
- * @throws IOException if an I/O error occurs
- */
- public void write(String str, int st, int end) throws IOException {
- out.write(str, st, end);
- }
-
- /**
- * Invokes the delegate's flush()
method.
- * @throws IOException if an I/O error occurs
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Invokes the delegate's close()
method.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- out.close();
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * A Proxy stream which acts as expected, that is it passes the method
+ * calls on to the proxied stream and doesn't change which methods are
+ * being called. It is an alternative base class to FilterWriter
+ * to increase reusability, because FilterWriter changes the
+ * methods being called, such as write(char[]) to write(char[], int, int)
+ * and write(String) to write(String, int, int).
+ *
+ * @author Stephen Colebourne
+ * @version $Id: ProxyWriter.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class ProxyWriter extends FilterWriter {
+
+ /**
+ * Constructs a new ProxyWriter.
+ *
+ * @param proxy the Writer to delegate to
+ */
+ public ProxyWriter(Writer proxy) {
+ super(proxy);
+ // the proxy is stored in a protected superclass variable named 'out'
+ }
+
+ /**
+ * Invokes the delegate's write(int)
method.
+ * @param idx the character to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(int idx) throws IOException {
+ out.write(idx);
+ }
+
+ /**
+ * Invokes the delegate's write(char[])
method.
+ * @param chr the characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr) throws IOException {
+ out.write(chr);
+ }
+
+ /**
+ * Invokes the delegate's write(char[], int, int)
method.
+ * @param chr the characters to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(char[] chr, int st, int end) throws IOException {
+ out.write(chr, st, end);
+ }
+
+ /**
+ * Invokes the delegate's write(String)
method.
+ * @param str the string to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str) throws IOException {
+ out.write(str);
+ }
+
+ /**
+ * Invokes the delegate's write(String)
method.
+ * @param str the string to write
+ * @param st The start offset
+ * @param end The number of characters to write
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str, int st, int end) throws IOException {
+ out.write(str, st, end);
+ }
+
+ /**
+ * Invokes the delegate's flush()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Invokes the delegate's close()
method.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ out.close();
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/TeeOutputStream.java b/src/org/apache/commons/io/output/TeeOutputStream.java
index ee957fb3b1d5fc4c7e3cf611e26a710ce8a47aeb..6f799d19c35f5cbedc93dd62fc78f29cfa1022ea 100644
--- a/src/org/apache/commons/io/output/TeeOutputStream.java
+++ b/src/org/apache/commons/io/output/TeeOutputStream.java
@@ -1,94 +1,94 @@
-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Classic splitter of OutputStream. Named after the unix 'tee'
- * command. It allows a stream to be branched off so there
- * are now two streams.
- *
- * @version $Id: TeeOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class TeeOutputStream extends ProxyOutputStream {
-
- /** the second OutputStream to write to */
- protected OutputStream branch;
-
- /**
- * Constructs a TeeOutputStream.
- * @param out the main OutputStream
- * @param branch the second OutputStream
- */
- public TeeOutputStream( OutputStream out, OutputStream branch ) {
- super(out);
- this.branch = branch;
- }
-
- /**
- * Write the bytes to both streams.
- * @param b the bytes to write
- * @throws IOException if an I/O error occurs
- */
- public synchronized void write(byte[] b) throws IOException {
- super.write(b);
- this.branch.write(b);
- }
-
- /**
- * Write the specified bytes to both streams.
- * @param b the bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
- * @throws IOException if an I/O error occurs
- */
- public synchronized void write(byte[] b, int off, int len) throws IOException {
- super.write(b, off, len);
- this.branch.write(b, off, len);
- }
-
- /**
- * Write a byte to both streams.
- * @param b the byte to write
- * @throws IOException if an I/O error occurs
- */
- public synchronized void write(int b) throws IOException {
- super.write(b);
- this.branch.write(b);
- }
-
- /**
- * Flushes both streams.
- * @throws IOException if an I/O error occurs
- */
- public void flush() throws IOException {
- super.flush();
- this.branch.flush();
- }
-
- /**
- * Closes both streams.
- * @throws IOException if an I/O error occurs
- */
- public void close() throws IOException {
- super.close();
- this.branch.close();
- }
-
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Classic splitter of OutputStream. Named after the unix 'tee'
+ * command. It allows a stream to be branched off so there
+ * are now two streams.
+ *
+ * @version $Id: TeeOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
+ */
+public class TeeOutputStream extends ProxyOutputStream {
+
+ /** the second OutputStream to write to */
+ protected OutputStream branch;
+
+ /**
+ * Constructs a TeeOutputStream.
+ * @param out the main OutputStream
+ * @param branch the second OutputStream
+ */
+ public TeeOutputStream( OutputStream out, OutputStream branch ) {
+ super(out);
+ this.branch = branch;
+ }
+
+ /**
+ * Write the bytes to both streams.
+ * @param b the bytes to write
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void write(byte[] b) throws IOException {
+ super.write(b);
+ this.branch.write(b);
+ }
+
+ /**
+ * Write the specified bytes to both streams.
+ * @param b the bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void write(byte[] b, int off, int len) throws IOException {
+ super.write(b, off, len);
+ this.branch.write(b, off, len);
+ }
+
+ /**
+ * Write a byte to both streams.
+ * @param b the byte to write
+ * @throws IOException if an I/O error occurs
+ */
+ public synchronized void write(int b) throws IOException {
+ super.write(b);
+ this.branch.write(b);
+ }
+
+ /**
+ * Flushes both streams.
+ * @throws IOException if an I/O error occurs
+ */
+ public void flush() throws IOException {
+ super.flush();
+ this.branch.flush();
+ }
+
+ /**
+ * Closes both streams.
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ super.close();
+ this.branch.close();
+ }
+
+}
diff --git a/src/org/apache/commons/io/output/ThresholdingOutputStream.java b/src/org/apache/commons/io/output/ThresholdingOutputStream.java
index fa69a804cd683d7115231fbc28a0c626ae38db02..ca6ede2344b11263721d67d3a3b5cccb0fe7a24e 100644
--- a/src/org/apache/commons/io/output/ThresholdingOutputStream.java
+++ b/src/org/apache/commons/io/output/ThresholdingOutputStream.java
@@ -1,257 +1,257 @@
-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/**
- * An output stream which triggers an event when a specified number of bytes of
- * data have been written to it. The event can be used, for example, to throw
- * an exception if a maximum has been reached, or to switch the underlying
- * stream type when the threshold is exceeded.
- * OutputStream
methods. However, these
- * overrides ultimately call the corresponding methods in the underlying output
- * stream implementation.
- * b.length
bytes from the specified byte array to this
- * output stream.
- *
- * @param b The array of bytes to be written.
- *
- * @exception IOException if an error occurs.
- */
- public void write(byte b[]) throws IOException
- {
- checkThreshold(b.length);
- getStream().write(b);
- written += b.length;
- }
-
-
- /**
- * Writes len
bytes from the specified byte array starting at
- * offset off
to this output stream.
- *
- * @param b The byte array from which the data will be written.
- * @param off The start offset in the byte array.
- * @param len The number of bytes to write.
- *
- * @exception IOException if an error occurs.
- */
- public void write(byte b[], int off, int len) throws IOException
- {
- checkThreshold(len);
- getStream().write(b, off, len);
- written += len;
- }
-
-
- /**
- * Flushes this output stream and forces any buffered output bytes to be
- * written out.
- *
- * @exception IOException if an error occurs.
- */
- public void flush() throws IOException
- {
- getStream().flush();
- }
-
-
- /**
- * Closes this output stream and releases any system resources associated
- * with this stream.
- *
- * @exception IOException if an error occurs.
- */
- public void close() throws IOException
- {
- try
- {
- flush();
- }
- catch (IOException ignored)
- {
- // ignore
- }
- getStream().close();
- }
-
-
- // --------------------------------------------------------- Public methods
-
-
- /**
- * Returns the threshold, in bytes, at which an event will be triggered.
- *
- * @return The threshold point, in bytes.
- */
- public int getThreshold()
- {
- return threshold;
- }
-
-
- /**
- * Returns the number of bytes that have been written to this output stream.
- *
- * @return The number of bytes written.
- */
- public long getByteCount()
- {
- return written;
- }
-
-
- /**
- * Determines whether or not the configured threshold has been exceeded for
- * this output stream.
- *
- * @return true
if the threshold has been reached;
- * false
otherwise.
- */
- public boolean isThresholdExceeded()
- {
- return (written > threshold);
- }
-
-
- // ------------------------------------------------------ Protected methods
-
-
- /**
- * Checks to see if writing the specified number of bytes would cause the
- * configured threshold to be exceeded. If so, triggers an event to allow
- * a concrete implementation to take action on this.
- *
- * @param count The number of bytes about to be written to the underlying
- * output stream.
- *
- * @exception IOException if an error occurs.
- */
- protected void checkThreshold(int count) throws IOException
- {
- if (!thresholdExceeded && (written + count > threshold))
- {
- thresholdExceeded = true;
- thresholdReached();
- }
- }
-
- /**
- * Resets the byteCount to zero. You can call this from
- * {@link #thresholdReached()} if you want the event to be triggered again.
- */
- protected void resetByteCount()
- {
- this.thresholdExceeded = false;
- this.written = 0;
- }
-
- // ------------------------------------------------------- Abstract methods
-
-
- /**
- * Returns the underlying output stream, to which the corresponding
- * OutputStream
methods in this class will ultimately delegate.
- *
- * @return The underlying output stream.
- *
- * @exception IOException if an error occurs.
- */
- protected abstract OutputStream getStream() throws IOException;
-
-
- /**
- * Indicates that the configured threshold has been reached, and that a
- * subclass should take whatever action necessary on this event. This may
- * include changing the underlying output stream.
- *
- * @exception IOException if an error occurs.
- */
- protected abstract void thresholdReached() throws IOException;
-}
+/*
+ * 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.commons.io.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * An output stream which triggers an event when a specified number of bytes of
+ * data have been written to it. The event can be used, for example, to throw
+ * an exception if a maximum has been reached, or to switch the underlying
+ * stream type when the threshold is exceeded.
+ * OutputStream
methods. However, these
+ * overrides ultimately call the corresponding methods in the underlying output
+ * stream implementation.
+ * b.length
bytes from the specified byte array to this
+ * output stream.
+ *
+ * @param b The array of bytes to be written.
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void write(byte b[]) throws IOException
+ {
+ checkThreshold(b.length);
+ getStream().write(b);
+ written += b.length;
+ }
+
+
+ /**
+ * Writes len
bytes from the specified byte array starting at
+ * offset off
to this output stream.
+ *
+ * @param b The byte array from which the data will be written.
+ * @param off The start offset in the byte array.
+ * @param len The number of bytes to write.
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void write(byte b[], int off, int len) throws IOException
+ {
+ checkThreshold(len);
+ getStream().write(b, off, len);
+ written += len;
+ }
+
+
+ /**
+ * Flushes this output stream and forces any buffered output bytes to be
+ * written out.
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void flush() throws IOException
+ {
+ getStream().flush();
+ }
+
+
+ /**
+ * Closes this output stream and releases any system resources associated
+ * with this stream.
+ *
+ * @exception IOException if an error occurs.
+ */
+ public void close() throws IOException
+ {
+ try
+ {
+ flush();
+ }
+ catch (IOException ignored)
+ {
+ // ignore
+ }
+ getStream().close();
+ }
+
+
+ // --------------------------------------------------------- Public methods
+
+
+ /**
+ * Returns the threshold, in bytes, at which an event will be triggered.
+ *
+ * @return The threshold point, in bytes.
+ */
+ public int getThreshold()
+ {
+ return threshold;
+ }
+
+
+ /**
+ * Returns the number of bytes that have been written to this output stream.
+ *
+ * @return The number of bytes written.
+ */
+ public long getByteCount()
+ {
+ return written;
+ }
+
+
+ /**
+ * Determines whether or not the configured threshold has been exceeded for
+ * this output stream.
+ *
+ * @return true
if the threshold has been reached;
+ * false
otherwise.
+ */
+ public boolean isThresholdExceeded()
+ {
+ return (written > threshold);
+ }
+
+
+ // ------------------------------------------------------ Protected methods
+
+
+ /**
+ * Checks to see if writing the specified number of bytes would cause the
+ * configured threshold to be exceeded. If so, triggers an event to allow
+ * a concrete implementation to take action on this.
+ *
+ * @param count The number of bytes about to be written to the underlying
+ * output stream.
+ *
+ * @exception IOException if an error occurs.
+ */
+ protected void checkThreshold(int count) throws IOException
+ {
+ if (!thresholdExceeded && (written + count > threshold))
+ {
+ thresholdExceeded = true;
+ thresholdReached();
+ }
+ }
+
+ /**
+ * Resets the byteCount to zero. You can call this from
+ * {@link #thresholdReached()} if you want the event to be triggered again.
+ */
+ protected void resetByteCount()
+ {
+ this.thresholdExceeded = false;
+ this.written = 0;
+ }
+
+ // ------------------------------------------------------- Abstract methods
+
+
+ /**
+ * Returns the underlying output stream, to which the corresponding
+ * OutputStream
methods in this class will ultimately delegate.
+ *
+ * @return The underlying output stream.
+ *
+ * @exception IOException if an error occurs.
+ */
+ protected abstract OutputStream getStream() throws IOException;
+
+
+ /**
+ * Indicates that the configured threshold has been reached, and that a
+ * subclass should take whatever action necessary on this event. This may
+ * include changing the underlying output stream.
+ *
+ * @exception IOException if an error occurs.
+ */
+ protected abstract void thresholdReached() throws IOException;
+}
diff --git a/src/org/apache/commons/io/output/package.html b/src/org/apache/commons/io/output/package.html
index db2cbce59e5d82b21545e4f89f78a1dd455f1fef..44156133099931af89a39850a604cf96188722d0 100644
--- a/src/org/apache/commons/io/output/package.html
+++ b/src/org/apache/commons/io/output/package.html
@@ -1,25 +1,25 @@
-
-
-
-OutputStream
and Writer
.
-OutputStream
and Writer
.
+ContentHandler
with default implementations of all
- * the methods of the ContentHandler
interface.
- *
- * The default is to todo nothing.
- *
- *
- * @version $Id: AbstractContentHandler.java,v 1.3 2004/10/02 12:41:10 ntherning Exp $
- */
-public abstract class AbstractContentHandler implements ContentHandler {
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endMultipart()
- */
- public void endMultipart() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
- */
- public void startMultipart(BodyDescriptor bd) {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
- */
- public void body(BodyDescriptor bd, InputStream is) throws IOException {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
- */
- public void endBodyPart() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endHeader()
- */
- public void endHeader() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endMessage()
- */
- public void endMessage() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
- */
- public void epilogue(InputStream is) throws IOException {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
- */
- public void field(String fieldData) {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
- */
- public void preamble(InputStream is) throws IOException {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
- */
- public void startBodyPart() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startHeader()
- */
- public void startHeader() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startMessage()
- */
- public void startMessage() {
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
- */
- public void raw(InputStream is) throws IOException {
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Abstract ContentHandler
with default implementations of all
+ * the methods of the ContentHandler
interface.
+ *
+ * The default is to todo nothing.
+ *
+ *
+ * @version $Id: AbstractContentHandler.java,v 1.3 2004/10/02 12:41:10 ntherning Exp $
+ */
+public abstract class AbstractContentHandler implements ContentHandler {
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endMultipart()
+ */
+ public void endMultipart() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
+ */
+ public void startMultipart(BodyDescriptor bd) {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
+ */
+ public void body(BodyDescriptor bd, InputStream is) throws IOException {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
+ */
+ public void endBodyPart() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endHeader()
+ */
+ public void endHeader() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endMessage()
+ */
+ public void endMessage() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
+ */
+ public void epilogue(InputStream is) throws IOException {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
+ */
+ public void field(String fieldData) {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
+ */
+ public void preamble(InputStream is) throws IOException {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
+ */
+ public void startBodyPart() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startHeader()
+ */
+ public void startHeader() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startMessage()
+ */
+ public void startMessage() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
+ */
+ public void raw(InputStream is) throws IOException {
+ }
+}
diff --git a/src/org/apache/james/mime4j/BodyDescriptor.java b/src/org/apache/james/mime4j/BodyDescriptor.java
index 515658a8df4dd383b1cf8aecd99c6d23c322c548..ca447b03252259d8898587b27e9d3c5cdf648e4e 100644
--- a/src/org/apache/james/mime4j/BodyDescriptor.java
+++ b/src/org/apache/james/mime4j/BodyDescriptor.java
@@ -1,410 +1,410 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Encapsulates the values of the MIME-specific header fields
- * (which starts with Content-
).
- *
- *
- * @version $Id: BodyDescriptor.java,v 1.4 2005/02/11 10:08:37 ntherning Exp $
- */
-public class BodyDescriptor {
- private static Log log = LogFactory.getLog(BodyDescriptor.class);
-
- private String mimeType = "text/plain";
- private String boundary = null;
- private String charset = "us-ascii";
- private String transferEncoding = "7bit";
- private Map parameters = new HashMap();
- private boolean contentTypeSet = false;
- private boolean contentTransferEncSet = false;
-
- /**
- * Creates a new root BodyDescriptor
instance.
- */
- public BodyDescriptor() {
- this(null);
- }
-
- /**
- * Creates a new BodyDescriptor
instance.
- *
- * @param parent the descriptor of the parent or null
if this
- * is the root descriptor.
- */
- public BodyDescriptor(BodyDescriptor parent) {
- if (parent != null && parent.isMimeType("multipart/digest")) {
- mimeType = "message/rfc822";
- } else {
- mimeType = "text/plain";
- }
- }
-
- /**
- * Should be called for each Content-
header field of
- * a MIME message or part.
- *
- * @param name the field name.
- * @param value the field value.
- */
- public void addField(String name, String value) {
-
- name = name.trim().toLowerCase();
-
- if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
- contentTransferEncSet = true;
-
- value = value.trim().toLowerCase();
- if (value.length() > 0) {
- transferEncoding = value;
- }
-
- } else if (name.equals("content-type") && !contentTypeSet) {
- contentTypeSet = true;
-
- value = value.trim();
-
- /*
- * Unfold Content-Type value
- */
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- if (c == '\r' || c == '\n') {
- continue;
- }
- sb.append(c);
- }
-
- Map params = getHeaderParams(sb.toString());
-
- String main = (String) params.get("");
- if (main != null) {
- main = main.toLowerCase().trim();
- int index = main.indexOf('/');
- boolean valid = false;
- if (index != -1) {
- String type = main.substring(0, index).trim();
- String subtype = main.substring(index + 1).trim();
- if (type.length() > 0 && subtype.length() > 0) {
- main = type + "/" + subtype;
- valid = true;
- }
- }
-
- if (!valid) {
- main = null;
- }
- }
- String b = (String) params.get("boundary");
-
- if (main != null
- && ((main.startsWith("multipart/") && b != null)
- || !main.startsWith("multipart/"))) {
-
- mimeType = main;
- }
-
- if (isMultipart()) {
- boundary = b;
- }
-
- String c = (String) params.get("charset");
- if (c != null) {
- c = c.trim();
- if (c.length() > 0) {
- charset = c.toLowerCase();
- }
- }
-
- /*
- * Add all other parameters to parameters.
- */
- parameters.putAll(params);
- parameters.remove("");
- parameters.remove("boundary");
- parameters.remove("charset");
- }
- }
-
- private Map getHeaderParams(String headerValue) {
- Map result = new HashMap();
-
- // split main value and parameters
- String main;
- String rest;
- if (headerValue.indexOf(";") == -1) {
- main = headerValue;
- rest = null;
- } else {
- main = headerValue.substring(0, headerValue.indexOf(";"));
- rest = headerValue.substring(main.length() + 1);
- }
-
- result.put("", main);
- if (rest != null) {
- char[] chars = rest.toCharArray();
- StringBuffer paramName = new StringBuffer();
- StringBuffer paramValue = new StringBuffer();
-
- final byte READY_FOR_NAME = 0;
- final byte IN_NAME = 1;
- final byte READY_FOR_VALUE = 2;
- final byte IN_VALUE = 3;
- final byte IN_QUOTED_VALUE = 4;
- final byte VALUE_DONE = 5;
- final byte ERROR = 99;
-
- byte state = READY_FOR_NAME;
- boolean escaped = false;
- for (int i = 0; i < chars.length; i++) {
- char c = chars[i];
-
- switch (state) {
- case ERROR:
- if (c == ';')
- state = READY_FOR_NAME;
- break;
-
- case READY_FOR_NAME:
- if (c == '=') {
- log.error("Expected header param name, got '='");
- state = ERROR;
- break;
- }
-
- paramName = new StringBuffer();
- paramValue = new StringBuffer();
-
- state = IN_NAME;
- // fall-through
-
- case IN_NAME:
- if (c == '=') {
- if (paramName.length() == 0)
- state = ERROR;
- else
- state = READY_FOR_VALUE;
- break;
- }
-
- // not '='... just add to name
- paramName.append(c);
- break;
-
- case READY_FOR_VALUE:
- boolean fallThrough = false;
- switch (c) {
- case ' ':
- case '\t':
- break; // ignore spaces, especially before '"'
-
- case '"':
- state = IN_QUOTED_VALUE;
- break;
-
- default:
- state = IN_VALUE;
- fallThrough = true;
- break;
- }
- if (!fallThrough)
- break;
-
- // fall-through
-
- case IN_VALUE:
- fallThrough = false;
- switch (c) {
- case ';':
- case ' ':
- case '\t':
- result.put(
- paramName.toString().trim().toLowerCase(),
- paramValue.toString().trim());
- state = VALUE_DONE;
- fallThrough = true;
- break;
- default:
- paramValue.append(c);
- break;
- }
- if (!fallThrough)
- break;
-
- case VALUE_DONE:
- switch (c) {
- case ';':
- state = READY_FOR_NAME;
- break;
-
- case ' ':
- case '\t':
- break;
-
- default:
- state = ERROR;
- break;
- }
- break;
-
- case IN_QUOTED_VALUE:
- switch (c) {
- case '"':
- if (!escaped) {
- // don't trim quoted strings; the spaces could be intentional.
- result.put(
- paramName.toString().trim().toLowerCase(),
- paramValue.toString());
- state = VALUE_DONE;
- } else {
- escaped = false;
- paramValue.append(c);
- }
- break;
-
- case '\\':
- if (escaped) {
- paramValue.append('\\');
- }
- escaped = !escaped;
- break;
-
- default:
- if (escaped) {
- paramValue.append('\\');
- }
- escaped = false;
- paramValue.append(c);
- break;
- }
- break;
-
- }
- }
-
- // done looping. check if anything is left over.
- if (state == IN_VALUE) {
- result.put(
- paramName.toString().trim().toLowerCase(),
- paramValue.toString().trim());
- }
- }
-
- return result;
- }
-
-
- public boolean isMimeType(String mimeType) {
- return this.mimeType.equals(mimeType.toLowerCase());
- }
-
- /**
- * Return true if the BodyDescriptor belongs to a message
- *
- * @return
- */
- public boolean isMessage() {
- return mimeType.equals("message/rfc822");
- }
-
- /**
- * Retrun true if the BodyDescripotro belogns to a multipart
- *
- * @return
- */
- public boolean isMultipart() {
- return mimeType.startsWith("multipart/");
- }
-
- /**
- * Return the MimeType
- *
- * @return mimeType
- */
- public String getMimeType() {
- return mimeType;
- }
-
- /**
- * Return the boundary
- *
- * @return boundary
- */
- public String getBoundary() {
- return boundary;
- }
-
- /**
- * Return the charset
- *
- * @return charset
- */
- public String getCharset() {
- return charset;
- }
-
- /**
- * Return all parameters for the BodyDescriptor
- *
- * @return parameters
- */
- public Map getParameters() {
- return parameters;
- }
-
- /**
- * Return the TransferEncoding
- *
- * @return transferEncoding
- */
- public String getTransferEncoding() {
- return transferEncoding;
- }
-
- /**
- * Return true if it's base64 encoded
- *
- * @return
- *
- */
- public boolean isBase64Encoded() {
- return "base64".equals(transferEncoding);
- }
-
- /**
- * Return true if it's quoted-printable
- * @return
- */
- public boolean isQuotedPrintableEncoded() {
- return "quoted-printable".equals(transferEncoding);
- }
-
- public String toString() {
- return mimeType;
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Encapsulates the values of the MIME-specific header fields
+ * (which starts with Content-
).
+ *
+ *
+ * @version $Id: BodyDescriptor.java,v 1.4 2005/02/11 10:08:37 ntherning Exp $
+ */
+public class BodyDescriptor {
+ private static Log log = LogFactory.getLog(BodyDescriptor.class);
+
+ private String mimeType = "text/plain";
+ private String boundary = null;
+ private String charset = "us-ascii";
+ private String transferEncoding = "7bit";
+ private Map parameters = new HashMap();
+ private boolean contentTypeSet = false;
+ private boolean contentTransferEncSet = false;
+
+ /**
+ * Creates a new root BodyDescriptor
instance.
+ */
+ public BodyDescriptor() {
+ this(null);
+ }
+
+ /**
+ * Creates a new BodyDescriptor
instance.
+ *
+ * @param parent the descriptor of the parent or null
if this
+ * is the root descriptor.
+ */
+ public BodyDescriptor(BodyDescriptor parent) {
+ if (parent != null && parent.isMimeType("multipart/digest")) {
+ mimeType = "message/rfc822";
+ } else {
+ mimeType = "text/plain";
+ }
+ }
+
+ /**
+ * Should be called for each Content-
header field of
+ * a MIME message or part.
+ *
+ * @param name the field name.
+ * @param value the field value.
+ */
+ public void addField(String name, String value) {
+
+ name = name.trim().toLowerCase();
+
+ if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
+ contentTransferEncSet = true;
+
+ value = value.trim().toLowerCase();
+ if (value.length() > 0) {
+ transferEncoding = value;
+ }
+
+ } else if (name.equals("content-type") && !contentTypeSet) {
+ contentTypeSet = true;
+
+ value = value.trim();
+
+ /*
+ * Unfold Content-Type value
+ */
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ if (c == '\r' || c == '\n') {
+ continue;
+ }
+ sb.append(c);
+ }
+
+ Map params = getHeaderParams(sb.toString());
+
+ String main = (String) params.get("");
+ if (main != null) {
+ main = main.toLowerCase().trim();
+ int index = main.indexOf('/');
+ boolean valid = false;
+ if (index != -1) {
+ String type = main.substring(0, index).trim();
+ String subtype = main.substring(index + 1).trim();
+ if (type.length() > 0 && subtype.length() > 0) {
+ main = type + "/" + subtype;
+ valid = true;
+ }
+ }
+
+ if (!valid) {
+ main = null;
+ }
+ }
+ String b = (String) params.get("boundary");
+
+ if (main != null
+ && ((main.startsWith("multipart/") && b != null)
+ || !main.startsWith("multipart/"))) {
+
+ mimeType = main;
+ }
+
+ if (isMultipart()) {
+ boundary = b;
+ }
+
+ String c = (String) params.get("charset");
+ if (c != null) {
+ c = c.trim();
+ if (c.length() > 0) {
+ charset = c.toLowerCase();
+ }
+ }
+
+ /*
+ * Add all other parameters to parameters.
+ */
+ parameters.putAll(params);
+ parameters.remove("");
+ parameters.remove("boundary");
+ parameters.remove("charset");
+ }
+ }
+
+ private Map getHeaderParams(String headerValue) {
+ Map result = new HashMap();
+
+ // split main value and parameters
+ String main;
+ String rest;
+ if (headerValue.indexOf(";") == -1) {
+ main = headerValue;
+ rest = null;
+ } else {
+ main = headerValue.substring(0, headerValue.indexOf(";"));
+ rest = headerValue.substring(main.length() + 1);
+ }
+
+ result.put("", main);
+ if (rest != null) {
+ char[] chars = rest.toCharArray();
+ StringBuffer paramName = new StringBuffer();
+ StringBuffer paramValue = new StringBuffer();
+
+ final byte READY_FOR_NAME = 0;
+ final byte IN_NAME = 1;
+ final byte READY_FOR_VALUE = 2;
+ final byte IN_VALUE = 3;
+ final byte IN_QUOTED_VALUE = 4;
+ final byte VALUE_DONE = 5;
+ final byte ERROR = 99;
+
+ byte state = READY_FOR_NAME;
+ boolean escaped = false;
+ for (int i = 0; i < chars.length; i++) {
+ char c = chars[i];
+
+ switch (state) {
+ case ERROR:
+ if (c == ';')
+ state = READY_FOR_NAME;
+ break;
+
+ case READY_FOR_NAME:
+ if (c == '=') {
+ log.error("Expected header param name, got '='");
+ state = ERROR;
+ break;
+ }
+
+ paramName = new StringBuffer();
+ paramValue = new StringBuffer();
+
+ state = IN_NAME;
+ // fall-through
+
+ case IN_NAME:
+ if (c == '=') {
+ if (paramName.length() == 0)
+ state = ERROR;
+ else
+ state = READY_FOR_VALUE;
+ break;
+ }
+
+ // not '='... just add to name
+ paramName.append(c);
+ break;
+
+ case READY_FOR_VALUE:
+ boolean fallThrough = false;
+ switch (c) {
+ case ' ':
+ case '\t':
+ break; // ignore spaces, especially before '"'
+
+ case '"':
+ state = IN_QUOTED_VALUE;
+ break;
+
+ default:
+ state = IN_VALUE;
+ fallThrough = true;
+ break;
+ }
+ if (!fallThrough)
+ break;
+
+ // fall-through
+
+ case IN_VALUE:
+ fallThrough = false;
+ switch (c) {
+ case ';':
+ case ' ':
+ case '\t':
+ result.put(
+ paramName.toString().trim().toLowerCase(),
+ paramValue.toString().trim());
+ state = VALUE_DONE;
+ fallThrough = true;
+ break;
+ default:
+ paramValue.append(c);
+ break;
+ }
+ if (!fallThrough)
+ break;
+
+ case VALUE_DONE:
+ switch (c) {
+ case ';':
+ state = READY_FOR_NAME;
+ break;
+
+ case ' ':
+ case '\t':
+ break;
+
+ default:
+ state = ERROR;
+ break;
+ }
+ break;
+
+ case IN_QUOTED_VALUE:
+ switch (c) {
+ case '"':
+ if (!escaped) {
+ // don't trim quoted strings; the spaces could be intentional.
+ result.put(
+ paramName.toString().trim().toLowerCase(),
+ paramValue.toString());
+ state = VALUE_DONE;
+ } else {
+ escaped = false;
+ paramValue.append(c);
+ }
+ break;
+
+ case '\\':
+ if (escaped) {
+ paramValue.append('\\');
+ }
+ escaped = !escaped;
+ break;
+
+ default:
+ if (escaped) {
+ paramValue.append('\\');
+ }
+ escaped = false;
+ paramValue.append(c);
+ break;
+ }
+ break;
+
+ }
+ }
+
+ // done looping. check if anything is left over.
+ if (state == IN_VALUE) {
+ result.put(
+ paramName.toString().trim().toLowerCase(),
+ paramValue.toString().trim());
+ }
+ }
+
+ return result;
+ }
+
+
+ public boolean isMimeType(String mimeType) {
+ return this.mimeType.equals(mimeType.toLowerCase());
+ }
+
+ /**
+ * Return true if the BodyDescriptor belongs to a message
+ *
+ * @return
+ */
+ public boolean isMessage() {
+ return mimeType.equals("message/rfc822");
+ }
+
+ /**
+ * Retrun true if the BodyDescripotro belogns to a multipart
+ *
+ * @return
+ */
+ public boolean isMultipart() {
+ return mimeType.startsWith("multipart/");
+ }
+
+ /**
+ * Return the MimeType
+ *
+ * @return mimeType
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * Return the boundary
+ *
+ * @return boundary
+ */
+ public String getBoundary() {
+ return boundary;
+ }
+
+ /**
+ * Return the charset
+ *
+ * @return charset
+ */
+ public String getCharset() {
+ return charset;
+ }
+
+ /**
+ * Return all parameters for the BodyDescriptor
+ *
+ * @return parameters
+ */
+ public Map getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Return the TransferEncoding
+ *
+ * @return transferEncoding
+ */
+ public String getTransferEncoding() {
+ return transferEncoding;
+ }
+
+ /**
+ * Return true if it's base64 encoded
+ *
+ * @return
+ *
+ */
+ public boolean isBase64Encoded() {
+ return "base64".equals(transferEncoding);
+ }
+
+ /**
+ * Return true if it's quoted-printable
+ * @return
+ */
+ public boolean isQuotedPrintableEncoded() {
+ return "quoted-printable".equals(transferEncoding);
+ }
+
+ public String toString() {
+ return mimeType;
+ }
+}
diff --git a/src/org/apache/james/mime4j/CloseShieldInputStream.java b/src/org/apache/james/mime4j/CloseShieldInputStream.java
index 94995d1102bfd9e9ba23560b5696ef783e6737df..3acc98f7c480c8b8102f3041e937ee40ba13c425 100644
--- a/src/org/apache/james/mime4j/CloseShieldInputStream.java
+++ b/src/org/apache/james/mime4j/CloseShieldInputStream.java
@@ -1,129 +1,129 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * InputStream that shields its underlying input stream from
- * being closed.
- *
- *
- * @version $Id: CloseShieldInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
- */
-public class CloseShieldInputStream extends InputStream {
-
- /**
- * Underlying InputStream
- */
- private InputStream is;
-
- public CloseShieldInputStream(InputStream is) {
- this.is = is;
- }
-
- public InputStream getUnderlyingStream() {
- return is;
- }
-
- /**
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- checkIfClosed();
- return is.read();
- }
-
- /**
- * @see java.io.InputStream#available()
- */
- public int available() throws IOException {
- checkIfClosed();
- return is.available();
- }
-
-
- /**
- * Set the underlying InputStream to null
- */
- public void close() throws IOException {
- is = null;
- }
-
- /**
- * @see java.io.FilterInputStream#reset()
- */
- public synchronized void reset() throws IOException {
- checkIfClosed();
- is.reset();
- }
-
- /**
- * @see java.io.FilterInputStream#markSupported()
- */
- public boolean markSupported() {
- if (is == null)
- return false;
- return is.markSupported();
- }
-
- /**
- * @see java.io.FilterInputStream#mark(int)
- */
- public synchronized void mark(int readlimit) {
- if (is != null)
- is.mark(readlimit);
- }
-
- /**
- * @see java.io.FilterInputStream#skip(long)
- */
- public long skip(long n) throws IOException {
- checkIfClosed();
- return is.skip(n);
- }
-
- /**
- * @see java.io.FilterInputStream#read(byte[])
- */
- public int read(byte b[]) throws IOException {
- checkIfClosed();
- return is.read(b);
- }
-
- /**
- * @see java.io.FilterInputStream#read(byte[], int, int)
- */
- public int read(byte b[], int off, int len) throws IOException {
- checkIfClosed();
- return is.read(b, off, len);
- }
-
- /**
- * Check if the underlying InputStream is null. If so throw an Exception
- *
- * @throws IOException if the underlying InputStream is null
- */
- private void checkIfClosed() throws IOException {
- if (is == null)
- throw new IOException("Stream is closed");
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * InputStream that shields its underlying input stream from
+ * being closed.
+ *
+ *
+ * @version $Id: CloseShieldInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
+ */
+public class CloseShieldInputStream extends InputStream {
+
+ /**
+ * Underlying InputStream
+ */
+ private InputStream is;
+
+ public CloseShieldInputStream(InputStream is) {
+ this.is = is;
+ }
+
+ public InputStream getUnderlyingStream() {
+ return is;
+ }
+
+ /**
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ checkIfClosed();
+ return is.read();
+ }
+
+ /**
+ * @see java.io.InputStream#available()
+ */
+ public int available() throws IOException {
+ checkIfClosed();
+ return is.available();
+ }
+
+
+ /**
+ * Set the underlying InputStream to null
+ */
+ public void close() throws IOException {
+ is = null;
+ }
+
+ /**
+ * @see java.io.FilterInputStream#reset()
+ */
+ public synchronized void reset() throws IOException {
+ checkIfClosed();
+ is.reset();
+ }
+
+ /**
+ * @see java.io.FilterInputStream#markSupported()
+ */
+ public boolean markSupported() {
+ if (is == null)
+ return false;
+ return is.markSupported();
+ }
+
+ /**
+ * @see java.io.FilterInputStream#mark(int)
+ */
+ public synchronized void mark(int readlimit) {
+ if (is != null)
+ is.mark(readlimit);
+ }
+
+ /**
+ * @see java.io.FilterInputStream#skip(long)
+ */
+ public long skip(long n) throws IOException {
+ checkIfClosed();
+ return is.skip(n);
+ }
+
+ /**
+ * @see java.io.FilterInputStream#read(byte[])
+ */
+ public int read(byte b[]) throws IOException {
+ checkIfClosed();
+ return is.read(b);
+ }
+
+ /**
+ * @see java.io.FilterInputStream#read(byte[], int, int)
+ */
+ public int read(byte b[], int off, int len) throws IOException {
+ checkIfClosed();
+ return is.read(b, off, len);
+ }
+
+ /**
+ * Check if the underlying InputStream is null. If so throw an Exception
+ *
+ * @throws IOException if the underlying InputStream is null
+ */
+ private void checkIfClosed() throws IOException {
+ if (is == null)
+ throw new IOException("Stream is closed");
+ }
+}
diff --git a/src/org/apache/james/mime4j/ContentHandler.java b/src/org/apache/james/mime4j/ContentHandler.java
index 946c8940171f9bf1111d1314f3410b3001ba799f..f8213a0d3c6a0913db01c12136c777f1f7f32497 100644
--- a/src/org/apache/james/mime4j/ContentHandler.java
+++ b/src/org/apache/james/mime4j/ContentHandler.java
@@ -1,177 +1,177 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * MimeStreamParser
instance using its
- * {@link org.apache.james.mime4j.MimeStreamParser#setContentHandler(ContentHandler)}
- * method. The parser uses the ContentHandler
instance to report
- * basic message-related events like the start and end of the body of a
- * part in a multipart MIME entity.
- *
- * startMessage()
- * startHeader()
- * field(...)
- * field(...)
- * ...
- * endHeader()
- * startMultipart()
- * preamble(...)
- * startBodyPart()
- * startHeader()
- * field(...)
- * field(...)
- * ...
- * endHeader()
- * body()
- * endBodyPart()
- * startBodyPart()
- * startHeader()
- * field(...)
- * field(...)
- * ...
- * endHeader()
- * body()
- * endBodyPart()
- * epilogue(...)
- * endMultipart()
- * endMessage()
- *
- * The above shows an example of a MIME message consisting of a multipart
- * body containing two body parts.
- * multipart/*
entity.
- */
- void startBodyPart();
-
- /**
- * Called when a body part ends.
- */
- void endBodyPart();
-
- /**
- * Called when a header (of a message or body part) is about to be parsed.
- */
- void startHeader();
-
- /**
- * Called for each field of a header.
- *
- * @param fieldData the raw contents of the field
- * (Field-Name: field value
). The value will not be
- * unfolded.
- */
- void field(String fieldData);
-
- /**
- * Called when there are no more header fields in a message or body part.
- */
- void endHeader();
-
- /**
- * Called for the preamble (whatever comes before the first body part)
- * of a multipart/*
entity.
- *
- * @param is used to get the contents of the preamble.
- * @throws IOException should be thrown on I/O errors.
- */
- void preamble(InputStream is) throws IOException;
-
- /**
- * Called for the epilogue (whatever comes after the final body part)
- * of a multipart/*
entity.
- *
- * @param is used to get the contents of the epilogue.
- * @throws IOException should be thrown on I/O errors.
- */
- void epilogue(InputStream is) throws IOException;
-
- /**
- * Called when the body of a multipart entity is about to be parsed.
- *
- * @param bd encapsulates the values (either read from the
- * message stream or, if not present, determined implictly
- * as described in the
- * MIME rfc:s) of the Content-Type
and
- * Content-Transfer-Encoding
header fields.
- */
- void startMultipart(BodyDescriptor bd);
-
- /**
- * Called when the body of an entity has been parsed.
- */
- void endMultipart();
-
- /**
- * Called when the body of a discrete (non-multipart) entity is about to
- * be parsed.
- *
- * @param bd see {@link #startMultipart(BodyDescriptor)}
- * @param is the contents of the body. NOTE: this is the raw body contents
- * - it will not be decoded if encoded. The bd
- * parameter should be used to determine how the stream data
- * should be decoded.
- * @throws IOException should be thrown on I/O errors.
- */
- void body(BodyDescriptor bd, InputStream is) throws IOException;
-
- /**
- * Called when a new entity (message or body part) starts and the
- * parser is in raw
mode.
- *
- * @param is the raw contents of the entity.
- * @throws IOException should be thrown on I/O errors.
- * @see MimeStreamParser#setRaw(boolean)
- */
- void raw(InputStream is) throws IOException;
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * MimeStreamParser
instance using its
+ * {@link org.apache.james.mime4j.MimeStreamParser#setContentHandler(ContentHandler)}
+ * method. The parser uses the ContentHandler
instance to report
+ * basic message-related events like the start and end of the body of a
+ * part in a multipart MIME entity.
+ *
+ * startMessage()
+ * startHeader()
+ * field(...)
+ * field(...)
+ * ...
+ * endHeader()
+ * startMultipart()
+ * preamble(...)
+ * startBodyPart()
+ * startHeader()
+ * field(...)
+ * field(...)
+ * ...
+ * endHeader()
+ * body()
+ * endBodyPart()
+ * startBodyPart()
+ * startHeader()
+ * field(...)
+ * field(...)
+ * ...
+ * endHeader()
+ * body()
+ * endBodyPart()
+ * epilogue(...)
+ * endMultipart()
+ * endMessage()
+ *
+ * The above shows an example of a MIME message consisting of a multipart
+ * body containing two body parts.
+ *
+ * See MIME RFCs 2045-2049 for more information on the structure of MIME + * messages and RFC 822 and 2822 for the general structure of Internet mail + * messages. + *
+ * + * + * @version $Id: ContentHandler.java,v 1.3 2004/10/02 12:41:10 ntherning Exp $ + */ +public interface ContentHandler { + /** + * Called when a new message starts (a top level message or an embedded + * rfc822 message). + */ + void startMessage(); + + /** + * Called when a message ends. + */ + void endMessage(); + + /** + * Called when a new body part starts inside a + *multipart/*
entity.
+ */
+ void startBodyPart();
+
+ /**
+ * Called when a body part ends.
+ */
+ void endBodyPart();
+
+ /**
+ * Called when a header (of a message or body part) is about to be parsed.
+ */
+ void startHeader();
+
+ /**
+ * Called for each field of a header.
+ *
+ * @param fieldData the raw contents of the field
+ * (Field-Name: field value
). The value will not be
+ * unfolded.
+ */
+ void field(String fieldData);
+
+ /**
+ * Called when there are no more header fields in a message or body part.
+ */
+ void endHeader();
+
+ /**
+ * Called for the preamble (whatever comes before the first body part)
+ * of a multipart/*
entity.
+ *
+ * @param is used to get the contents of the preamble.
+ * @throws IOException should be thrown on I/O errors.
+ */
+ void preamble(InputStream is) throws IOException;
+
+ /**
+ * Called for the epilogue (whatever comes after the final body part)
+ * of a multipart/*
entity.
+ *
+ * @param is used to get the contents of the epilogue.
+ * @throws IOException should be thrown on I/O errors.
+ */
+ void epilogue(InputStream is) throws IOException;
+
+ /**
+ * Called when the body of a multipart entity is about to be parsed.
+ *
+ * @param bd encapsulates the values (either read from the
+ * message stream or, if not present, determined implictly
+ * as described in the
+ * MIME rfc:s) of the Content-Type
and
+ * Content-Transfer-Encoding
header fields.
+ */
+ void startMultipart(BodyDescriptor bd);
+
+ /**
+ * Called when the body of an entity has been parsed.
+ */
+ void endMultipart();
+
+ /**
+ * Called when the body of a discrete (non-multipart) entity is about to
+ * be parsed.
+ *
+ * @param bd see {@link #startMultipart(BodyDescriptor)}
+ * @param is the contents of the body. NOTE: this is the raw body contents
+ * - it will not be decoded if encoded. The bd
+ * parameter should be used to determine how the stream data
+ * should be decoded.
+ * @throws IOException should be thrown on I/O errors.
+ */
+ void body(BodyDescriptor bd, InputStream is) throws IOException;
+
+ /**
+ * Called when a new entity (message or body part) starts and the
+ * parser is in raw
mode.
+ *
+ * @param is the raw contents of the entity.
+ * @throws IOException should be thrown on I/O errors.
+ * @see MimeStreamParser#setRaw(boolean)
+ */
+ void raw(InputStream is) throws IOException;
+}
diff --git a/src/org/apache/james/mime4j/EOLConvertingInputStream.java b/src/org/apache/james/mime4j/EOLConvertingInputStream.java
index 7d5009ca573ea763aa78d709a8cb9ba1590a3f10..01a7f5db3fff6c1c5d04d3dc7bde969d22070547 100644
--- a/src/org/apache/james/mime4j/EOLConvertingInputStream.java
+++ b/src/org/apache/james/mime4j/EOLConvertingInputStream.java
@@ -1,108 +1,108 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-
-/**
- * InputStream which converts \r
- * bytes not followed by \n
and \n
not
- * preceded by \r
to \r\n
.
- *
- *
- * @version $Id: EOLConvertingInputStream.java,v 1.4 2004/11/29 13:15:42 ntherning Exp $
- */
-public class EOLConvertingInputStream extends InputStream {
- /** Converts single '\r' to '\r\n' */
- public static final int CONVERT_CR = 1;
- /** Converts single '\n' to '\r\n' */
- public static final int CONVERT_LF = 2;
- /** Converts single '\r' and '\n' to '\r\n' */
- public static final int CONVERT_BOTH = 3;
-
- private PushbackInputStream in = null;
- private int previous = 0;
- private int flags = CONVERT_BOTH;
-
- /**
- * Creates a new EOLConvertingInputStream
- * instance converting bytes in the given InputStream
.
- * The flag CONVERT_BOTH
is the default.
- *
- * @param in the InputStream
to read from.
- */
- public EOLConvertingInputStream(InputStream in) {
- this(in, CONVERT_BOTH);
- }
- /**
- * Creates a new EOLConvertingInputStream
- * instance converting bytes in the given InputStream
.
- *
- * @param in the InputStream
to read from.
- * @param flags one of CONVERT_CR
, CONVERT_LF
or
- * CONVERT_BOTH
.
- */
- public EOLConvertingInputStream(InputStream in, int flags) {
- super();
-
- this.in = new PushbackInputStream(in, 2);
- this.flags = flags;
- }
-
- /**
- * Closes the underlying stream.
- *
- * @throws IOException on I/O errors.
- */
- public void close() throws IOException {
- in.close();
- }
-
- /**
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- int b = in.read();
-
- if (b == -1) {
- return -1;
- }
-
- if ((flags & CONVERT_CR) != 0 && b == '\r') {
- int c = in.read();
- if (c != -1) {
- in.unread(c);
- }
- if (c != '\n') {
- in.unread('\n');
- }
- } else if ((flags & CONVERT_LF) != 0 && b == '\n' && previous != '\r') {
- b = '\r';
- in.unread('\n');
- }
-
- previous = b;
-
- return b;
- }
-
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+/**
+ * InputStream which converts \r
+ * bytes not followed by \n
and \n
not
+ * preceded by \r
to \r\n
.
+ *
+ *
+ * @version $Id: EOLConvertingInputStream.java,v 1.4 2004/11/29 13:15:42 ntherning Exp $
+ */
+public class EOLConvertingInputStream extends InputStream {
+ /** Converts single '\r' to '\r\n' */
+ public static final int CONVERT_CR = 1;
+ /** Converts single '\n' to '\r\n' */
+ public static final int CONVERT_LF = 2;
+ /** Converts single '\r' and '\n' to '\r\n' */
+ public static final int CONVERT_BOTH = 3;
+
+ private PushbackInputStream in = null;
+ private int previous = 0;
+ private int flags = CONVERT_BOTH;
+
+ /**
+ * Creates a new EOLConvertingInputStream
+ * instance converting bytes in the given InputStream
.
+ * The flag CONVERT_BOTH
is the default.
+ *
+ * @param in the InputStream
to read from.
+ */
+ public EOLConvertingInputStream(InputStream in) {
+ this(in, CONVERT_BOTH);
+ }
+ /**
+ * Creates a new EOLConvertingInputStream
+ * instance converting bytes in the given InputStream
.
+ *
+ * @param in the InputStream
to read from.
+ * @param flags one of CONVERT_CR
, CONVERT_LF
or
+ * CONVERT_BOTH
.
+ */
+ public EOLConvertingInputStream(InputStream in, int flags) {
+ super();
+
+ this.in = new PushbackInputStream(in, 2);
+ this.flags = flags;
+ }
+
+ /**
+ * Closes the underlying stream.
+ *
+ * @throws IOException on I/O errors.
+ */
+ public void close() throws IOException {
+ in.close();
+ }
+
+ /**
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ int b = in.read();
+
+ if (b == -1) {
+ return -1;
+ }
+
+ if ((flags & CONVERT_CR) != 0 && b == '\r') {
+ int c = in.read();
+ if (c != -1) {
+ in.unread(c);
+ }
+ if (c != '\n') {
+ in.unread('\n');
+ }
+ } else if ((flags & CONVERT_LF) != 0 && b == '\n' && previous != '\r') {
+ b = '\r';
+ in.unread('\n');
+ }
+
+ previous = b;
+
+ return b;
+ }
+
+}
diff --git a/src/org/apache/james/mime4j/MimeBoundaryInputStream.java b/src/org/apache/james/mime4j/MimeBoundaryInputStream.java
index 0fffb7820bfe7425231cd2391c66009f4fff9658..75d1bf7fcdd242d1deb474c81ae636f039d6074d 100644
--- a/src/org/apache/james/mime4j/MimeBoundaryInputStream.java
+++ b/src/org/apache/james/mime4j/MimeBoundaryInputStream.java
@@ -1,184 +1,184 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-
-/**
- * Stream that constrains itself to a single MIME body part.
- * After the stream ends (i.e. read() returns -1) {@link #hasMoreParts()}
- * can be used to determine if a final boundary has been seen or not.
- * If {@link #parentEOF()} is true
an unexpected end of stream
- * has been detected in the parent stream.
- *
- *
- *
- * @version $Id: MimeBoundaryInputStream.java,v 1.2 2004/11/29 13:15:42 ntherning Exp $
- */
-public class MimeBoundaryInputStream extends InputStream {
-
- private PushbackInputStream s = null;
- private byte[] boundary = null;
- private boolean first = true;
- private boolean eof = false;
- private boolean parenteof = false;
- private boolean moreParts = true;
-
- /**
- * Creates a new MimeBoundaryInputStream.
- * @param s The underlying stream.
- * @param boundary Boundary string (not including leading hyphens).
- */
- public MimeBoundaryInputStream(InputStream s, String boundary)
- throws IOException {
-
- this.s = new PushbackInputStream(s, boundary.length() + 4);
-
- boundary = "--" + boundary;
- this.boundary = new byte[boundary.length()];
- for (int i = 0; i < this.boundary.length; i++) {
- this.boundary[i] = (byte) boundary.charAt(i);
- }
-
- /*
- * By reading one byte we will update moreParts to be as expected
- * before any bytes have been read.
- */
- int b = read();
- if (b != -1) {
- this.s.unread(b);
- }
- }
-
- /**
- * Closes the underlying stream.
- *
- * @throws IOException on I/O errors.
- */
- public void close() throws IOException {
- s.close();
- }
-
- /**
- * Determines if the underlying stream has more parts (this stream has
- * not seen an end boundary).
- *
- * @return true
if there are more parts in the underlying
- * stream, false
otherwise.
- */
- public boolean hasMoreParts() {
- return moreParts;
- }
-
- /**
- * Determines if the parent stream has reached EOF
- *
- * @return true
if EOF has been reached for the parent stream,
- * false
otherwise.
- */
- public boolean parentEOF() {
- return parenteof;
- }
-
- /**
- * Consumes all unread bytes of this stream. After a call to this method
- * this stream will have reached EOF.
- *
- * @throws IOException on I/O errors.
- */
- public void consume() throws IOException {
- while (read() != -1) {
- }
- }
-
- /**
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- if (eof) {
- return -1;
- }
-
- if (first) {
- first = false;
- if (matchBoundary()) {
- return -1;
- }
- }
-
- int b1 = s.read();
- int b2 = s.read();
-
- if (b1 == '\r' && b2 == '\n') {
- if (matchBoundary()) {
- return -1;
- }
- }
-
- if (b2 != -1) {
- s.unread(b2);
- }
-
- parenteof = b1 == -1;
- eof = parenteof;
-
- return b1;
- }
-
- private boolean matchBoundary() throws IOException {
-
- for (int i = 0; i < boundary.length; i++) {
- int b = s.read();
- if (b != boundary[i]) {
- if (b != -1) {
- s.unread(b);
- }
- for (int j = i - 1; j >= 0; j--) {
- s.unread(boundary[j]);
- }
- return false;
- }
- }
-
- /*
- * We have a match. Is it an end boundary?
- */
- int prev = s.read();
- int curr = s.read();
- moreParts = !(prev == '-' && curr == '-');
- do {
- if (curr == '\n' && prev == '\r') {
- break;
- }
- prev = curr;
- } while ((curr = s.read()) != -1);
-
- if (curr == -1) {
- moreParts = false;
- parenteof = true;
- }
-
- eof = true;
-
- return true;
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+/**
+ * Stream that constrains itself to a single MIME body part.
+ * After the stream ends (i.e. read() returns -1) {@link #hasMoreParts()}
+ * can be used to determine if a final boundary has been seen or not.
+ * If {@link #parentEOF()} is true
an unexpected end of stream
+ * has been detected in the parent stream.
+ *
+ *
+ *
+ * @version $Id: MimeBoundaryInputStream.java,v 1.2 2004/11/29 13:15:42 ntherning Exp $
+ */
+public class MimeBoundaryInputStream extends InputStream {
+
+ private PushbackInputStream s = null;
+ private byte[] boundary = null;
+ private boolean first = true;
+ private boolean eof = false;
+ private boolean parenteof = false;
+ private boolean moreParts = true;
+
+ /**
+ * Creates a new MimeBoundaryInputStream.
+ * @param s The underlying stream.
+ * @param boundary Boundary string (not including leading hyphens).
+ */
+ public MimeBoundaryInputStream(InputStream s, String boundary)
+ throws IOException {
+
+ this.s = new PushbackInputStream(s, boundary.length() + 4);
+
+ boundary = "--" + boundary;
+ this.boundary = new byte[boundary.length()];
+ for (int i = 0; i < this.boundary.length; i++) {
+ this.boundary[i] = (byte) boundary.charAt(i);
+ }
+
+ /*
+ * By reading one byte we will update moreParts to be as expected
+ * before any bytes have been read.
+ */
+ int b = read();
+ if (b != -1) {
+ this.s.unread(b);
+ }
+ }
+
+ /**
+ * Closes the underlying stream.
+ *
+ * @throws IOException on I/O errors.
+ */
+ public void close() throws IOException {
+ s.close();
+ }
+
+ /**
+ * Determines if the underlying stream has more parts (this stream has
+ * not seen an end boundary).
+ *
+ * @return true
if there are more parts in the underlying
+ * stream, false
otherwise.
+ */
+ public boolean hasMoreParts() {
+ return moreParts;
+ }
+
+ /**
+ * Determines if the parent stream has reached EOF
+ *
+ * @return true
if EOF has been reached for the parent stream,
+ * false
otherwise.
+ */
+ public boolean parentEOF() {
+ return parenteof;
+ }
+
+ /**
+ * Consumes all unread bytes of this stream. After a call to this method
+ * this stream will have reached EOF.
+ *
+ * @throws IOException on I/O errors.
+ */
+ public void consume() throws IOException {
+ while (read() != -1) {
+ }
+ }
+
+ /**
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ if (eof) {
+ return -1;
+ }
+
+ if (first) {
+ first = false;
+ if (matchBoundary()) {
+ return -1;
+ }
+ }
+
+ int b1 = s.read();
+ int b2 = s.read();
+
+ if (b1 == '\r' && b2 == '\n') {
+ if (matchBoundary()) {
+ return -1;
+ }
+ }
+
+ if (b2 != -1) {
+ s.unread(b2);
+ }
+
+ parenteof = b1 == -1;
+ eof = parenteof;
+
+ return b1;
+ }
+
+ private boolean matchBoundary() throws IOException {
+
+ for (int i = 0; i < boundary.length; i++) {
+ int b = s.read();
+ if (b != boundary[i]) {
+ if (b != -1) {
+ s.unread(b);
+ }
+ for (int j = i - 1; j >= 0; j--) {
+ s.unread(boundary[j]);
+ }
+ return false;
+ }
+ }
+
+ /*
+ * We have a match. Is it an end boundary?
+ */
+ int prev = s.read();
+ int curr = s.read();
+ moreParts = !(prev == '-' && curr == '-');
+ do {
+ if (curr == '\n' && prev == '\r') {
+ break;
+ }
+ prev = curr;
+ } while ((curr = s.read()) != -1);
+
+ if (curr == -1) {
+ moreParts = false;
+ parenteof = true;
+ }
+
+ eof = true;
+
+ return true;
+ }
+}
diff --git a/src/org/apache/james/mime4j/MimeStreamParser.java b/src/org/apache/james/mime4j/MimeStreamParser.java
index 2e486adc3370c2860ac73067db01634545ef66c6..5f2d0991432f531b7827749aa98b3e9f48976747 100644
--- a/src/org/apache/james/mime4j/MimeStreamParser.java
+++ b/src/org/apache/james/mime4j/MimeStreamParser.java
@@ -1,320 +1,320 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.BitSet;
-import java.util.LinkedList;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.decoder.Base64InputStream;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
-
-/**
- *
- * Parses MIME (or RFC822) message streams of bytes or characters and reports
- * parsing events to a ContentHandler
instance.
- *
- * Typical usage:
- *
- * ContentHandler handler = new MyHandler(); - * MimeStreamParser parser = new MimeStreamParser(); - * parser.setContentHandler(handler); - * parser.parse(new BufferedInputStream(new FileInputStream("mime.msg"))); - *- * NOTE: All lines must end with CRLF - * (
\r\n
). If you are unsure of the line endings in your stream
- * you should wrap it in a {@link org.apache.james.mime4j.EOLConvertingInputStream} instance.
- *
- *
- * @version $Id: MimeStreamParser.java,v 1.8 2005/02/11 10:12:02 ntherning Exp $
- */
-public class MimeStreamParser {
- private static final Log log = LogFactory.getLog(MimeStreamParser.class);
-
- private static BitSet fieldChars = null;
-
- private RootInputStream rootStream = null;
- private LinkedList bodyDescriptors = new LinkedList();
- private ContentHandler handler = null;
- private boolean raw = false;
-
- static {
- fieldChars = new BitSet();
- for (int i = 0x21; i <= 0x39; i++) {
- fieldChars.set(i);
- }
- for (int i = 0x3b; i <= 0x7e; i++) {
- fieldChars.set(i);
- }
- }
-
- /**
- * Creates a new MimeStreamParser
instance.
- */
- public MimeStreamParser() {
- }
-
- /**
- * Parses a stream of bytes containing a MIME message.
- *
- * @param is the stream to parse.
- * @throws IOException on I/O errors.
- */
- public void parse(InputStream is) throws IOException {
- rootStream = new RootInputStream(is);
- parseMessage(rootStream);
- }
-
- /**
- * Determines if this parser is currently in raw mode.
- *
- * @return true
if in raw mode, false
- * otherwise.
- * @see #setRaw(boolean)
- */
- public boolean isRaw() {
- return raw;
- }
-
- /**
- * Enables or disables raw mode. In raw mode all future entities
- * (messages or body parts) in the stream will be reported to the
- * {@link ContentHandler#raw(InputStream)} handler method only.
- * The stream will contain the entire unparsed entity contents
- * including header fields and whatever is in the body.
- *
- * @param raw true
enables raw mode, false
- * disables it.
- */
- public void setRaw(boolean raw) {
- this.raw = raw;
- }
-
- /**
- * Finishes the parsing and stops reading lines.
- * NOTE: No more lines will be parsed but the parser
- * will still call
- * {@link ContentHandler#endMultipart()},
- * {@link ContentHandler#endBodyPart()},
- * {@link ContentHandler#endMessage()}, etc to match previous calls
- * to
- * {@link ContentHandler#startMultipart(BodyDescriptor)},
- * {@link ContentHandler#startBodyPart()},
- * {@link ContentHandler#startMessage()}, etc.
- */
- public void stop() {
- rootStream.truncate();
- }
-
- /**
- * Parses an entity which consists of a header followed by a body containing
- * arbitrary data, body parts or an embedded message.
- *
- * @param is the stream to parse.
- * @throws IOException on I/O errors.
- */
- private void parseEntity(InputStream is) throws IOException {
- BodyDescriptor bd = parseHeader(is);
-
- if (bd.isMultipart()) {
- bodyDescriptors.addFirst(bd);
-
- handler.startMultipart(bd);
-
- MimeBoundaryInputStream tempIs =
- new MimeBoundaryInputStream(is, bd.getBoundary());
- handler.preamble(new CloseShieldInputStream(tempIs));
- tempIs.consume();
-
- while (tempIs.hasMoreParts()) {
- tempIs = new MimeBoundaryInputStream(is, bd.getBoundary());
- parseBodyPart(tempIs);
- tempIs.consume();
- if (tempIs.parentEOF()) {
- if (log.isWarnEnabled()) {
- log.warn("Line " + rootStream.getLineNumber()
- + ": Body part ended prematurely. "
- + "Higher level boundary detected or "
- + "EOF reached.");
- }
- break;
- }
- }
-
- handler.epilogue(new CloseShieldInputStream(is));
-
- handler.endMultipart();
-
- bodyDescriptors.removeFirst();
-
- } else if (bd.isMessage()) {
- if (bd.isBase64Encoded()) {
- log.warn("base64 encoded message/rfc822 detected");
- is = new EOLConvertingInputStream(
- new Base64InputStream(is));
- } else if (bd.isQuotedPrintableEncoded()) {
- log.warn("quoted-printable encoded message/rfc822 detected");
- is = new EOLConvertingInputStream(
- new QuotedPrintableInputStream(is));
- }
- bodyDescriptors.addFirst(bd);
- parseMessage(is);
- bodyDescriptors.removeFirst();
- } else {
- handler.body(bd, new CloseShieldInputStream(is));
- }
-
- /*
- * Make sure the stream has been consumed.
- */
- while (is.read() != -1) {
- }
- }
-
- private void parseMessage(InputStream is) throws IOException {
- if (raw) {
- handler.raw(new CloseShieldInputStream(is));
- } else {
- handler.startMessage();
- parseEntity(is);
- handler.endMessage();
- }
- }
-
- private void parseBodyPart(InputStream is) throws IOException {
- if (raw) {
- handler.raw(new CloseShieldInputStream(is));
- } else {
- handler.startBodyPart();
- parseEntity(is);
- handler.endBodyPart();
- }
- }
-
- /**
- * Parses a header.
- *
- * @param is the stream to parse.
- * @return a BodyDescriptor
describing the body following
- * the header.
- */
- private BodyDescriptor parseHeader(InputStream is) throws IOException {
- BodyDescriptor bd = new BodyDescriptor(bodyDescriptors.isEmpty()
- ? null : (BodyDescriptor) bodyDescriptors.getFirst());
-
- handler.startHeader();
-
- int lineNumber = rootStream.getLineNumber();
-
- StringBuffer sb = new StringBuffer();
- int curr = 0;
- int prev = 0;
- while ((curr = is.read()) != -1) {
- if (curr == '\n' && (prev == '\n' || prev == 0)) {
- /*
- * [\r]\n[\r]\n or an immediate \r\n have been seen.
- */
- sb.deleteCharAt(sb.length() - 1);
- break;
- }
- sb.append((char) curr);
- prev = curr == '\r' ? prev : curr;
- }
-
- if (curr == -1 && log.isWarnEnabled()) {
- log.warn("Line " + rootStream.getLineNumber()
- + ": Unexpected end of headers detected. "
- + "Boundary detected in header or EOF reached.");
- }
-
- int start = 0;
- int pos = 0;
- int startLineNumber = lineNumber;
- while (pos < sb.length()) {
- while (pos < sb.length() && sb.charAt(pos) != '\r') {
- pos++;
- }
- if (pos < sb.length() - 1 && sb.charAt(pos + 1) != '\n') {
- pos++;
- continue;
- }
-
- if (pos >= sb.length() - 2 || fieldChars.get(sb.charAt(pos + 2))) {
-
- /*
- * field should be the complete field data excluding the
- * trailing \r\n.
- */
- String field = sb.substring(start, pos);
- start = pos + 2;
-
- /*
- * Check for a valid field.
- */
- int index = field.indexOf(':');
- boolean valid = false;
- if (index != -1 && fieldChars.get(field.charAt(0))) {
- valid = true;
- String fieldName = field.substring(0, index).trim();
- for (int i = 0; i < fieldName.length(); i++) {
- if (!fieldChars.get(fieldName.charAt(i))) {
- valid = false;
- break;
- }
- }
-
- if (valid) {
- handler.field(field);
- bd.addField(fieldName, field.substring(index + 1));
- }
- }
-
- if (!valid && log.isWarnEnabled()) {
- log.warn("Line " + startLineNumber
- + ": Ignoring invalid field: '" + field.trim() + "'");
- }
-
- startLineNumber = lineNumber;
- }
-
- pos += 2;
- lineNumber++;
- }
-
- handler.endHeader();
-
- return bd;
- }
-
- /**
- * Sets the ContentHandler
to use when reporting
- * parsing events.
- *
- * @param h the ContentHandler
.
- */
- public void setContentHandler(ContentHandler h) {
- this.handler = h;
- }
-
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.BitSet;
+import java.util.LinkedList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
+
+/**
+ *
+ * Parses MIME (or RFC822) message streams of bytes or characters and reports
+ * parsing events to a ContentHandler
instance.
+ *
+ * Typical usage:
+ *
+ * ContentHandler handler = new MyHandler(); + * MimeStreamParser parser = new MimeStreamParser(); + * parser.setContentHandler(handler); + * parser.parse(new BufferedInputStream(new FileInputStream("mime.msg"))); + *+ * NOTE: All lines must end with CRLF + * (
\r\n
). If you are unsure of the line endings in your stream
+ * you should wrap it in a {@link org.apache.james.mime4j.EOLConvertingInputStream} instance.
+ *
+ *
+ * @version $Id: MimeStreamParser.java,v 1.8 2005/02/11 10:12:02 ntherning Exp $
+ */
+public class MimeStreamParser {
+ private static final Log log = LogFactory.getLog(MimeStreamParser.class);
+
+ private static BitSet fieldChars = null;
+
+ private RootInputStream rootStream = null;
+ private LinkedList bodyDescriptors = new LinkedList();
+ private ContentHandler handler = null;
+ private boolean raw = false;
+
+ static {
+ fieldChars = new BitSet();
+ for (int i = 0x21; i <= 0x39; i++) {
+ fieldChars.set(i);
+ }
+ for (int i = 0x3b; i <= 0x7e; i++) {
+ fieldChars.set(i);
+ }
+ }
+
+ /**
+ * Creates a new MimeStreamParser
instance.
+ */
+ public MimeStreamParser() {
+ }
+
+ /**
+ * Parses a stream of bytes containing a MIME message.
+ *
+ * @param is the stream to parse.
+ * @throws IOException on I/O errors.
+ */
+ public void parse(InputStream is) throws IOException {
+ rootStream = new RootInputStream(is);
+ parseMessage(rootStream);
+ }
+
+ /**
+ * Determines if this parser is currently in raw mode.
+ *
+ * @return true
if in raw mode, false
+ * otherwise.
+ * @see #setRaw(boolean)
+ */
+ public boolean isRaw() {
+ return raw;
+ }
+
+ /**
+ * Enables or disables raw mode. In raw mode all future entities
+ * (messages or body parts) in the stream will be reported to the
+ * {@link ContentHandler#raw(InputStream)} handler method only.
+ * The stream will contain the entire unparsed entity contents
+ * including header fields and whatever is in the body.
+ *
+ * @param raw true
enables raw mode, false
+ * disables it.
+ */
+ public void setRaw(boolean raw) {
+ this.raw = raw;
+ }
+
+ /**
+ * Finishes the parsing and stops reading lines.
+ * NOTE: No more lines will be parsed but the parser
+ * will still call
+ * {@link ContentHandler#endMultipart()},
+ * {@link ContentHandler#endBodyPart()},
+ * {@link ContentHandler#endMessage()}, etc to match previous calls
+ * to
+ * {@link ContentHandler#startMultipart(BodyDescriptor)},
+ * {@link ContentHandler#startBodyPart()},
+ * {@link ContentHandler#startMessage()}, etc.
+ */
+ public void stop() {
+ rootStream.truncate();
+ }
+
+ /**
+ * Parses an entity which consists of a header followed by a body containing
+ * arbitrary data, body parts or an embedded message.
+ *
+ * @param is the stream to parse.
+ * @throws IOException on I/O errors.
+ */
+ private void parseEntity(InputStream is) throws IOException {
+ BodyDescriptor bd = parseHeader(is);
+
+ if (bd.isMultipart()) {
+ bodyDescriptors.addFirst(bd);
+
+ handler.startMultipart(bd);
+
+ MimeBoundaryInputStream tempIs =
+ new MimeBoundaryInputStream(is, bd.getBoundary());
+ handler.preamble(new CloseShieldInputStream(tempIs));
+ tempIs.consume();
+
+ while (tempIs.hasMoreParts()) {
+ tempIs = new MimeBoundaryInputStream(is, bd.getBoundary());
+ parseBodyPart(tempIs);
+ tempIs.consume();
+ if (tempIs.parentEOF()) {
+ if (log.isWarnEnabled()) {
+ log.warn("Line " + rootStream.getLineNumber()
+ + ": Body part ended prematurely. "
+ + "Higher level boundary detected or "
+ + "EOF reached.");
+ }
+ break;
+ }
+ }
+
+ handler.epilogue(new CloseShieldInputStream(is));
+
+ handler.endMultipart();
+
+ bodyDescriptors.removeFirst();
+
+ } else if (bd.isMessage()) {
+ if (bd.isBase64Encoded()) {
+ log.warn("base64 encoded message/rfc822 detected");
+ is = new EOLConvertingInputStream(
+ new Base64InputStream(is));
+ } else if (bd.isQuotedPrintableEncoded()) {
+ log.warn("quoted-printable encoded message/rfc822 detected");
+ is = new EOLConvertingInputStream(
+ new QuotedPrintableInputStream(is));
+ }
+ bodyDescriptors.addFirst(bd);
+ parseMessage(is);
+ bodyDescriptors.removeFirst();
+ } else {
+ handler.body(bd, new CloseShieldInputStream(is));
+ }
+
+ /*
+ * Make sure the stream has been consumed.
+ */
+ while (is.read() != -1) {
+ }
+ }
+
+ private void parseMessage(InputStream is) throws IOException {
+ if (raw) {
+ handler.raw(new CloseShieldInputStream(is));
+ } else {
+ handler.startMessage();
+ parseEntity(is);
+ handler.endMessage();
+ }
+ }
+
+ private void parseBodyPart(InputStream is) throws IOException {
+ if (raw) {
+ handler.raw(new CloseShieldInputStream(is));
+ } else {
+ handler.startBodyPart();
+ parseEntity(is);
+ handler.endBodyPart();
+ }
+ }
+
+ /**
+ * Parses a header.
+ *
+ * @param is the stream to parse.
+ * @return a BodyDescriptor
describing the body following
+ * the header.
+ */
+ private BodyDescriptor parseHeader(InputStream is) throws IOException {
+ BodyDescriptor bd = new BodyDescriptor(bodyDescriptors.isEmpty()
+ ? null : (BodyDescriptor) bodyDescriptors.getFirst());
+
+ handler.startHeader();
+
+ int lineNumber = rootStream.getLineNumber();
+
+ StringBuffer sb = new StringBuffer();
+ int curr = 0;
+ int prev = 0;
+ while ((curr = is.read()) != -1) {
+ if (curr == '\n' && (prev == '\n' || prev == 0)) {
+ /*
+ * [\r]\n[\r]\n or an immediate \r\n have been seen.
+ */
+ sb.deleteCharAt(sb.length() - 1);
+ break;
+ }
+ sb.append((char) curr);
+ prev = curr == '\r' ? prev : curr;
+ }
+
+ if (curr == -1 && log.isWarnEnabled()) {
+ log.warn("Line " + rootStream.getLineNumber()
+ + ": Unexpected end of headers detected. "
+ + "Boundary detected in header or EOF reached.");
+ }
+
+ int start = 0;
+ int pos = 0;
+ int startLineNumber = lineNumber;
+ while (pos < sb.length()) {
+ while (pos < sb.length() && sb.charAt(pos) != '\r') {
+ pos++;
+ }
+ if (pos < sb.length() - 1 && sb.charAt(pos + 1) != '\n') {
+ pos++;
+ continue;
+ }
+
+ if (pos >= sb.length() - 2 || fieldChars.get(sb.charAt(pos + 2))) {
+
+ /*
+ * field should be the complete field data excluding the
+ * trailing \r\n.
+ */
+ String field = sb.substring(start, pos);
+ start = pos + 2;
+
+ /*
+ * Check for a valid field.
+ */
+ int index = field.indexOf(':');
+ boolean valid = false;
+ if (index != -1 && fieldChars.get(field.charAt(0))) {
+ valid = true;
+ String fieldName = field.substring(0, index).trim();
+ for (int i = 0; i < fieldName.length(); i++) {
+ if (!fieldChars.get(fieldName.charAt(i))) {
+ valid = false;
+ break;
+ }
+ }
+
+ if (valid) {
+ handler.field(field);
+ bd.addField(fieldName, field.substring(index + 1));
+ }
+ }
+
+ if (!valid && log.isWarnEnabled()) {
+ log.warn("Line " + startLineNumber
+ + ": Ignoring invalid field: '" + field.trim() + "'");
+ }
+
+ startLineNumber = lineNumber;
+ }
+
+ pos += 2;
+ lineNumber++;
+ }
+
+ handler.endHeader();
+
+ return bd;
+ }
+
+ /**
+ * Sets the ContentHandler
to use when reporting
+ * parsing events.
+ *
+ * @param h the ContentHandler
.
+ */
+ public void setContentHandler(ContentHandler h) {
+ this.handler = h;
+ }
+
+}
diff --git a/src/org/apache/james/mime4j/RootInputStream.java b/src/org/apache/james/mime4j/RootInputStream.java
index fa848df18fac6b8ae4e0beddf1e7fcce26377124..ebf36dce21094a32bcbbbf38eda8d62b6f2932ab 100644
--- a/src/org/apache/james/mime4j/RootInputStream.java
+++ b/src/org/apache/james/mime4j/RootInputStream.java
@@ -1,111 +1,111 @@
-/****************************************************************
- * 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.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * InputStream
used by the parser to wrap the original user
- * supplied stream. This stream keeps track of the current line number and
- * can also be truncated. When truncated the stream will appear to have
- * reached end of file. This is used by the parser's
- * {@link org.apache.james.mime4j.MimeStreamParser#stop()} method.
- *
- *
- * @version $Id: RootInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
- */
-class RootInputStream extends InputStream {
- private InputStream is = null;
- private int lineNumber = 1;
- private int prev = -1;
- private boolean truncated = false;
-
- /**
- * Creates a new RootInputStream
.
- *
- * @param in the stream to read from.
- */
- public RootInputStream(InputStream is) {
- this.is = is;
- }
-
- /**
- * Gets the current line number starting at 1
- * (the number of \r\n
read so far plus 1).
- *
- * @return the current line number.
- */
- public int getLineNumber() {
- return lineNumber;
- }
-
- /**
- * Truncates this InputStream
. After this call any
- * call to {@link #read()}, {@link #read(byte[]) or
- * {@link #read(byte[], int, int)} will return
- * -1 as if end-of-file had been reached.
- */
- public void truncate() {
- this.truncated = true;
- }
-
- /**
- * @see java.io.InputStream#read()
- */
- public int read() throws IOException {
- if (truncated) {
- return -1;
- }
-
- int b = is.read();
- if (prev == '\r' && b == '\n') {
- lineNumber++;
- }
- prev = b;
- return b;
- }
-
- /**
- *
- * @see java.io.InputStream#read(byte[], int, int)
- */
- public int read(byte[] b, int off, int len) throws IOException {
- if (truncated) {
- return -1;
- }
-
- int n = is.read(b, off, len);
- for (int i = off; i < off + n; i++) {
- if (prev == '\r' && b[i] == '\n') {
- lineNumber++;
- }
- prev = b[i];
- }
- return n;
- }
-
- /**
- * @see java.io.InputStream#read(byte[])
- */
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * InputStream
used by the parser to wrap the original user
+ * supplied stream. This stream keeps track of the current line number and
+ * can also be truncated. When truncated the stream will appear to have
+ * reached end of file. This is used by the parser's
+ * {@link org.apache.james.mime4j.MimeStreamParser#stop()} method.
+ *
+ *
+ * @version $Id: RootInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
+ */
+class RootInputStream extends InputStream {
+ private InputStream is = null;
+ private int lineNumber = 1;
+ private int prev = -1;
+ private boolean truncated = false;
+
+ /**
+ * Creates a new RootInputStream
.
+ *
+ * @param in the stream to read from.
+ */
+ public RootInputStream(InputStream is) {
+ this.is = is;
+ }
+
+ /**
+ * Gets the current line number starting at 1
+ * (the number of \r\n
read so far plus 1).
+ *
+ * @return the current line number.
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ /**
+ * Truncates this InputStream
. After this call any
+ * call to {@link #read()}, {@link #read(byte[]) or
+ * {@link #read(byte[], int, int)} will return
+ * -1 as if end-of-file had been reached.
+ */
+ public void truncate() {
+ this.truncated = true;
+ }
+
+ /**
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ if (truncated) {
+ return -1;
+ }
+
+ int b = is.read();
+ if (prev == '\r' && b == '\n') {
+ lineNumber++;
+ }
+ prev = b;
+ return b;
+ }
+
+ /**
+ *
+ * @see java.io.InputStream#read(byte[], int, int)
+ */
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (truncated) {
+ return -1;
+ }
+
+ int n = is.read(b, off, len);
+ for (int i = off; i < off + n; i++) {
+ if (prev == '\r' && b[i] == '\n') {
+ lineNumber++;
+ }
+ prev = b[i];
+ }
+ return n;
+ }
+
+ /**
+ * @see java.io.InputStream#read(byte[])
+ */
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+}
diff --git a/src/org/apache/james/mime4j/SimpleContentHandler.java b/src/org/apache/james/mime4j/SimpleContentHandler.java
index 13f1fd2c6b3f507129843163c0d4081c8f5fc5b5..7d25d080458fcb166179349d4e3eedf4b53de16a 100644
--- a/src/org/apache/james/mime4j/SimpleContentHandler.java
+++ b/src/org/apache/james/mime4j/SimpleContentHandler.java
@@ -1,100 +1,100 @@
-/****************************************************************
- * 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.mime4j;
-
-import org.apache.james.mime4j.decoder.Base64InputStream;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.message.Header;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * Abstract implementation of ContentHandler that automates common
- * tasks. Currently performs header parsing and applies content-transfer
- * decoding to body parts.
- *
- *
- */
-public abstract class SimpleContentHandler extends AbstractContentHandler {
-
- /**
- * Called after headers are parsed.
- */
- public abstract void headers(Header header);
-
- /**
- * Called when the body of a discrete (non-multipart) entity is encountered.
-
- * @param bd encapsulates the values (either read from the
- * message stream or, if not present, determined implictly
- * as described in the
- * MIME rfc:s) of the Content-Type
and
- * Content-Transfer-Encoding
header fields.
- * @param is the contents of the body. Base64 or quoted-printable
- * decoding will be applied transparently.
- * @throws IOException should be thrown on I/O errors.
- */
- public abstract void bodyDecoded(BodyDescriptor bd, InputStream is) throws IOException;
-
-
- /* Implement introduced callbacks. */
-
- private Header currHeader;
-
- /**
- * @see org.apache.james.mime4j.AbstractContentHandler#startHeader()
- */
- public final void startHeader() {
- currHeader = new Header();
- }
-
- /**
- * @see org.apache.james.mime4j.AbstractContentHandler#field(java.lang.String)
- */
- public final void field(String fieldData) {
- currHeader.addField(Field.parse(fieldData));
- }
-
- /**
- * @see org.apache.james.mime4j.AbstractContentHandler#endHeader()
- */
- public final void endHeader() {
- Header tmp = currHeader;
- currHeader = null;
- headers(tmp);
- }
-
- /**
- * @see org.apache.james.mime4j.AbstractContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
- */
- public final void body(BodyDescriptor bd, InputStream is) throws IOException {
- if (bd.isBase64Encoded()) {
- bodyDecoded(bd, new Base64InputStream(is));
- }
- else if (bd.isQuotedPrintableEncoded()) {
- bodyDecoded(bd, new QuotedPrintableInputStream(is));
- }
- else {
- bodyDecoded(bd, is);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j;
+
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.message.Header;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Abstract implementation of ContentHandler that automates common
+ * tasks. Currently performs header parsing and applies content-transfer
+ * decoding to body parts.
+ *
+ *
+ */
+public abstract class SimpleContentHandler extends AbstractContentHandler {
+
+ /**
+ * Called after headers are parsed.
+ */
+ public abstract void headers(Header header);
+
+ /**
+ * Called when the body of a discrete (non-multipart) entity is encountered.
+
+ * @param bd encapsulates the values (either read from the
+ * message stream or, if not present, determined implictly
+ * as described in the
+ * MIME rfc:s) of the Content-Type
and
+ * Content-Transfer-Encoding
header fields.
+ * @param is the contents of the body. Base64 or quoted-printable
+ * decoding will be applied transparently.
+ * @throws IOException should be thrown on I/O errors.
+ */
+ public abstract void bodyDecoded(BodyDescriptor bd, InputStream is) throws IOException;
+
+
+ /* Implement introduced callbacks. */
+
+ private Header currHeader;
+
+ /**
+ * @see org.apache.james.mime4j.AbstractContentHandler#startHeader()
+ */
+ public final void startHeader() {
+ currHeader = new Header();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.AbstractContentHandler#field(java.lang.String)
+ */
+ public final void field(String fieldData) {
+ currHeader.addField(Field.parse(fieldData));
+ }
+
+ /**
+ * @see org.apache.james.mime4j.AbstractContentHandler#endHeader()
+ */
+ public final void endHeader() {
+ Header tmp = currHeader;
+ currHeader = null;
+ headers(tmp);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.AbstractContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
+ */
+ public final void body(BodyDescriptor bd, InputStream is) throws IOException {
+ if (bd.isBase64Encoded()) {
+ bodyDecoded(bd, new Base64InputStream(is));
+ }
+ else if (bd.isQuotedPrintableEncoded()) {
+ bodyDecoded(bd, new QuotedPrintableInputStream(is));
+ }
+ else {
+ bodyDecoded(bd, is);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/decoder/Base64InputStream.java b/src/org/apache/james/mime4j/decoder/Base64InputStream.java
index 930b982c409acf6f52b1a8acc6fa1639d6f13978..9af54951b60d294a8e1b300dcd7d1969f86781f7 100644
--- a/src/org/apache/james/mime4j/decoder/Base64InputStream.java
+++ b/src/org/apache/james/mime4j/decoder/Base64InputStream.java
@@ -1,146 +1,146 @@
-/****************************************************************
- * 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.mime4j.decoder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Performs Base-64 decoding on an underlying stream.
- *
- *
- * @version $Id: Base64InputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
- */
-public class Base64InputStream extends InputStream {
- private static Log log = LogFactory.getLog(Base64InputStream.class);
-
- private final InputStream s;
- private final ByteQueue byteq = new ByteQueue(3);
- private boolean done = false;
-
- public Base64InputStream(InputStream s) {
- this.s = s;
- }
-
- /**
- * Closes the underlying stream.
- *
- * @throws IOException on I/O errors.
- */
- public void close() throws IOException {
- s.close();
- }
-
- public int read() throws IOException {
- if (byteq.count() == 0) {
- fillBuffer();
- if (byteq.count() == 0) {
- return -1;
- }
- }
-
- byte val = byteq.dequeue();
- if (val >= 0)
- return val;
- else
- return val & 0xFF;
- }
-
- /**
- * Retrieve data from the underlying stream, decode it,
- * and put the results in the byteq.
- * @throws IOException
- */
- private void fillBuffer() throws IOException {
- byte[] data = new byte[4];
- int pos = 0;
-
- int i;
- while (!done) {
- switch (i = s.read()) {
- case -1:
- if (pos > 0) {
- log.warn("Unexpected EOF in MIME parser, dropping "
- + pos + " sextets");
- }
- return;
- case '=':
- decodeAndEnqueue(data, pos);
- done = true;
- break;
- default:
- byte sX = TRANSLATION[i];
- if (sX < 0)
- continue;
- data[pos++] = sX;
- if (pos == data.length) {
- decodeAndEnqueue(data, pos);
- return;
- }
- break;
- }
- }
- }
-
- private void decodeAndEnqueue(byte[] data, int len) {
- int accum = 0;
- accum |= data[0] << 18;
- accum |= data[1] << 12;
- accum |= data[2] << 6;
- accum |= data[3];
-
- byte b1 = (byte)(accum >>> 16);
- byteq.enqueue(b1);
-
- if (len > 2) {
- byte b2 = (byte)((accum >>> 8) & 0xFF);
- byteq.enqueue(b2);
-
- if (len > 3) {
- byte b3 = (byte)(accum & 0xFF);
- byteq.enqueue(b3);
- }
- }
- }
-
- private static byte[] TRANSLATION = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40 */
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xF0 */
- };
-
-
-}
+/****************************************************************
+ * 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.mime4j.decoder;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Performs Base-64 decoding on an underlying stream.
+ *
+ *
+ * @version $Id: Base64InputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
+ */
+public class Base64InputStream extends InputStream {
+ private static Log log = LogFactory.getLog(Base64InputStream.class);
+
+ private final InputStream s;
+ private final ByteQueue byteq = new ByteQueue(3);
+ private boolean done = false;
+
+ public Base64InputStream(InputStream s) {
+ this.s = s;
+ }
+
+ /**
+ * Closes the underlying stream.
+ *
+ * @throws IOException on I/O errors.
+ */
+ public void close() throws IOException {
+ s.close();
+ }
+
+ public int read() throws IOException {
+ if (byteq.count() == 0) {
+ fillBuffer();
+ if (byteq.count() == 0) {
+ return -1;
+ }
+ }
+
+ byte val = byteq.dequeue();
+ if (val >= 0)
+ return val;
+ else
+ return val & 0xFF;
+ }
+
+ /**
+ * Retrieve data from the underlying stream, decode it,
+ * and put the results in the byteq.
+ * @throws IOException
+ */
+ private void fillBuffer() throws IOException {
+ byte[] data = new byte[4];
+ int pos = 0;
+
+ int i;
+ while (!done) {
+ switch (i = s.read()) {
+ case -1:
+ if (pos > 0) {
+ log.warn("Unexpected EOF in MIME parser, dropping "
+ + pos + " sextets");
+ }
+ return;
+ case '=':
+ decodeAndEnqueue(data, pos);
+ done = true;
+ break;
+ default:
+ byte sX = TRANSLATION[i];
+ if (sX < 0)
+ continue;
+ data[pos++] = sX;
+ if (pos == data.length) {
+ decodeAndEnqueue(data, pos);
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ private void decodeAndEnqueue(byte[] data, int len) {
+ int accum = 0;
+ accum |= data[0] << 18;
+ accum |= data[1] << 12;
+ accum |= data[2] << 6;
+ accum |= data[3];
+
+ byte b1 = (byte)(accum >>> 16);
+ byteq.enqueue(b1);
+
+ if (len > 2) {
+ byte b2 = (byte)((accum >>> 8) & 0xFF);
+ byteq.enqueue(b2);
+
+ if (len > 3) {
+ byte b3 = (byte)(accum & 0xFF);
+ byteq.enqueue(b3);
+ }
+ }
+ }
+
+ private static byte[] TRANSLATION = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40 */
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xF0 */
+ };
+
+
+}
diff --git a/src/org/apache/james/mime4j/decoder/ByteQueue.java b/src/org/apache/james/mime4j/decoder/ByteQueue.java
index 68e7d3380c8ac2a9c4c0519d0711497055748c01..6d7ccef5243725a87cd66591568847570f279b76 100644
--- a/src/org/apache/james/mime4j/decoder/ByteQueue.java
+++ b/src/org/apache/james/mime4j/decoder/ByteQueue.java
@@ -1,62 +1,62 @@
-/****************************************************************
- * 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.mime4j.decoder;
-
-import java.util.Iterator;
-
-public class ByteQueue {
-
- private UnboundedFifoByteBuffer buf;
- private int initialCapacity = -1;
-
- public ByteQueue() {
- buf = new UnboundedFifoByteBuffer();
- }
-
- public ByteQueue(int initialCapacity) {
- buf = new UnboundedFifoByteBuffer(initialCapacity);
- this.initialCapacity = initialCapacity;
- }
-
- public void enqueue(byte b) {
- buf.add(b);
- }
-
- public byte dequeue() {
- return buf.remove();
- }
-
- public int count() {
- return buf.size();
- }
-
- public void clear() {
- if (initialCapacity != -1)
- buf = new UnboundedFifoByteBuffer(initialCapacity);
- else
- buf = new UnboundedFifoByteBuffer();
- }
-
- public Iterator iterator() {
- return buf.iterator();
- }
-
-
-}
+/****************************************************************
+ * 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.mime4j.decoder;
+
+import java.util.Iterator;
+
+public class ByteQueue {
+
+ private UnboundedFifoByteBuffer buf;
+ private int initialCapacity = -1;
+
+ public ByteQueue() {
+ buf = new UnboundedFifoByteBuffer();
+ }
+
+ public ByteQueue(int initialCapacity) {
+ buf = new UnboundedFifoByteBuffer(initialCapacity);
+ this.initialCapacity = initialCapacity;
+ }
+
+ public void enqueue(byte b) {
+ buf.add(b);
+ }
+
+ public byte dequeue() {
+ return buf.remove();
+ }
+
+ public int count() {
+ return buf.size();
+ }
+
+ public void clear() {
+ if (initialCapacity != -1)
+ buf = new UnboundedFifoByteBuffer(initialCapacity);
+ else
+ buf = new UnboundedFifoByteBuffer();
+ }
+
+ public Iterator iterator() {
+ return buf.iterator();
+ }
+
+
+}
diff --git a/src/org/apache/james/mime4j/decoder/DecoderUtil.java b/src/org/apache/james/mime4j/decoder/DecoderUtil.java
index 7876ff700291e30a0eada638280d18855976b63e..c391293673c68b7951ca705db7d39184a210956a 100644
--- a/src/org/apache/james/mime4j/decoder/DecoderUtil.java
+++ b/src/org/apache/james/mime4j/decoder/DecoderUtil.java
@@ -1,277 +1,277 @@
-/****************************************************************
- * 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.mime4j.decoder;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.util.CharsetUtil;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Static methods for decoding strings, byte arrays and encoded words.
- *
- *
- * @version $Id: DecoderUtil.java,v 1.3 2005/02/07 15:33:59 ntherning Exp $
- */
-public class DecoderUtil {
- private static Log log = LogFactory.getLog(DecoderUtil.class);
-
- /**
- * Decodes a string containing quoted-printable encoded data.
- *
- * @param s the string to decode.
- * @return the decoded bytes.
- */
- public static byte[] decodeBaseQuotedPrintable(String s) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- try {
- byte[] bytes = s.getBytes("US-ASCII");
-
- QuotedPrintableInputStream is = new QuotedPrintableInputStream(
- new ByteArrayInputStream(bytes));
-
- int b = 0;
- while ((b = is.read()) != -1) {
- baos.write(b);
- }
- } catch (IOException e) {
- /*
- * This should never happen!
- */
- log.error(e);
- }
-
- return baos.toByteArray();
- }
-
- /**
- * Decodes a string containing base64 encoded data.
- *
- * @param s the string to decode.
- * @return the decoded bytes.
- */
- public static byte[] decodeBase64(String s) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- try {
- byte[] bytes = s.getBytes("US-ASCII");
-
- Base64InputStream is = new Base64InputStream(
- new ByteArrayInputStream(bytes));
-
- int b = 0;
- while ((b = is.read()) != -1) {
- baos.write(b);
- }
- } catch (IOException e) {
- /*
- * This should never happen!
- */
- log.error(e);
- }
-
- return baos.toByteArray();
- }
-
- /**
- * Decodes an encoded word encoded with the 'B' encoding (described in
- * RFC 2047) found in a header field body.
- *
- * @param encodedWord the encoded word to decode.
- * @param charset the Java charset to use.
- * @return the decoded string.
- * @throws UnsupportedEncodingException if the given Java charset isn't
- * supported.
- */
- public static String decodeB(String encodedWord, String charset)
- throws UnsupportedEncodingException {
-
- return new String(decodeBase64(encodedWord), charset);
- }
-
- /**
- * Decodes an encoded word encoded with the 'Q' encoding (described in
- * RFC 2047) found in a header field body.
- *
- * @param encodedWord the encoded word to decode.
- * @param charset the Java charset to use.
- * @return the decoded string.
- * @throws UnsupportedEncodingException if the given Java charset isn't
- * supported.
- */
- public static String decodeQ(String encodedWord, String charset)
- throws UnsupportedEncodingException {
-
- /*
- * Replace _ with =20
- */
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < encodedWord.length(); i++) {
- char c = encodedWord.charAt(i);
- if (c == '_') {
- sb.append("=20");
- } else {
- sb.append(c);
- }
- }
-
- return new String(decodeBaseQuotedPrintable(sb.toString()), charset);
- }
-
- /**
- * Decodes a string containing encoded words as defined by RFC 2047.
- * Encoded words in have the form
- * =?charset?enc?Encoded word?= where enc is either 'Q' or 'q' for
- * quoted-printable and 'B' or 'b' for Base64.
- *
- * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
- *
- * @param body the string to decode.
- * @return the decoded string.
- */
- public static String decodeEncodedWords(String body) {
-
- // ANDROID: Most strings will not include "=?" so a quick test can prevent unneeded
- // object creation. This could also be handled via lazy creation of the StringBuilder.
- if (body.indexOf("=?") == -1) {
- return body;
- }
-
- int previousEnd = 0;
- boolean previousWasEncoded = false;
-
- StringBuilder sb = new StringBuilder();
-
- while (true) {
- int begin = body.indexOf("=?", previousEnd);
-
- // ANDROID: The mime4j original version has an error here. It gets confused if
- // the encoded string begins with an '=' (just after "?Q?"). This patch seeks forward
- // to find the two '?' in the "header", before looking for the final "?=".
- int endScan = begin + 2;
- if (begin != -1) {
- int qm1 = body.indexOf('?', endScan + 2);
- int qm2 = body.indexOf('?', qm1 + 1);
- if (qm2 != -1) {
- endScan = qm2 + 1;
- }
- }
-
- int end = begin == -1 ? -1 : body.indexOf("?=", endScan);
- if (end == -1) {
- if (previousEnd == 0)
- return body;
-
- sb.append(body.substring(previousEnd));
- return sb.toString();
- }
- end += 2;
-
- String sep = body.substring(previousEnd, begin);
-
- String decoded = decodeEncodedWord(body, begin, end);
- if (decoded == null) {
- sb.append(sep);
- sb.append(body.substring(begin, end));
- } else {
- if (!previousWasEncoded || !CharsetUtil.isWhitespace(sep)) {
- sb.append(sep);
- }
- sb.append(decoded);
- }
-
- previousEnd = end;
- previousWasEncoded = decoded != null;
- }
- }
-
- // return null on error
- private static String decodeEncodedWord(String body, int begin, int end) {
- int qm1 = body.indexOf('?', begin + 2);
- if (qm1 == end - 2)
- return null;
-
- int qm2 = body.indexOf('?', qm1 + 1);
- if (qm2 == end - 2)
- return null;
-
- String mimeCharset = body.substring(begin + 2, qm1);
- String encoding = body.substring(qm1 + 1, qm2);
- String encodedText = body.substring(qm2 + 1, end - 2);
-
- String charset = CharsetUtil.toJavaCharset(mimeCharset);
- if (charset == null) {
- if (log.isWarnEnabled()) {
- log.warn("MIME charset '" + mimeCharset + "' in encoded word '"
- + body.substring(begin, end) + "' doesn't have a "
- + "corresponding Java charset");
- }
- return null;
- } else if (!CharsetUtil.isDecodingSupported(charset)) {
- if (log.isWarnEnabled()) {
- log.warn("Current JDK doesn't support decoding of charset '"
- + charset + "' (MIME charset '" + mimeCharset
- + "' in encoded word '" + body.substring(begin, end)
- + "')");
- }
- return null;
- }
-
- if (encodedText.length() == 0) {
- if (log.isWarnEnabled()) {
- log.warn("Missing encoded text in encoded word: '"
- + body.substring(begin, end) + "'");
- }
- return null;
- }
-
- try {
- if (encoding.equalsIgnoreCase("Q")) {
- return DecoderUtil.decodeQ(encodedText, charset);
- } else if (encoding.equalsIgnoreCase("B")) {
- return DecoderUtil.decodeB(encodedText, charset);
- } else {
- if (log.isWarnEnabled()) {
- log.warn("Warning: Unknown encoding in encoded word '"
- + body.substring(begin, end) + "'");
- }
- return null;
- }
- } catch (UnsupportedEncodingException e) {
- // should not happen because of isDecodingSupported check above
- if (log.isWarnEnabled()) {
- log.warn("Unsupported encoding in encoded word '"
- + body.substring(begin, end) + "'", e);
- }
- return null;
- } catch (RuntimeException e) {
- if (log.isWarnEnabled()) {
- log.warn("Could not decode encoded word '"
- + body.substring(begin, end) + "'", e);
- }
- return null;
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.decoder;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Static methods for decoding strings, byte arrays and encoded words.
+ *
+ *
+ * @version $Id: DecoderUtil.java,v 1.3 2005/02/07 15:33:59 ntherning Exp $
+ */
+public class DecoderUtil {
+ private static Log log = LogFactory.getLog(DecoderUtil.class);
+
+ /**
+ * Decodes a string containing quoted-printable encoded data.
+ *
+ * @param s the string to decode.
+ * @return the decoded bytes.
+ */
+ public static byte[] decodeBaseQuotedPrintable(String s) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ try {
+ byte[] bytes = s.getBytes("US-ASCII");
+
+ QuotedPrintableInputStream is = new QuotedPrintableInputStream(
+ new ByteArrayInputStream(bytes));
+
+ int b = 0;
+ while ((b = is.read()) != -1) {
+ baos.write(b);
+ }
+ } catch (IOException e) {
+ /*
+ * This should never happen!
+ */
+ log.error(e);
+ }
+
+ return baos.toByteArray();
+ }
+
+ /**
+ * Decodes a string containing base64 encoded data.
+ *
+ * @param s the string to decode.
+ * @return the decoded bytes.
+ */
+ public static byte[] decodeBase64(String s) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ try {
+ byte[] bytes = s.getBytes("US-ASCII");
+
+ Base64InputStream is = new Base64InputStream(
+ new ByteArrayInputStream(bytes));
+
+ int b = 0;
+ while ((b = is.read()) != -1) {
+ baos.write(b);
+ }
+ } catch (IOException e) {
+ /*
+ * This should never happen!
+ */
+ log.error(e);
+ }
+
+ return baos.toByteArray();
+ }
+
+ /**
+ * Decodes an encoded word encoded with the 'B' encoding (described in
+ * RFC 2047) found in a header field body.
+ *
+ * @param encodedWord the encoded word to decode.
+ * @param charset the Java charset to use.
+ * @return the decoded string.
+ * @throws UnsupportedEncodingException if the given Java charset isn't
+ * supported.
+ */
+ public static String decodeB(String encodedWord, String charset)
+ throws UnsupportedEncodingException {
+
+ return new String(decodeBase64(encodedWord), charset);
+ }
+
+ /**
+ * Decodes an encoded word encoded with the 'Q' encoding (described in
+ * RFC 2047) found in a header field body.
+ *
+ * @param encodedWord the encoded word to decode.
+ * @param charset the Java charset to use.
+ * @return the decoded string.
+ * @throws UnsupportedEncodingException if the given Java charset isn't
+ * supported.
+ */
+ public static String decodeQ(String encodedWord, String charset)
+ throws UnsupportedEncodingException {
+
+ /*
+ * Replace _ with =20
+ */
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < encodedWord.length(); i++) {
+ char c = encodedWord.charAt(i);
+ if (c == '_') {
+ sb.append("=20");
+ } else {
+ sb.append(c);
+ }
+ }
+
+ return new String(decodeBaseQuotedPrintable(sb.toString()), charset);
+ }
+
+ /**
+ * Decodes a string containing encoded words as defined by RFC 2047.
+ * Encoded words in have the form
+ * =?charset?enc?Encoded word?= where enc is either 'Q' or 'q' for
+ * quoted-printable and 'B' or 'b' for Base64.
+ *
+ * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
+ *
+ * @param body the string to decode.
+ * @return the decoded string.
+ */
+ public static String decodeEncodedWords(String body) {
+
+ // ANDROID: Most strings will not include "=?" so a quick test can prevent unneeded
+ // object creation. This could also be handled via lazy creation of the StringBuilder.
+ if (body.indexOf("=?") == -1) {
+ return body;
+ }
+
+ int previousEnd = 0;
+ boolean previousWasEncoded = false;
+
+ StringBuilder sb = new StringBuilder();
+
+ while (true) {
+ int begin = body.indexOf("=?", previousEnd);
+
+ // ANDROID: The mime4j original version has an error here. It gets confused if
+ // the encoded string begins with an '=' (just after "?Q?"). This patch seeks forward
+ // to find the two '?' in the "header", before looking for the final "?=".
+ int endScan = begin + 2;
+ if (begin != -1) {
+ int qm1 = body.indexOf('?', endScan + 2);
+ int qm2 = body.indexOf('?', qm1 + 1);
+ if (qm2 != -1) {
+ endScan = qm2 + 1;
+ }
+ }
+
+ int end = begin == -1 ? -1 : body.indexOf("?=", endScan);
+ if (end == -1) {
+ if (previousEnd == 0)
+ return body;
+
+ sb.append(body.substring(previousEnd));
+ return sb.toString();
+ }
+ end += 2;
+
+ String sep = body.substring(previousEnd, begin);
+
+ String decoded = decodeEncodedWord(body, begin, end);
+ if (decoded == null) {
+ sb.append(sep);
+ sb.append(body.substring(begin, end));
+ } else {
+ if (!previousWasEncoded || !CharsetUtil.isWhitespace(sep)) {
+ sb.append(sep);
+ }
+ sb.append(decoded);
+ }
+
+ previousEnd = end;
+ previousWasEncoded = decoded != null;
+ }
+ }
+
+ // return null on error
+ private static String decodeEncodedWord(String body, int begin, int end) {
+ int qm1 = body.indexOf('?', begin + 2);
+ if (qm1 == end - 2)
+ return null;
+
+ int qm2 = body.indexOf('?', qm1 + 1);
+ if (qm2 == end - 2)
+ return null;
+
+ String mimeCharset = body.substring(begin + 2, qm1);
+ String encoding = body.substring(qm1 + 1, qm2);
+ String encodedText = body.substring(qm2 + 1, end - 2);
+
+ String charset = CharsetUtil.toJavaCharset(mimeCharset);
+ if (charset == null) {
+ if (log.isWarnEnabled()) {
+ log.warn("MIME charset '" + mimeCharset + "' in encoded word '"
+ + body.substring(begin, end) + "' doesn't have a "
+ + "corresponding Java charset");
+ }
+ return null;
+ } else if (!CharsetUtil.isDecodingSupported(charset)) {
+ if (log.isWarnEnabled()) {
+ log.warn("Current JDK doesn't support decoding of charset '"
+ + charset + "' (MIME charset '" + mimeCharset
+ + "' in encoded word '" + body.substring(begin, end)
+ + "')");
+ }
+ return null;
+ }
+
+ if (encodedText.length() == 0) {
+ if (log.isWarnEnabled()) {
+ log.warn("Missing encoded text in encoded word: '"
+ + body.substring(begin, end) + "'");
+ }
+ return null;
+ }
+
+ try {
+ if (encoding.equalsIgnoreCase("Q")) {
+ return DecoderUtil.decodeQ(encodedText, charset);
+ } else if (encoding.equalsIgnoreCase("B")) {
+ return DecoderUtil.decodeB(encodedText, charset);
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn("Warning: Unknown encoding in encoded word '"
+ + body.substring(begin, end) + "'");
+ }
+ return null;
+ }
+ } catch (UnsupportedEncodingException e) {
+ // should not happen because of isDecodingSupported check above
+ if (log.isWarnEnabled()) {
+ log.warn("Unsupported encoding in encoded word '"
+ + body.substring(begin, end) + "'", e);
+ }
+ return null;
+ } catch (RuntimeException e) {
+ if (log.isWarnEnabled()) {
+ log.warn("Could not decode encoded word '"
+ + body.substring(begin, end) + "'", e);
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java b/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java
index eb3f09c9a92ec104b9f7ea3e7bb5e3836b74715a..3a3a1a45105a5e3b0ebbedd8599736434e26f094 100644
--- a/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java
+++ b/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java
@@ -1,227 +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.mime4j.decoder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Performs Quoted-Printable decoding on an underlying stream.
- *
- *
- *
- * @version $Id: QuotedPrintableInputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
- */
-public class QuotedPrintableInputStream extends InputStream {
- private static Log log = LogFactory.getLog(QuotedPrintableInputStream.class);
-
- private InputStream stream;
- ByteQueue byteq = new ByteQueue();
- ByteQueue pushbackq = new ByteQueue();
- private byte state = 0;
-
- public QuotedPrintableInputStream(InputStream stream) {
- this.stream = stream;
- }
-
- /**
- * Closes the underlying stream.
- *
- * @throws IOException on I/O errors.
- */
- public void close() throws IOException {
- stream.close();
- }
-
- public int read() throws IOException {
- fillBuffer();
- if (byteq.count() == 0)
- return -1;
- else {
- byte val = byteq.dequeue();
- if (val >= 0)
- return val;
- else
- return val & 0xFF;
- }
- }
-
- /**
- * Pulls bytes out of the underlying stream and places them in the
- * pushback queue. This is necessary (vs. reading from the
- * underlying stream directly) to detect and filter out "transport
- * padding" whitespace, i.e., all whitespace that appears immediately
- * before a CRLF.
- *
- * @throws IOException Underlying stream threw IOException.
- */
- private void populatePushbackQueue() throws IOException {
- //Debug.verify(pushbackq.count() == 0, "PopulatePushbackQueue called when pushback queue was not empty!");
-
- if (pushbackq.count() != 0)
- return;
-
- while (true) {
- int i = stream.read();
- switch (i) {
- case -1:
- // stream is done
- pushbackq.clear(); // discard any whitespace preceding EOF
- return;
- case ' ':
- case '\t':
- pushbackq.enqueue((byte)i);
- break;
- case '\r':
- case '\n':
- pushbackq.clear(); // discard any whitespace preceding EOL
- pushbackq.enqueue((byte)i);
- return;
- default:
- pushbackq.enqueue((byte)i);
- return;
- }
- }
- }
-
- /**
- * Causes the pushback queue to get populated if it is empty, then
- * consumes and decodes bytes out of it until one or more bytes are
- * in the byte queue. This decoding step performs the actual QP
- * decoding.
- *
- * @throws IOException Underlying stream threw IOException.
- */
- private void fillBuffer() throws IOException {
- byte msdChar = 0; // first digit of escaped num
- while (byteq.count() == 0) {
- if (pushbackq.count() == 0) {
- populatePushbackQueue();
- if (pushbackq.count() == 0)
- return;
- }
-
- byte b = (byte)pushbackq.dequeue();
-
- switch (state) {
- case 0: // start state, no bytes pending
- if (b != '=') {
- byteq.enqueue(b);
- break; // state remains 0
- } else {
- state = 1;
- break;
- }
- case 1: // encountered "=" so far
- if (b == '\r') {
- state = 2;
- break;
- } else if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) {
- state = 3;
- msdChar = b; // save until next digit encountered
- break;
- } else if (b == '=') {
- /*
- * Special case when == is encountered.
- * Emit one = and stay in this state.
- */
- if (log.isWarnEnabled()) {
- log.warn("Malformed MIME; got ==");
- }
- byteq.enqueue((byte)'=');
- break;
- } else {
- if (log.isWarnEnabled()) {
- log.warn("Malformed MIME; expected \\r or "
- + "[0-9A-Z], got " + b);
- }
- state = 0;
- byteq.enqueue((byte)'=');
- byteq.enqueue(b);
- break;
- }
- case 2: // encountered "=\r" so far
- if (b == '\n') {
- state = 0;
- break;
- } else {
- if (log.isWarnEnabled()) {
- log.warn("Malformed MIME; expected "
- + (int)'\n' + ", got " + b);
- }
- state = 0;
- byteq.enqueue((byte)'=');
- byteq.enqueue((byte)'\r');
- byteq.enqueue(b);
- break;
- }
- case 3: // encountered =
- * The removal order of an UnboundedFifoByteBuffer
is based on the insertion
- * order; elements are removed in the same order in which they were added.
- * The iteration order is the same as the removal order.
- *
- * The {@link #remove()} and {@link #get()} operations perform in constant time. - * The {@link #add(Object)} operation performs in amortized constant time. All - * other operations perform in linear time or worse. - *
- * Note that this implementation is not synchronized. The following can be
- * used to provide synchronized access to your UnboundedFifoByteBuffer
:
- *
- * Buffer fifo = BufferUtils.synchronizedBuffer(new UnboundedFifoByteBuffer()); - *- *
- * This buffer prevents null objects from being added. - * - * @since Commons Collections 3.0 (previously in main package v2.1) - * @version $Revision: 1.1 $ $Date: 2004/08/24 06:52:02 $ - * - * - * - * - * - * - */ -class UnboundedFifoByteBuffer { - - protected byte[] buffer; - protected int head; - protected int tail; - - /** - * Constructs an UnboundedFifoByteBuffer with the default number of elements. - * It is exactly the same as performing the following: - * - *
- * new UnboundedFifoByteBuffer(32); - *- */ - public UnboundedFifoByteBuffer() { - this(32); - } - - /** - * Constructs an UnboundedFifoByteBuffer with the specified number of elements. - * The integer must be a positive integer. - * - * @param initialSize the initial size of the buffer - * @throws IllegalArgumentException if the size is less than 1 - */ - public UnboundedFifoByteBuffer(int initialSize) { - if (initialSize <= 0) { - throw new IllegalArgumentException("The size must be greater than 0"); - } - buffer = new byte[initialSize + 1]; - head = 0; - tail = 0; - } - - /** - * Returns the number of elements stored in the buffer. - * - * @return this buffer's size - */ - public int size() { - int size = 0; - - if (tail < head) { - size = buffer.length - head + tail; - } else { - size = tail - head; - } - - return size; - } - - /** - * Returns true if this buffer is empty; false otherwise. - * - * @return true if this buffer is empty - */ - public boolean isEmpty() { - return (size() == 0); - } - - /** - * Adds the given element to this buffer. - * - * @param b the byte to add - * @return true, always - */ - public boolean add(final byte b) { - - if (size() + 1 >= buffer.length) { - byte[] tmp = new byte[((buffer.length - 1) * 2) + 1]; - - int j = 0; - for (int i = head; i != tail;) { - tmp[j] = buffer[i]; - buffer[i] = 0; - - j++; - i++; - if (i == buffer.length) { - i = 0; - } - } - - buffer = tmp; - head = 0; - tail = j; - } - - buffer[tail] = b; - tail++; - if (tail >= buffer.length) { - tail = 0; - } - return true; - } - - /** - * Returns the next object in the buffer. - * - * @return the next object in the buffer - * @throws BufferUnderflowException if this buffer is empty - */ - public byte get() { - if (isEmpty()) { - throw new IllegalStateException("The buffer is already empty"); - } - - return buffer[head]; - } - - /** - * Removes the next object from the buffer - * - * @return the removed object - * @throws BufferUnderflowException if this buffer is empty - */ - public byte remove() { - if (isEmpty()) { - throw new IllegalStateException("The buffer is already empty"); - } - - byte element = buffer[head]; - - head++; - if (head >= buffer.length) { - head = 0; - } - - return element; - } - - /** - * Increments the internal index. - * - * @param index the index to increment - * @return the updated index - */ - private int increment(int index) { - index++; - if (index >= buffer.length) { - index = 0; - } - return index; - } - - /** - * Decrements the internal index. - * - * @param index the index to decrement - * @return the updated index - */ - private int decrement(int index) { - index--; - if (index < 0) { - index = buffer.length - 1; - } - return index; - } - - /** - * Returns an iterator over this buffer's elements. - * - * @return an iterator over this buffer's elements - */ - public Iterator iterator() { - return new Iterator() { - - private int index = head; - private int lastReturnedIndex = -1; - - public boolean hasNext() { - return index != tail; - - } - - public Object next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - lastReturnedIndex = index; - index = increment(index); - return new Byte(buffer[lastReturnedIndex]); - } - - public void remove() { - if (lastReturnedIndex == -1) { - throw new IllegalStateException(); - } - - // First element can be removed quickly - if (lastReturnedIndex == head) { - UnboundedFifoByteBuffer.this.remove(); - lastReturnedIndex = -1; - return; - } - - // Other elements require us to shift the subsequent elements - int i = lastReturnedIndex + 1; - while (i != tail) { - if (i >= buffer.length) { - buffer[i - 1] = buffer[0]; - i = 0; - } else { - buffer[i - 1] = buffer[i]; - i++; - } - } - - lastReturnedIndex = -1; - tail = decrement(tail); - buffer[tail] = 0; - index = decrement(index); - } - - }; - } - +/**************************************************************** + * 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.mime4j.decoder; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * UnboundedFifoByteBuffer is a very efficient buffer implementation. + * According to performance testing, it exhibits a constant access time, but it + * also outperforms ArrayList when used for the same purpose. + *
+ * The removal order of an UnboundedFifoByteBuffer
is based on the insertion
+ * order; elements are removed in the same order in which they were added.
+ * The iteration order is the same as the removal order.
+ *
+ * The {@link #remove()} and {@link #get()} operations perform in constant time. + * The {@link #add(Object)} operation performs in amortized constant time. All + * other operations perform in linear time or worse. + *
+ * Note that this implementation is not synchronized. The following can be
+ * used to provide synchronized access to your UnboundedFifoByteBuffer
:
+ *
+ * Buffer fifo = BufferUtils.synchronizedBuffer(new UnboundedFifoByteBuffer()); + *+ *
+ * This buffer prevents null objects from being added. + * + * @since Commons Collections 3.0 (previously in main package v2.1) + * @version $Revision: 1.1 $ $Date: 2004/08/24 06:52:02 $ + * + * + * + * + * + * + */ +class UnboundedFifoByteBuffer { + + protected byte[] buffer; + protected int head; + protected int tail; + + /** + * Constructs an UnboundedFifoByteBuffer with the default number of elements. + * It is exactly the same as performing the following: + * + *
+ * new UnboundedFifoByteBuffer(32); + *+ */ + public UnboundedFifoByteBuffer() { + this(32); + } + + /** + * Constructs an UnboundedFifoByteBuffer with the specified number of elements. + * The integer must be a positive integer. + * + * @param initialSize the initial size of the buffer + * @throws IllegalArgumentException if the size is less than 1 + */ + public UnboundedFifoByteBuffer(int initialSize) { + if (initialSize <= 0) { + throw new IllegalArgumentException("The size must be greater than 0"); + } + buffer = new byte[initialSize + 1]; + head = 0; + tail = 0; + } + + /** + * Returns the number of elements stored in the buffer. + * + * @return this buffer's size + */ + public int size() { + int size = 0; + + if (tail < head) { + size = buffer.length - head + tail; + } else { + size = tail - head; + } + + return size; + } + + /** + * Returns true if this buffer is empty; false otherwise. + * + * @return true if this buffer is empty + */ + public boolean isEmpty() { + return (size() == 0); + } + + /** + * Adds the given element to this buffer. + * + * @param b the byte to add + * @return true, always + */ + public boolean add(final byte b) { + + if (size() + 1 >= buffer.length) { + byte[] tmp = new byte[((buffer.length - 1) * 2) + 1]; + + int j = 0; + for (int i = head; i != tail;) { + tmp[j] = buffer[i]; + buffer[i] = 0; + + j++; + i++; + if (i == buffer.length) { + i = 0; + } + } + + buffer = tmp; + head = 0; + tail = j; + } + + buffer[tail] = b; + tail++; + if (tail >= buffer.length) { + tail = 0; + } + return true; + } + + /** + * Returns the next object in the buffer. + * + * @return the next object in the buffer + * @throws BufferUnderflowException if this buffer is empty + */ + public byte get() { + if (isEmpty()) { + throw new IllegalStateException("The buffer is already empty"); + } + + return buffer[head]; + } + + /** + * Removes the next object from the buffer + * + * @return the removed object + * @throws BufferUnderflowException if this buffer is empty + */ + public byte remove() { + if (isEmpty()) { + throw new IllegalStateException("The buffer is already empty"); + } + + byte element = buffer[head]; + + head++; + if (head >= buffer.length) { + head = 0; + } + + return element; + } + + /** + * Increments the internal index. + * + * @param index the index to increment + * @return the updated index + */ + private int increment(int index) { + index++; + if (index >= buffer.length) { + index = 0; + } + return index; + } + + /** + * Decrements the internal index. + * + * @param index the index to decrement + * @return the updated index + */ + private int decrement(int index) { + index--; + if (index < 0) { + index = buffer.length - 1; + } + return index; + } + + /** + * Returns an iterator over this buffer's elements. + * + * @return an iterator over this buffer's elements + */ + public Iterator iterator() { + return new Iterator() { + + private int index = head; + private int lastReturnedIndex = -1; + + public boolean hasNext() { + return index != tail; + + } + + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + lastReturnedIndex = index; + index = increment(index); + return new Byte(buffer[lastReturnedIndex]); + } + + public void remove() { + if (lastReturnedIndex == -1) { + throw new IllegalStateException(); + } + + // First element can be removed quickly + if (lastReturnedIndex == head) { + UnboundedFifoByteBuffer.this.remove(); + lastReturnedIndex = -1; + return; + } + + // Other elements require us to shift the subsequent elements + int i = lastReturnedIndex + 1; + while (i != tail) { + if (i >= buffer.length) { + buffer[i - 1] = buffer[0]; + i = 0; + } else { + buffer[i - 1] = buffer[i]; + i++; + } + } + + lastReturnedIndex = -1; + tail = decrement(tail); + buffer[tail] = 0; + index = decrement(index); + } + + }; + } + } \ No newline at end of file diff --git a/src/org/apache/james/mime4j/field/AddressListField.java b/src/org/apache/james/mime4j/field/AddressListField.java index 0e4297c76a65958bb01c18b477fc3179a7627a17..a2e6f992f6de0f289a48f3d6cbd2b4c6c78cf6bd 100644 --- a/src/org/apache/james/mime4j/field/AddressListField.java +++ b/src/org/apache/james/mime4j/field/AddressListField.java @@ -1,63 +1,63 @@ -/**************************************************************** - * 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.mime4j.field; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.james.mime4j.field.address.AddressList; -import org.apache.james.mime4j.field.address.parser.ParseException; - -public class AddressListField extends Field { - private AddressList addressList; - private ParseException parseException; - - protected AddressListField(String name, String body, String raw, AddressList addressList, ParseException parseException) { - super(name, body, raw); - this.addressList = addressList; - this.parseException = parseException; - } - - public AddressList getAddressList() { - return addressList; - } - - public ParseException getParseException() { - return parseException; - } - - public static class Parser implements FieldParser { - private static Log log = LogFactory.getLog(Parser.class); - - public Field parse(final String name, final String body, final String raw) { - AddressList addressList = null; - ParseException parseException = null; - try { - addressList = AddressList.parse(body); - } - catch (ParseException e) { - if (log.isDebugEnabled()) { - log.debug("Parsing value '" + body + "': "+ e.getMessage()); - } - parseException = e; - } - return new AddressListField(name, body, raw, addressList, parseException); - } - } -} +/**************************************************************** + * 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.mime4j.field; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.james.mime4j.field.address.AddressList; +import org.apache.james.mime4j.field.address.parser.ParseException; + +public class AddressListField extends Field { + private AddressList addressList; + private ParseException parseException; + + protected AddressListField(String name, String body, String raw, AddressList addressList, ParseException parseException) { + super(name, body, raw); + this.addressList = addressList; + this.parseException = parseException; + } + + public AddressList getAddressList() { + return addressList; + } + + public ParseException getParseException() { + return parseException; + } + + public static class Parser implements FieldParser { + private static Log log = LogFactory.getLog(Parser.class); + + public Field parse(final String name, final String body, final String raw) { + AddressList addressList = null; + ParseException parseException = null; + try { + addressList = AddressList.parse(body); + } + catch (ParseException e) { + if (log.isDebugEnabled()) { + log.debug("Parsing value '" + body + "': "+ e.getMessage()); + } + parseException = e; + } + return new AddressListField(name, body, raw, addressList, parseException); + } + } +} diff --git a/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java b/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java index eb6151377ae91bf0a5f8a11bb28cc561d4e11176..73d8d233921b3f8d61dee4f592960c98dd881b8b 100644 --- a/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java +++ b/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java @@ -1,88 +1,88 @@ -/**************************************************************** - * 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.mime4j.field; - - - -/** - * Represents a
Content-Transfer-Encoding
field.
- *
- *
- * @version $Id: ContentTransferEncodingField.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public class ContentTransferEncodingField extends Field {
- /**
- * The 7bit
encoding.
- */
- public static final String ENC_7BIT = "7bit";
- /**
- * The 8bit
encoding.
- */
- public static final String ENC_8BIT = "8bit";
- /**
- * The binary
encoding.
- */
- public static final String ENC_BINARY = "binary";
- /**
- * The quoted-printable
encoding.
- */
- public static final String ENC_QUOTED_PRINTABLE = "quoted-printable";
- /**
- * The base64
encoding.
- */
- public static final String ENC_BASE64 = "base64";
-
- private String encoding;
-
- protected ContentTransferEncodingField(String name, String body, String raw, String encoding) {
- super(name, body, raw);
- this.encoding = encoding;
- }
-
- /**
- * Gets the encoding defined in this field.
- *
- * @return the encoding or an empty string if not set.
- */
- public String getEncoding() {
- return encoding;
- }
-
- /**
- * Gets the encoding of the given field if. Returns the default
- * 7bit
if not set or if
- * f
is null
.
- *
- * @return the encoding.
- */
- public static String getEncoding(ContentTransferEncodingField f) {
- if (f != null && f.getEncoding().length() != 0) {
- return f.getEncoding();
- }
- return ENC_7BIT;
- }
-
- public static class Parser implements FieldParser {
- public Field parse(final String name, final String body, final String raw) {
- final String encoding = body.trim().toLowerCase();
- return new ContentTransferEncodingField(name, body, raw, encoding);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+
+
+/**
+ * Represents a Content-Transfer-Encoding
field.
+ *
+ *
+ * @version $Id: ContentTransferEncodingField.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class ContentTransferEncodingField extends Field {
+ /**
+ * The 7bit
encoding.
+ */
+ public static final String ENC_7BIT = "7bit";
+ /**
+ * The 8bit
encoding.
+ */
+ public static final String ENC_8BIT = "8bit";
+ /**
+ * The binary
encoding.
+ */
+ public static final String ENC_BINARY = "binary";
+ /**
+ * The quoted-printable
encoding.
+ */
+ public static final String ENC_QUOTED_PRINTABLE = "quoted-printable";
+ /**
+ * The base64
encoding.
+ */
+ public static final String ENC_BASE64 = "base64";
+
+ private String encoding;
+
+ protected ContentTransferEncodingField(String name, String body, String raw, String encoding) {
+ super(name, body, raw);
+ this.encoding = encoding;
+ }
+
+ /**
+ * Gets the encoding defined in this field.
+ *
+ * @return the encoding or an empty string if not set.
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Gets the encoding of the given field if. Returns the default
+ * 7bit
if not set or if
+ * f
is null
.
+ *
+ * @return the encoding.
+ */
+ public static String getEncoding(ContentTransferEncodingField f) {
+ if (f != null && f.getEncoding().length() != 0) {
+ return f.getEncoding();
+ }
+ return ENC_7BIT;
+ }
+
+ public static class Parser implements FieldParser {
+ public Field parse(final String name, final String body, final String raw) {
+ final String encoding = body.trim().toLowerCase();
+ return new ContentTransferEncodingField(name, body, raw, encoding);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/ContentTypeField.java b/src/org/apache/james/mime4j/field/ContentTypeField.java
index 51616419d76ca413799ed0272090f3dab4cd0f95..01f640ccece2f57ab83ee8b8b0e18d2ec8b53c11 100644
--- a/src/org/apache/james/mime4j/field/ContentTypeField.java
+++ b/src/org/apache/james/mime4j/field/ContentTypeField.java
@@ -1,256 +1,256 @@
-/****************************************************************
- * 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.mime4j.field;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.field.contenttype.parser.ContentTypeParser;
-import org.apache.james.mime4j.field.contenttype.parser.ParseException;
-import org.apache.james.mime4j.field.contenttype.parser.TokenMgrError;
-
-/**
- * Represents a Content-Type
field.
- *
- * TODO: Remove dependency on Java 1.4 regexps
- * - * - * @version $Id: ContentTypeField.java,v 1.6 2005/01/27 14:16:31 ntherning Exp $ - */ -public class ContentTypeField extends Field { - - /** - * The prefix of allmultipart
MIME types.
- */
- public static final String TYPE_MULTIPART_PREFIX = "multipart/";
- /**
- * The multipart/digest
MIME type.
- */
- public static final String TYPE_MULTIPART_DIGEST = "multipart/digest";
- /**
- * The text/plain
MIME type.
- */
- public static final String TYPE_TEXT_PLAIN = "text/plain";
- /**
- * The message/rfc822
MIME type.
- */
- public static final String TYPE_MESSAGE_RFC822 = "message/rfc822";
- /**
- * The name of the boundary
parameter.
- */
- public static final String PARAM_BOUNDARY = "boundary";
- /**
- * The name of the charset
parameter.
- */
- public static final String PARAM_CHARSET = "charset";
-
- private String mimeType = "";
- private Map parameters = null;
- private ParseException parseException;
-
- protected ContentTypeField(String name, String body, String raw, String mimeType, Map parameters, ParseException parseException) {
- super(name, body, raw);
- this.mimeType = mimeType;
- this.parameters = parameters;
- this.parseException = parseException;
- }
-
- /**
- * Gets the exception that was raised during parsing of
- * the field value, if any; otherwise, null.
- */
- public ParseException getParseException() {
- return parseException;
- }
-
- /**
- * Gets the MIME type defined in this Content-Type field.
- *
- * @return the MIME type or an empty string if not set.
- */
- public String getMimeType() {
- return mimeType;
- }
-
- /**
- * Gets the MIME type defined in the child's
- * Content-Type field or derives a MIME type from the parent
- * if child is null
or hasn't got a MIME type value set.
- * If child's MIME type is multipart but no boundary
- * has been set the MIME type of child will be derived from
- * the parent.
- *
- * @param child the child.
- * @param parent the parent.
- * @return the MIME type.
- */
- public static String getMimeType(ContentTypeField child,
- ContentTypeField parent) {
-
- if (child == null || child.getMimeType().length() == 0
- || child.isMultipart() && child.getBoundary() == null) {
-
- if (parent != null && parent.isMimeType(TYPE_MULTIPART_DIGEST)) {
- return TYPE_MESSAGE_RFC822;
- } else {
- return TYPE_TEXT_PLAIN;
- }
- }
-
- return child.getMimeType();
- }
-
- /**
- * Gets the value of a parameter. Parameter names are case-insensitive.
- *
- * @param name the name of the parameter to get.
- * @return the parameter value or null
if not set.
- */
- public String getParameter(String name) {
- return parameters != null
- ? (String) parameters.get(name.toLowerCase())
- : null;
- }
-
- /**
- * Gets all parameters.
- *
- * @return the parameters.
- */
- public Map getParameters() {
- return parameters != null
- ? Collections.unmodifiableMap(parameters)
- : Collections.EMPTY_MAP;
- }
-
- /**
- * Gets the value of the boundary
parameter if set.
- *
- * @return the boundary
parameter value or null
- * if not set.
- */
- public String getBoundary() {
- return getParameter(PARAM_BOUNDARY);
- }
-
- /**
- * Gets the value of the charset
parameter if set.
- *
- * @return the charset
parameter value or null
- * if not set.
- */
- public String getCharset() {
- return getParameter(PARAM_CHARSET);
- }
-
- /**
- * Gets the value of the charset
parameter if set for the
- * given field. Returns the default us-ascii
if not set or if
- * f
is null
.
- *
- * @return the charset
parameter value.
- */
- public static String getCharset(ContentTypeField f) {
- if (f != null) {
- if (f.getCharset() != null && f.getCharset().length() > 0) {
- return f.getCharset();
- }
- }
- return "us-ascii";
- }
-
- /**
- * Determines if the MIME type of this field matches the given one.
- *
- * @param mimeType the MIME type to match against.
- * @return true
if the MIME type of this field matches,
- * false
otherwise.
- */
- public boolean isMimeType(String mimeType) {
- return this.mimeType.equalsIgnoreCase(mimeType);
- }
-
- /**
- * Determines if the MIME type of this field is multipart/*
.
- *
- * @return true
if this field is has a multipart/*
- * MIME type, false
otherwise.
- */
- public boolean isMultipart() {
- return mimeType.startsWith(TYPE_MULTIPART_PREFIX);
- }
-
- public static class Parser implements FieldParser {
- private static Log log = LogFactory.getLog(Parser.class);
-
- public Field parse(final String name, final String body, final String raw) {
- ParseException parseException = null;
- String mimeType = "";
- Map parameters = null;
-
- ContentTypeParser parser = new ContentTypeParser(new StringReader(body));
- try {
- parser.parseAll();
- }
- catch (ParseException e) {
- if (log.isDebugEnabled()) {
- log.debug("Parsing value '" + body + "': "+ e.getMessage());
- }
- parseException = e;
- }
- catch (TokenMgrError e) {
- if (log.isDebugEnabled()) {
- log.debug("Parsing value '" + body + "': "+ e.getMessage());
- }
- parseException = new ParseException(e.getMessage());
- }
-
- try {
- final String type = parser.getType();
- final String subType = parser.getSubType();
-
- if (type != null && subType != null) {
- mimeType = (type + "/" + parser.getSubType()).toLowerCase();
-
- ArrayList paramNames = parser.getParamNames();
- ArrayList paramValues = parser.getParamValues();
-
- if (paramNames != null && paramValues != null) {
- for (int i = 0; i < paramNames.size() && i < paramValues.size(); i++) {
- if (parameters == null)
- parameters = new HashMap((int)(paramNames.size() * 1.3 + 1));
- String paramName = ((String)paramNames.get(i)).toLowerCase();
- String paramValue = ((String)paramValues.get(i));
- parameters.put(paramName, paramValue);
- }
- }
- }
- }
- catch (NullPointerException npe) {
- }
- return new ContentTypeField(name, body, raw, mimeType, parameters, parseException);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.field.contenttype.parser.ContentTypeParser;
+import org.apache.james.mime4j.field.contenttype.parser.ParseException;
+import org.apache.james.mime4j.field.contenttype.parser.TokenMgrError;
+
+/**
+ * Represents a Content-Type
field.
+ *
+ * TODO: Remove dependency on Java 1.4 regexps
+ * + * + * @version $Id: ContentTypeField.java,v 1.6 2005/01/27 14:16:31 ntherning Exp $ + */ +public class ContentTypeField extends Field { + + /** + * The prefix of allmultipart
MIME types.
+ */
+ public static final String TYPE_MULTIPART_PREFIX = "multipart/";
+ /**
+ * The multipart/digest
MIME type.
+ */
+ public static final String TYPE_MULTIPART_DIGEST = "multipart/digest";
+ /**
+ * The text/plain
MIME type.
+ */
+ public static final String TYPE_TEXT_PLAIN = "text/plain";
+ /**
+ * The message/rfc822
MIME type.
+ */
+ public static final String TYPE_MESSAGE_RFC822 = "message/rfc822";
+ /**
+ * The name of the boundary
parameter.
+ */
+ public static final String PARAM_BOUNDARY = "boundary";
+ /**
+ * The name of the charset
parameter.
+ */
+ public static final String PARAM_CHARSET = "charset";
+
+ private String mimeType = "";
+ private Map parameters = null;
+ private ParseException parseException;
+
+ protected ContentTypeField(String name, String body, String raw, String mimeType, Map parameters, ParseException parseException) {
+ super(name, body, raw);
+ this.mimeType = mimeType;
+ this.parameters = parameters;
+ this.parseException = parseException;
+ }
+
+ /**
+ * Gets the exception that was raised during parsing of
+ * the field value, if any; otherwise, null.
+ */
+ public ParseException getParseException() {
+ return parseException;
+ }
+
+ /**
+ * Gets the MIME type defined in this Content-Type field.
+ *
+ * @return the MIME type or an empty string if not set.
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * Gets the MIME type defined in the child's
+ * Content-Type field or derives a MIME type from the parent
+ * if child is null
or hasn't got a MIME type value set.
+ * If child's MIME type is multipart but no boundary
+ * has been set the MIME type of child will be derived from
+ * the parent.
+ *
+ * @param child the child.
+ * @param parent the parent.
+ * @return the MIME type.
+ */
+ public static String getMimeType(ContentTypeField child,
+ ContentTypeField parent) {
+
+ if (child == null || child.getMimeType().length() == 0
+ || child.isMultipart() && child.getBoundary() == null) {
+
+ if (parent != null && parent.isMimeType(TYPE_MULTIPART_DIGEST)) {
+ return TYPE_MESSAGE_RFC822;
+ } else {
+ return TYPE_TEXT_PLAIN;
+ }
+ }
+
+ return child.getMimeType();
+ }
+
+ /**
+ * Gets the value of a parameter. Parameter names are case-insensitive.
+ *
+ * @param name the name of the parameter to get.
+ * @return the parameter value or null
if not set.
+ */
+ public String getParameter(String name) {
+ return parameters != null
+ ? (String) parameters.get(name.toLowerCase())
+ : null;
+ }
+
+ /**
+ * Gets all parameters.
+ *
+ * @return the parameters.
+ */
+ public Map getParameters() {
+ return parameters != null
+ ? Collections.unmodifiableMap(parameters)
+ : Collections.EMPTY_MAP;
+ }
+
+ /**
+ * Gets the value of the boundary
parameter if set.
+ *
+ * @return the boundary
parameter value or null
+ * if not set.
+ */
+ public String getBoundary() {
+ return getParameter(PARAM_BOUNDARY);
+ }
+
+ /**
+ * Gets the value of the charset
parameter if set.
+ *
+ * @return the charset
parameter value or null
+ * if not set.
+ */
+ public String getCharset() {
+ return getParameter(PARAM_CHARSET);
+ }
+
+ /**
+ * Gets the value of the charset
parameter if set for the
+ * given field. Returns the default us-ascii
if not set or if
+ * f
is null
.
+ *
+ * @return the charset
parameter value.
+ */
+ public static String getCharset(ContentTypeField f) {
+ if (f != null) {
+ if (f.getCharset() != null && f.getCharset().length() > 0) {
+ return f.getCharset();
+ }
+ }
+ return "us-ascii";
+ }
+
+ /**
+ * Determines if the MIME type of this field matches the given one.
+ *
+ * @param mimeType the MIME type to match against.
+ * @return true
if the MIME type of this field matches,
+ * false
otherwise.
+ */
+ public boolean isMimeType(String mimeType) {
+ return this.mimeType.equalsIgnoreCase(mimeType);
+ }
+
+ /**
+ * Determines if the MIME type of this field is multipart/*
.
+ *
+ * @return true
if this field is has a multipart/*
+ * MIME type, false
otherwise.
+ */
+ public boolean isMultipart() {
+ return mimeType.startsWith(TYPE_MULTIPART_PREFIX);
+ }
+
+ public static class Parser implements FieldParser {
+ private static Log log = LogFactory.getLog(Parser.class);
+
+ public Field parse(final String name, final String body, final String raw) {
+ ParseException parseException = null;
+ String mimeType = "";
+ Map parameters = null;
+
+ ContentTypeParser parser = new ContentTypeParser(new StringReader(body));
+ try {
+ parser.parseAll();
+ }
+ catch (ParseException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing value '" + body + "': "+ e.getMessage());
+ }
+ parseException = e;
+ }
+ catch (TokenMgrError e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing value '" + body + "': "+ e.getMessage());
+ }
+ parseException = new ParseException(e.getMessage());
+ }
+
+ try {
+ final String type = parser.getType();
+ final String subType = parser.getSubType();
+
+ if (type != null && subType != null) {
+ mimeType = (type + "/" + parser.getSubType()).toLowerCase();
+
+ ArrayList paramNames = parser.getParamNames();
+ ArrayList paramValues = parser.getParamValues();
+
+ if (paramNames != null && paramValues != null) {
+ for (int i = 0; i < paramNames.size() && i < paramValues.size(); i++) {
+ if (parameters == null)
+ parameters = new HashMap((int)(paramNames.size() * 1.3 + 1));
+ String paramName = ((String)paramNames.get(i)).toLowerCase();
+ String paramValue = ((String)paramValues.get(i));
+ parameters.put(paramName, paramValue);
+ }
+ }
+ }
+ }
+ catch (NullPointerException npe) {
+ }
+ return new ContentTypeField(name, body, raw, mimeType, parameters, parseException);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/DateTimeField.java b/src/org/apache/james/mime4j/field/DateTimeField.java
index a7b24b5bd7eb5b1b12f61983e96b81d9825d2e32..fa34ceda4b7e41d24f8c889a817b25fc292566ce 100644
--- a/src/org/apache/james/mime4j/field/DateTimeField.java
+++ b/src/org/apache/james/mime4j/field/DateTimeField.java
@@ -1,65 +1,65 @@
-/****************************************************************
- * 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.mime4j.field;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.field.datetime.DateTime;
-import org.apache.james.mime4j.field.datetime.parser.ParseException;
-
-import java.util.Date;
-
-public class DateTimeField extends Field {
- private Date date;
- private ParseException parseException;
-
- protected DateTimeField(String name, String body, String raw, Date date, ParseException parseException) {
- super(name, body, raw);
- this.date = date;
- this.parseException = parseException;
- }
-
- public Date getDate() {
- return date;
- }
-
- public ParseException getParseException() {
- return parseException;
- }
-
- public static class Parser implements FieldParser {
- private static Log log = LogFactory.getLog(Parser.class);
-
- public Field parse(final String name, final String body, final String raw) {
- Date date = null;
- ParseException parseException = null;
- try {
- date = DateTime.parse(body).getDate();
- }
- catch (ParseException e) {
- if (log.isDebugEnabled()) {
- log.debug("Parsing value '" + body + "': "+ e.getMessage());
- }
- parseException = e;
- }
- return new DateTimeField(name, body, raw, date, parseException);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.field.datetime.DateTime;
+import org.apache.james.mime4j.field.datetime.parser.ParseException;
+
+import java.util.Date;
+
+public class DateTimeField extends Field {
+ private Date date;
+ private ParseException parseException;
+
+ protected DateTimeField(String name, String body, String raw, Date date, ParseException parseException) {
+ super(name, body, raw);
+ this.date = date;
+ this.parseException = parseException;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public ParseException getParseException() {
+ return parseException;
+ }
+
+ public static class Parser implements FieldParser {
+ private static Log log = LogFactory.getLog(Parser.class);
+
+ public Field parse(final String name, final String body, final String raw) {
+ Date date = null;
+ ParseException parseException = null;
+ try {
+ date = DateTime.parse(body).getDate();
+ }
+ catch (ParseException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing value '" + body + "': "+ e.getMessage());
+ }
+ parseException = e;
+ }
+ return new DateTimeField(name, body, raw, date, parseException);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/DefaultFieldParser.java b/src/org/apache/james/mime4j/field/DefaultFieldParser.java
index 84fcdcb2d5976fd0f478174fac12d0616400992b..3695afe3e183afaf07f6dbbaec496adc0e445365 100644
--- a/src/org/apache/james/mime4j/field/DefaultFieldParser.java
+++ b/src/org/apache/james/mime4j/field/DefaultFieldParser.java
@@ -1,45 +1,45 @@
-/*
- * Copyright 2006 the mime4j project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.james.mime4j.field;
-
-public class DefaultFieldParser extends DelegatingFieldParser {
-
- public DefaultFieldParser() {
- setFieldParser(Field.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
- setFieldParser(Field.CONTENT_TYPE, new ContentTypeField.Parser());
-
- final DateTimeField.Parser dateTimeParser = new DateTimeField.Parser();
- setFieldParser(Field.DATE, dateTimeParser);
- setFieldParser(Field.RESENT_DATE, dateTimeParser);
-
- final MailboxListField.Parser mailboxListParser = new MailboxListField.Parser();
- setFieldParser(Field.FROM, mailboxListParser);
- setFieldParser(Field.RESENT_FROM, mailboxListParser);
-
- final MailboxField.Parser mailboxParser = new MailboxField.Parser();
- setFieldParser(Field.SENDER, mailboxParser);
- setFieldParser(Field.RESENT_SENDER, mailboxParser);
-
- final AddressListField.Parser addressListParser = new AddressListField.Parser();
- setFieldParser(Field.TO, addressListParser);
- setFieldParser(Field.RESENT_TO, addressListParser);
- setFieldParser(Field.CC, addressListParser);
- setFieldParser(Field.RESENT_CC, addressListParser);
- setFieldParser(Field.BCC, addressListParser);
- setFieldParser(Field.RESENT_BCC, addressListParser);
- setFieldParser(Field.REPLY_TO, addressListParser);
- }
-}
+/*
+ * Copyright 2006 the mime4j project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.james.mime4j.field;
+
+public class DefaultFieldParser extends DelegatingFieldParser {
+
+ public DefaultFieldParser() {
+ setFieldParser(Field.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
+ setFieldParser(Field.CONTENT_TYPE, new ContentTypeField.Parser());
+
+ final DateTimeField.Parser dateTimeParser = new DateTimeField.Parser();
+ setFieldParser(Field.DATE, dateTimeParser);
+ setFieldParser(Field.RESENT_DATE, dateTimeParser);
+
+ final MailboxListField.Parser mailboxListParser = new MailboxListField.Parser();
+ setFieldParser(Field.FROM, mailboxListParser);
+ setFieldParser(Field.RESENT_FROM, mailboxListParser);
+
+ final MailboxField.Parser mailboxParser = new MailboxField.Parser();
+ setFieldParser(Field.SENDER, mailboxParser);
+ setFieldParser(Field.RESENT_SENDER, mailboxParser);
+
+ final AddressListField.Parser addressListParser = new AddressListField.Parser();
+ setFieldParser(Field.TO, addressListParser);
+ setFieldParser(Field.RESENT_TO, addressListParser);
+ setFieldParser(Field.CC, addressListParser);
+ setFieldParser(Field.RESENT_CC, addressListParser);
+ setFieldParser(Field.BCC, addressListParser);
+ setFieldParser(Field.RESENT_BCC, addressListParser);
+ setFieldParser(Field.REPLY_TO, addressListParser);
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/DelegatingFieldParser.java b/src/org/apache/james/mime4j/field/DelegatingFieldParser.java
index e7787a3363765f18293259356f9eed7e563de4a4..c06160292b032d2838ba805dd4437bd66224d2ba 100644
--- a/src/org/apache/james/mime4j/field/DelegatingFieldParser.java
+++ b/src/org/apache/james/mime4j/field/DelegatingFieldParser.java
@@ -1,47 +1,47 @@
-/*
- * Copyright 2006 the mime4j project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.james.mime4j.field;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DelegatingFieldParser implements FieldParser {
-
- private Map parsers = new HashMap();
- private FieldParser defaultParser = new UnstructuredField.Parser();
-
- /**
- * Sets the parser used for the field named name
.
- * @param name the name of the field
- * @param parser the parser for fields named name
- */
- public void setFieldParser(final String name, final FieldParser parser) {
- parsers.put(name.toLowerCase(), parser);
- }
-
- public FieldParser getParser(final String name) {
- final FieldParser field = (FieldParser) parsers.get(name.toLowerCase());
- if(field==null) {
- return defaultParser;
- }
- return field;
- }
-
- public Field parse(final String name, final String body, final String raw) {
- final FieldParser parser = getParser(name);
- return parser.parse(name, body, raw);
- }
-}
+/*
+ * Copyright 2006 the mime4j project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.james.mime4j.field;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DelegatingFieldParser implements FieldParser {
+
+ private Map parsers = new HashMap();
+ private FieldParser defaultParser = new UnstructuredField.Parser();
+
+ /**
+ * Sets the parser used for the field named name
.
+ * @param name the name of the field
+ * @param parser the parser for fields named name
+ */
+ public void setFieldParser(final String name, final FieldParser parser) {
+ parsers.put(name.toLowerCase(), parser);
+ }
+
+ public FieldParser getParser(final String name) {
+ final FieldParser field = (FieldParser) parsers.get(name.toLowerCase());
+ if(field==null) {
+ return defaultParser;
+ }
+ return field;
+ }
+
+ public Field parse(final String name, final String body, final String raw) {
+ final FieldParser parser = getParser(name);
+ return parser.parse(name, body, raw);
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/Field.java b/src/org/apache/james/mime4j/field/Field.java
index 7c2a20dc8efb0fa68b0d4927cd1e3630af7b2695..4dea5c5cfb6e0560b037f203ca26b5b36579dd48 100644
--- a/src/org/apache/james/mime4j/field/Field.java
+++ b/src/org/apache/james/mime4j/field/Field.java
@@ -1,192 +1,192 @@
-/****************************************************************
- * 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.mime4j.field;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The base class of all field classes.
- *
- *
- * @version $Id: Field.java,v 1.6 2004/10/25 07:26:46 ntherning Exp $
- */
-public abstract class Field {
- public static final String SENDER = "Sender";
- public static final String FROM = "From";
- public static final String TO = "To";
- public static final String CC = "Cc";
- public static final String BCC = "Bcc";
- public static final String REPLY_TO = "Reply-To";
- public static final String RESENT_SENDER = "Resent-Sender";
- public static final String RESENT_FROM = "Resent-From";
- public static final String RESENT_TO = "Resent-To";
- public static final String RESENT_CC = "Resent-Cc";
- public static final String RESENT_BCC = "Resent-Bcc";
-
- public static final String DATE = "Date";
- public static final String RESENT_DATE = "Resent-Date";
-
- public static final String SUBJECT = "Subject";
- public static final String CONTENT_TYPE = "Content-Type";
- public static final String CONTENT_TRANSFER_ENCODING =
- "Content-Transfer-Encoding";
-
- private static final String FIELD_NAME_PATTERN =
- "^([\\x21-\\x39\\x3b-\\x7e]+)[ \t]*:";
- private static final Pattern fieldNamePattern =
- Pattern.compile(FIELD_NAME_PATTERN);
-
- private static final DefaultFieldParser parser = new DefaultFieldParser();
-
- private final String name;
- private final String body;
- private final String raw;
-
- protected Field(final String name, final String body, final String raw) {
- this.name = name;
- this.body = body;
- this.raw = raw;
- }
-
- /**
- * Parses the given string and returns an instance of the
- * Field
class. The type of the class returned depends on
- * the field name:
- * Field name | Class returned | - *Content-Type | org.apache.james.mime4j.field.ContentTypeField | - *other | org.apache.james.mime4j.field.UnstructuredField | - *
Field
instance.
- * @throws IllegalArgumentException on parse errors.
- */
- public static Field parse(final String raw) {
-
- /*
- * Unfold the field.
- */
- final String unfolded = raw.replaceAll("\r|\n", "");
-
- /*
- * Split into name and value.
- */
- final Matcher fieldMatcher = fieldNamePattern.matcher(unfolded);
- if (!fieldMatcher.find()) {
- throw new IllegalArgumentException("Invalid field in string");
- }
- final String name = fieldMatcher.group(1);
-
- String body = unfolded.substring(fieldMatcher.end());
- if (body.length() > 0 && body.charAt(0) == ' ') {
- body = body.substring(1);
- }
-
- return parser.parse(name, body, raw);
- }
-
- /**
- * Gets the default parser used to parse fields.
- * @return the default field parser
- */
- public static DefaultFieldParser getParser() {
- return parser;
- }
-
- /**
- * Gets the name of the field (Subject
,
- * From
, etc).
- *
- * @return the field name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Gets the original raw field string.
- *
- * @return the original raw field string.
- */
- public String getRaw() {
- return raw;
- }
-
- /**
- * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field
- * body string.
- *
- * @return the unfolded unparsed field body string.
- */
- public String getBody() {
- return body;
- }
-
- /**
- * Determines if this is a Content-Type
field.
- *
- * @return true
if this is a Content-Type
field,
- * false
otherwise.
- */
- public boolean isContentType() {
- return CONTENT_TYPE.equalsIgnoreCase(name);
- }
-
- /**
- * Determines if this is a Subject
field.
- *
- * @return true
if this is a Subject
field,
- * false
otherwise.
- */
- public boolean isSubject() {
- return SUBJECT.equalsIgnoreCase(name);
- }
-
- /**
- * Determines if this is a From
field.
- *
- * @return true
if this is a From
field,
- * false
otherwise.
- */
- public boolean isFrom() {
- return FROM.equalsIgnoreCase(name);
- }
-
- /**
- * Determines if this is a To
field.
- *
- * @return true
if this is a To
field,
- * false
otherwise.
- */
- public boolean isTo() {
- return TO.equalsIgnoreCase(name);
- }
-
- /**
- * @see #getRaw()
- */
- public String toString() {
- return raw;
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The base class of all field classes.
+ *
+ *
+ * @version $Id: Field.java,v 1.6 2004/10/25 07:26:46 ntherning Exp $
+ */
+public abstract class Field {
+ public static final String SENDER = "Sender";
+ public static final String FROM = "From";
+ public static final String TO = "To";
+ public static final String CC = "Cc";
+ public static final String BCC = "Bcc";
+ public static final String REPLY_TO = "Reply-To";
+ public static final String RESENT_SENDER = "Resent-Sender";
+ public static final String RESENT_FROM = "Resent-From";
+ public static final String RESENT_TO = "Resent-To";
+ public static final String RESENT_CC = "Resent-Cc";
+ public static final String RESENT_BCC = "Resent-Bcc";
+
+ public static final String DATE = "Date";
+ public static final String RESENT_DATE = "Resent-Date";
+
+ public static final String SUBJECT = "Subject";
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String CONTENT_TRANSFER_ENCODING =
+ "Content-Transfer-Encoding";
+
+ private static final String FIELD_NAME_PATTERN =
+ "^([\\x21-\\x39\\x3b-\\x7e]+)[ \t]*:";
+ private static final Pattern fieldNamePattern =
+ Pattern.compile(FIELD_NAME_PATTERN);
+
+ private static final DefaultFieldParser parser = new DefaultFieldParser();
+
+ private final String name;
+ private final String body;
+ private final String raw;
+
+ protected Field(final String name, final String body, final String raw) {
+ this.name = name;
+ this.body = body;
+ this.raw = raw;
+ }
+
+ /**
+ * Parses the given string and returns an instance of the
+ * Field
class. The type of the class returned depends on
+ * the field name:
+ * Field name | Class returned | + *Content-Type | org.apache.james.mime4j.field.ContentTypeField | + *other | org.apache.james.mime4j.field.UnstructuredField | + *
Field
instance.
+ * @throws IllegalArgumentException on parse errors.
+ */
+ public static Field parse(final String raw) {
+
+ /*
+ * Unfold the field.
+ */
+ final String unfolded = raw.replaceAll("\r|\n", "");
+
+ /*
+ * Split into name and value.
+ */
+ final Matcher fieldMatcher = fieldNamePattern.matcher(unfolded);
+ if (!fieldMatcher.find()) {
+ throw new IllegalArgumentException("Invalid field in string");
+ }
+ final String name = fieldMatcher.group(1);
+
+ String body = unfolded.substring(fieldMatcher.end());
+ if (body.length() > 0 && body.charAt(0) == ' ') {
+ body = body.substring(1);
+ }
+
+ return parser.parse(name, body, raw);
+ }
+
+ /**
+ * Gets the default parser used to parse fields.
+ * @return the default field parser
+ */
+ public static DefaultFieldParser getParser() {
+ return parser;
+ }
+
+ /**
+ * Gets the name of the field (Subject
,
+ * From
, etc).
+ *
+ * @return the field name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the original raw field string.
+ *
+ * @return the original raw field string.
+ */
+ public String getRaw() {
+ return raw;
+ }
+
+ /**
+ * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field
+ * body string.
+ *
+ * @return the unfolded unparsed field body string.
+ */
+ public String getBody() {
+ return body;
+ }
+
+ /**
+ * Determines if this is a Content-Type
field.
+ *
+ * @return true
if this is a Content-Type
field,
+ * false
otherwise.
+ */
+ public boolean isContentType() {
+ return CONTENT_TYPE.equalsIgnoreCase(name);
+ }
+
+ /**
+ * Determines if this is a Subject
field.
+ *
+ * @return true
if this is a Subject
field,
+ * false
otherwise.
+ */
+ public boolean isSubject() {
+ return SUBJECT.equalsIgnoreCase(name);
+ }
+
+ /**
+ * Determines if this is a From
field.
+ *
+ * @return true
if this is a From
field,
+ * false
otherwise.
+ */
+ public boolean isFrom() {
+ return FROM.equalsIgnoreCase(name);
+ }
+
+ /**
+ * Determines if this is a To
field.
+ *
+ * @return true
if this is a To
field,
+ * false
otherwise.
+ */
+ public boolean isTo() {
+ return TO.equalsIgnoreCase(name);
+ }
+
+ /**
+ * @see #getRaw()
+ */
+ public String toString() {
+ return raw;
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/FieldParser.java b/src/org/apache/james/mime4j/field/FieldParser.java
index 4f33c9e26602502eb5556c70bba6c11f021f56e2..78aaf133497f3aff6b1db25461c72958bba869c1 100644
--- a/src/org/apache/james/mime4j/field/FieldParser.java
+++ b/src/org/apache/james/mime4j/field/FieldParser.java
@@ -1,21 +1,21 @@
-/*
- * Copyright 2006 the mime4j project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.james.mime4j.field;
-
-public interface FieldParser {
-
- Field parse(final String name, final String body, final String raw);
-}
+/*
+ * Copyright 2006 the mime4j project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.james.mime4j.field;
+
+public interface FieldParser {
+
+ Field parse(final String name, final String body, final String raw);
+}
diff --git a/src/org/apache/james/mime4j/field/MailboxField.java b/src/org/apache/james/mime4j/field/MailboxField.java
index 96cca551fd6a61bf96b6bac975108e5acf8c42fd..867a38a1391680040e13e44a924cdcbd9146b7ae 100644
--- a/src/org/apache/james/mime4j/field/MailboxField.java
+++ b/src/org/apache/james/mime4j/field/MailboxField.java
@@ -1,68 +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.mime4j.field;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.field.address.AddressList;
-import org.apache.james.mime4j.field.address.Mailbox;
-import org.apache.james.mime4j.field.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-public class MailboxField extends Field {
- private final Mailbox mailbox;
- private final ParseException parseException;
-
- protected MailboxField(final String name, final String body, final String raw, final Mailbox mailbox, final ParseException parseException) {
- super(name, body, raw);
- this.mailbox = mailbox;
- this.parseException = parseException;
- }
-
- public Mailbox getMailbox() {
- return mailbox;
- }
-
- public ParseException getParseException() {
- return parseException;
- }
-
- public static class Parser implements FieldParser {
- private static Log log = LogFactory.getLog(Parser.class);
-
- public Field parse(final String name, final String body, final String raw) {
- Mailbox mailbox = null;
- ParseException parseException = null;
- try {
- MailboxList mailboxList = AddressList.parse(body).flatten();
- if (mailboxList.size() > 0) {
- mailbox = mailboxList.get(0);
- }
- }
- catch (ParseException e) {
- if (log.isDebugEnabled()) {
- log.debug("Parsing value '" + body + "': "+ e.getMessage());
- }
- parseException = e;
- }
- return new MailboxField(name, body, raw, mailbox, parseException);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.field.address.AddressList;
+import org.apache.james.mime4j.field.address.Mailbox;
+import org.apache.james.mime4j.field.address.MailboxList;
+import org.apache.james.mime4j.field.address.parser.ParseException;
+
+public class MailboxField extends Field {
+ private final Mailbox mailbox;
+ private final ParseException parseException;
+
+ protected MailboxField(final String name, final String body, final String raw, final Mailbox mailbox, final ParseException parseException) {
+ super(name, body, raw);
+ this.mailbox = mailbox;
+ this.parseException = parseException;
+ }
+
+ public Mailbox getMailbox() {
+ return mailbox;
+ }
+
+ public ParseException getParseException() {
+ return parseException;
+ }
+
+ public static class Parser implements FieldParser {
+ private static Log log = LogFactory.getLog(Parser.class);
+
+ public Field parse(final String name, final String body, final String raw) {
+ Mailbox mailbox = null;
+ ParseException parseException = null;
+ try {
+ MailboxList mailboxList = AddressList.parse(body).flatten();
+ if (mailboxList.size() > 0) {
+ mailbox = mailboxList.get(0);
+ }
+ }
+ catch (ParseException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing value '" + body + "': "+ e.getMessage());
+ }
+ parseException = e;
+ }
+ return new MailboxField(name, body, raw, mailbox, parseException);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/MailboxListField.java b/src/org/apache/james/mime4j/field/MailboxListField.java
index efb18cd351a67c171aaff12e6209ea87ce033536..e5b986deac8c681fb0a6473c2670fb2a5363e6be 100644
--- a/src/org/apache/james/mime4j/field/MailboxListField.java
+++ b/src/org/apache/james/mime4j/field/MailboxListField.java
@@ -1,65 +1,65 @@
-/****************************************************************
- * 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.mime4j.field;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.field.address.AddressList;
-import org.apache.james.mime4j.field.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-public class MailboxListField extends Field {
-
- private MailboxList mailboxList;
- private ParseException parseException;
-
- protected MailboxListField(final String name, final String body, final String raw, final MailboxList mailboxList, final ParseException parseException) {
- super(name, body, raw);
- this.mailboxList = mailboxList;
- this.parseException = parseException;
- }
-
- public MailboxList getMailboxList() {
- return mailboxList;
- }
-
- public ParseException getParseException() {
- return parseException;
- }
-
- public static class Parser implements FieldParser {
- private static Log log = LogFactory.getLog(Parser.class);
-
- public Field parse(final String name, final String body, final String raw) {
- MailboxList mailboxList = null;
- ParseException parseException = null;
- try {
- mailboxList = AddressList.parse(body).flatten();
- }
- catch (ParseException e) {
- if (log.isDebugEnabled()) {
- log.debug("Parsing value '" + body + "': "+ e.getMessage());
- }
- parseException = e;
- }
- return new MailboxListField(name, body, raw, mailboxList, parseException);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.field.address.AddressList;
+import org.apache.james.mime4j.field.address.MailboxList;
+import org.apache.james.mime4j.field.address.parser.ParseException;
+
+public class MailboxListField extends Field {
+
+ private MailboxList mailboxList;
+ private ParseException parseException;
+
+ protected MailboxListField(final String name, final String body, final String raw, final MailboxList mailboxList, final ParseException parseException) {
+ super(name, body, raw);
+ this.mailboxList = mailboxList;
+ this.parseException = parseException;
+ }
+
+ public MailboxList getMailboxList() {
+ return mailboxList;
+ }
+
+ public ParseException getParseException() {
+ return parseException;
+ }
+
+ public static class Parser implements FieldParser {
+ private static Log log = LogFactory.getLog(Parser.class);
+
+ public Field parse(final String name, final String body, final String raw) {
+ MailboxList mailboxList = null;
+ ParseException parseException = null;
+ try {
+ mailboxList = AddressList.parse(body).flatten();
+ }
+ catch (ParseException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing value '" + body + "': "+ e.getMessage());
+ }
+ parseException = e;
+ }
+ return new MailboxListField(name, body, raw, mailboxList, parseException);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/UnstructuredField.java b/src/org/apache/james/mime4j/field/UnstructuredField.java
index 5e2adf9f2d11706875b6cbb9672218f530828a06..6084e44355be2623771c46c75b3a0ef76c35e3fb 100644
--- a/src/org/apache/james/mime4j/field/UnstructuredField.java
+++ b/src/org/apache/james/mime4j/field/UnstructuredField.java
@@ -1,49 +1,49 @@
-/****************************************************************
- * 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.mime4j.field;
-
-import org.apache.james.mime4j.decoder.DecoderUtil;
-
-
-/**
- * Simple unstructured field such as Subject
.
- *
- *
- * @version $Id: UnstructuredField.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
- */
-public class UnstructuredField extends Field {
- private String value;
-
- protected UnstructuredField(String name, String body, String raw, String value) {
- super(name, body, raw);
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- public static class Parser implements FieldParser {
- public Field parse(final String name, final String body, final String raw) {
- final String value = DecoderUtil.decodeEncodedWords(body);
- return new UnstructuredField(name, body, raw, value);
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field;
+
+import org.apache.james.mime4j.decoder.DecoderUtil;
+
+
+/**
+ * Simple unstructured field such as Subject
.
+ *
+ *
+ * @version $Id: UnstructuredField.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
+ */
+public class UnstructuredField extends Field {
+ private String value;
+
+ protected UnstructuredField(String name, String body, String raw, String value) {
+ super(name, body, raw);
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static class Parser implements FieldParser {
+ public Field parse(final String name, final String body, final String raw) {
+ final String value = DecoderUtil.decodeEncodedWords(body);
+ return new UnstructuredField(name, body, raw, value);
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/address/Address.java b/src/org/apache/james/mime4j/field/address/Address.java
index 47cee0ba018d2394e759860ec6a2cd18960385b8..5438eb5b269a003ad35c9c487b75d5e4005d28a2 100644
--- a/src/org/apache/james/mime4j/field/address/Address.java
+++ b/src/org/apache/james/mime4j/field/address/Address.java
@@ -1,52 +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.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * The abstract base for classes that represent RFC2822 addresses.
- * This includes groups and mailboxes.
- *
- * Currently, no public methods are introduced on this class.
- *
- *
- */
-public abstract class Address {
-
- /**
- * Adds any mailboxes represented by this address
- * into the given ArrayList. Note that this method
- * has default (package) access, so a doAddMailboxesTo
- * method is needed to allow the behavior to be
- * overridden by subclasses.
- */
- final void addMailboxesTo(ArrayList results) {
- doAddMailboxesTo(results);
- }
-
- /**
- * Adds any mailboxes represented by this address
- * into the given ArrayList. Must be overridden by
- * concrete subclasses.
- */
- protected abstract void doAddMailboxesTo(ArrayList results);
-
-}
+/****************************************************************
+ * 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.mime4j.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * The abstract base for classes that represent RFC2822 addresses.
+ * This includes groups and mailboxes.
+ *
+ * Currently, no public methods are introduced on this class.
+ *
+ *
+ */
+public abstract class Address {
+
+ /**
+ * Adds any mailboxes represented by this address
+ * into the given ArrayList. Note that this method
+ * has default (package) access, so a doAddMailboxesTo
+ * method is needed to allow the behavior to be
+ * overridden by subclasses.
+ */
+ final void addMailboxesTo(ArrayList results) {
+ doAddMailboxesTo(results);
+ }
+
+ /**
+ * Adds any mailboxes represented by this address
+ * into the given ArrayList. Must be overridden by
+ * concrete subclasses.
+ */
+ protected abstract void doAddMailboxesTo(ArrayList results);
+
+}
diff --git a/src/org/apache/james/mime4j/field/address/AddressList.java b/src/org/apache/james/mime4j/field/address/AddressList.java
index 75072bde4e1d63feb9ec4fb340afd71f3f7b24ff..f623239d083995b4677390976879d93730b9003f 100644
--- a/src/org/apache/james/mime4j/field/address/AddressList.java
+++ b/src/org/apache/james/mime4j/field/address/AddressList.java
@@ -1,140 +1,140 @@
-/****************************************************************
- * 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.mime4j.field.address;
-
-import org.apache.james.mime4j.field.address.parser.AddressListParser;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-
-/**
- * An immutable, random-access list of Address objects.
- *
- *
- */
-public class AddressList {
-
- private ArrayList addresses;
-
- /**
- * @param addresses An ArrayList that contains only Address objects.
- * @param dontCopy true iff it is not possible for the addresses ArrayList to be modified by someone else.
- */
- public AddressList(ArrayList addresses, boolean dontCopy) {
- if (addresses != null)
- this.addresses = (dontCopy ? addresses : (ArrayList) addresses.clone());
- else
- this.addresses = new ArrayList(0);
- }
-
- /**
- * The number of elements in this list.
- */
- public int size() {
- return addresses.size();
- }
-
- /**
- * Gets an address.
- */
- public Address get(int index) {
- if (0 > index || size() <= index)
- throw new IndexOutOfBoundsException();
- return (Address) addresses.get(index);
- }
-
- /**
- * Returns a flat list of all mailboxes represented
- * in this address list. Use this if you don't care
- * about grouping.
- */
- public MailboxList flatten() {
- // in the common case, all addresses are mailboxes
- boolean groupDetected = false;
- for (int i = 0; i < size(); i++) {
- if (!(get(i) instanceof Mailbox)) {
- groupDetected = true;
- break;
- }
- }
-
- if (!groupDetected)
- return new MailboxList(addresses, true);
-
- ArrayList results = new ArrayList();
- for (int i = 0; i < size(); i++) {
- Address addr = get(i);
- addr.addMailboxesTo(results);
- }
-
- // copy-on-construct this time, because subclasses
- // could have held onto a reference to the results
- return new MailboxList(results, false);
- }
-
- /**
- * Dumps a representation of this address list to
- * stdout, for debugging purposes.
- */
- public void print() {
- for (int i = 0; i < size(); i++) {
- Address addr = get(i);
- System.out.println(addr.toString());
- }
- }
-
-
-
- /**
- * Parse the address list string, such as the value
- * of a From, To, Cc, Bcc, Sender, or Reply-To
- * header.
- *
- * The string MUST be unfolded already.
- */
- public static AddressList parse(String rawAddressList) throws ParseException {
- AddressListParser parser = new AddressListParser(new StringReader(rawAddressList));
- return Builder.getInstance().buildAddressList(parser.parse());
- }
-
- /**
- * Test console.
- */
- public static void main(String[] args) throws Exception {
- java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
- while (true) {
- try {
- System.out.print("> ");
- String line = reader.readLine();
- if (line.length() == 0 || line.toLowerCase().equals("exit") || line.toLowerCase().equals("quit")) {
- System.out.println("Goodbye.");
- return;
- }
- AddressList list = parse(line);
- list.print();
- }
- catch(Exception e) {
- e.printStackTrace();
- Thread.sleep(300);
- }
- }
- }
-}
+/****************************************************************
+ * 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.mime4j.field.address;
+
+import org.apache.james.mime4j.field.address.parser.AddressListParser;
+import org.apache.james.mime4j.field.address.parser.ParseException;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+
+/**
+ * An immutable, random-access list of Address objects.
+ *
+ *
+ */
+public class AddressList {
+
+ private ArrayList addresses;
+
+ /**
+ * @param addresses An ArrayList that contains only Address objects.
+ * @param dontCopy true iff it is not possible for the addresses ArrayList to be modified by someone else.
+ */
+ public AddressList(ArrayList addresses, boolean dontCopy) {
+ if (addresses != null)
+ this.addresses = (dontCopy ? addresses : (ArrayList) addresses.clone());
+ else
+ this.addresses = new ArrayList(0);
+ }
+
+ /**
+ * The number of elements in this list.
+ */
+ public int size() {
+ return addresses.size();
+ }
+
+ /**
+ * Gets an address.
+ */
+ public Address get(int index) {
+ if (0 > index || size() <= index)
+ throw new IndexOutOfBoundsException();
+ return (Address) addresses.get(index);
+ }
+
+ /**
+ * Returns a flat list of all mailboxes represented
+ * in this address list. Use this if you don't care
+ * about grouping.
+ */
+ public MailboxList flatten() {
+ // in the common case, all addresses are mailboxes
+ boolean groupDetected = false;
+ for (int i = 0; i < size(); i++) {
+ if (!(get(i) instanceof Mailbox)) {
+ groupDetected = true;
+ break;
+ }
+ }
+
+ if (!groupDetected)
+ return new MailboxList(addresses, true);
+
+ ArrayList results = new ArrayList();
+ for (int i = 0; i < size(); i++) {
+ Address addr = get(i);
+ addr.addMailboxesTo(results);
+ }
+
+ // copy-on-construct this time, because subclasses
+ // could have held onto a reference to the results
+ return new MailboxList(results, false);
+ }
+
+ /**
+ * Dumps a representation of this address list to
+ * stdout, for debugging purposes.
+ */
+ public void print() {
+ for (int i = 0; i < size(); i++) {
+ Address addr = get(i);
+ System.out.println(addr.toString());
+ }
+ }
+
+
+
+ /**
+ * Parse the address list string, such as the value
+ * of a From, To, Cc, Bcc, Sender, or Reply-To
+ * header.
+ *
+ * The string MUST be unfolded already.
+ */
+ public static AddressList parse(String rawAddressList) throws ParseException {
+ AddressListParser parser = new AddressListParser(new StringReader(rawAddressList));
+ return Builder.getInstance().buildAddressList(parser.parse());
+ }
+
+ /**
+ * Test console.
+ */
+ public static void main(String[] args) throws Exception {
+ java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
+ while (true) {
+ try {
+ System.out.print("> ");
+ String line = reader.readLine();
+ if (line.length() == 0 || line.toLowerCase().equals("exit") || line.toLowerCase().equals("quit")) {
+ System.out.println("Goodbye.");
+ return;
+ }
+ AddressList list = parse(line);
+ list.print();
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ Thread.sleep(300);
+ }
+ }
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/address/Builder.java b/src/org/apache/james/mime4j/field/address/Builder.java
index 3699afed71f4a5089280443125be40448208b2a9..b17f4e3f7ad168b1632f775785d13d1f97139f64 100644
--- a/src/org/apache/james/mime4j/field/address/Builder.java
+++ b/src/org/apache/james/mime4j/field/address/Builder.java
@@ -1,244 +1,244 @@
-/****************************************************************
- * 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.mime4j.field.address;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.james.mime4j.decoder.DecoderUtil;
-import org.apache.james.mime4j.field.address.parser.*;
-import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
-import org.apache.james.mime4j.field.address.parser.ASTaddress;
-import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
-import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
-import org.apache.james.mime4j.field.address.parser.ASTdomain;
-import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
-import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
-import org.apache.james.mime4j.field.address.parser.ASTmailbox;
-import org.apache.james.mime4j.field.address.parser.ASTname_addr;
-import org.apache.james.mime4j.field.address.parser.ASTphrase;
-import org.apache.james.mime4j.field.address.parser.ASTroute;
-import org.apache.james.mime4j.field.address.parser.Node;
-import org.apache.james.mime4j.field.address.parser.SimpleNode;
-import org.apache.james.mime4j.field.address.parser.Token;
-
-/**
- * Transforms the JJTree-generated abstract syntax tree
- * into a graph of org.apache.james.mime4j.field.address objects.
- *
- *
- */
-class Builder {
-
- private static Builder singleton = new Builder();
-
- public static Builder getInstance() {
- return singleton;
- }
-
-
-
- public AddressList buildAddressList(ASTaddress_list node) {
- ArrayList list = new ArrayList();
- for (int i = 0; i < node.jjtGetNumChildren(); i++) {
- ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
- Address address = buildAddress(childNode);
- list.add(address);
- }
- return new AddressList(list, true);
- }
-
- private Address buildAddress(ASTaddress node) {
- ChildNodeIterator it = new ChildNodeIterator(node);
- Node n = it.nextNode();
- if (n instanceof ASTaddr_spec) {
- return buildAddrSpec((ASTaddr_spec)n);
- }
- else if (n instanceof ASTangle_addr) {
- return buildAngleAddr((ASTangle_addr)n);
- }
- else if (n instanceof ASTphrase) {
- String name = buildString((ASTphrase)n, false);
- Node n2 = it.nextNode();
- if (n2 instanceof ASTgroup_body) {
- return new Group(name, buildGroupBody((ASTgroup_body)n2));
- }
- else if (n2 instanceof ASTangle_addr) {
- name = DecoderUtil.decodeEncodedWords(name);
- return new NamedMailbox(name, buildAngleAddr((ASTangle_addr)n2));
- }
- else {
- throw new IllegalStateException();
- }
- }
- else {
- throw new IllegalStateException();
- }
- }
-
-
-
- private MailboxList buildGroupBody(ASTgroup_body node) {
- ArrayList results = new ArrayList();
- ChildNodeIterator it = new ChildNodeIterator(node);
- while (it.hasNext()) {
- Node n = it.nextNode();
- if (n instanceof ASTmailbox)
- results.add(buildMailbox((ASTmailbox)n));
- else
- throw new IllegalStateException();
- }
- return new MailboxList(results, true);
- }
-
- private Mailbox buildMailbox(ASTmailbox node) {
- ChildNodeIterator it = new ChildNodeIterator(node);
- Node n = it.nextNode();
- if (n instanceof ASTaddr_spec) {
- return buildAddrSpec((ASTaddr_spec)n);
- }
- else if (n instanceof ASTangle_addr) {
- return buildAngleAddr((ASTangle_addr)n);
- }
- else if (n instanceof ASTname_addr) {
- return buildNameAddr((ASTname_addr)n);
- }
- else {
- throw new IllegalStateException();
- }
- }
-
- private NamedMailbox buildNameAddr(ASTname_addr node) {
- ChildNodeIterator it = new ChildNodeIterator(node);
- Node n = it.nextNode();
- String name;
- if (n instanceof ASTphrase) {
- name = buildString((ASTphrase)n, false);
- }
- else {
- throw new IllegalStateException();
- }
-
- n = it.nextNode();
- if (n instanceof ASTangle_addr) {
- name = DecoderUtil.decodeEncodedWords(name);
- return new NamedMailbox(name, buildAngleAddr((ASTangle_addr) n));
- }
- else {
- throw new IllegalStateException();
- }
- }
-
- private Mailbox buildAngleAddr(ASTangle_addr node) {
- ChildNodeIterator it = new ChildNodeIterator(node);
- DomainList route = null;
- Node n = it.nextNode();
- if (n instanceof ASTroute) {
- route = buildRoute((ASTroute)n);
- n = it.nextNode();
- }
- else if (n instanceof ASTaddr_spec)
- ; // do nothing
- else
- throw new IllegalStateException();
-
- if (n instanceof ASTaddr_spec)
- return buildAddrSpec(route, (ASTaddr_spec)n);
- else
- throw new IllegalStateException();
- }
-
- private DomainList buildRoute(ASTroute node) {
- ArrayList results = new ArrayList(node.jjtGetNumChildren());
- ChildNodeIterator it = new ChildNodeIterator(node);
- while (it.hasNext()) {
- Node n = it.nextNode();
- if (n instanceof ASTdomain)
- results.add(buildString((ASTdomain)n, true));
- else
- throw new IllegalStateException();
- }
- return new DomainList(results, true);
- }
-
- private Mailbox buildAddrSpec(ASTaddr_spec node) {
- return buildAddrSpec(null, node);
- }
- private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
- ChildNodeIterator it = new ChildNodeIterator(node);
- String localPart = buildString((ASTlocal_part)it.nextNode(), true);
- String domain = buildString((ASTdomain)it.nextNode(), true);
- return new Mailbox(route, localPart, domain);
- }
-
-
- private String buildString(SimpleNode node, boolean stripSpaces) {
- Token head = node.firstToken;
- Token tail = node.lastToken;
- StringBuffer out = new StringBuffer();
-
- while (head != tail) {
- out.append(head.image);
- head = head.next;
- if (!stripSpaces)
- addSpecials(out, head.specialToken);
- }
- out.append(tail.image);
-
- return out.toString();
- }
-
- private void addSpecials(StringBuffer out, Token specialToken) {
- if (specialToken != null) {
- addSpecials(out, specialToken.specialToken);
- out.append(specialToken.image);
- }
- }
-
- private static class ChildNodeIterator implements Iterator {
-
- private SimpleNode simpleNode;
- private int index;
- private int len;
-
- public ChildNodeIterator(SimpleNode simpleNode) {
- this.simpleNode = simpleNode;
- this.len = simpleNode.jjtGetNumChildren();
- this.index = 0;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public boolean hasNext() {
- return index < len;
- }
-
- public Object next() {
- return nextNode();
- }
-
- public Node nextNode() {
- return simpleNode.jjtGetChild(index++);
- }
-
- }
-}
+/****************************************************************
+ * 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.mime4j.field.address;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.decoder.DecoderUtil;
+import org.apache.james.mime4j.field.address.parser.*;
+import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
+import org.apache.james.mime4j.field.address.parser.ASTaddress;
+import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
+import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
+import org.apache.james.mime4j.field.address.parser.ASTdomain;
+import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
+import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
+import org.apache.james.mime4j.field.address.parser.ASTmailbox;
+import org.apache.james.mime4j.field.address.parser.ASTname_addr;
+import org.apache.james.mime4j.field.address.parser.ASTphrase;
+import org.apache.james.mime4j.field.address.parser.ASTroute;
+import org.apache.james.mime4j.field.address.parser.Node;
+import org.apache.james.mime4j.field.address.parser.SimpleNode;
+import org.apache.james.mime4j.field.address.parser.Token;
+
+/**
+ * Transforms the JJTree-generated abstract syntax tree
+ * into a graph of org.apache.james.mime4j.field.address objects.
+ *
+ *
+ */
+class Builder {
+
+ private static Builder singleton = new Builder();
+
+ public static Builder getInstance() {
+ return singleton;
+ }
+
+
+
+ public AddressList buildAddressList(ASTaddress_list node) {
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < node.jjtGetNumChildren(); i++) {
+ ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
+ Address address = buildAddress(childNode);
+ list.add(address);
+ }
+ return new AddressList(list, true);
+ }
+
+ private Address buildAddress(ASTaddress node) {
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ Node n = it.nextNode();
+ if (n instanceof ASTaddr_spec) {
+ return buildAddrSpec((ASTaddr_spec)n);
+ }
+ else if (n instanceof ASTangle_addr) {
+ return buildAngleAddr((ASTangle_addr)n);
+ }
+ else if (n instanceof ASTphrase) {
+ String name = buildString((ASTphrase)n, false);
+ Node n2 = it.nextNode();
+ if (n2 instanceof ASTgroup_body) {
+ return new Group(name, buildGroupBody((ASTgroup_body)n2));
+ }
+ else if (n2 instanceof ASTangle_addr) {
+ name = DecoderUtil.decodeEncodedWords(name);
+ return new NamedMailbox(name, buildAngleAddr((ASTangle_addr)n2));
+ }
+ else {
+ throw new IllegalStateException();
+ }
+ }
+ else {
+ throw new IllegalStateException();
+ }
+ }
+
+
+
+ private MailboxList buildGroupBody(ASTgroup_body node) {
+ ArrayList results = new ArrayList();
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ while (it.hasNext()) {
+ Node n = it.nextNode();
+ if (n instanceof ASTmailbox)
+ results.add(buildMailbox((ASTmailbox)n));
+ else
+ throw new IllegalStateException();
+ }
+ return new MailboxList(results, true);
+ }
+
+ private Mailbox buildMailbox(ASTmailbox node) {
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ Node n = it.nextNode();
+ if (n instanceof ASTaddr_spec) {
+ return buildAddrSpec((ASTaddr_spec)n);
+ }
+ else if (n instanceof ASTangle_addr) {
+ return buildAngleAddr((ASTangle_addr)n);
+ }
+ else if (n instanceof ASTname_addr) {
+ return buildNameAddr((ASTname_addr)n);
+ }
+ else {
+ throw new IllegalStateException();
+ }
+ }
+
+ private NamedMailbox buildNameAddr(ASTname_addr node) {
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ Node n = it.nextNode();
+ String name;
+ if (n instanceof ASTphrase) {
+ name = buildString((ASTphrase)n, false);
+ }
+ else {
+ throw new IllegalStateException();
+ }
+
+ n = it.nextNode();
+ if (n instanceof ASTangle_addr) {
+ name = DecoderUtil.decodeEncodedWords(name);
+ return new NamedMailbox(name, buildAngleAddr((ASTangle_addr) n));
+ }
+ else {
+ throw new IllegalStateException();
+ }
+ }
+
+ private Mailbox buildAngleAddr(ASTangle_addr node) {
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ DomainList route = null;
+ Node n = it.nextNode();
+ if (n instanceof ASTroute) {
+ route = buildRoute((ASTroute)n);
+ n = it.nextNode();
+ }
+ else if (n instanceof ASTaddr_spec)
+ ; // do nothing
+ else
+ throw new IllegalStateException();
+
+ if (n instanceof ASTaddr_spec)
+ return buildAddrSpec(route, (ASTaddr_spec)n);
+ else
+ throw new IllegalStateException();
+ }
+
+ private DomainList buildRoute(ASTroute node) {
+ ArrayList results = new ArrayList(node.jjtGetNumChildren());
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ while (it.hasNext()) {
+ Node n = it.nextNode();
+ if (n instanceof ASTdomain)
+ results.add(buildString((ASTdomain)n, true));
+ else
+ throw new IllegalStateException();
+ }
+ return new DomainList(results, true);
+ }
+
+ private Mailbox buildAddrSpec(ASTaddr_spec node) {
+ return buildAddrSpec(null, node);
+ }
+ private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
+ ChildNodeIterator it = new ChildNodeIterator(node);
+ String localPart = buildString((ASTlocal_part)it.nextNode(), true);
+ String domain = buildString((ASTdomain)it.nextNode(), true);
+ return new Mailbox(route, localPart, domain);
+ }
+
+
+ private String buildString(SimpleNode node, boolean stripSpaces) {
+ Token head = node.firstToken;
+ Token tail = node.lastToken;
+ StringBuffer out = new StringBuffer();
+
+ while (head != tail) {
+ out.append(head.image);
+ head = head.next;
+ if (!stripSpaces)
+ addSpecials(out, head.specialToken);
+ }
+ out.append(tail.image);
+
+ return out.toString();
+ }
+
+ private void addSpecials(StringBuffer out, Token specialToken) {
+ if (specialToken != null) {
+ addSpecials(out, specialToken.specialToken);
+ out.append(specialToken.image);
+ }
+ }
+
+ private static class ChildNodeIterator implements Iterator {
+
+ private SimpleNode simpleNode;
+ private int index;
+ private int len;
+
+ public ChildNodeIterator(SimpleNode simpleNode) {
+ this.simpleNode = simpleNode;
+ this.len = simpleNode.jjtGetNumChildren();
+ this.index = 0;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasNext() {
+ return index < len;
+ }
+
+ public Object next() {
+ return nextNode();
+ }
+
+ public Node nextNode() {
+ return simpleNode.jjtGetChild(index++);
+ }
+
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/address/DomainList.java b/src/org/apache/james/mime4j/field/address/DomainList.java
index 23c377e9e868ff776e6ca46e94f8d561d6f3d92b..d90b2228575e41d69c4f3099746fcab555ca799a 100644
--- a/src/org/apache/james/mime4j/field/address/DomainList.java
+++ b/src/org/apache/james/mime4j/field/address/DomainList.java
@@ -1,76 +1,76 @@
-/****************************************************************
- * 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.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * An immutable, random-access list of Strings (that
- * are supposedly domain names or domain literals).
- *
- *
- */
-public class DomainList {
- private ArrayList domains;
-
- /**
- * @param domains An ArrayList that contains only String objects.
- * @param dontCopy true iff it is not possible for the domains ArrayList to be modified by someone else.
- */
- public DomainList(ArrayList domains, boolean dontCopy) {
- if (domains != null)
- this.domains = (dontCopy ? domains : (ArrayList) domains.clone());
- else
- this.domains = new ArrayList(0);
- }
-
- /**
- * The number of elements in this list.
- */
- public int size() {
- return domains.size();
- }
-
- /**
- * Gets the domain name or domain literal at the
- * specified index.
- * @throws IndexOutOfBoundsException If index is < 0 or >= size().
- */
- public String get(int index) {
- if (0 > index || size() <= index)
- throw new IndexOutOfBoundsException();
- return (String) domains.get(index);
- }
-
- /**
- * Returns the list of domains formatted as a route
- * string (not including the trailing ':').
- */
- public String toRouteString() {
- StringBuffer out = new StringBuffer();
- for (int i = 0; i < domains.size(); i++) {
- out.append("@");
- out.append(get(i));
- if (i + 1 < domains.size())
- out.append(",");
- }
- return out.toString();
- }
-}
+/****************************************************************
+ * 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.mime4j.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * An immutable, random-access list of Strings (that
+ * are supposedly domain names or domain literals).
+ *
+ *
+ */
+public class DomainList {
+ private ArrayList domains;
+
+ /**
+ * @param domains An ArrayList that contains only String objects.
+ * @param dontCopy true iff it is not possible for the domains ArrayList to be modified by someone else.
+ */
+ public DomainList(ArrayList domains, boolean dontCopy) {
+ if (domains != null)
+ this.domains = (dontCopy ? domains : (ArrayList) domains.clone());
+ else
+ this.domains = new ArrayList(0);
+ }
+
+ /**
+ * The number of elements in this list.
+ */
+ public int size() {
+ return domains.size();
+ }
+
+ /**
+ * Gets the domain name or domain literal at the
+ * specified index.
+ * @throws IndexOutOfBoundsException If index is < 0 or >= size().
+ */
+ public String get(int index) {
+ if (0 > index || size() <= index)
+ throw new IndexOutOfBoundsException();
+ return (String) domains.get(index);
+ }
+
+ /**
+ * Returns the list of domains formatted as a route
+ * string (not including the trailing ':').
+ */
+ public String toRouteString() {
+ StringBuffer out = new StringBuffer();
+ for (int i = 0; i < domains.size(); i++) {
+ out.append("@");
+ out.append(get(i));
+ if (i + 1 < domains.size())
+ out.append(",");
+ }
+ return out.toString();
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/address/Group.java b/src/org/apache/james/mime4j/field/address/Group.java
index eb4002708ebd926cba2f662f7cb33867be37153a..63e294549e7ae957a8b3e0f5b99d59c68eb9149d 100644
--- a/src/org/apache/james/mime4j/field/address/Group.java
+++ b/src/org/apache/james/mime4j/field/address/Group.java
@@ -1,73 +1,73 @@
-/****************************************************************
- * 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.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * A named group of zero or more mailboxes.
- *
- *
- */
-public class Group extends Address {
- private String name;
- private MailboxList mailboxList;
-
- /**
- * @param name The group name.
- * @param mailboxes The mailboxes in this group.
- */
- public Group(String name, MailboxList mailboxes) {
- this.name = name;
- this.mailboxList = mailboxes;
- }
-
- /**
- * Returns the group name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the mailboxes in this group.
- */
- public MailboxList getMailboxes() {
- return mailboxList;
- }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append(name);
- buf.append(":");
- for (int i = 0; i < mailboxList.size(); i++) {
- buf.append(mailboxList.get(i).toString());
- if (i + 1 < mailboxList.size())
- buf.append(",");
- }
- buf.append(";");
- return buf.toString();
- }
-
- protected void doAddMailboxesTo(ArrayList results) {
- for (int i = 0; i < mailboxList.size(); i++)
- results.add(mailboxList.get(i));
- }
-}
+/****************************************************************
+ * 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.mime4j.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * A named group of zero or more mailboxes.
+ *
+ *
+ */
+public class Group extends Address {
+ private String name;
+ private MailboxList mailboxList;
+
+ /**
+ * @param name The group name.
+ * @param mailboxes The mailboxes in this group.
+ */
+ public Group(String name, MailboxList mailboxes) {
+ this.name = name;
+ this.mailboxList = mailboxes;
+ }
+
+ /**
+ * Returns the group name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the mailboxes in this group.
+ */
+ public MailboxList getMailboxes() {
+ return mailboxList;
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append(name);
+ buf.append(":");
+ for (int i = 0; i < mailboxList.size(); i++) {
+ buf.append(mailboxList.get(i).toString());
+ if (i + 1 < mailboxList.size())
+ buf.append(",");
+ }
+ buf.append(";");
+ return buf.toString();
+ }
+
+ protected void doAddMailboxesTo(ArrayList results) {
+ for (int i = 0; i < mailboxList.size(); i++)
+ results.add(mailboxList.get(i));
+ }
+}
diff --git a/src/org/apache/james/mime4j/field/address/Mailbox.java b/src/org/apache/james/mime4j/field/address/Mailbox.java
index 57668abfe9596e73e62cab2c421e8931eebbcaf8..1bc32b8187637cafd0e90eb54f72f5f694cd210e 100644
--- a/src/org/apache/james/mime4j/field/address/Mailbox.java
+++ b/src/org/apache/james/mime4j/field/address/Mailbox.java
@@ -1,119 +1,119 @@
-/****************************************************************
- * 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.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * Represents a single e-mail address.
- *
- *
- */
-public class Mailbox extends Address {
- private DomainList route;
- private String localPart;
- private String domain;
-
- /**
- * Creates a mailbox without a route. Routes are obsolete.
- * @param localPart The part of the e-mail address to the left of the "@".
- * @param domain The part of the e-mail address to the right of the "@".
- */
- public Mailbox(String localPart, String domain) {
- this(null, localPart, domain);
- }
-
- /**
- * Creates a mailbox with a route. Routes are obsolete.
- * @param route The zero or more domains that make up the route. Can be null.
- * @param localPart The part of the e-mail address to the left of the "@".
- * @param domain The part of the e-mail address to the right of the "@".
- */
- public Mailbox(DomainList route, String localPart, String domain) {
- this.route = route;
- this.localPart = localPart;
- this.domain = domain;
- }
-
- /**
- * Returns the route list.
- */
- public DomainList getRoute() {
- return route;
- }
-
- /**
- * Returns the left part of the e-mail address
- * (before "@").
- */
- public String getLocalPart() {
- return localPart;
- }
-
- /**
- * Returns the right part of the e-mail address
- * (after "@").
- */
- public String getDomain() {
- return domain;
- }
-
- /**
- * Formats the address as a string, not including
- * the route.
- *
- * @see #getAddressString(boolean)
- */
- public String getAddressString() {
- return getAddressString(false);
- }
-
- /**
- * Note that this value may not be usable
- * for transport purposes, only display purposes.
- *
- * For example, if the unparsed address was
- *
- * <"Joe Cheng"@joecheng.com>
- *
- * this method would return
- *
- * Body
implementation providing the parent
- * functionality required by bodies.
- *
- *
- * @version $Id: AbstractBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public abstract class AbstractBody implements Body {
- private Entity parent = null;
-
- /**
- * @see org.apache.james.mime4j.message.Body#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- }
-
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+
+/**
+ * Abstract Body
implementation providing the parent
+ * functionality required by bodies.
+ *
+ *
+ * @version $Id: AbstractBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public abstract class AbstractBody implements Body {
+ private Entity parent = null;
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+}
diff --git a/src/org/apache/james/mime4j/message/BinaryBody.java b/src/org/apache/james/mime4j/message/BinaryBody.java
index bfc992a8fe34cefd81d2a38ad98e3f46f3ef6df9..fc05a7d8a9a984432a7fdc89233c8d4c4133779a 100644
--- a/src/org/apache/james/mime4j/message/BinaryBody.java
+++ b/src/org/apache/james/mime4j/message/BinaryBody.java
@@ -1,42 +1,42 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * Interface implemented by bodies containing binary data.
- *
- *
- * @version $Id: BinaryBody.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public interface BinaryBody extends Body {
-
- /**
- * Gets a InputStream
which reads the bytes of the
- * body.
- *
- * @return the stream.
- * @throws IOException on I/O errors.
- */
- InputStream getInputStream() throws IOException;
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Interface implemented by bodies containing binary data.
+ *
+ *
+ * @version $Id: BinaryBody.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public interface BinaryBody extends Body {
+
+ /**
+ * Gets a InputStream
which reads the bytes of the
+ * body.
+ *
+ * @return the stream.
+ * @throws IOException on I/O errors.
+ */
+ InputStream getInputStream() throws IOException;
+}
diff --git a/src/org/apache/james/mime4j/message/Body.java b/src/org/apache/james/mime4j/message/Body.java
index 54b8948dbbd1a4e1f19a51f56b3f4f76229d301a..5d9b3819065c08433a77abae1a6f9e9a5b58a281 100644
--- a/src/org/apache/james/mime4j/message/Body.java
+++ b/src/org/apache/james/mime4j/message/Body.java
@@ -1,54 +1,54 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Encapsulates the body of an entity (see RFC 2045).
- *
- *
- * @version $Id: Body.java,v 1.4 2004/10/04 15:36:43 ntherning Exp $
- */
-public interface Body {
-
- /**
- * Gets the parent of this body.
- *
- * @return the parent.
- */
- Entity getParent();
-
- /**
- * Sets the parent of this body.
- *
- * @param parent the parent.
- */
- void setParent(Entity parent);
-
- /**
- * Writes this body to the given stream in MIME message format.
- *
- * @param out the stream to write to.
- * @throws IOException on I/O errors.
- */
- void writeTo(OutputStream out) throws IOException;
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Encapsulates the body of an entity (see RFC 2045).
+ *
+ *
+ * @version $Id: Body.java,v 1.4 2004/10/04 15:36:43 ntherning Exp $
+ */
+public interface Body {
+
+ /**
+ * Gets the parent of this body.
+ *
+ * @return the parent.
+ */
+ Entity getParent();
+
+ /**
+ * Sets the parent of this body.
+ *
+ * @param parent the parent.
+ */
+ void setParent(Entity parent);
+
+ /**
+ * Writes this body to the given stream in MIME message format.
+ *
+ * @param out the stream to write to.
+ * @throws IOException on I/O errors.
+ */
+ void writeTo(OutputStream out) throws IOException;
+}
diff --git a/src/org/apache/james/mime4j/message/BodyPart.java b/src/org/apache/james/mime4j/message/BodyPart.java
index 474030d7f5ec4f4ead376176501dfbbbb6928251..76401833668e3bcc2823d8fa3ff9c2d7251a9ec8 100644
--- a/src/org/apache/james/mime4j/message/BodyPart.java
+++ b/src/org/apache/james/mime4j/message/BodyPart.java
@@ -1,42 +1,42 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/**
- * Represents a MIME body part (see RFC 2045).
- *
- *
- * @version $Id: BodyPart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public class BodyPart extends Entity {
-
- /**
- *
- * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- getHeader().writeTo(out);
- getBody().writeTo(out);
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * Represents a MIME body part (see RFC 2045).
+ *
+ *
+ * @version $Id: BodyPart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class BodyPart extends Entity {
+
+ /**
+ *
+ * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ getHeader().writeTo(out);
+ getBody().writeTo(out);
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/Entity.java b/src/org/apache/james/mime4j/message/Entity.java
index 96f2a4875ff6f7e598e95ac7dc08ba9e2d89f0fa..06039f3d784feb9b7d9ba18ca9948087688bdf85 100644
--- a/src/org/apache/james/mime4j/message/Entity.java
+++ b/src/org/apache/james/mime4j/message/Entity.java
@@ -1,170 +1,170 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.james.mime4j.field.ContentTransferEncodingField;
-import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
-
-/**
- * MIME entity. An entity has a header and a body (see RFC 2045).
- *
- *
- * @version $Id: Entity.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public abstract class Entity {
- private Header header = null;
- private Body body = null;
- private Entity parent = null;
-
- /**
- * Gets the parent entity of this entity.
- * Returns null
if this is the root entity.
- *
- * @return the parent or null
.
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * Sets the parent entity of this entity.
- *
- * @param parent the parent entity or null
if
- * this will be the root entity.
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- }
-
- /**
- * Gets the entity header.
- *
- * @return the header.
- */
- public Header getHeader() {
- return header;
- }
-
- /**
- * Sets the entity header.
- *
- * @param header the header.
- */
- public void setHeader(Header header) {
- this.header = header;
- }
-
- /**
- * Gets the body of this entity.
- *
- * @return the body,
- */
- public Body getBody() {
- return body;
- }
-
- /**
- * Sets the body of this entity.
- *
- * @param body the body.
- */
- public void setBody(Body body) {
- this.body = body;
- body.setParent(this);
- }
-
- /**
- * Determines the MIME type of this Entity
. The MIME type
- * is derived by looking at the parent's Content-Type field if no
- * Content-Type field is set for this Entity
.
- *
- * @return the MIME type.
- */
- public String getMimeType() {
- ContentTypeField child =
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
- ContentTypeField parent = getParent() != null
- ? (ContentTypeField) getParent().getHeader().
- getField(Field.CONTENT_TYPE)
- : null;
-
- return ContentTypeField.getMimeType(child, parent);
- }
-
- /**
- * Determines the MIME character set encoding of this Entity
.
- *
- * @return the MIME character set encoding.
- */
- public String getCharset() {
- return ContentTypeField.getCharset(
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
- }
-
- /**
- * Determines the transfer encoding of this Entity
.
- *
- * @return the transfer encoding.
- */
- public String getContentTransferEncoding() {
- ContentTransferEncodingField f = (ContentTransferEncodingField)
- getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
-
- return ContentTransferEncodingField.getEncoding(f);
- }
-
- /**
- * Determines if the MIME type of this Entity
matches the
- * given one. MIME types are case-insensitive.
- *
- * @param type the MIME type to match against.
- * @return true
on match, false
otherwise.
- */
- public boolean isMimeType(String type) {
- return getMimeType().equalsIgnoreCase(type);
- }
-
- /**
- * Determines if the MIME type of this Entity
is
- * multipart/*
. Since multipart-entities must have
- * a boundary parameter in the Content-Type
field this
- * method returns false
if no boundary exists.
- *
- * @return true
on match, false
otherwise.
- */
- public boolean isMultipart() {
- ContentTypeField f =
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
- return f != null && f.getBoundary() != null
- && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
- }
-
- /**
- * Write the content to the given outputstream
- *
- * @param out the outputstream to write to
- * @throws IOException
- */
- public abstract void writeTo(OutputStream out) throws IOException;
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.james.mime4j.field.ContentTransferEncodingField;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+
+/**
+ * MIME entity. An entity has a header and a body (see RFC 2045).
+ *
+ *
+ * @version $Id: Entity.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public abstract class Entity {
+ private Header header = null;
+ private Body body = null;
+ private Entity parent = null;
+
+ /**
+ * Gets the parent entity of this entity.
+ * Returns null
if this is the root entity.
+ *
+ * @return the parent or null
.
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * Sets the parent entity of this entity.
+ *
+ * @param parent the parent entity or null
if
+ * this will be the root entity.
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Gets the entity header.
+ *
+ * @return the header.
+ */
+ public Header getHeader() {
+ return header;
+ }
+
+ /**
+ * Sets the entity header.
+ *
+ * @param header the header.
+ */
+ public void setHeader(Header header) {
+ this.header = header;
+ }
+
+ /**
+ * Gets the body of this entity.
+ *
+ * @return the body,
+ */
+ public Body getBody() {
+ return body;
+ }
+
+ /**
+ * Sets the body of this entity.
+ *
+ * @param body the body.
+ */
+ public void setBody(Body body) {
+ this.body = body;
+ body.setParent(this);
+ }
+
+ /**
+ * Determines the MIME type of this Entity
. The MIME type
+ * is derived by looking at the parent's Content-Type field if no
+ * Content-Type field is set for this Entity
.
+ *
+ * @return the MIME type.
+ */
+ public String getMimeType() {
+ ContentTypeField child =
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+ ContentTypeField parent = getParent() != null
+ ? (ContentTypeField) getParent().getHeader().
+ getField(Field.CONTENT_TYPE)
+ : null;
+
+ return ContentTypeField.getMimeType(child, parent);
+ }
+
+ /**
+ * Determines the MIME character set encoding of this Entity
.
+ *
+ * @return the MIME character set encoding.
+ */
+ public String getCharset() {
+ return ContentTypeField.getCharset(
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
+ }
+
+ /**
+ * Determines the transfer encoding of this Entity
.
+ *
+ * @return the transfer encoding.
+ */
+ public String getContentTransferEncoding() {
+ ContentTransferEncodingField f = (ContentTransferEncodingField)
+ getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
+
+ return ContentTransferEncodingField.getEncoding(f);
+ }
+
+ /**
+ * Determines if the MIME type of this Entity
matches the
+ * given one. MIME types are case-insensitive.
+ *
+ * @param type the MIME type to match against.
+ * @return true
on match, false
otherwise.
+ */
+ public boolean isMimeType(String type) {
+ return getMimeType().equalsIgnoreCase(type);
+ }
+
+ /**
+ * Determines if the MIME type of this Entity
is
+ * multipart/*
. Since multipart-entities must have
+ * a boundary parameter in the Content-Type
field this
+ * method returns false
if no boundary exists.
+ *
+ * @return true
on match, false
otherwise.
+ */
+ public boolean isMultipart() {
+ ContentTypeField f =
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+ return f != null && f.getBoundary() != null
+ && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
+ }
+
+ /**
+ * Write the content to the given outputstream
+ *
+ * @param out the outputstream to write to
+ * @throws IOException
+ */
+ public abstract void writeTo(OutputStream out) throws IOException;
+}
diff --git a/src/org/apache/james/mime4j/message/Header.java b/src/org/apache/james/mime4j/message/Header.java
index 90a0ef4802ab511bfb569c5c9320b79061b10c47..3e974647910ce5c56e8fdb6390e6938530db2313 100644
--- a/src/org/apache/james/mime4j/message/Header.java
+++ b/src/org/apache/james/mime4j/message/Header.java
@@ -1,155 +1,155 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.james.mime4j.AbstractContentHandler;
-import org.apache.james.mime4j.MimeStreamParser;
-import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.util.CharsetUtil;
-
-
-/**
- * The header of an entity (see RFC 2045).
- *
- *
- * @version $Id: Header.java,v 1.3 2004/10/04 15:36:44 ntherning Exp $
- */
-public class Header {
- private List fields = new LinkedList();
- private HashMap fieldMap = new HashMap();
-
- /**
- * Creates a new empty Header
.
- */
- public Header() {
- }
-
- /**
- * Creates a new Header
from the specified stream.
- *
- * @param is the stream to read the header from.
- */
- public Header(InputStream is) throws IOException {
- final MimeStreamParser parser = new MimeStreamParser();
- parser.setContentHandler(new AbstractContentHandler() {
- public void endHeader() {
- parser.stop();
- }
- public void field(String fieldData) {
- addField(Field.parse(fieldData));
- }
- });
- parser.parse(is);
- }
-
- /**
- * Adds a field to the end of the list of fields.
- *
- * @param field the field to add.
- */
- public void addField(Field field) {
- List values = (List) fieldMap.get(field.getName().toLowerCase());
- if (values == null) {
- values = new LinkedList();
- fieldMap.put(field.getName().toLowerCase(), values);
- }
- values.add(field);
- fields.add(field);
- }
-
- /**
- * Gets the fields of this header. The returned list will not be
- * modifiable.
- *
- * @return the list of Field
objects.
- */
- public List getFields() {
- return Collections.unmodifiableList(fields);
- }
-
- /**
- * Gets a Field
given a field name. If there are multiple
- * such fields defined in this header the first one will be returned.
- *
- * @param name the field name (e.g. From, Subject).
- * @return the field or null
if none found.
- */
- public Field getField(String name) {
- List l = (List) fieldMap.get(name.toLowerCase());
- if (l != null && !l.isEmpty()) {
- return (Field) l.get(0);
- }
- return null;
- }
-
- /**
- * Gets all Field
s having the specified field name.
- *
- * @param name the field name (e.g. From, Subject).
- * @return the list of fields.
- */
- public List getFields(String name) {
- List l = (List) fieldMap.get(name.toLowerCase());
- return Collections.unmodifiableList(l);
- }
-
- /**
- * Return Header Object as String representation. Each headerline is
- * seperated by "\r\n"
- *
- * @return headers
- */
- public String toString() {
- StringBuffer str = new StringBuffer();
- for (Iterator it = fields.iterator(); it.hasNext();) {
- str.append(it.next().toString());
- str.append("\r\n");
- }
- return str.toString();
- }
-
-
- /**
- * Write the Header to the given OutputStream
- *
- * @param out the OutputStream to write to
- * @throws IOException
- */
- public void writeTo(OutputStream out) throws IOException {
- String charString = ((ContentTypeField) getField(Field.CONTENT_TYPE)).getCharset();
-
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(charString)),8192);
- writer.write(toString()+ "\r\n");
- writer.flush();
- }
-
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.AbstractContentHandler;
+import org.apache.james.mime4j.MimeStreamParser;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+
+/**
+ * The header of an entity (see RFC 2045).
+ *
+ *
+ * @version $Id: Header.java,v 1.3 2004/10/04 15:36:44 ntherning Exp $
+ */
+public class Header {
+ private List fields = new LinkedList();
+ private HashMap fieldMap = new HashMap();
+
+ /**
+ * Creates a new empty Header
.
+ */
+ public Header() {
+ }
+
+ /**
+ * Creates a new Header
from the specified stream.
+ *
+ * @param is the stream to read the header from.
+ */
+ public Header(InputStream is) throws IOException {
+ final MimeStreamParser parser = new MimeStreamParser();
+ parser.setContentHandler(new AbstractContentHandler() {
+ public void endHeader() {
+ parser.stop();
+ }
+ public void field(String fieldData) {
+ addField(Field.parse(fieldData));
+ }
+ });
+ parser.parse(is);
+ }
+
+ /**
+ * Adds a field to the end of the list of fields.
+ *
+ * @param field the field to add.
+ */
+ public void addField(Field field) {
+ List values = (List) fieldMap.get(field.getName().toLowerCase());
+ if (values == null) {
+ values = new LinkedList();
+ fieldMap.put(field.getName().toLowerCase(), values);
+ }
+ values.add(field);
+ fields.add(field);
+ }
+
+ /**
+ * Gets the fields of this header. The returned list will not be
+ * modifiable.
+ *
+ * @return the list of Field
objects.
+ */
+ public List getFields() {
+ return Collections.unmodifiableList(fields);
+ }
+
+ /**
+ * Gets a Field
given a field name. If there are multiple
+ * such fields defined in this header the first one will be returned.
+ *
+ * @param name the field name (e.g. From, Subject).
+ * @return the field or null
if none found.
+ */
+ public Field getField(String name) {
+ List l = (List) fieldMap.get(name.toLowerCase());
+ if (l != null && !l.isEmpty()) {
+ return (Field) l.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Gets all Field
s having the specified field name.
+ *
+ * @param name the field name (e.g. From, Subject).
+ * @return the list of fields.
+ */
+ public List getFields(String name) {
+ List l = (List) fieldMap.get(name.toLowerCase());
+ return Collections.unmodifiableList(l);
+ }
+
+ /**
+ * Return Header Object as String representation. Each headerline is
+ * seperated by "\r\n"
+ *
+ * @return headers
+ */
+ public String toString() {
+ StringBuffer str = new StringBuffer();
+ for (Iterator it = fields.iterator(); it.hasNext();) {
+ str.append(it.next().toString());
+ str.append("\r\n");
+ }
+ return str.toString();
+ }
+
+
+ /**
+ * Write the Header to the given OutputStream
+ *
+ * @param out the OutputStream to write to
+ * @throws IOException
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ String charString = ((ContentTypeField) getField(Field.CONTENT_TYPE)).getCharset();
+
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(charString)),8192);
+ writer.write(toString()+ "\r\n");
+ writer.flush();
+ }
+
+}
diff --git a/src/org/apache/james/mime4j/message/MemoryBinaryBody.java b/src/org/apache/james/mime4j/message/MemoryBinaryBody.java
index 0db44e199b7ce8afa5ebb797ec20fb7b3aa07015..fb78ff0802b1a64837a84ddf1bfdf6e1f7595ee9 100644
--- a/src/org/apache/james/mime4j/message/MemoryBinaryBody.java
+++ b/src/org/apache/james/mime4j/message/MemoryBinaryBody.java
@@ -1,90 +1,90 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.util.TempPath;
-import org.apache.james.mime4j.util.TempStorage;
-
-
-/**
- * Binary body backed by a {@link org.apache.james.mime4j.util.TempFile}.
- *
- *
- * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-class MemoryBinaryBody extends AbstractBody implements BinaryBody {
- private static Log log = LogFactory.getLog(MemoryBinaryBody.class);
-
- private Entity parent = null;
- private byte[] tempFile = null;
-
- /**
- * Use the given InputStream to build the TemporyFileBinaryBody
- *
- * @param is the InputStream to use as source
- * @throws IOException
- */
- public MemoryBinaryBody(InputStream is) throws IOException {
-
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- IOUtils.copy(is, out);
- out.close();
- tempFile = out.toByteArray();
- }
-
- /**
- * @see org.apache.james.mime4j.message.AbstractBody#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
- */
- public InputStream getInputStream() throws IOException {
- return new ByteArrayInputStream(tempFile);
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- IOUtils.copy(getInputStream(),out);
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.TempPath;
+import org.apache.james.mime4j.util.TempStorage;
+
+
+/**
+ * Binary body backed by a {@link org.apache.james.mime4j.util.TempFile}.
+ *
+ *
+ * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+class MemoryBinaryBody extends AbstractBody implements BinaryBody {
+ private static Log log = LogFactory.getLog(MemoryBinaryBody.class);
+
+ private Entity parent = null;
+ private byte[] tempFile = null;
+
+ /**
+ * Use the given InputStream to build the TemporyFileBinaryBody
+ *
+ * @param is the InputStream to use as source
+ * @throws IOException
+ */
+ public MemoryBinaryBody(InputStream is) throws IOException {
+
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ tempFile = out.toByteArray();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.AbstractBody#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(tempFile);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ IOUtils.copy(getInputStream(),out);
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/MemoryTextBody.java b/src/org/apache/james/mime4j/message/MemoryTextBody.java
index e5e9d9d728cd1dbbe3a269d6ba041a58e9cf9dc2..ce4318a4da59a7d5d386df333fecefb7ae9c911b 100644
--- a/src/org/apache/james/mime4j/message/MemoryTextBody.java
+++ b/src/org/apache/james/mime4j/message/MemoryTextBody.java
@@ -1,116 +1,116 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.util.CharsetUtil;
-import org.apache.james.mime4j.util.TempPath;
-import org.apache.james.mime4j.util.TempStorage;
-
-
-/**
- * Text body backed by a {@link org.apache.james.mime4j.util.TempFile}.
- *
- *
- * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
- */
-class MemoryTextBody extends AbstractBody implements TextBody {
- private static Log log = LogFactory.getLog(MemoryTextBody.class);
-
- private String mimeCharset = null;
- private byte[] tempFile = null;
-
- public MemoryTextBody(InputStream is) throws IOException {
- this(is, null);
- }
-
- public MemoryTextBody(InputStream is, String mimeCharset)
- throws IOException {
-
- this.mimeCharset = mimeCharset;
-
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- IOUtils.copy(is, out);
- out.close();
- tempFile = out.toByteArray();
- }
-
- /**
- * @see org.apache.james.mime4j.message.TextBody#getReader()
- */
- public Reader getReader() throws UnsupportedEncodingException, IOException {
- String javaCharset = null;
- if (mimeCharset != null) {
- javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
- }
-
- if (javaCharset == null) {
- javaCharset = "ISO-8859-1";
-
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using " + javaCharset
- + " instead.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using " + javaCharset
- + " instead.");
- }
- }
- }
- /*
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using the "
- + "platform's default charset.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using the "
- + "platform's default charset.");
- }
- }
-
- return new InputStreamReader(tempFile.getInputStream());
- }*/
-
- return new InputStreamReader(new ByteArrayInputStream(tempFile), javaCharset);
- }
-
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- IOUtils.copy(new ByteArrayInputStream(tempFile), out);
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.CharsetUtil;
+import org.apache.james.mime4j.util.TempPath;
+import org.apache.james.mime4j.util.TempStorage;
+
+
+/**
+ * Text body backed by a {@link org.apache.james.mime4j.util.TempFile}.
+ *
+ *
+ * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
+ */
+class MemoryTextBody extends AbstractBody implements TextBody {
+ private static Log log = LogFactory.getLog(MemoryTextBody.class);
+
+ private String mimeCharset = null;
+ private byte[] tempFile = null;
+
+ public MemoryTextBody(InputStream is) throws IOException {
+ this(is, null);
+ }
+
+ public MemoryTextBody(InputStream is, String mimeCharset)
+ throws IOException {
+
+ this.mimeCharset = mimeCharset;
+
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ tempFile = out.toByteArray();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.TextBody#getReader()
+ */
+ public Reader getReader() throws UnsupportedEncodingException, IOException {
+ String javaCharset = null;
+ if (mimeCharset != null) {
+ javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
+ }
+
+ if (javaCharset == null) {
+ javaCharset = "ISO-8859-1";
+
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using " + javaCharset
+ + " instead.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using " + javaCharset
+ + " instead.");
+ }
+ }
+ }
+ /*
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using the "
+ + "platform's default charset.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using the "
+ + "platform's default charset.");
+ }
+ }
+
+ return new InputStreamReader(tempFile.getInputStream());
+ }*/
+
+ return new InputStreamReader(new ByteArrayInputStream(tempFile), javaCharset);
+ }
+
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ IOUtils.copy(new ByteArrayInputStream(tempFile), out);
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/Message.java b/src/org/apache/james/mime4j/message/Message.java
index fc28c586acf7d0ff1dde405a80952062dc8c03c0..14aacfc2b85c30668b23b7eeee03542ee57d1967 100644
--- a/src/org/apache/james/mime4j/message/Message.java
+++ b/src/org/apache/james/mime4j/message/Message.java
@@ -1,256 +1,256 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Stack;
-
-import org.apache.james.mime4j.BodyDescriptor;
-import org.apache.james.mime4j.ContentHandler;
-import org.apache.james.mime4j.MimeStreamParser;
-import org.apache.james.mime4j.decoder.Base64InputStream;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.field.UnstructuredField;
-
-
-/**
- * Represents a MIME message. The following code parses a stream into a
- * Message
object.
- *
- * - * Message msg = new Message(new BufferedInputStream( - * new FileInputStream("mime.msg"))); - *- * - * - * - * @version $Id: Message.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $ - */ -public class Message extends Entity implements Body { - - /** - * Creates a new empty
Message
.
- */
- public Message() {
- }
-
- /**
- * Parses the specified MIME message stream into a Message
- * instance.
- *
- * @param is the stream to parse.
- * @throws IOException on I/O errors.
- */
- public Message(InputStream is) throws IOException {
- MimeStreamParser parser = new MimeStreamParser();
- parser.setContentHandler(new MessageBuilder());
- parser.parse(is);
- }
-
-
- /**
- * Gets the Subject
field.
- *
- * @return the Subject
field or null
if it
- * doesn't exist.
- */
- public UnstructuredField getSubject() {
- return (UnstructuredField) getHeader().getField(Field.SUBJECT);
- }
-
- /**
- *
- * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- getHeader().writeTo(out);
-
- Body body = getBody();
- if (body instanceof Multipart) {
- Multipart mp = (Multipart) body;
- mp.writeTo(out);
- } else {
- body.writeTo(out);
- }
- }
-
-
- private class MessageBuilder implements ContentHandler {
- private Stack stack = new Stack();
-
- public MessageBuilder() {
- }
-
- private void expect(Class c) {
- if (!c.isInstance(stack.peek())) {
- throw new IllegalStateException("Internal stack error: "
- + "Expected '" + c.getName() + "' found '"
- + stack.peek().getClass().getName() + "'");
- }
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startMessage()
- */
- public void startMessage() {
- if (stack.isEmpty()) {
- stack.push(Message.this);
- } else {
- expect(Entity.class);
- Message m = new Message();
- ((Entity) stack.peek()).setBody(m);
- stack.push(m);
- }
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endMessage()
- */
- public void endMessage() {
- expect(Message.class);
- stack.pop();
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startHeader()
- */
- public void startHeader() {
- stack.push(new Header());
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
- */
- public void field(String fieldData) {
- expect(Header.class);
- ((Header) stack.peek()).addField(Field.parse(fieldData));
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endHeader()
- */
- public void endHeader() {
- expect(Header.class);
- Header h = (Header) stack.pop();
- expect(Entity.class);
- ((Entity) stack.peek()).setHeader(h);
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
- */
- public void startMultipart(BodyDescriptor bd) {
- expect(Entity.class);
-
- Entity e = (Entity) stack.peek();
- Multipart multiPart = new Multipart();
- e.setBody(multiPart);
- stack.push(multiPart);
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
- */
- public void body(BodyDescriptor bd, InputStream is) throws IOException {
- expect(Entity.class);
-
- String enc = bd.getTransferEncoding();
- if ("base64".equals(enc)) {
- is = new Base64InputStream(is);
- } else if ("quoted-printable".equals(enc)) {
- is = new QuotedPrintableInputStream(is);
- }
-
- Body body = null;
- if (bd.getMimeType().startsWith("text/")) {
- body = new MemoryTextBody(is, bd.getCharset());
- } else {
- body = new MemoryBinaryBody(is);
- }
-
- ((Entity) stack.peek()).setBody(body);
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endMultipart()
- */
- public void endMultipart() {
- stack.pop();
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
- */
- public void startBodyPart() {
- expect(Multipart.class);
-
- BodyPart bodyPart = new BodyPart();
- ((Multipart) stack.peek()).addBodyPart(bodyPart);
- stack.push(bodyPart);
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
- */
- public void endBodyPart() {
- expect(BodyPart.class);
- stack.pop();
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
- */
- public void epilogue(InputStream is) throws IOException {
- expect(Multipart.class);
- StringBuffer sb = new StringBuffer();
- int b;
- while ((b = is.read()) != -1) {
- sb.append((char) b);
- }
- ((Multipart) stack.peek()).setEpilogue(sb.toString());
- }
-
- /**
- * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
- */
- public void preamble(InputStream is) throws IOException {
- expect(Multipart.class);
- StringBuffer sb = new StringBuffer();
- int b;
- while ((b = is.read()) != -1) {
- sb.append((char) b);
- }
- ((Multipart) stack.peek()).setPreamble(sb.toString());
- }
-
- /**
- * TODO: Implement me
- *
- * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
- */
- public void raw(InputStream is) throws IOException {
- throw new UnsupportedOperationException("Not supported");
- }
-
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Stack;
+
+import org.apache.james.mime4j.BodyDescriptor;
+import org.apache.james.mime4j.ContentHandler;
+import org.apache.james.mime4j.MimeStreamParser;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.UnstructuredField;
+
+
+/**
+ * Represents a MIME message. The following code parses a stream into a
+ * Message
object.
+ *
+ * + * Message msg = new Message(new BufferedInputStream( + * new FileInputStream("mime.msg"))); + *+ * + * + * + * @version $Id: Message.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $ + */ +public class Message extends Entity implements Body { + + /** + * Creates a new empty
Message
.
+ */
+ public Message() {
+ }
+
+ /**
+ * Parses the specified MIME message stream into a Message
+ * instance.
+ *
+ * @param is the stream to parse.
+ * @throws IOException on I/O errors.
+ */
+ public Message(InputStream is) throws IOException {
+ MimeStreamParser parser = new MimeStreamParser();
+ parser.setContentHandler(new MessageBuilder());
+ parser.parse(is);
+ }
+
+
+ /**
+ * Gets the Subject
field.
+ *
+ * @return the Subject
field or null
if it
+ * doesn't exist.
+ */
+ public UnstructuredField getSubject() {
+ return (UnstructuredField) getHeader().getField(Field.SUBJECT);
+ }
+
+ /**
+ *
+ * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ getHeader().writeTo(out);
+
+ Body body = getBody();
+ if (body instanceof Multipart) {
+ Multipart mp = (Multipart) body;
+ mp.writeTo(out);
+ } else {
+ body.writeTo(out);
+ }
+ }
+
+
+ private class MessageBuilder implements ContentHandler {
+ private Stack stack = new Stack();
+
+ public MessageBuilder() {
+ }
+
+ private void expect(Class c) {
+ if (!c.isInstance(stack.peek())) {
+ throw new IllegalStateException("Internal stack error: "
+ + "Expected '" + c.getName() + "' found '"
+ + stack.peek().getClass().getName() + "'");
+ }
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startMessage()
+ */
+ public void startMessage() {
+ if (stack.isEmpty()) {
+ stack.push(Message.this);
+ } else {
+ expect(Entity.class);
+ Message m = new Message();
+ ((Entity) stack.peek()).setBody(m);
+ stack.push(m);
+ }
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endMessage()
+ */
+ public void endMessage() {
+ expect(Message.class);
+ stack.pop();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startHeader()
+ */
+ public void startHeader() {
+ stack.push(new Header());
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
+ */
+ public void field(String fieldData) {
+ expect(Header.class);
+ ((Header) stack.peek()).addField(Field.parse(fieldData));
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endHeader()
+ */
+ public void endHeader() {
+ expect(Header.class);
+ Header h = (Header) stack.pop();
+ expect(Entity.class);
+ ((Entity) stack.peek()).setHeader(h);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
+ */
+ public void startMultipart(BodyDescriptor bd) {
+ expect(Entity.class);
+
+ Entity e = (Entity) stack.peek();
+ Multipart multiPart = new Multipart();
+ e.setBody(multiPart);
+ stack.push(multiPart);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
+ */
+ public void body(BodyDescriptor bd, InputStream is) throws IOException {
+ expect(Entity.class);
+
+ String enc = bd.getTransferEncoding();
+ if ("base64".equals(enc)) {
+ is = new Base64InputStream(is);
+ } else if ("quoted-printable".equals(enc)) {
+ is = new QuotedPrintableInputStream(is);
+ }
+
+ Body body = null;
+ if (bd.getMimeType().startsWith("text/")) {
+ body = new MemoryTextBody(is, bd.getCharset());
+ } else {
+ body = new MemoryBinaryBody(is);
+ }
+
+ ((Entity) stack.peek()).setBody(body);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endMultipart()
+ */
+ public void endMultipart() {
+ stack.pop();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
+ */
+ public void startBodyPart() {
+ expect(Multipart.class);
+
+ BodyPart bodyPart = new BodyPart();
+ ((Multipart) stack.peek()).addBodyPart(bodyPart);
+ stack.push(bodyPart);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
+ */
+ public void endBodyPart() {
+ expect(BodyPart.class);
+ stack.pop();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
+ */
+ public void epilogue(InputStream is) throws IOException {
+ expect(Multipart.class);
+ StringBuffer sb = new StringBuffer();
+ int b;
+ while ((b = is.read()) != -1) {
+ sb.append((char) b);
+ }
+ ((Multipart) stack.peek()).setEpilogue(sb.toString());
+ }
+
+ /**
+ * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
+ */
+ public void preamble(InputStream is) throws IOException {
+ expect(Multipart.class);
+ StringBuffer sb = new StringBuffer();
+ int b;
+ while ((b = is.read()) != -1) {
+ sb.append((char) b);
+ }
+ ((Multipart) stack.peek()).setPreamble(sb.toString());
+ }
+
+ /**
+ * TODO: Implement me
+ *
+ * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
+ */
+ public void raw(InputStream is) throws IOException {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/Multipart.java b/src/org/apache/james/mime4j/message/Multipart.java
index 3c4b519c4848b6ef922b7cb100e2bceb2b19b054..a3a255b71e3a435c80fab042d2242e311c53f398 100644
--- a/src/org/apache/james/mime4j/message/Multipart.java
+++ b/src/org/apache/james/mime4j/message/Multipart.java
@@ -1,203 +1,203 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.util.CharsetUtil;
-
-/**
- * Represents a MIME multipart body (see RFC 2045).A multipart body has a
- * ordered list of body parts. The multipart body also has a preamble and
- * epilogue. The preamble consists of whatever characters appear before the
- * first body part while the epilogue consists of whatever characters come
- * after the last body part.
- *
- *
- * @version $Id: Multipart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public class Multipart implements Body {
- private String preamble = "";
- private String epilogue = "";
- private List bodyParts = new LinkedList();
- private Entity parent = null;
- private String subType = "alternative";
-
- /**
- * Creates a new empty Multipart
instance.
- */
- public Multipart() {
- }
-
- /**
- * Gets the multipart sub-type. E.g. alternative
(the default)
- * or parallel
. See RFC 2045 for common sub-types and their
- * meaning.
- *
- * @return the multipart sub-type.
- */
- public String getSubType() {
- return subType;
- }
-
- /**
- * Sets the multipart sub-type. E.g. alternative
- * or parallel
. See RFC 2045 for common sub-types and their
- * meaning.
- *
- * @param subType the sub-type.
- */
- public void setSubType(String subType) {
- this.subType = subType;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- for (Iterator it = bodyParts.iterator(); it.hasNext();) {
- ((BodyPart) it.next()).setParent(parent);
- }
- }
-
- /**
- * Gets the epilogue.
- *
- * @return the epilogue.
- */
- public String getEpilogue() {
- return epilogue;
- }
-
- /**
- * Sets the epilogue.
- *
- * @param epilogue the epilogue.
- */
- public void setEpilogue(String epilogue) {
- this.epilogue = epilogue;
- }
-
- /**
- * Gets the list of body parts. The list is immutable.
- *
- * @return the list of BodyPart
objects.
- */
- public List getBodyParts() {
- return Collections.unmodifiableList(bodyParts);
- }
-
- /**
- * Sets the list of body parts.
- *
- * @param bodyParts the new list of BodyPart
objects.
- */
- public void setBodyParts(List bodyParts) {
- this.bodyParts = bodyParts;
- for (Iterator it = bodyParts.iterator(); it.hasNext();) {
- ((BodyPart) it.next()).setParent(parent);
- }
- }
-
- /**
- * Adds a body part to the end of the list of body parts.
- *
- * @param bodyPart the body part.
- */
- public void addBodyPart(BodyPart bodyPart) {
- bodyParts.add(bodyPart);
- bodyPart.setParent(parent);
- }
-
- /**
- * Gets the preamble.
- *
- * @return the preamble.
- */
- public String getPreamble() {
- return preamble;
- }
-
- /**
- * Sets the preamble.
- *
- * @param preamble the preamble.
- */
- public void setPreamble(String preamble) {
- this.preamble = preamble;
- }
-
- /**
- *
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- String boundary = getBoundary();
- List bodyParts = getBodyParts();
-
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(getCharset())),8192);
-
- writer.write(getPreamble() + "\r\n");
-
- for (int i = 0; i < bodyParts.size(); i++) {
- writer.write(boundary + "\r\n");
- ((BodyPart) bodyParts.get(i)).writeTo(out);
- }
-
- writer.write(getEpilogue() + "\r\n");
- writer.write(boundary + "--" + "\r\n");
-
- }
-
- /**
- * Return the boundory of the parent Entity
- *
- * @return boundery
- */
- private String getBoundary() {
- Entity e = getParent();
- ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
- Field.CONTENT_TYPE);
- return cField.getBoundary();
- }
-
- private String getCharset() {
- Entity e = getParent();
- String charString = ((ContentTypeField) e.getHeader().getField(Field.CONTENT_TYPE)).getCharset();
- return charString;
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+/**
+ * Represents a MIME multipart body (see RFC 2045).A multipart body has a
+ * ordered list of body parts. The multipart body also has a preamble and
+ * epilogue. The preamble consists of whatever characters appear before the
+ * first body part while the epilogue consists of whatever characters come
+ * after the last body part.
+ *
+ *
+ * @version $Id: Multipart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class Multipart implements Body {
+ private String preamble = "";
+ private String epilogue = "";
+ private List bodyParts = new LinkedList();
+ private Entity parent = null;
+ private String subType = "alternative";
+
+ /**
+ * Creates a new empty Multipart
instance.
+ */
+ public Multipart() {
+ }
+
+ /**
+ * Gets the multipart sub-type. E.g. alternative
(the default)
+ * or parallel
. See RFC 2045 for common sub-types and their
+ * meaning.
+ *
+ * @return the multipart sub-type.
+ */
+ public String getSubType() {
+ return subType;
+ }
+
+ /**
+ * Sets the multipart sub-type. E.g. alternative
+ * or parallel
. See RFC 2045 for common sub-types and their
+ * meaning.
+ *
+ * @param subType the sub-type.
+ */
+ public void setSubType(String subType) {
+ this.subType = subType;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ for (Iterator it = bodyParts.iterator(); it.hasNext();) {
+ ((BodyPart) it.next()).setParent(parent);
+ }
+ }
+
+ /**
+ * Gets the epilogue.
+ *
+ * @return the epilogue.
+ */
+ public String getEpilogue() {
+ return epilogue;
+ }
+
+ /**
+ * Sets the epilogue.
+ *
+ * @param epilogue the epilogue.
+ */
+ public void setEpilogue(String epilogue) {
+ this.epilogue = epilogue;
+ }
+
+ /**
+ * Gets the list of body parts. The list is immutable.
+ *
+ * @return the list of BodyPart
objects.
+ */
+ public List getBodyParts() {
+ return Collections.unmodifiableList(bodyParts);
+ }
+
+ /**
+ * Sets the list of body parts.
+ *
+ * @param bodyParts the new list of BodyPart
objects.
+ */
+ public void setBodyParts(List bodyParts) {
+ this.bodyParts = bodyParts;
+ for (Iterator it = bodyParts.iterator(); it.hasNext();) {
+ ((BodyPart) it.next()).setParent(parent);
+ }
+ }
+
+ /**
+ * Adds a body part to the end of the list of body parts.
+ *
+ * @param bodyPart the body part.
+ */
+ public void addBodyPart(BodyPart bodyPart) {
+ bodyParts.add(bodyPart);
+ bodyPart.setParent(parent);
+ }
+
+ /**
+ * Gets the preamble.
+ *
+ * @return the preamble.
+ */
+ public String getPreamble() {
+ return preamble;
+ }
+
+ /**
+ * Sets the preamble.
+ *
+ * @param preamble the preamble.
+ */
+ public void setPreamble(String preamble) {
+ this.preamble = preamble;
+ }
+
+ /**
+ *
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ String boundary = getBoundary();
+ List bodyParts = getBodyParts();
+
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(getCharset())),8192);
+
+ writer.write(getPreamble() + "\r\n");
+
+ for (int i = 0; i < bodyParts.size(); i++) {
+ writer.write(boundary + "\r\n");
+ ((BodyPart) bodyParts.get(i)).writeTo(out);
+ }
+
+ writer.write(getEpilogue() + "\r\n");
+ writer.write(boundary + "--" + "\r\n");
+
+ }
+
+ /**
+ * Return the boundory of the parent Entity
+ *
+ * @return boundery
+ */
+ private String getBoundary() {
+ Entity e = getParent();
+ ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
+ Field.CONTENT_TYPE);
+ return cField.getBoundary();
+ }
+
+ private String getCharset() {
+ Entity e = getParent();
+ String charString = ((ContentTypeField) e.getHeader().getField(Field.CONTENT_TYPE)).getCharset();
+ return charString;
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/TempFileBinaryBody.java b/src/org/apache/james/mime4j/message/TempFileBinaryBody.java
index 3ded83db8addf1bca64f27f35bb587c2cc5756b9..2151a53cde89846538d13f04b6b893e61c6d32fd 100644
--- a/src/org/apache/james/mime4j/message/TempFileBinaryBody.java
+++ b/src/org/apache/james/mime4j/message/TempFileBinaryBody.java
@@ -1,89 +1,89 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.util.TempFile;
-import org.apache.james.mime4j.util.TempPath;
-import org.apache.james.mime4j.util.TempStorage;
-
-
-/**
- * Binary body backed by a {@link org.apache.james.mime4j.util.TempFile}.
- *
- *
- * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-class TempFileBinaryBody extends AbstractBody implements BinaryBody {
- private static Log log = LogFactory.getLog(TempFileBinaryBody.class);
-
- private Entity parent = null;
- private TempFile tempFile = null;
-
- /**
- * Use the given InputStream to build the TemporyFileBinaryBody
- *
- * @param is the InputStream to use as source
- * @throws IOException
- */
- public TempFileBinaryBody(InputStream is) throws IOException {
-
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
- tempFile = tempPath.createTempFile("attachment", ".bin");
-
- OutputStream out = tempFile.getOutputStream();
- IOUtils.copy(is, out);
- out.close();
- }
-
- /**
- * @see org.apache.james.mime4j.message.AbstractBody#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
- */
- public InputStream getInputStream() throws IOException {
- return tempFile.getInputStream();
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- IOUtils.copy(getInputStream(),out);
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.TempFile;
+import org.apache.james.mime4j.util.TempPath;
+import org.apache.james.mime4j.util.TempStorage;
+
+
+/**
+ * Binary body backed by a {@link org.apache.james.mime4j.util.TempFile}.
+ *
+ *
+ * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+class TempFileBinaryBody extends AbstractBody implements BinaryBody {
+ private static Log log = LogFactory.getLog(TempFileBinaryBody.class);
+
+ private Entity parent = null;
+ private TempFile tempFile = null;
+
+ /**
+ * Use the given InputStream to build the TemporyFileBinaryBody
+ *
+ * @param is the InputStream to use as source
+ * @throws IOException
+ */
+ public TempFileBinaryBody(InputStream is) throws IOException {
+
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+ tempFile = tempPath.createTempFile("attachment", ".bin");
+
+ OutputStream out = tempFile.getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.AbstractBody#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return tempFile.getInputStream();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ IOUtils.copy(getInputStream(),out);
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/TempFileTextBody.java b/src/org/apache/james/mime4j/message/TempFileTextBody.java
index 0b3b70c25add14546bdd9fe9a9282763854257a7..25a3b295871ac2f0cf38ca5bed823f62cb1e4e69 100644
--- a/src/org/apache/james/mime4j/message/TempFileTextBody.java
+++ b/src/org/apache/james/mime4j/message/TempFileTextBody.java
@@ -1,115 +1,115 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.util.CharsetUtil;
-import org.apache.james.mime4j.util.TempFile;
-import org.apache.james.mime4j.util.TempPath;
-import org.apache.james.mime4j.util.TempStorage;
-
-
-/**
- * Text body backed by a {@link org.apache.james.mime4j.util.TempFile}.
- *
- *
- * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
- */
-class TempFileTextBody extends AbstractBody implements TextBody {
- private static Log log = LogFactory.getLog(TempFileTextBody.class);
-
- private String mimeCharset = null;
- private TempFile tempFile = null;
-
- public TempFileTextBody(InputStream is) throws IOException {
- this(is, null);
- }
-
- public TempFileTextBody(InputStream is, String mimeCharset)
- throws IOException {
-
- this.mimeCharset = mimeCharset;
-
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
- tempFile = tempPath.createTempFile("attachment", ".txt");
-
- OutputStream out = tempFile.getOutputStream();
- IOUtils.copy(is, out);
- out.close();
- }
-
- /**
- * @see org.apache.james.mime4j.message.TextBody#getReader()
- */
- public Reader getReader() throws UnsupportedEncodingException, IOException {
- String javaCharset = null;
- if (mimeCharset != null) {
- javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
- }
-
- if (javaCharset == null) {
- javaCharset = "ISO-8859-1";
-
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using " + javaCharset
- + " instead.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using " + javaCharset
- + " instead.");
- }
- }
- }
- /*
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using the "
- + "platform's default charset.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using the "
- + "platform's default charset.");
- }
- }
-
- return new InputStreamReader(tempFile.getInputStream());
- }*/
-
- return new InputStreamReader(tempFile.getInputStream(), javaCharset);
- }
-
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
- */
- public void writeTo(OutputStream out) throws IOException {
- IOUtils.copy(tempFile.getInputStream(), out);
- }
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.CharsetUtil;
+import org.apache.james.mime4j.util.TempFile;
+import org.apache.james.mime4j.util.TempPath;
+import org.apache.james.mime4j.util.TempStorage;
+
+
+/**
+ * Text body backed by a {@link org.apache.james.mime4j.util.TempFile}.
+ *
+ *
+ * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
+ */
+class TempFileTextBody extends AbstractBody implements TextBody {
+ private static Log log = LogFactory.getLog(TempFileTextBody.class);
+
+ private String mimeCharset = null;
+ private TempFile tempFile = null;
+
+ public TempFileTextBody(InputStream is) throws IOException {
+ this(is, null);
+ }
+
+ public TempFileTextBody(InputStream is, String mimeCharset)
+ throws IOException {
+
+ this.mimeCharset = mimeCharset;
+
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+ tempFile = tempPath.createTempFile("attachment", ".txt");
+
+ OutputStream out = tempFile.getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.TextBody#getReader()
+ */
+ public Reader getReader() throws UnsupportedEncodingException, IOException {
+ String javaCharset = null;
+ if (mimeCharset != null) {
+ javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
+ }
+
+ if (javaCharset == null) {
+ javaCharset = "ISO-8859-1";
+
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using " + javaCharset
+ + " instead.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using " + javaCharset
+ + " instead.");
+ }
+ }
+ }
+ /*
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using the "
+ + "platform's default charset.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using the "
+ + "platform's default charset.");
+ }
+ }
+
+ return new InputStreamReader(tempFile.getInputStream());
+ }*/
+
+ return new InputStreamReader(tempFile.getInputStream(), javaCharset);
+ }
+
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ IOUtils.copy(tempFile.getInputStream(), out);
+ }
+}
diff --git a/src/org/apache/james/mime4j/message/TextBody.java b/src/org/apache/james/mime4j/message/TextBody.java
index 4fe714466512a557e5391e60a8f50b5d1a76d4f8..cbf24c2e7646eda6ea037f79fade0cc7db934b07 100644
--- a/src/org/apache/james/mime4j/message/TextBody.java
+++ b/src/org/apache/james/mime4j/message/TextBody.java
@@ -1,42 +1,42 @@
-/****************************************************************
- * 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.mime4j.message;
-
-import java.io.IOException;
-import java.io.Reader;
-
-
-/**
- * Encapsulates the contents of a text/*
entity body.
- *
- *
- * @version $Id: TextBody.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public interface TextBody extends Body {
-
- /**
- * Gets a Reader
which may be used to read out the contents
- * of this body.
- *
- * @return the Reader
.
- * @throws IOException on I/O errors.
- */
- Reader getReader() throws IOException;
-}
+/****************************************************************
+ * 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.mime4j.message;
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+/**
+ * Encapsulates the contents of a text/*
entity body.
+ *
+ *
+ * @version $Id: TextBody.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public interface TextBody extends Body {
+
+ /**
+ * Gets a Reader
which may be used to read out the contents
+ * of this body.
+ *
+ * @return the Reader
.
+ * @throws IOException on I/O errors.
+ */
+ Reader getReader() throws IOException;
+}
diff --git a/src/org/apache/james/mime4j/util/CharsetUtil.java b/src/org/apache/james/mime4j/util/CharsetUtil.java
index 8bb04403932751447764a946b8e8746b81efbb84..e18ceb3fb08e9fd63a9e7622da907565ab7c9542 100644
--- a/src/org/apache/james/mime4j/util/CharsetUtil.java
+++ b/src/org/apache/james/mime4j/util/CharsetUtil.java
@@ -1,1245 +1,1245 @@
-/****************************************************************
- * 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.mime4j.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.HashMap;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Utility class for working with character sets. It is somewhat similar to
- * the Java 1.4 java.nio.charset.Charset
class but knows many
- * more aliases and is compatible with Java 1.3. It will use a simple detection
- * mechanism to detect what character sets the current VM supports. This will
- * be a sub-set of the character sets listed in the
- *
- * Java 1.5 (J2SE5.0) Supported Encodings document.
- * - * The - * IANA Character Sets document has been used to determine the preferred - * MIME character set names and to get a list of known aliases. - *
- * This is a complete list of the character sets known to this class: - *
Canonical (Java) name | - *MIME preferred | - *Aliases | - *
ASCII | - *US-ASCII | - *ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ISO646-US us IBM367 cp367 csASCII ascii7 646 iso_646.irv:1983 | - *
Big5 | - *Big5 | - *csBig5 CN-Big5 BIG-FIVE BIGFIVE | - *
Big5_HKSCS | - *Big5-HKSCS | - *big5hkscs | - *
Big5_Solaris | - *? | - *- * |
Cp037 | - *IBM037 | - *ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl csIBM037 | - *
Cp1006 | - *? | - *- * |
Cp1025 | - *? | - *- * |
Cp1026 | - *IBM1026 | - *csIBM1026 | - *
Cp1046 | - *? | - *- * |
Cp1047 | - *IBM1047 | - *IBM-1047 | - *
Cp1097 | - *? | - *- * |
Cp1098 | - *? | - *- * |
Cp1112 | - *? | - *- * |
Cp1122 | - *? | - *- * |
Cp1123 | - *? | - *- * |
Cp1124 | - *? | - *- * |
Cp1140 | - *IBM01140 | - *CCSID01140 CP01140 ebcdic-us-37+euro | - *
Cp1141 | - *IBM01141 | - *CCSID01141 CP01141 ebcdic-de-273+euro | - *
Cp1142 | - *IBM01142 | - *CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro | - *
Cp1143 | - *IBM01143 | - *CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro | - *
Cp1144 | - *IBM01144 | - *CCSID01144 CP01144 ebcdic-it-280+euro | - *
Cp1145 | - *IBM01145 | - *CCSID01145 CP01145 ebcdic-es-284+euro | - *
Cp1146 | - *IBM01146 | - *CCSID01146 CP01146 ebcdic-gb-285+euro | - *
Cp1147 | - *IBM01147 | - *CCSID01147 CP01147 ebcdic-fr-297+euro | - *
Cp1148 | - *IBM01148 | - *CCSID01148 CP01148 ebcdic-international-500+euro | - *
Cp1149 | - *IBM01149 | - *CCSID01149 CP01149 ebcdic-is-871+euro | - *
Cp1250 | - *windows-1250 | - *- * |
Cp1251 | - *windows-1251 | - *- * |
Cp1252 | - *windows-1252 | - *- * |
Cp1253 | - *windows-1253 | - *- * |
Cp1254 | - *windows-1254 | - *- * |
Cp1255 | - *windows-1255 | - *- * |
Cp1256 | - *windows-1256 | - *- * |
Cp1257 | - *windows-1257 | - *- * |
Cp1258 | - *windows-1258 | - *- * |
Cp1381 | - *? | - *- * |
Cp1383 | - *? | - *- * |
Cp273 | - *IBM273 | - *csIBM273 | - *
Cp277 | - *IBM277 | - *EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 | - *
Cp278 | - *IBM278 | - *CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 | - *
Cp280 | - *IBM280 | - *ebcdic-cp-it csIBM280 | - *
Cp284 | - *IBM284 | - *ebcdic-cp-es csIBM284 | - *
Cp285 | - *IBM285 | - *ebcdic-cp-gb csIBM285 | - *
Cp297 | - *IBM297 | - *ebcdic-cp-fr csIBM297 | - *
Cp33722 | - *? | - *- * |
Cp420 | - *IBM420 | - *ebcdic-cp-ar1 csIBM420 | - *
Cp424 | - *IBM424 | - *ebcdic-cp-he csIBM424 | - *
Cp437 | - *IBM437 | - *437 csPC8CodePage437 | - *
Cp500 | - *IBM500 | - *ebcdic-cp-be ebcdic-cp-ch csIBM500 | - *
Cp737 | - *? | - *- * |
Cp775 | - *IBM775 | - *csPC775Baltic | - *
Cp838 | - *IBM-Thai | - *- * |
Cp850 | - *IBM850 | - *850 csPC850Multilingual | - *
Cp852 | - *IBM852 | - *852 csPCp852 | - *
Cp855 | - *IBM855 | - *855 csIBM855 | - *
Cp856 | - *? | - *- * |
Cp857 | - *IBM857 | - *857 csIBM857 | - *
Cp858 | - *IBM00858 | - *CCSID00858 CP00858 PC-Multilingual-850+euro | - *
Cp860 | - *IBM860 | - *860 csIBM860 | - *
Cp861 | - *IBM861 | - *861 cp-is csIBM861 | - *
Cp862 | - *IBM862 | - *862 csPC862LatinHebrew | - *
Cp863 | - *IBM863 | - *863 csIBM863 | - *
Cp864 | - *IBM864 | - *cp864 csIBM864 | - *
Cp865 | - *IBM865 | - *865 csIBM865 | - *
Cp866 | - *IBM866 | - *866 csIBM866 | - *
Cp868 | - *IBM868 | - *cp-ar csIBM868 | - *
Cp869 | - *IBM869 | - *cp-gr csIBM869 | - *
Cp870 | - *IBM870 | - *ebcdic-cp-roece ebcdic-cp-yu csIBM870 | - *
Cp871 | - *IBM871 | - *ebcdic-cp-is csIBM871 | - *
Cp875 | - *? | - *- * |
Cp918 | - *IBM918 | - *ebcdic-cp-ar2 csIBM918 | - *
Cp921 | - *? | - *- * |
Cp922 | - *? | - *- * |
Cp930 | - *? | - *- * |
Cp933 | - *? | - *- * |
Cp935 | - *? | - *- * |
Cp937 | - *? | - *- * |
Cp939 | - *? | - *- * |
Cp942 | - *? | - *- * |
Cp942C | - *? | - *- * |
Cp943 | - *? | - *- * |
Cp943C | - *? | - *- * |
Cp948 | - *? | - *- * |
Cp949 | - *? | - *- * |
Cp949C | - *? | - *- * |
Cp950 | - *? | - *- * |
Cp964 | - *? | - *- * |
Cp970 | - *? | - *- * |
EUC_CN | - *GB2312 | - *x-EUC-CN csGB2312 euccn euc-cn gb2312-80 gb2312-1980 CN-GB CN-GB-ISOIR165 | - *
EUC_JP | - *EUC-JP | - *csEUCPkdFmtJapanese Extended_UNIX_Code_Packed_Format_for_Japanese eucjis x-eucjp eucjp x-euc-jp | - *
EUC_JP_LINUX | - *? | - *- * |
EUC_JP_Solaris | - *? | - *- * |
EUC_KR | - *EUC-KR | - *csEUCKR ksc5601 5601 ksc5601_1987 ksc_5601 ksc5601-1987 ks_c_5601-1987 euckr | - *
EUC_TW | - *EUC-TW | - *x-EUC-TW cns11643 euctw | - *
GB18030 | - *GB18030 | - *gb18030-2000 | - *
GBK | - *windows-936 | - *CP936 MS936 ms_936 x-mswin-936 | - *
ISCII91 | - *? | - *x-ISCII91 iscii | - *
ISO2022CN | - *ISO-2022-CN | - *- * |
ISO2022JP | - *ISO-2022-JP | - *csISO2022JP JIS jis_encoding csjisencoding | - *
ISO2022KR | - *ISO-2022-KR | - *csISO2022KR | - *
ISO2022_CN_CNS | - *? | - *- * |
ISO2022_CN_GB | - *? | - *- * |
ISO8859_1 | - *ISO-8859-1 | - *ISO_8859-1:1987 iso-ir-100 ISO_8859-1 latin1 l1 IBM819 CP819 csISOLatin1 8859_1 819 IBM-819 ISO8859-1 ISO_8859_1 | - *
ISO8859_13 | - *ISO-8859-13 | - *- * |
ISO8859_15 | - *ISO-8859-15 | - *ISO_8859-15 Latin-9 8859_15 csISOlatin9 IBM923 cp923 923 L9 IBM-923 ISO8859-15 LATIN9 LATIN0 csISOlatin0 ISO8859_15_FDIS | - *
ISO8859_2 | - *ISO-8859-2 | - *ISO_8859-2:1987 iso-ir-101 ISO_8859-2 latin2 l2 csISOLatin2 8859_2 iso8859_2 | - *
ISO8859_3 | - *ISO-8859-3 | - *ISO_8859-3:1988 iso-ir-109 ISO_8859-3 latin3 l3 csISOLatin3 8859_3 | - *
ISO8859_4 | - *ISO-8859-4 | - *ISO_8859-4:1988 iso-ir-110 ISO_8859-4 latin4 l4 csISOLatin4 8859_4 | - *
ISO8859_5 | - *ISO-8859-5 | - *ISO_8859-5:1988 iso-ir-144 ISO_8859-5 cyrillic csISOLatinCyrillic 8859_5 | - *
ISO8859_6 | - *ISO-8859-6 | - *ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ECMA-114 ASMO-708 arabic csISOLatinArabic 8859_6 | - *
ISO8859_7 | - *ISO-8859-7 | - *ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ELOT_928 ECMA-118 greek greek8 csISOLatinGreek 8859_7 sun_eu_greek | - *
ISO8859_8 | - *ISO-8859-8 | - *ISO_8859-8:1988 iso-ir-138 ISO_8859-8 hebrew csISOLatinHebrew 8859_8 | - *
ISO8859_9 | - *ISO-8859-9 | - *ISO_8859-9:1989 iso-ir-148 ISO_8859-9 latin5 l5 csISOLatin5 8859_9 | - *
JISAutoDetect | - *? | - *- * |
JIS_C6626-1983 | - *JIS_C6626-1983 | - *x-JIS0208 JIS0208 csISO87JISX0208 x0208 JIS_X0208-1983 iso-ir-87 | - *
JIS_X0201 | - *JIS_X0201 | - *X0201 JIS0201 csHalfWidthKatakana | - *
JIS_X0212-1990 | - *JIS_X0212-1990 | - *iso-ir-159 x0212 JIS0212 csISO159JISX02121990 | - *
KOI8_R | - *KOI8-R | - *csKOI8R koi8 | - *
MS874 | - *windows-874 | - *cp874 | - *
MS932 | - *Windows-31J | - *windows-932 csWindows31J x-ms-cp932 | - *
MS949 | - *windows-949 | - *windows949 ms_949 x-windows-949 | - *
MS950 | - *windows-950 | - *x-windows-950 | - *
MS950_HKSCS | - *- * | - * |
MacArabic | - *? | - *- * |
MacCentralEurope | - *? | - *- * |
MacCroatian | - *? | - *- * |
MacCyrillic | - *? | - *- * |
MacDingbat | - *? | - *- * |
MacGreek | - *MacGreek | - *- * |
MacHebrew | - *? | - *- * |
MacIceland | - *? | - *- * |
MacRoman | - *MacRoman | - *Macintosh MAC csMacintosh | - *
MacRomania | - *? | - *- * |
MacSymbol | - *? | - *- * |
MacThai | - *? | - *- * |
MacTurkish | - *? | - *- * |
MacUkraine | - *? | - *- * |
SJIS | - *Shift_JIS | - *MS_Kanji csShiftJIS shift-jis x-sjis pck | - *
TIS620 | - *TIS-620 | - *- * |
UTF-16 | - *UTF-16 | - *UTF_16 | - *
UTF8 | - *UTF-8 | - *- * |
UnicodeBig | - *? | - *- * |
UnicodeBigUnmarked | - *UTF-16BE | - *X-UTF-16BE UTF_16BE ISO-10646-UCS-2 | - *
UnicodeLittle | - *? | - *- * |
UnicodeLittleUnmarked | - *UTF-16LE | - *UTF_16LE X-UTF-16LE | - *
x-Johab | - *johab | - *johab cp1361 ms1361 ksc5601-1992 ksc5601_1992 | - *
x-iso-8859-11 | - *? | - *- * |
true
if the specified character is a whitespace
- * character (CR, LF, SP or HT).
- *
- * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
- *
- * @param ch
- * character to test.
- * @return true
if the specified character is a whitespace
- * character, false
otherwise.
- */
- public static boolean isWhitespace(char ch) {
- return ch == SP || ch == HT || ch == CR || ch == LF;
- }
-
- /**
- * Returns true
if the specified string consists entirely of
- * whitespace characters.
- *
- * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
- *
- * @param s
- * string to test.
- * @return true
if the specified string consists entirely of
- * whitespace characters, false
otherwise.
- */
- public static boolean isWhitespace(final String s) {
- if (s == null) {
- throw new IllegalArgumentException("String may not be null");
- }
- final int len = s.length();
- for (int i = 0; i < len; i++) {
- if (!isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Determines if the VM supports encoding (chars to bytes) the
- * specified character set. NOTE: the given character set name may
- * not be known to the VM even if this method returns true
.
- * Use {@link #toJavaCharset(String)} to get the canonical Java character
- * set name.
- *
- * @param charsetName the characters set name.
- * @return true
if encoding is supported, false
- * otherwise.
- */
- public static boolean isEncodingSupported(String charsetName) {
- return encodingSupported.contains(charsetName.toLowerCase());
- }
-
- /**
- * Determines if the VM supports decoding (bytes to chars) the
- * specified character set. NOTE: the given character set name may
- * not be known to the VM even if this method returns true
.
- * Use {@link #toJavaCharset(String)} to get the canonical Java character
- * set name.
- *
- * @param charsetName the characters set name.
- * @return true
if decoding is supported, false
- * otherwise.
- */
- public static boolean isDecodingSupported(String charsetName) {
- return decodingSupported.contains(charsetName.toLowerCase());
- }
-
- /**
- * Gets the preferred MIME character set name for the specified
- * character set or null
if not known.
- *
- * @param charsetName the character set name to look for.
- * @return the MIME preferred name or null
if not known.
- */
- public static String toMimeCharset(String charsetName) {
- Charset c = (Charset) charsetMap.get(charsetName.toLowerCase());
- if (c != null) {
- return c.mime;
- }
- return null;
- }
-
- /**
- * Gets the canonical Java character set name for the specified
- * character set or null
if not known. This should be
- * called before doing any conversions using the Java API. NOTE:
- * you must use {@link #isEncodingSupported(String)} or
- * {@link #isDecodingSupported(String)} to make sure the returned
- * Java character set is supported by the current VM.
- *
- * @param charsetName the character set name to look for.
- * @return the canonical Java name or null
if not known.
- */
- public static String toJavaCharset(String charsetName) {
- Charset c = (Charset) charsetMap.get(charsetName.toLowerCase());
- if (c != null) {
- return c.canonical;
- }
- return null;
- }
-
- public static java.nio.charset.Charset getCharset(String charsetName) {
- String defaultCharset = "ISO-8859-1";
-
- // Use the default chareset if given charset is null
- if(charsetName == null) charsetName = defaultCharset;
-
- try {
- return java.nio.charset.Charset.forName(charsetName);
- } catch (IllegalCharsetNameException e) {
- log.info("Illegal charset " + charsetName + ", fallback to " + defaultCharset + ": " + e);
- // Use default charset on exception
- return java.nio.charset.Charset.forName(defaultCharset);
- } catch (UnsupportedCharsetException ex) {
- log.info("Unsupported charset " + charsetName + ", fallback to " + defaultCharset + ": " + ex);
- // Use default charset on exception
- return java.nio.charset.Charset.forName(defaultCharset);
- }
-
- }
- /*
- * Uncomment the code below and run the main method to regenerate the
- * Javadoc table above when the known charsets change.
- */
-
- /*
- private static String dumpHtmlTable() {
- LinkedList l = new LinkedList(Arrays.asList(JAVA_CHARSETS));
- Collections.sort(l);
- StringBuffer sb = new StringBuffer();
- sb.append(" * Canonical (Java) name | \n"); - sb.append(" *MIME preferred | \n"); - sb.append(" *Aliases | \n"); - sb.append(" *
" + c.canonical + " | \n"); - sb.append(" *" + (c.mime == null ? "?" : c.mime)+ " | \n"); - sb.append(" *"); - for (int i = 0; c.aliases != null && i < c.aliases.length; i++) { - sb.append(c.aliases[i] + " "); - } - sb.append(" | \n"); - sb.append(" *
java.nio.charset.Charset
class but knows many
+ * more aliases and is compatible with Java 1.3. It will use a simple detection
+ * mechanism to detect what character sets the current VM supports. This will
+ * be a sub-set of the character sets listed in the
+ *
+ * Java 1.5 (J2SE5.0) Supported Encodings document.
+ * + * The + * IANA Character Sets document has been used to determine the preferred + * MIME character set names and to get a list of known aliases. + *
+ * This is a complete list of the character sets known to this class: + *
Canonical (Java) name | + *MIME preferred | + *Aliases | + *
ASCII | + *US-ASCII | + *ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ISO646-US us IBM367 cp367 csASCII ascii7 646 iso_646.irv:1983 | + *
Big5 | + *Big5 | + *csBig5 CN-Big5 BIG-FIVE BIGFIVE | + *
Big5_HKSCS | + *Big5-HKSCS | + *big5hkscs | + *
Big5_Solaris | + *? | + *+ * |
Cp037 | + *IBM037 | + *ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl csIBM037 | + *
Cp1006 | + *? | + *+ * |
Cp1025 | + *? | + *+ * |
Cp1026 | + *IBM1026 | + *csIBM1026 | + *
Cp1046 | + *? | + *+ * |
Cp1047 | + *IBM1047 | + *IBM-1047 | + *
Cp1097 | + *? | + *+ * |
Cp1098 | + *? | + *+ * |
Cp1112 | + *? | + *+ * |
Cp1122 | + *? | + *+ * |
Cp1123 | + *? | + *+ * |
Cp1124 | + *? | + *+ * |
Cp1140 | + *IBM01140 | + *CCSID01140 CP01140 ebcdic-us-37+euro | + *
Cp1141 | + *IBM01141 | + *CCSID01141 CP01141 ebcdic-de-273+euro | + *
Cp1142 | + *IBM01142 | + *CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro | + *
Cp1143 | + *IBM01143 | + *CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro | + *
Cp1144 | + *IBM01144 | + *CCSID01144 CP01144 ebcdic-it-280+euro | + *
Cp1145 | + *IBM01145 | + *CCSID01145 CP01145 ebcdic-es-284+euro | + *
Cp1146 | + *IBM01146 | + *CCSID01146 CP01146 ebcdic-gb-285+euro | + *
Cp1147 | + *IBM01147 | + *CCSID01147 CP01147 ebcdic-fr-297+euro | + *
Cp1148 | + *IBM01148 | + *CCSID01148 CP01148 ebcdic-international-500+euro | + *
Cp1149 | + *IBM01149 | + *CCSID01149 CP01149 ebcdic-is-871+euro | + *
Cp1250 | + *windows-1250 | + *+ * |
Cp1251 | + *windows-1251 | + *+ * |
Cp1252 | + *windows-1252 | + *+ * |
Cp1253 | + *windows-1253 | + *+ * |
Cp1254 | + *windows-1254 | + *+ * |
Cp1255 | + *windows-1255 | + *+ * |
Cp1256 | + *windows-1256 | + *+ * |
Cp1257 | + *windows-1257 | + *+ * |
Cp1258 | + *windows-1258 | + *+ * |
Cp1381 | + *? | + *+ * |
Cp1383 | + *? | + *+ * |
Cp273 | + *IBM273 | + *csIBM273 | + *
Cp277 | + *IBM277 | + *EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 | + *
Cp278 | + *IBM278 | + *CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 | + *
Cp280 | + *IBM280 | + *ebcdic-cp-it csIBM280 | + *
Cp284 | + *IBM284 | + *ebcdic-cp-es csIBM284 | + *
Cp285 | + *IBM285 | + *ebcdic-cp-gb csIBM285 | + *
Cp297 | + *IBM297 | + *ebcdic-cp-fr csIBM297 | + *
Cp33722 | + *? | + *+ * |
Cp420 | + *IBM420 | + *ebcdic-cp-ar1 csIBM420 | + *
Cp424 | + *IBM424 | + *ebcdic-cp-he csIBM424 | + *
Cp437 | + *IBM437 | + *437 csPC8CodePage437 | + *
Cp500 | + *IBM500 | + *ebcdic-cp-be ebcdic-cp-ch csIBM500 | + *
Cp737 | + *? | + *+ * |
Cp775 | + *IBM775 | + *csPC775Baltic | + *
Cp838 | + *IBM-Thai | + *+ * |
Cp850 | + *IBM850 | + *850 csPC850Multilingual | + *
Cp852 | + *IBM852 | + *852 csPCp852 | + *
Cp855 | + *IBM855 | + *855 csIBM855 | + *
Cp856 | + *? | + *+ * |
Cp857 | + *IBM857 | + *857 csIBM857 | + *
Cp858 | + *IBM00858 | + *CCSID00858 CP00858 PC-Multilingual-850+euro | + *
Cp860 | + *IBM860 | + *860 csIBM860 | + *
Cp861 | + *IBM861 | + *861 cp-is csIBM861 | + *
Cp862 | + *IBM862 | + *862 csPC862LatinHebrew | + *
Cp863 | + *IBM863 | + *863 csIBM863 | + *
Cp864 | + *IBM864 | + *cp864 csIBM864 | + *
Cp865 | + *IBM865 | + *865 csIBM865 | + *
Cp866 | + *IBM866 | + *866 csIBM866 | + *
Cp868 | + *IBM868 | + *cp-ar csIBM868 | + *
Cp869 | + *IBM869 | + *cp-gr csIBM869 | + *
Cp870 | + *IBM870 | + *ebcdic-cp-roece ebcdic-cp-yu csIBM870 | + *
Cp871 | + *IBM871 | + *ebcdic-cp-is csIBM871 | + *
Cp875 | + *? | + *+ * |
Cp918 | + *IBM918 | + *ebcdic-cp-ar2 csIBM918 | + *
Cp921 | + *? | + *+ * |
Cp922 | + *? | + *+ * |
Cp930 | + *? | + *+ * |
Cp933 | + *? | + *+ * |
Cp935 | + *? | + *+ * |
Cp937 | + *? | + *+ * |
Cp939 | + *? | + *+ * |
Cp942 | + *? | + *+ * |
Cp942C | + *? | + *+ * |
Cp943 | + *? | + *+ * |
Cp943C | + *? | + *+ * |
Cp948 | + *? | + *+ * |
Cp949 | + *? | + *+ * |
Cp949C | + *? | + *+ * |
Cp950 | + *? | + *+ * |
Cp964 | + *? | + *+ * |
Cp970 | + *? | + *+ * |
EUC_CN | + *GB2312 | + *x-EUC-CN csGB2312 euccn euc-cn gb2312-80 gb2312-1980 CN-GB CN-GB-ISOIR165 | + *
EUC_JP | + *EUC-JP | + *csEUCPkdFmtJapanese Extended_UNIX_Code_Packed_Format_for_Japanese eucjis x-eucjp eucjp x-euc-jp | + *
EUC_JP_LINUX | + *? | + *+ * |
EUC_JP_Solaris | + *? | + *+ * |
EUC_KR | + *EUC-KR | + *csEUCKR ksc5601 5601 ksc5601_1987 ksc_5601 ksc5601-1987 ks_c_5601-1987 euckr | + *
EUC_TW | + *EUC-TW | + *x-EUC-TW cns11643 euctw | + *
GB18030 | + *GB18030 | + *gb18030-2000 | + *
GBK | + *windows-936 | + *CP936 MS936 ms_936 x-mswin-936 | + *
ISCII91 | + *? | + *x-ISCII91 iscii | + *
ISO2022CN | + *ISO-2022-CN | + *+ * |
ISO2022JP | + *ISO-2022-JP | + *csISO2022JP JIS jis_encoding csjisencoding | + *
ISO2022KR | + *ISO-2022-KR | + *csISO2022KR | + *
ISO2022_CN_CNS | + *? | + *+ * |
ISO2022_CN_GB | + *? | + *+ * |
ISO8859_1 | + *ISO-8859-1 | + *ISO_8859-1:1987 iso-ir-100 ISO_8859-1 latin1 l1 IBM819 CP819 csISOLatin1 8859_1 819 IBM-819 ISO8859-1 ISO_8859_1 | + *
ISO8859_13 | + *ISO-8859-13 | + *+ * |
ISO8859_15 | + *ISO-8859-15 | + *ISO_8859-15 Latin-9 8859_15 csISOlatin9 IBM923 cp923 923 L9 IBM-923 ISO8859-15 LATIN9 LATIN0 csISOlatin0 ISO8859_15_FDIS | + *
ISO8859_2 | + *ISO-8859-2 | + *ISO_8859-2:1987 iso-ir-101 ISO_8859-2 latin2 l2 csISOLatin2 8859_2 iso8859_2 | + *
ISO8859_3 | + *ISO-8859-3 | + *ISO_8859-3:1988 iso-ir-109 ISO_8859-3 latin3 l3 csISOLatin3 8859_3 | + *
ISO8859_4 | + *ISO-8859-4 | + *ISO_8859-4:1988 iso-ir-110 ISO_8859-4 latin4 l4 csISOLatin4 8859_4 | + *
ISO8859_5 | + *ISO-8859-5 | + *ISO_8859-5:1988 iso-ir-144 ISO_8859-5 cyrillic csISOLatinCyrillic 8859_5 | + *
ISO8859_6 | + *ISO-8859-6 | + *ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ECMA-114 ASMO-708 arabic csISOLatinArabic 8859_6 | + *
ISO8859_7 | + *ISO-8859-7 | + *ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ELOT_928 ECMA-118 greek greek8 csISOLatinGreek 8859_7 sun_eu_greek | + *
ISO8859_8 | + *ISO-8859-8 | + *ISO_8859-8:1988 iso-ir-138 ISO_8859-8 hebrew csISOLatinHebrew 8859_8 | + *
ISO8859_9 | + *ISO-8859-9 | + *ISO_8859-9:1989 iso-ir-148 ISO_8859-9 latin5 l5 csISOLatin5 8859_9 | + *
JISAutoDetect | + *? | + *+ * |
JIS_C6626-1983 | + *JIS_C6626-1983 | + *x-JIS0208 JIS0208 csISO87JISX0208 x0208 JIS_X0208-1983 iso-ir-87 | + *
JIS_X0201 | + *JIS_X0201 | + *X0201 JIS0201 csHalfWidthKatakana | + *
JIS_X0212-1990 | + *JIS_X0212-1990 | + *iso-ir-159 x0212 JIS0212 csISO159JISX02121990 | + *
KOI8_R | + *KOI8-R | + *csKOI8R koi8 | + *
MS874 | + *windows-874 | + *cp874 | + *
MS932 | + *Windows-31J | + *windows-932 csWindows31J x-ms-cp932 | + *
MS949 | + *windows-949 | + *windows949 ms_949 x-windows-949 | + *
MS950 | + *windows-950 | + *x-windows-950 | + *
MS950_HKSCS | + *+ * | + * |
MacArabic | + *? | + *+ * |
MacCentralEurope | + *? | + *+ * |
MacCroatian | + *? | + *+ * |
MacCyrillic | + *? | + *+ * |
MacDingbat | + *? | + *+ * |
MacGreek | + *MacGreek | + *+ * |
MacHebrew | + *? | + *+ * |
MacIceland | + *? | + *+ * |
MacRoman | + *MacRoman | + *Macintosh MAC csMacintosh | + *
MacRomania | + *? | + *+ * |
MacSymbol | + *? | + *+ * |
MacThai | + *? | + *+ * |
MacTurkish | + *? | + *+ * |
MacUkraine | + *? | + *+ * |
SJIS | + *Shift_JIS | + *MS_Kanji csShiftJIS shift-jis x-sjis pck | + *
TIS620 | + *TIS-620 | + *+ * |
UTF-16 | + *UTF-16 | + *UTF_16 | + *
UTF8 | + *UTF-8 | + *+ * |
UnicodeBig | + *? | + *+ * |
UnicodeBigUnmarked | + *UTF-16BE | + *X-UTF-16BE UTF_16BE ISO-10646-UCS-2 | + *
UnicodeLittle | + *? | + *+ * |
UnicodeLittleUnmarked | + *UTF-16LE | + *UTF_16LE X-UTF-16LE | + *
x-Johab | + *johab | + *johab cp1361 ms1361 ksc5601-1992 ksc5601_1992 | + *
x-iso-8859-11 | + *? | + *+ * |
true
if the specified character is a whitespace
+ * character (CR, LF, SP or HT).
+ *
+ * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
+ *
+ * @param ch
+ * character to test.
+ * @return true
if the specified character is a whitespace
+ * character, false
otherwise.
+ */
+ public static boolean isWhitespace(char ch) {
+ return ch == SP || ch == HT || ch == CR || ch == LF;
+ }
+
+ /**
+ * Returns true
if the specified string consists entirely of
+ * whitespace characters.
+ *
+ * ANDROID: COPIED FROM A NEWER VERSION OF MIME4J
+ *
+ * @param s
+ * string to test.
+ * @return true
if the specified string consists entirely of
+ * whitespace characters, false
otherwise.
+ */
+ public static boolean isWhitespace(final String s) {
+ if (s == null) {
+ throw new IllegalArgumentException("String may not be null");
+ }
+ final int len = s.length();
+ for (int i = 0; i < len; i++) {
+ if (!isWhitespace(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Determines if the VM supports encoding (chars to bytes) the
+ * specified character set. NOTE: the given character set name may
+ * not be known to the VM even if this method returns true
.
+ * Use {@link #toJavaCharset(String)} to get the canonical Java character
+ * set name.
+ *
+ * @param charsetName the characters set name.
+ * @return true
if encoding is supported, false
+ * otherwise.
+ */
+ public static boolean isEncodingSupported(String charsetName) {
+ return encodingSupported.contains(charsetName.toLowerCase());
+ }
+
+ /**
+ * Determines if the VM supports decoding (bytes to chars) the
+ * specified character set. NOTE: the given character set name may
+ * not be known to the VM even if this method returns true
.
+ * Use {@link #toJavaCharset(String)} to get the canonical Java character
+ * set name.
+ *
+ * @param charsetName the characters set name.
+ * @return true
if decoding is supported, false
+ * otherwise.
+ */
+ public static boolean isDecodingSupported(String charsetName) {
+ return decodingSupported.contains(charsetName.toLowerCase());
+ }
+
+ /**
+ * Gets the preferred MIME character set name for the specified
+ * character set or null
if not known.
+ *
+ * @param charsetName the character set name to look for.
+ * @return the MIME preferred name or null
if not known.
+ */
+ public static String toMimeCharset(String charsetName) {
+ Charset c = (Charset) charsetMap.get(charsetName.toLowerCase());
+ if (c != null) {
+ return c.mime;
+ }
+ return null;
+ }
+
+ /**
+ * Gets the canonical Java character set name for the specified
+ * character set or null
if not known. This should be
+ * called before doing any conversions using the Java API. NOTE:
+ * you must use {@link #isEncodingSupported(String)} or
+ * {@link #isDecodingSupported(String)} to make sure the returned
+ * Java character set is supported by the current VM.
+ *
+ * @param charsetName the character set name to look for.
+ * @return the canonical Java name or null
if not known.
+ */
+ public static String toJavaCharset(String charsetName) {
+ Charset c = (Charset) charsetMap.get(charsetName.toLowerCase());
+ if (c != null) {
+ return c.canonical;
+ }
+ return null;
+ }
+
+ public static java.nio.charset.Charset getCharset(String charsetName) {
+ String defaultCharset = "ISO-8859-1";
+
+ // Use the default chareset if given charset is null
+ if(charsetName == null) charsetName = defaultCharset;
+
+ try {
+ return java.nio.charset.Charset.forName(charsetName);
+ } catch (IllegalCharsetNameException e) {
+ log.info("Illegal charset " + charsetName + ", fallback to " + defaultCharset + ": " + e);
+ // Use default charset on exception
+ return java.nio.charset.Charset.forName(defaultCharset);
+ } catch (UnsupportedCharsetException ex) {
+ log.info("Unsupported charset " + charsetName + ", fallback to " + defaultCharset + ": " + ex);
+ // Use default charset on exception
+ return java.nio.charset.Charset.forName(defaultCharset);
+ }
+
+ }
+ /*
+ * Uncomment the code below and run the main method to regenerate the
+ * Javadoc table above when the known charsets change.
+ */
+
+ /*
+ private static String dumpHtmlTable() {
+ LinkedList l = new LinkedList(Arrays.asList(JAVA_CHARSETS));
+ Collections.sort(l);
+ StringBuffer sb = new StringBuffer();
+ sb.append(" * Canonical (Java) name | \n"); + sb.append(" *MIME preferred | \n"); + sb.append(" *Aliases | \n"); + sb.append(" *
" + c.canonical + " | \n"); + sb.append(" *" + (c.mime == null ? "?" : c.mime)+ " | \n"); + sb.append(" *"); + for (int i = 0; c.aliases != null && i < c.aliases.length; i++) { + sb.append(c.aliases[i] + " "); + } + sb.append(" | \n"); + sb.append(" *
SimpleTempStorageManager
instance.
- */
- public SimpleTempStorage() {
- rootPath = new SimpleTempPath(System.getProperty("java.io.tmpdir"));
- }
-
- private TempPath createTempPath(TempPath parent, String prefix)
- throws IOException {
-
- if (prefix == null) {
- prefix = "";
- }
-
- File p = null;
- int count = 1000;
- do {
- long n = Math.abs(random.nextLong());
- p = new File(parent.getAbsolutePath(), prefix + n);
- count--;
- } while (p.exists() && count > 0);
-
- if (p.exists() || !p.mkdirs()) {
- log.error("Unable to mkdirs on " + p.getAbsolutePath());
- throw new IOException("Creating dir '"
- + p.getAbsolutePath() + "' failed.");
- }
-
- return new SimpleTempPath(p);
- }
-
- private TempFile createTempFile(TempPath parent, String prefix,
- String suffix) throws IOException {
-
- if (prefix == null) {
- prefix = "";
- }
- if (suffix == null) {
- suffix = ".tmp";
- }
-
- File f = null;
-
- int count = 1000;
- synchronized (this) {
- do {
- long n = Math.abs(random.nextLong());
- f = new File(parent.getAbsolutePath(), prefix + n + suffix);
- count--;
- } while (f.exists() && count > 0);
-
- if (f.exists()) {
- throw new IOException("Creating temp file failed: "
- + "Unable to find unique file name");
- }
-
- try {
- f.createNewFile();
- } catch (IOException e) {
- throw new IOException("Creating dir '"
- + f.getAbsolutePath() + "' failed.");
- }
- }
-
- return new SimpleTempFile(f);
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempStorage#getRootTempPath()
- */
- public TempPath getRootTempPath() {
- return rootPath;
- }
-
- private class SimpleTempPath implements TempPath {
- private File path = null;
-
- private SimpleTempPath(String path) {
- this.path = new File(path);
- }
-
- private SimpleTempPath(File path) {
- this.path = path;
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#createTempFile()
- */
- public TempFile createTempFile() throws IOException {
- return SimpleTempStorage.this.createTempFile(this, null, null);
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#createTempFile(java.lang.String, java.lang.String)
- */
- public TempFile createTempFile(String prefix, String suffix)
- throws IOException {
-
- return SimpleTempStorage.this.createTempFile(this, prefix, suffix);
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#createTempFile(java.lang.String, java.lang.String, boolean)
- */
- public TempFile createTempFile(String prefix, String suffix,
- boolean allowInMemory)
- throws IOException {
-
- return SimpleTempStorage.this.createTempFile(this, prefix, suffix);
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#getAbsolutePath()
- */
- public String getAbsolutePath() {
- return path.getAbsolutePath();
- }
-
- /**
- * Do nothing
- */
- public void delete() {
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#createTempPath()
- */
- public TempPath createTempPath() throws IOException {
- return SimpleTempStorage.this.createTempPath(this, null);
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempPath#createTempPath(java.lang.String)
- */
- public TempPath createTempPath(String prefix) throws IOException {
- return SimpleTempStorage.this.createTempPath(this, prefix);
- }
-
- }
-
- private class SimpleTempFile implements TempFile {
- private File file = null;
-
- private SimpleTempFile(File file) {
- this.file = file;
- this.file.deleteOnExit();
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempFile#getInputStream()
- */
- public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new FileInputStream(file));
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempFile#getOutputStream()
- */
- public OutputStream getOutputStream() throws IOException {
- return new BufferedOutputStream(new FileOutputStream(file));
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempFile#getAbsolutePath()
- */
- public String getAbsolutePath() {
- return file.getAbsolutePath();
- }
-
- /**
- * Do nothing
- */
- public void delete() {
- // Not implementated
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempFile#isInMemory()
- */
- public boolean isInMemory() {
- return false;
- }
-
- /**
- * @see org.apache.james.mime4j.util.TempFile#length()
- */
- public long length() {
- return file.length();
- }
-
- }
-}
+/****************************************************************
+ * 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.mime4j.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Random;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @version $Id: SimpleTempStorage.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class SimpleTempStorage extends TempStorage {
+ private static Log log = LogFactory.getLog(SimpleTempStorage.class);
+
+ private TempPath rootPath = null;
+ private Random random = new Random();
+
+ /**
+ * Creates a new SimpleTempStorageManager
instance.
+ */
+ public SimpleTempStorage() {
+ rootPath = new SimpleTempPath(System.getProperty("java.io.tmpdir"));
+ }
+
+ private TempPath createTempPath(TempPath parent, String prefix)
+ throws IOException {
+
+ if (prefix == null) {
+ prefix = "";
+ }
+
+ File p = null;
+ int count = 1000;
+ do {
+ long n = Math.abs(random.nextLong());
+ p = new File(parent.getAbsolutePath(), prefix + n);
+ count--;
+ } while (p.exists() && count > 0);
+
+ if (p.exists() || !p.mkdirs()) {
+ log.error("Unable to mkdirs on " + p.getAbsolutePath());
+ throw new IOException("Creating dir '"
+ + p.getAbsolutePath() + "' failed.");
+ }
+
+ return new SimpleTempPath(p);
+ }
+
+ private TempFile createTempFile(TempPath parent, String prefix,
+ String suffix) throws IOException {
+
+ if (prefix == null) {
+ prefix = "";
+ }
+ if (suffix == null) {
+ suffix = ".tmp";
+ }
+
+ File f = null;
+
+ int count = 1000;
+ synchronized (this) {
+ do {
+ long n = Math.abs(random.nextLong());
+ f = new File(parent.getAbsolutePath(), prefix + n + suffix);
+ count--;
+ } while (f.exists() && count > 0);
+
+ if (f.exists()) {
+ throw new IOException("Creating temp file failed: "
+ + "Unable to find unique file name");
+ }
+
+ try {
+ f.createNewFile();
+ } catch (IOException e) {
+ throw new IOException("Creating dir '"
+ + f.getAbsolutePath() + "' failed.");
+ }
+ }
+
+ return new SimpleTempFile(f);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempStorage#getRootTempPath()
+ */
+ public TempPath getRootTempPath() {
+ return rootPath;
+ }
+
+ private class SimpleTempPath implements TempPath {
+ private File path = null;
+
+ private SimpleTempPath(String path) {
+ this.path = new File(path);
+ }
+
+ private SimpleTempPath(File path) {
+ this.path = path;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#createTempFile()
+ */
+ public TempFile createTempFile() throws IOException {
+ return SimpleTempStorage.this.createTempFile(this, null, null);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#createTempFile(java.lang.String, java.lang.String)
+ */
+ public TempFile createTempFile(String prefix, String suffix)
+ throws IOException {
+
+ return SimpleTempStorage.this.createTempFile(this, prefix, suffix);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#createTempFile(java.lang.String, java.lang.String, boolean)
+ */
+ public TempFile createTempFile(String prefix, String suffix,
+ boolean allowInMemory)
+ throws IOException {
+
+ return SimpleTempStorage.this.createTempFile(this, prefix, suffix);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#getAbsolutePath()
+ */
+ public String getAbsolutePath() {
+ return path.getAbsolutePath();
+ }
+
+ /**
+ * Do nothing
+ */
+ public void delete() {
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#createTempPath()
+ */
+ public TempPath createTempPath() throws IOException {
+ return SimpleTempStorage.this.createTempPath(this, null);
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempPath#createTempPath(java.lang.String)
+ */
+ public TempPath createTempPath(String prefix) throws IOException {
+ return SimpleTempStorage.this.createTempPath(this, prefix);
+ }
+
+ }
+
+ private class SimpleTempFile implements TempFile {
+ private File file = null;
+
+ private SimpleTempFile(File file) {
+ this.file = file;
+ this.file.deleteOnExit();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempFile#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return new BufferedInputStream(new FileInputStream(file));
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempFile#getOutputStream()
+ */
+ public OutputStream getOutputStream() throws IOException {
+ return new BufferedOutputStream(new FileOutputStream(file));
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempFile#getAbsolutePath()
+ */
+ public String getAbsolutePath() {
+ return file.getAbsolutePath();
+ }
+
+ /**
+ * Do nothing
+ */
+ public void delete() {
+ // Not implementated
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempFile#isInMemory()
+ */
+ public boolean isInMemory() {
+ return false;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.util.TempFile#length()
+ */
+ public long length() {
+ return file.length();
+ }
+
+ }
+}
diff --git a/src/org/apache/james/mime4j/util/TempFile.java b/src/org/apache/james/mime4j/util/TempFile.java
index f67e1e93ee55f146281268b268d184bb95b1638c..cc2ea6d98ef2d025a55e962d224f4f38c40373a5 100644
--- a/src/org/apache/james/mime4j/util/TempFile.java
+++ b/src/org/apache/james/mime4j/util/TempFile.java
@@ -1,84 +1,84 @@
-/****************************************************************
- * 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.mime4j.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * @version $Id: TempFile.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public interface TempFile {
- /**
- * Gets an InputStream
to read bytes from this temporary file.
- * NOTE: The stream should NOT be wrapped in
- * BufferedInputStream
by the caller. If the implementing
- * TempFile
creates a FileInputStream
or any
- * other stream which would benefit from being buffered it's the
- * TempFile
's responsibility to wrap it.
- *
- * @return the stream.
- * @throws IOException
- */
- InputStream getInputStream() throws IOException;
-
- /**
- * Gets an OutputStream
to write bytes to this temporary file.
- * NOTE: The stream should NOT be wrapped in
- * BufferedOutputStream
by the caller. If the implementing
- * TempFile
creates a FileOutputStream
or any
- * other stream which would benefit from being buffered it's the
- * TempFile
's responsibility to wrap it.
- *
- * @return the stream.
- * @throws IOException
- */
- OutputStream getOutputStream() throws IOException;
-
- /**
- * Returns the absolute path including file name of this
- * TempFile
. The path may be null
if this is
- * an in-memory file.
- *
- * @return the absolute path.
- */
- String getAbsolutePath();
-
- /**
- * Deletes this file as soon as possible.
- */
- void delete();
-
- /**
- * Determines if this is an in-memory file.
- *
- * @return true
if this file is currently in memory,
- * false
otherwise.
- */
- boolean isInMemory();
-
- /**
- * Gets the length of this temporary file.
- *
- * @return the length.
- */
- long length();
-}
+/****************************************************************
+ * 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.mime4j.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @version $Id: TempFile.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public interface TempFile {
+ /**
+ * Gets an InputStream
to read bytes from this temporary file.
+ * NOTE: The stream should NOT be wrapped in
+ * BufferedInputStream
by the caller. If the implementing
+ * TempFile
creates a FileInputStream
or any
+ * other stream which would benefit from being buffered it's the
+ * TempFile
's responsibility to wrap it.
+ *
+ * @return the stream.
+ * @throws IOException
+ */
+ InputStream getInputStream() throws IOException;
+
+ /**
+ * Gets an OutputStream
to write bytes to this temporary file.
+ * NOTE: The stream should NOT be wrapped in
+ * BufferedOutputStream
by the caller. If the implementing
+ * TempFile
creates a FileOutputStream
or any
+ * other stream which would benefit from being buffered it's the
+ * TempFile
's responsibility to wrap it.
+ *
+ * @return the stream.
+ * @throws IOException
+ */
+ OutputStream getOutputStream() throws IOException;
+
+ /**
+ * Returns the absolute path including file name of this
+ * TempFile
. The path may be null
if this is
+ * an in-memory file.
+ *
+ * @return the absolute path.
+ */
+ String getAbsolutePath();
+
+ /**
+ * Deletes this file as soon as possible.
+ */
+ void delete();
+
+ /**
+ * Determines if this is an in-memory file.
+ *
+ * @return true
if this file is currently in memory,
+ * false
otherwise.
+ */
+ boolean isInMemory();
+
+ /**
+ * Gets the length of this temporary file.
+ *
+ * @return the length.
+ */
+ long length();
+}
diff --git a/src/org/apache/james/mime4j/util/TempPath.java b/src/org/apache/james/mime4j/util/TempPath.java
index 3b55aa6db00a4420b2b201906fe661cf7143ddf6..3c4cf8163e0be09ecae52d6a33d571bb0c23e32c 100644
--- a/src/org/apache/james/mime4j/util/TempPath.java
+++ b/src/org/apache/james/mime4j/util/TempPath.java
@@ -1,73 +1,73 @@
-/****************************************************************
- * 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.mime4j.util;
-
-import java.io.IOException;
-
-/**
- *
- * @version $Id: TempPath.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public interface TempPath {
- TempPath createTempPath() throws IOException;
- TempPath createTempPath(String prefix) throws IOException;
-
- /**
- * Creates a new temporary file. Wheter it will be be created in memory
- * or on disk is up to to the implementation.
- * The prefix will be empty and the suffix will be
- * .tmp
if created on disk.
- *
- * @return the temporary file.
- */
- TempFile createTempFile() throws IOException;
-
- /**
- * Creates a new temporary file. Wheter it will be be created in memory
- * or on disk is up to to the implementation.
- * The prefix and suffix can be set by the user.
- *
- * @param prefix the prefix to use. null
gives no prefix.
- * @param suffix the suffix to use. null
gives
- * .tmp
.
- * @return the temporary file.
- */
- TempFile createTempFile(String prefix, String suffix) throws IOException;
-
- /**
- * Creates a new temporary file. Wheter it will be be created in memory
- * or on disk can be specified using the allowInMemory
- * parameter. If the implementation doesn't support in-memory files
- * the new file will be created on disk.
- * The prefix and suffix can be set by the user.
- *
- * @param prefix the prefix to use. null
gives no prefix.
- * @param suffix the suffix to use. null
gives
- * .tmp
.
- * @param allowInMemory if true
the file MIGHT be created in
- * memory if supported by the implentation. If false
the
- * file MUST be created on disk.
- * @return the temporary file.
- */
- TempFile createTempFile(String prefix, String suffix,
- boolean allowInMemory) throws IOException;
- String getAbsolutePath();
- void delete();
-}
+/****************************************************************
+ * 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.mime4j.util;
+
+import java.io.IOException;
+
+/**
+ *
+ * @version $Id: TempPath.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public interface TempPath {
+ TempPath createTempPath() throws IOException;
+ TempPath createTempPath(String prefix) throws IOException;
+
+ /**
+ * Creates a new temporary file. Wheter it will be be created in memory
+ * or on disk is up to to the implementation.
+ * The prefix will be empty and the suffix will be
+ * .tmp
if created on disk.
+ *
+ * @return the temporary file.
+ */
+ TempFile createTempFile() throws IOException;
+
+ /**
+ * Creates a new temporary file. Wheter it will be be created in memory
+ * or on disk is up to to the implementation.
+ * The prefix and suffix can be set by the user.
+ *
+ * @param prefix the prefix to use. null
gives no prefix.
+ * @param suffix the suffix to use. null
gives
+ * .tmp
.
+ * @return the temporary file.
+ */
+ TempFile createTempFile(String prefix, String suffix) throws IOException;
+
+ /**
+ * Creates a new temporary file. Wheter it will be be created in memory
+ * or on disk can be specified using the allowInMemory
+ * parameter. If the implementation doesn't support in-memory files
+ * the new file will be created on disk.
+ * The prefix and suffix can be set by the user.
+ *
+ * @param prefix the prefix to use. null
gives no prefix.
+ * @param suffix the suffix to use. null
gives
+ * .tmp
.
+ * @param allowInMemory if true
the file MIGHT be created in
+ * memory if supported by the implentation. If false
the
+ * file MUST be created on disk.
+ * @return the temporary file.
+ */
+ TempFile createTempFile(String prefix, String suffix,
+ boolean allowInMemory) throws IOException;
+ String getAbsolutePath();
+ void delete();
+}
diff --git a/src/org/apache/james/mime4j/util/TempStorage.java b/src/org/apache/james/mime4j/util/TempStorage.java
index ca951531aa33ed1c9f58a020b49ab3bfd928a4ac..a8546a1e5cff016a97522a24ae6b4e514a1129fc 100644
--- a/src/org/apache/james/mime4j/util/TempStorage.java
+++ b/src/org/apache/james/mime4j/util/TempStorage.java
@@ -1,70 +1,70 @@
-/****************************************************************
- * 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.mime4j.util;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- *
- * @version $Id: TempStorage.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public abstract class TempStorage {
- private static Log log = LogFactory.getLog(TempStorage.class);
- private static TempStorage inst = null;
-
- static {
-
- String clazz = System.getProperty("org.apache.james.mime4j.tempStorage");
- try {
-
- if (inst != null) {
- inst = (TempStorage) Class.forName(clazz).newInstance();
- }
-
- } catch (Throwable t) {
- log.warn("Unable to create or instantiate TempStorage class '"
- + clazz + "' using SimpleTempStorage instead", t);
- }
-
- if (inst == null) {
- inst = new SimpleTempStorage();
- }
- }
-
- /**
- * Gets the root temporary path which should be used to
- * create new temporary paths or files.
- *
- * @return the root temporary path.
- */
- public abstract TempPath getRootTempPath();
-
- public static TempStorage getInstance() {
- return inst;
- }
-
- public static void setInstance(TempStorage inst) {
- if (inst == null) {
- throw new NullPointerException("inst");
- }
- TempStorage.inst = inst;
- }
-}
+/****************************************************************
+ * 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.mime4j.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @version $Id: TempStorage.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public abstract class TempStorage {
+ private static Log log = LogFactory.getLog(TempStorage.class);
+ private static TempStorage inst = null;
+
+ static {
+
+ String clazz = System.getProperty("org.apache.james.mime4j.tempStorage");
+ try {
+
+ if (inst != null) {
+ inst = (TempStorage) Class.forName(clazz).newInstance();
+ }
+
+ } catch (Throwable t) {
+ log.warn("Unable to create or instantiate TempStorage class '"
+ + clazz + "' using SimpleTempStorage instead", t);
+ }
+
+ if (inst == null) {
+ inst = new SimpleTempStorage();
+ }
+ }
+
+ /**
+ * Gets the root temporary path which should be used to
+ * create new temporary paths or files.
+ *
+ * @return the root temporary path.
+ */
+ public abstract TempPath getRootTempPath();
+
+ public static TempStorage getInstance() {
+ return inst;
+ }
+
+ public static void setInstance(TempStorage inst) {
+ if (inst == null) {
+ throw new NullPointerException("inst");
+ }
+ TempStorage.inst = inst;
+ }
+}