1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-27 11:42:16 -05:00

Start building using a JAR of MIME4J

This commit is contained in:
Jesse Vincent 2011-01-31 17:19:58 +00:00
parent eb6e48c7bd
commit 7b2cd531ca
189 changed files with 0 additions and 35719 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,65 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j;
/**
* MIME processing exception.
* <p>
* A <code>MimeException</code> may be thrown by a {@link org.apache.james.mime4j.parser.ContentHandler} to
* indicate that it has failed to process a message event and that no further
* events should be generated.
* <p>
* <code>MimeException</code> also gets thrown by the parser to indicate MIME
* protocol errors, e.g. if a message boundary is too long or a header field
* cannot be parsed.
*/
public class MimeException extends Exception {
private static final long serialVersionUID = 8352821278714188542L;
/**
* Constructs a new MIME exception with the specified detail message.
*
* @param message detail message
*/
public MimeException(String message) {
super(message);
}
/**
* Constructs a MIME exception with the specified cause.
*
* @param cause cause of the exception
*/
public MimeException(Throwable cause) {
super(cause);
}
/**
* Constructs a MIME exception with the specified detail message and cause.
*
* @param message detail message
* @param cause cause of the exception
*/
public MimeException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,58 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j;
import java.io.IOException;
/**
* A wrapper class based on {@link IOException} for MIME protocol exceptions.
* <p>
* This exception is used to signal a <code>MimeException</code> in methods
* that only permit <code>IOException</code> to be thrown.
* <p>
* The cause of a <code>MimeIOException</code> is always a
* <code>MimeException</code> therefore.
*/
public class MimeIOException extends IOException {
private static final long serialVersionUID = 5393613459533735409L;
/**
* Constructs an IO exception based on {@link MimeException}.
*
* @param cause the cause.
*/
public MimeIOException(MimeException cause) {
super(cause == null ? null : cause.getMessage());
initCause(cause);
}
/**
* Returns the <code>MimeException</code> that caused this
* <code>MimeIOException</code>.
*
* @return the cause of this <code>MimeIOException</code>.
*/
@Override
public MimeException getCause() {
return (MimeException) super.getCause();
}
}

View File

@ -1,286 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.IOException;
import java.io.InputStream;
import org.apache.james.mime4j.util.ByteArrayBuffer;
/**
* Performs Base-64 decoding on an underlying stream.
*/
public class Base64InputStream extends InputStream {
private static final int ENCODED_BUFFER_SIZE = 1536;
private static final int[] BASE64_DECODE = new int[256];
static {
for (int i = 0; i < 256; i++)
BASE64_DECODE[i] = -1;
for (int i = 0; i < Base64OutputStream.BASE64_TABLE.length; i++)
BASE64_DECODE[Base64OutputStream.BASE64_TABLE[i] & 0xff] = i;
}
private static final byte BASE64_PAD = '=';
private static final int EOF = -1;
private final byte[] singleByte = new byte[1];
private final InputStream in;
private final byte[] encoded;
private final ByteArrayBuffer decodedBuf;
private int position = 0; // current index into encoded buffer
private int size = 0; // current size of encoded buffer
private boolean closed = false;
private boolean eof; // end of file or pad character reached
private final DecodeMonitor monitor;
public Base64InputStream(InputStream in, DecodeMonitor monitor) {
this(ENCODED_BUFFER_SIZE, in, monitor);
}
protected Base64InputStream(int bufsize, InputStream in, DecodeMonitor monitor) {
if (in == null)
throw new IllegalArgumentException();
this.encoded = new byte[bufsize];
this.decodedBuf = new ByteArrayBuffer(512);
this.in = in;
this.monitor = monitor;
}
public Base64InputStream(InputStream in) {
this(in, false);
}
public Base64InputStream(InputStream in, boolean strict) {
this(ENCODED_BUFFER_SIZE, in, strict ? DecodeMonitor.STRICT : DecodeMonitor.SILENT);
}
@Override
public int read() throws IOException {
if (closed)
throw new IOException("Stream has been closed");
while (true) {
int bytes = read0(singleByte, 0, 1);
if (bytes == EOF)
return EOF;
if (bytes == 1)
return singleByte[0] & 0xff;
}
}
@Override
public int read(byte[] buffer) throws IOException {
if (closed)
throw new IOException("Stream has been closed");
if (buffer == null)
throw new NullPointerException();
if (buffer.length == 0)
return 0;
return read0(buffer, 0, buffer.length);
}
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
if (closed)
throw new IOException("Stream has been closed");
if (buffer == null)
throw new NullPointerException();
if (offset < 0 || length < 0 || offset + length > buffer.length)
throw new IndexOutOfBoundsException();
if (length == 0)
return 0;
return read0(buffer, offset, length);
}
@Override
public void close() throws IOException {
if (closed)
return;
closed = true;
}
private int read0(final byte[] buffer, final int off, final int len) throws IOException {
int from = off;
int to = off + len;
int index = off;
// check if a previous invocation left decoded content
if (decodedBuf.length() > 0) {
int chunk = Math.min(decodedBuf.length(), len);
System.arraycopy(decodedBuf.buffer(), 0, buffer, index, chunk);
decodedBuf.remove(0, chunk);
index += chunk;
}
// eof or pad reached?
if (eof)
return index == from ? EOF : index - from;
// decode into given buffer
int data = 0; // holds decoded data; up to four sextets
int sextets = 0; // number of sextets
while (index < to) {
// make sure buffer not empty
while (position == size) {
int n = in.read(encoded, 0, encoded.length);
if (n == EOF) {
eof = true;
if (sextets != 0) {
// error in encoded data
handleUnexpectedEof(sextets);
}
return index == from ? EOF : index - from;
} else if (n > 0) {
position = 0;
size = n;
} else {
assert n == 0;
}
}
// decode buffer
while (position < size && index < to) {
int value = encoded[position++] & 0xff;
if (value == BASE64_PAD) {
index = decodePad(data, sextets, buffer, index, to);
return index - from;
}
int decoded = BASE64_DECODE[value];
if (decoded < 0) { // -1: not a base64 char
if (value != 0x0D && value != 0x0A && value != 0x20) {
if (monitor.warn("Unexpected base64 byte: "+(byte) value, "ignoring."))
throw new IOException("Unexpected base64 byte");
}
continue;
}
data = (data << 6) | decoded;
sextets++;
if (sextets == 4) {
sextets = 0;
byte b1 = (byte) (data >>> 16);
byte b2 = (byte) (data >>> 8);
byte b3 = (byte) data;
if (index < to - 2) {
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
} else {
if (index < to - 1) {
buffer[index++] = b1;
buffer[index++] = b2;
decodedBuf.append(b3);
} else if (index < to) {
buffer[index++] = b1;
decodedBuf.append(b2);
decodedBuf.append(b3);
} else {
decodedBuf.append(b1);
decodedBuf.append(b2);
decodedBuf.append(b3);
}
assert index == to;
return to - from;
}
}
}
}
assert sextets == 0;
assert index == to;
return to - from;
}
private int decodePad(int data, int sextets, final byte[] buffer,
int index, final int end) throws IOException {
eof = true;
if (sextets == 2) {
// one byte encoded as "XY=="
byte b = (byte) (data >>> 4);
if (index < end) {
buffer[index++] = b;
} else {
decodedBuf.append(b);
}
} else if (sextets == 3) {
// two bytes encoded as "XYZ="
byte b1 = (byte) (data >>> 10);
byte b2 = (byte) ((data >>> 2) & 0xFF);
if (index < end - 1) {
buffer[index++] = b1;
buffer[index++] = b2;
} else if (index < end) {
buffer[index++] = b1;
decodedBuf.append(b2);
} else {
decodedBuf.append(b1);
decodedBuf.append(b2);
}
} else {
// error in encoded data
handleUnexpecedPad(sextets);
}
return index;
}
private void handleUnexpectedEof(int sextets) throws IOException {
if (monitor.warn("Unexpected end of BASE64 stream", "dropping " + sextets + " sextet(s)"))
throw new IOException("Unexpected end of BASE64 stream");
}
private void handleUnexpecedPad(int sextets) throws IOException {
if (monitor.warn("Unexpected padding character", "dropping " + sextets + " sextet(s)"))
throw new IOException("Unexpected padding character");
}
}

View File

@ -1,321 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
/**
* This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite>
* from RFC 2045 <cite>Multipurpose Internet Mail Extensions (MIME) Part One:
* Format of Internet Message Bodies</cite> by Freed and Borenstein.
* <p>
* Code is based on Base64 and Base64OutputStream code from Commons-Codec 1.4.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
*/
public class Base64OutputStream extends FilterOutputStream {
// Default line length per RFC 2045 section 6.8.
private static final int DEFAULT_LINE_LENGTH = 76;
// CRLF line separator per RFC 2045 section 2.1.
private static final byte[] CRLF_SEPARATOR = { '\r', '\n' };
// This array is a lookup table that translates 6-bit positive integer index
// values into their "Base64 Alphabet" equivalents as specified in Table 1
// of RFC 2045.
static final byte[] BASE64_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '+', '/' };
// Byte used to pad output.
private static final byte BASE64_PAD = '=';
// This set contains all base64 characters including the pad character. Used
// solely to check if a line separator contains any of these characters.
private static final Set<Byte> BASE64_CHARS = new HashSet<Byte>();
static {
for (byte b : BASE64_TABLE) {
BASE64_CHARS.add(b);
}
BASE64_CHARS.add(BASE64_PAD);
}
// Mask used to extract 6 bits
private static final int MASK_6BITS = 0x3f;
private static final int ENCODED_BUFFER_SIZE = 2048;
private final byte[] singleByte = new byte[1];
private final int lineLength;
private final byte[] lineSeparator;
private boolean closed = false;
private final byte[] encoded;
private int position = 0;
private int data = 0;
private int modulus = 0;
private int linePosition = 0;
/**
* Creates a <code>Base64OutputStream</code> that writes the encoded data
* to the given output stream using the default line length (76) and line
* separator (CRLF).
*
* @param out
* underlying output stream.
*/
public Base64OutputStream(OutputStream out) {
this(out, DEFAULT_LINE_LENGTH, CRLF_SEPARATOR);
}
/**
* Creates a <code>Base64OutputStream</code> that writes the encoded data
* to the given output stream using the given line length and the default
* line separator (CRLF).
* <p>
* The given line length will be rounded up to the nearest multiple of 4. If
* the line length is zero then the output will not be split into lines.
*
* @param out
* underlying output stream.
* @param lineLength
* desired line length.
*/
public Base64OutputStream(OutputStream out, int lineLength) {
this(out, lineLength, CRLF_SEPARATOR);
}
/**
* Creates a <code>Base64OutputStream</code> that writes the encoded data
* to the given output stream using the given line length and line
* separator.
* <p>
* The given line length will be rounded up to the nearest multiple of 4. If
* the line length is zero then the output will not be split into lines and
* the line separator is ignored.
* <p>
* The line separator must not include characters from the BASE64 alphabet
* (including the padding character <code>=</code>).
*
* @param out
* underlying output stream.
* @param lineLength
* desired line length.
* @param lineSeparator
* line separator to use.
*/
public Base64OutputStream(OutputStream out, int lineLength,
byte[] lineSeparator) {
super(out);
if (out == null)
throw new IllegalArgumentException();
if (lineLength < 0)
throw new IllegalArgumentException();
checkLineSeparator(lineSeparator);
this.lineLength = lineLength;
this.lineSeparator = new byte[lineSeparator.length];
System.arraycopy(lineSeparator, 0, this.lineSeparator, 0,
lineSeparator.length);
this.encoded = new byte[ENCODED_BUFFER_SIZE];
}
@Override
public final void write(final int b) throws IOException {
if (closed)
throw new IOException("Base64OutputStream has been closed");
singleByte[0] = (byte) b;
write0(singleByte, 0, 1);
}
@Override
public final void write(final byte[] buffer) throws IOException {
if (closed)
throw new IOException("Base64OutputStream has been closed");
if (buffer == null)
throw new NullPointerException();
if (buffer.length == 0)
return;
write0(buffer, 0, buffer.length);
}
@Override
public final void write(final byte[] buffer, final int offset,
final int length) throws IOException {
if (closed)
throw new IOException("Base64OutputStream has been closed");
if (buffer == null)
throw new NullPointerException();
if (offset < 0 || length < 0 || offset + length > buffer.length)
throw new IndexOutOfBoundsException();
if (length == 0)
return;
write0(buffer, offset, offset + length);
}
@Override
public void flush() throws IOException {
if (closed)
throw new IOException("Base64OutputStream has been closed");
flush0();
}
@Override
public void close() throws IOException {
if (closed)
return;
closed = true;
close0();
}
private void write0(final byte[] buffer, final int from, final int to)
throws IOException {
for (int i = from; i < to; i++) {
data = (data << 8) | (buffer[i] & 0xff);
if (++modulus == 3) {
modulus = 0;
// write line separator if necessary
if (lineLength > 0 && linePosition >= lineLength) {
// writeLineSeparator() inlined for performance reasons
linePosition = 0;
if (encoded.length - position < lineSeparator.length)
flush0();
for (byte ls : lineSeparator)
encoded[position++] = ls;
}
// encode data into 4 bytes
if (encoded.length - position < 4)
flush0();
encoded[position++] = BASE64_TABLE[(data >> 18) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[(data >> 12) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[(data >> 6) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[data & MASK_6BITS];
linePosition += 4;
}
}
}
private void flush0() throws IOException {
if (position > 0) {
out.write(encoded, 0, position);
position = 0;
}
}
private void close0() throws IOException {
if (modulus != 0)
writePad();
// write line separator at the end of the encoded data
if (lineLength > 0 && linePosition > 0) {
writeLineSeparator();
}
flush0();
}
private void writePad() throws IOException {
// write line separator if necessary
if (lineLength > 0 && linePosition >= lineLength) {
writeLineSeparator();
}
// encode data into 4 bytes
if (encoded.length - position < 4)
flush0();
if (modulus == 1) {
encoded[position++] = BASE64_TABLE[(data >> 2) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[(data << 4) & MASK_6BITS];
encoded[position++] = BASE64_PAD;
encoded[position++] = BASE64_PAD;
} else {
assert modulus == 2;
encoded[position++] = BASE64_TABLE[(data >> 10) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[(data >> 4) & MASK_6BITS];
encoded[position++] = BASE64_TABLE[(data << 2) & MASK_6BITS];
encoded[position++] = BASE64_PAD;
}
linePosition += 4;
}
private void writeLineSeparator() throws IOException {
linePosition = 0;
if (encoded.length - position < lineSeparator.length)
flush0();
for (byte ls : lineSeparator)
encoded[position++] = ls;
}
private void checkLineSeparator(byte[] lineSeparator) {
if (lineSeparator.length > ENCODED_BUFFER_SIZE)
throw new IllegalArgumentException("line separator length exceeds "
+ ENCODED_BUFFER_SIZE);
for (byte b : lineSeparator) {
if (BASE64_CHARS.contains(b)) {
throw new IllegalArgumentException(
"line separator must not contain base64 character '"
+ (char) (b & 0xff) + "'");
}
}
}
}

View File

@ -1,108 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Utility methods related to codecs.
*/
public class CodecUtil {
static final int DEFAULT_ENCODING_BUFFER_SIZE = 1024;
/**
* Copies the contents of one stream to the other.
* @param in not null
* @param out not null
* @throws IOException
*/
public static void copy(final InputStream in, final OutputStream out) throws IOException {
final byte[] buffer = new byte[DEFAULT_ENCODING_BUFFER_SIZE];
int inputLength;
while (-1 != (inputLength = in.read(buffer))) {
out.write(buffer, 0, inputLength);
}
}
/**
* Encodes the given stream using Quoted-Printable.
* This assumes that stream is binary and therefore escapes
* all line endings.
* @param in not null
* @param out not null
* @throws IOException
*/
public static void encodeQuotedPrintableBinary(final InputStream in, final OutputStream out) throws IOException {
QuotedPrintableOutputStream qpOut = new QuotedPrintableOutputStream(out, true);
copy(in, qpOut);
qpOut.close();
}
/**
* Encodes the given stream using Quoted-Printable.
* This assumes that stream is text and therefore does not escape
* all line endings.
* @param in not null
* @param out not null
* @throws IOException
*/
public static void encodeQuotedPrintable(final InputStream in, final OutputStream out) throws IOException {
QuotedPrintableOutputStream qpOut = new QuotedPrintableOutputStream(out, false);
copy(in, qpOut);
qpOut.close();
}
/**
* Encodes the given stream using base64.
*
* @param in not null
* @param out not null
* @throws IOException if an I/O error occurs
*/
public static void encodeBase64(final InputStream in, final OutputStream out) throws IOException {
Base64OutputStream b64Out = new Base64OutputStream(out);
copy(in, b64Out);
b64Out.close();
}
/**
* Wraps the given stream in a Quoted-Printable encoder.
* @param out not null
* @return encoding outputstream
* @throws IOException
*/
public static OutputStream wrapQuotedPrintable(final OutputStream out, boolean binary) throws IOException {
return new QuotedPrintableOutputStream(out, binary);
}
/**
* Wraps the given stream in a Base64 encoder.
* @param out not null
* @return encoding outputstream
* @throws IOException
*/
public static OutputStream wrapBase64(final OutputStream out) throws IOException {
return new Base64OutputStream(out);
}
}

View File

@ -1,65 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
/**
* This class is used to drive how decoder/parser should deal with malformed
* and unexpected data.
*
* 2 basic implementations are provided:
* STRICT return "true" on any occourence.
* SILENT ignores any problem.
*
* @see org.apache.james.mime4j.field.LoggingMonitor for an example
* about logging malformations via Commons-logging.
*/
public class DecodeMonitor {
/**
* The STRICT monitor throws an exception on every event.
*/
public static final DecodeMonitor STRICT = new DecodeMonitor() {
@Override
public boolean warn(String error, String dropDesc) {
return true;
}
@Override
public boolean isListening() {
return true;
}
};
/**
* The SILENT monitor ignore requests.
*/
public static final DecodeMonitor SILENT = new DecodeMonitor();
public boolean warn(String error, String dropDesc) {
return false;
}
public boolean isListening() {
return false;
}
}

View File

@ -1,260 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.james.mime4j.util.CharsetUtil;
/**
* Static methods for decoding strings, byte arrays and encoded words.
*/
public class DecoderUtil {
private static final Pattern PATTERN_ENCODED_WORD = Pattern.compile(
"(.*?)=\\?([^\\?]+?)\\?(\\w)\\?([^\\?]+?)\\?=", Pattern.DOTALL);
/**
* Decodes a string containing quoted-printable encoded data.
*
* @param s the string to decode.
* @return the decoded bytes.
*/
private static byte[] decodeQuotedPrintable(String s, DecodeMonitor monitor) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] bytes = s.getBytes("US-ASCII");
QuotedPrintableInputStream is = new QuotedPrintableInputStream(
new ByteArrayInputStream(bytes), monitor);
int b = 0;
while ((b = is.read()) != -1) {
baos.write(b);
}
} catch (IOException e) {
// This should never happen!
throw new IllegalStateException(e);
}
return baos.toByteArray();
}
/**
* Decodes a string containing base64 encoded data.
*
* @param s the string to decode.
* @param monitor
* @return the decoded bytes.
*/
private static byte[] decodeBase64(String s, DecodeMonitor monitor) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] bytes = s.getBytes("US-ASCII");
Base64InputStream is = new Base64InputStream(
new ByteArrayInputStream(bytes), monitor);
int b = 0;
while ((b = is.read()) != -1) {
baos.write(b);
}
} catch (IOException e) {
// This should never happen!
throw new IllegalStateException(e);
}
return baos.toByteArray();
}
/**
* Decodes an encoded text encoded with the 'B' encoding (described in
* RFC 2047) found in a header field body.
*
* @param encodedText the encoded text to decode.
* @param charset the Java charset to use.
* @param monitor
* @return the decoded string.
* @throws UnsupportedEncodingException if the given Java charset isn't
* supported.
*/
static String decodeB(String encodedText, String charset, DecodeMonitor monitor)
throws UnsupportedEncodingException {
byte[] decodedBytes = decodeBase64(encodedText, monitor);
return new String(decodedBytes, charset);
}
/**
* Decodes an encoded text encoded with the 'Q' encoding (described in
* RFC 2047) found in a header field body.
*
* @param encodedText the encoded text to decode.
* @param charset the Java charset to use.
* @return the decoded string.
* @throws UnsupportedEncodingException if the given Java charset isn't
* supported.
*/
static String decodeQ(String encodedText, String charset, DecodeMonitor monitor)
throws UnsupportedEncodingException {
encodedText = replaceUnderscores(encodedText);
byte[] decodedBytes = decodeQuotedPrintable(encodedText, monitor);
return new String(decodedBytes, charset);
}
static String decodeEncodedWords(String body) {
return decodeEncodedWords(body, DecodeMonitor.SILENT);
}
/**
* Decodes a string containing encoded words as defined by RFC 2047. Encoded
* words have the form =?charset?enc?encoded-text?= where enc is either 'Q'
* or 'q' for quoted-printable and 'B' or 'b' for base64.
*
* @param body the string to decode
* @param monitor the DecodeMonitor to be used.
* @return the decoded string.
* @throws IllegalArgumentException only if the DecodeMonitor strategy throws it (Strict parsing)
*/
public static String decodeEncodedWords(String body, DecodeMonitor monitor) throws IllegalArgumentException {
int tailIndex = 0;
boolean lastMatchValid = false;
StringBuilder sb = new StringBuilder();
for (Matcher matcher = PATTERN_ENCODED_WORD.matcher(body); matcher.find();) {
String separator = matcher.group(1);
String mimeCharset = matcher.group(2);
String encoding = matcher.group(3);
String encodedText = matcher.group(4);
String decoded = null;
decoded = tryDecodeEncodedWord(mimeCharset, encoding, encodedText, monitor);
if (decoded == null) {
sb.append(matcher.group(0));
} else {
if (!lastMatchValid || !CharsetUtil.isWhitespace(separator)) {
sb.append(separator);
}
sb.append(decoded);
}
tailIndex = matcher.end();
lastMatchValid = decoded != null;
}
if (tailIndex == 0) {
return body;
} else {
sb.append(body.substring(tailIndex));
return sb.toString();
}
}
// return null on error
private static String tryDecodeEncodedWord(final String mimeCharset,
final String encoding, final String encodedText, DecodeMonitor monitor) throws IllegalArgumentException {
String charset = CharsetUtil.toJavaCharset(mimeCharset);
if (charset == null) {
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Mime charser '", mimeCharset, "' doesn't have a corresponding Java charset");
return null;
} else if (!CharsetUtil.isDecodingSupported(charset)) {
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Current JDK doesn't support decoding of charset '", charset,
"' - MIME charset '", mimeCharset, "' in encoded word");
return null;
}
if (encodedText.length() == 0) {
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Missing encoded text in encoded word");
return null;
}
try {
if (encoding.equalsIgnoreCase("Q")) {
return DecoderUtil.decodeQ(encodedText, charset, monitor);
} else if (encoding.equalsIgnoreCase("B")) {
return DecoderUtil.decodeB(encodedText, charset, monitor);
} else {
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Warning: Unknown encoding in encoded word");
return null;
}
} catch (UnsupportedEncodingException e) {
// should not happen because of isDecodingSupported check above
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Unsupported encoding (", e.getMessage(), ") in encoded word");
return null;
} catch (RuntimeException e) {
monitor(monitor, mimeCharset, encoding, encodedText, "leaving word encoded",
"Could not decode (", e.getMessage(), ") encoded word");
return null;
}
}
private static void monitor(DecodeMonitor monitor, String mimeCharset, String encoding,
String encodedText, String dropDesc, String... strings) throws IllegalArgumentException {
if (monitor.isListening()) {
String encodedWord = recombine(mimeCharset, encoding, encodedText);
StringBuilder text = new StringBuilder();
for (String str : strings) {
text.append(str);
}
text.append(" (");
text.append(encodedWord);
text.append(")");
String exceptionDesc = text.toString();
if (monitor.warn(exceptionDesc, dropDesc))
throw new IllegalArgumentException(text.toString());
}
}
private static String recombine(final String mimeCharset,
final String encoding, final String encodedText) {
return "=?" + mimeCharset + "?" + encoding + "?" + encodedText + "?=";
}
// Replace _ with =20
private static String replaceUnderscores(String str) {
// probably faster than String#replace(CharSequence, CharSequence)
StringBuilder sb = new StringBuilder(128);
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '_') {
sb.append("=20");
} else {
sb.append(c);
}
}
return sb.toString();
}
}

View File

@ -1,609 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.BitSet;
import java.util.Locale;
import org.apache.james.mime4j.util.CharsetUtil;
/**
* Static methods for encoding header field values. This includes encoded-words
* as defined in <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a>
* or display-names of an e-mail address, for example.
*/
public class EncoderUtil {
private static final byte[] BASE64_TABLE = Base64OutputStream.BASE64_TABLE;
private static final char BASE64_PAD = '=';
private static final BitSet Q_REGULAR_CHARS = initChars("=_?");
private static final BitSet Q_RESTRICTED_CHARS = initChars("=_?\"#$%&'(),.:;<>@[\\]^`{|}~");
private static final int MAX_USED_CHARACTERS = 50;
private static final String ENC_WORD_PREFIX = "=?";
private static final String ENC_WORD_SUFFIX = "?=";
private static final int ENCODED_WORD_MAX_LENGTH = 75; // RFC 2047
private static final BitSet TOKEN_CHARS = initChars("()<>@,;:\\\"/[]?=");
private static final BitSet ATEXT_CHARS = initChars("()<>@.,;:\\\"[]");
private static BitSet initChars(String specials) {
BitSet bs = new BitSet(128);
for (char ch = 33; ch < 127; ch++) {
if (specials.indexOf(ch) == -1) {
bs.set(ch);
}
}
return bs;
}
/**
* Selects one of the two encodings specified in RFC 2047.
*/
public enum Encoding {
/** The B encoding (identical to base64 defined in RFC 2045). */
B,
/** The Q encoding (similar to quoted-printable defined in RFC 2045). */
Q
}
/**
* Indicates the intended usage of an encoded word.
*/
public enum Usage {
/**
* Encoded word is used to replace a 'text' token in any Subject or
* Comments header field.
*/
TEXT_TOKEN,
/**
* Encoded word is used to replace a 'word' entity within a 'phrase',
* for example, one that precedes an address in a From, To, or Cc
* header.
*/
WORD_ENTITY
}
private EncoderUtil() {
}
/**
* Encodes the display-name portion of an address. See <a
* href='http://www.faqs.org/rfcs/rfc5322.html'>RFC 5322</a> section 3.4
* and <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a> section
* 5.3. The specified string should not be folded.
*
* @param displayName
* display-name to encode.
* @return encoded display-name.
*/
public static String encodeAddressDisplayName(String displayName) {
// display-name = phrase
// phrase = 1*( encoded-word / word )
// word = atom / quoted-string
// atom = [CFWS] 1*atext [CFWS]
// CFWS = comment or folding white space
if (isAtomPhrase(displayName)) {
return displayName;
} else if (hasToBeEncoded(displayName, 0)) {
return encodeEncodedWord(displayName, Usage.WORD_ENTITY);
} else {
return quote(displayName);
}
}
/**
* Encodes the local part of an address specification as described in RFC
* 5322 section 3.4.1. Leading and trailing CFWS should have been removed
* before calling this method. The specified string should not contain any
* illegal (control or non-ASCII) characters.
*
* @param localPart
* the local part to encode
* @return the encoded local part.
*/
public static String encodeAddressLocalPart(String localPart) {
// local-part = dot-atom / quoted-string
// dot-atom = [CFWS] dot-atom-text [CFWS]
// CFWS = comment or folding white space
if (isDotAtomText(localPart)) {
return localPart;
} else {
return quote(localPart);
}
}
/**
* Encodes the specified strings into a header parameter as described in RFC
* 2045 section 5.1 and RFC 2183 section 2. The specified strings should not
* contain any illegal (control or non-ASCII) characters.
*
* @param name
* parameter name.
* @param value
* parameter value.
* @return encoded result.
*/
public static String encodeHeaderParameter(String name, String value) {
name = name.toLowerCase(Locale.US);
// value := token / quoted-string
if (isToken(value)) {
return name + "=" + value;
} else {
return name + "=" + quote(value);
}
}
/**
* Shortcut method that encodes the specified text into an encoded-word if
* the text has to be encoded.
*
* @param text
* text to encode.
* @param usage
* whether the encoded-word is to be used to replace a text token
* or a word entity (see RFC 822).
* @param usedCharacters
* number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
* @return the specified text if encoding is not necessary or an encoded
* word or a sequence of encoded words otherwise.
*/
public static String encodeIfNecessary(String text, Usage usage,
int usedCharacters) {
if (hasToBeEncoded(text, usedCharacters))
return encodeEncodedWord(text, usage, usedCharacters);
else
return text;
}
/**
* Determines if the specified string has to encoded into an encoded-word.
* Returns <code>true</code> if the text contains characters that don't
* fall into the printable ASCII character set or if the text contains a
* 'word' (sequence of non-whitespace characters) longer than 77 characters
* (including characters already used up in the line).
*
* @param text
* text to analyze.
* @param usedCharacters
* number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
* @return <code>true</code> if the specified text has to be encoded into
* an encoded-word, <code>false</code> otherwise.
*/
public static boolean hasToBeEncoded(String text, int usedCharacters) {
if (text == null)
throw new IllegalArgumentException();
if (usedCharacters < 0 || usedCharacters > MAX_USED_CHARACTERS)
throw new IllegalArgumentException();
int nonWhiteSpaceCount = usedCharacters;
for (int idx = 0; idx < text.length(); idx++) {
char ch = text.charAt(idx);
if (ch == '\t' || ch == ' ') {
nonWhiteSpaceCount = 0;
} else {
nonWhiteSpaceCount++;
if (nonWhiteSpaceCount > 77) {
// Line cannot be folded into multiple lines with no more
// than 78 characters each. Encoding as encoded-words makes
// that possible. One character has to be reserved for
// folding white space; that leaves 77 characters.
return true;
}
if (ch < 32 || ch >= 127) {
// non-printable ascii character has to be encoded
return true;
}
}
}
return false;
}
/**
* Encodes the specified text into an encoded word or a sequence of encoded
* words separated by space. The text is separated into a sequence of
* encoded words if it does not fit in a single one.
* <p>
* The charset to encode the specified text into a byte array and the
* encoding to use for the encoded-word are detected automatically.
* <p>
* This method assumes that zero characters have already been used up in the
* current line.
*
* @param text
* text to encode.
* @param usage
* whether the encoded-word is to be used to replace a text token
* or a word entity (see RFC 822).
* @return the encoded word (or sequence of encoded words if the given text
* does not fit in a single encoded word).
* @see #hasToBeEncoded(String, int)
*/
public static String encodeEncodedWord(String text, Usage usage) {
return encodeEncodedWord(text, usage, 0, null, null);
}
/**
* Encodes the specified text into an encoded word or a sequence of encoded
* words separated by space. The text is separated into a sequence of
* encoded words if it does not fit in a single one.
* <p>
* The charset to encode the specified text into a byte array and the
* encoding to use for the encoded-word are detected automatically.
*
* @param text
* text to encode.
* @param usage
* whether the encoded-word is to be used to replace a text token
* or a word entity (see RFC 822).
* @param usedCharacters
* number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
* @return the encoded word (or sequence of encoded words if the given text
* does not fit in a single encoded word).
* @see #hasToBeEncoded(String, int)
*/
public static String encodeEncodedWord(String text, Usage usage,
int usedCharacters) {
return encodeEncodedWord(text, usage, usedCharacters, null, null);
}
/**
* Encodes the specified text into an encoded word or a sequence of encoded
* words separated by space. The text is separated into a sequence of
* encoded words if it does not fit in a single one.
*
* @param text
* text to encode.
* @param usage
* whether the encoded-word is to be used to replace a text token
* or a word entity (see RFC 822).
* @param usedCharacters
* number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
* @param charset
* the Java charset that should be used to encode the specified
* string into a byte array. A suitable charset is detected
* automatically if this parameter is <code>null</code>.
* @param encoding
* the encoding to use for the encoded-word (either B or Q). A
* suitable encoding is automatically chosen if this parameter is
* <code>null</code>.
* @return the encoded word (or sequence of encoded words if the given text
* does not fit in a single encoded word).
* @see #hasToBeEncoded(String, int)
*/
public static String encodeEncodedWord(String text, Usage usage,
int usedCharacters, Charset charset, Encoding encoding) {
if (text == null)
throw new IllegalArgumentException();
if (usedCharacters < 0 || usedCharacters > MAX_USED_CHARACTERS)
throw new IllegalArgumentException();
if (charset == null)
charset = determineCharset(text);
String mimeCharset = CharsetUtil.toMimeCharset(charset.name());
if (mimeCharset == null) {
// cannot happen if charset was originally null
throw new IllegalArgumentException("Unsupported charset");
}
byte[] bytes = encode(text, charset);
if (encoding == null)
encoding = determineEncoding(bytes, usage);
if (encoding == Encoding.B) {
String prefix = ENC_WORD_PREFIX + mimeCharset + "?B?";
return encodeB(prefix, text, usedCharacters, charset, bytes);
} else {
String prefix = ENC_WORD_PREFIX + mimeCharset + "?Q?";
return encodeQ(prefix, text, usage, usedCharacters, charset, bytes);
}
}
/**
* Encodes the specified byte array using the B encoding defined in RFC
* 2047.
*
* @param bytes
* byte array to encode.
* @return encoded string.
*/
public static String encodeB(byte[] bytes) {
StringBuilder sb = new StringBuilder();
int idx = 0;
final int end = bytes.length;
for (; idx < end - 2; idx += 3) {
int data = (bytes[idx] & 0xff) << 16 | (bytes[idx + 1] & 0xff) << 8
| bytes[idx + 2] & 0xff;
sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
sb.append((char) BASE64_TABLE[data >> 6 & 0x3f]);
sb.append((char) BASE64_TABLE[data & 0x3f]);
}
if (idx == end - 2) {
int data = (bytes[idx] & 0xff) << 16 | (bytes[idx + 1] & 0xff) << 8;
sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
sb.append((char) BASE64_TABLE[data >> 6 & 0x3f]);
sb.append(BASE64_PAD);
} else if (idx == end - 1) {
int data = (bytes[idx] & 0xff) << 16;
sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
sb.append(BASE64_PAD);
sb.append(BASE64_PAD);
}
return sb.toString();
}
/**
* Encodes the specified byte array using the Q encoding defined in RFC
* 2047.
*
* @param bytes
* byte array to encode.
* @param usage
* whether the encoded-word is to be used to replace a text token
* or a word entity (see RFC 822).
* @return encoded string.
*/
public static String encodeQ(byte[] bytes, Usage usage) {
BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
: Q_RESTRICTED_CHARS;
StringBuilder sb = new StringBuilder();
final int end = bytes.length;
for (int idx = 0; idx < end; idx++) {
int v = bytes[idx] & 0xff;
if (v == 32) {
sb.append('_');
} else if (!qChars.get(v)) {
sb.append('=');
sb.append(hexDigit(v >>> 4));
sb.append(hexDigit(v & 0xf));
} else {
sb.append((char) v);
}
}
return sb.toString();
}
/**
* Tests whether the specified string is a token as defined in RFC 2045
* section 5.1.
*
* @param str
* string to test.
* @return <code>true</code> if the specified string is a RFC 2045 token,
* <code>false</code> otherwise.
*/
public static boolean isToken(String str) {
// token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
// tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" /
// <"> / "/" / "[" / "]" / "?" / "="
// CTL := 0.- 31., 127.
final int length = str.length();
if (length == 0)
return false;
for (int idx = 0; idx < length; idx++) {
char ch = str.charAt(idx);
if (!TOKEN_CHARS.get(ch))
return false;
}
return true;
}
private static boolean isAtomPhrase(String str) {
// atom = [CFWS] 1*atext [CFWS]
boolean containsAText = false;
final int length = str.length();
for (int idx = 0; idx < length; idx++) {
char ch = str.charAt(idx);
if (ATEXT_CHARS.get(ch)) {
containsAText = true;
} else if (!CharsetUtil.isWhitespace(ch)) {
return false;
}
}
return containsAText;
}
// RFC 5322 section 3.2.3
private static boolean isDotAtomText(String str) {
// dot-atom-text = 1*atext *("." 1*atext)
// atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" /
// "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
char prev = '.';
final int length = str.length();
if (length == 0)
return false;
for (int idx = 0; idx < length; idx++) {
char ch = str.charAt(idx);
if (ch == '.') {
if (prev == '.' || idx == length - 1)
return false;
} else {
if (!ATEXT_CHARS.get(ch))
return false;
}
prev = ch;
}
return true;
}
// RFC 5322 section 3.2.4
private static String quote(String str) {
// quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
// qcontent = qtext / quoted-pair
// qtext = %d33 / %d35-91 / %d93-126
// quoted-pair = ("\" (VCHAR / WSP))
// VCHAR = %x21-7E
// DQUOTE = %x22
String escaped = str.replaceAll("[\\\\\"]", "\\\\$0");
return "\"" + escaped + "\"";
}
private static String encodeB(String prefix, String text,
int usedCharacters, Charset charset, byte[] bytes) {
int encodedLength = bEncodedLength(bytes);
int totalLength = prefix.length() + encodedLength
+ ENC_WORD_SUFFIX.length();
if (totalLength <= ENCODED_WORD_MAX_LENGTH - usedCharacters) {
return prefix + encodeB(bytes) + ENC_WORD_SUFFIX;
} else {
String part1 = text.substring(0, text.length() / 2);
byte[] bytes1 = encode(part1, charset);
String word1 = encodeB(prefix, part1, usedCharacters, charset,
bytes1);
String part2 = text.substring(text.length() / 2);
byte[] bytes2 = encode(part2, charset);
String word2 = encodeB(prefix, part2, 0, charset, bytes2);
return word1 + " " + word2;
}
}
private static int bEncodedLength(byte[] bytes) {
return (bytes.length + 2) / 3 * 4;
}
private static String encodeQ(String prefix, String text, Usage usage,
int usedCharacters, Charset charset, byte[] bytes) {
int encodedLength = qEncodedLength(bytes, usage);
int totalLength = prefix.length() + encodedLength
+ ENC_WORD_SUFFIX.length();
if (totalLength <= ENCODED_WORD_MAX_LENGTH - usedCharacters) {
return prefix + encodeQ(bytes, usage) + ENC_WORD_SUFFIX;
} else {
String part1 = text.substring(0, text.length() / 2);
byte[] bytes1 = encode(part1, charset);
String word1 = encodeQ(prefix, part1, usage, usedCharacters,
charset, bytes1);
String part2 = text.substring(text.length() / 2);
byte[] bytes2 = encode(part2, charset);
String word2 = encodeQ(prefix, part2, usage, 0, charset, bytes2);
return word1 + " " + word2;
}
}
private static int qEncodedLength(byte[] bytes, Usage usage) {
BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
: Q_RESTRICTED_CHARS;
int count = 0;
for (int idx = 0; idx < bytes.length; idx++) {
int v = bytes[idx] & 0xff;
if (v == 32) {
count++;
} else if (!qChars.get(v)) {
count += 3;
} else {
count++;
}
}
return count;
}
private static byte[] encode(String text, Charset charset) {
ByteBuffer buffer = charset.encode(text);
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);
return bytes;
}
private static Charset determineCharset(String text) {
// it is an important property of iso-8859-1 that it directly maps
// unicode code points 0000 to 00ff to byte values 00 to ff.
boolean ascii = true;
final int len = text.length();
for (int index = 0; index < len; index++) {
char ch = text.charAt(index);
if (ch > 0xff) {
return CharsetUtil.UTF_8;
}
if (ch > 0x7f) {
ascii = false;
}
}
return ascii ? CharsetUtil.US_ASCII : CharsetUtil.ISO_8859_1;
}
private static Encoding determineEncoding(byte[] bytes, Usage usage) {
if (bytes.length == 0)
return Encoding.Q;
BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
: Q_RESTRICTED_CHARS;
int qEncoded = 0;
for (int i = 0; i < bytes.length; i++) {
int v = bytes[i] & 0xff;
if (v != 32 && !qChars.get(v)) {
qEncoded++;
}
}
int percentage = qEncoded * 100 / bytes.length;
return percentage > 30 ? Encoding.B : Encoding.Q;
}
private static char hexDigit(int i) {
return i < 10 ? (char) (i + '0') : (char) (i - 10 + 'A');
}
}

View File

@ -1,309 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.IOException;
import java.io.InputStream;
import org.apache.james.mime4j.util.ByteArrayBuffer;
/**
* Performs Quoted-Printable decoding on an underlying stream.
*/
public class QuotedPrintableInputStream extends InputStream {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 2;
private static final byte EQ = 0x3D;
private static final byte CR = 0x0D;
private static final byte LF = 0x0A;
private final byte[] singleByte = new byte[1];
private final InputStream in;
private final ByteArrayBuffer decodedBuf;
private final ByteArrayBuffer blanks;
private final byte[] encoded;
private int pos = 0; // current index into encoded buffer
private int limit = 0; // current size of encoded buffer
private boolean closed;
private final DecodeMonitor monitor;
public QuotedPrintableInputStream(final InputStream in, DecodeMonitor monitor) {
this(DEFAULT_BUFFER_SIZE, in, monitor);
}
protected QuotedPrintableInputStream(final int bufsize, final InputStream in, DecodeMonitor monitor) {
super();
this.in = in;
this.encoded = new byte[bufsize];
this.decodedBuf = new ByteArrayBuffer(512);
this.blanks = new ByteArrayBuffer(512);
this.closed = false;
this.monitor = monitor;
}
protected QuotedPrintableInputStream(final int bufsize, final InputStream in, boolean strict) {
this(bufsize, in, strict ? DecodeMonitor.STRICT : DecodeMonitor.SILENT);
}
public QuotedPrintableInputStream(final InputStream in, boolean strict) {
this(DEFAULT_BUFFER_SIZE, in, strict);
}
public QuotedPrintableInputStream(final InputStream in) {
this(in, false);
}
/**
* Terminates Quoted-Printable coded content. This method does NOT close
* the underlying input stream.
*
* @throws IOException on I/O errors.
*/
@Override
public void close() throws IOException {
closed = true;
}
private int fillBuffer() throws IOException {
// Compact buffer if needed
if (pos < limit) {
System.arraycopy(encoded, pos, encoded, 0, limit - pos);
limit -= pos;
pos = 0;
} else {
limit = 0;
pos = 0;
}
int capacity = encoded.length - limit;
if (capacity > 0) {
int bytesRead = in.read(encoded, limit, capacity);
if (bytesRead > 0) {
limit += bytesRead;
}
return bytesRead;
} else {
return 0;
}
}
private int getnext() {
if (pos < limit) {
byte b = encoded[pos];
pos++;
return b & 0xFF;
} else {
return -1;
}
}
private int peek(int i) {
if (pos + i < limit) {
return encoded[pos + i] & 0xFF;
} else {
return -1;
}
}
private int transfer(
final int b, final byte[] buffer, final int from, final int to, boolean keepblanks) throws IOException {
int index = from;
if (keepblanks && blanks.length() > 0) {
int chunk = Math.min(blanks.length(), to - index);
System.arraycopy(blanks.buffer(), 0, buffer, index, chunk);
index += chunk;
int remaining = blanks.length() - chunk;
if (remaining > 0) {
decodedBuf.append(blanks.buffer(), chunk, remaining);
}
blanks.clear();
} else if (blanks.length() > 0 && !keepblanks) {
StringBuilder sb = new StringBuilder(blanks.length() * 3);
for (int i = 0; i < blanks.length(); i++) sb.append(" "+blanks.byteAt(i));
if (monitor.warn("ignored blanks", sb.toString()))
throw new IOException("ignored blanks");
}
if (b != -1) {
if (index < to) {
buffer[index++] = (byte) b;
} else {
decodedBuf.append(b);
}
}
return index;
}
private int read0(final byte[] buffer, final int off, final int len) throws IOException {
boolean eof = false;
int from = off;
int to = off + len;
int index = off;
// check if a previous invocation left decoded content
if (decodedBuf.length() > 0) {
int chunk = Math.min(decodedBuf.length(), to - index);
System.arraycopy(decodedBuf.buffer(), 0, buffer, index, chunk);
decodedBuf.remove(0, chunk);
index += chunk;
}
while (index < to) {
if (limit - pos < 3) {
int bytesRead = fillBuffer();
eof = bytesRead == -1;
}
// end of stream?
if (limit - pos == 0 && eof) {
return index == from ? -1 : index - from;
}
boolean lastWasCR = false;
while (pos < limit && index < to) {
int b = encoded[pos++] & 0xFF;
if (lastWasCR && b != LF) {
if (monitor.warn("Found CR without LF", "Leaving it as is"))
throw new IOException("Found CR without LF");
index = transfer(CR, buffer, index, to, false);
} else if (!lastWasCR && b == LF) {
if (monitor.warn("Found LF without CR", "Translating to CRLF"))
throw new IOException("Found LF without CR");
}
if (b == CR) {
lastWasCR = true;
continue;
} else {
lastWasCR = false;
}
if (b == LF) {
// at end of line
if (blanks.length() == 0) {
index = transfer(CR, buffer, index, to, false);
index = transfer(LF, buffer, index, to, false);
} else {
if (blanks.byteAt(0) != EQ) {
// hard line break
index = transfer(CR, buffer, index, to, false);
index = transfer(LF, buffer, index, to, false);
}
}
blanks.clear();
} else if (b == EQ) {
if (limit - pos < 2 && !eof) {
// not enough buffered data
pos--;
break;
}
// found special char '='
int b2 = getnext();
if (b2 == EQ) {
index = transfer(b2, buffer, index, to, true);
// deal with '==\r\n' brokenness
int bb1 = peek(0);
int bb2 = peek(1);
if (bb1 == LF || (bb1 == CR && bb2 == LF)) {
monitor.warn("Unexpected ==EOL encountered", "== 0x"+bb1+" 0x"+bb2);
blanks.append(b2);
} else {
monitor.warn("Unexpected == encountered", "==");
}
} else if (Character.isWhitespace((char) b2)) {
// soft line break
index = transfer(-1, buffer, index, to, true);
if (b2 != LF) {
blanks.append(b);
blanks.append(b2);
}
} else {
int b3 = getnext();
int upper = convert(b2);
int lower = convert(b3);
if (upper < 0 || lower < 0) {
monitor.warn("Malformed encoded value encountered", "leaving "+((char) EQ)+((char) b2)+((char) b3)+" as is");
// TODO see MIME4J-160
index = transfer(EQ, buffer, index, to, true);
index = transfer(b2, buffer, index, to, false);
index = transfer(b3, buffer, index, to, false);
} else {
index = transfer((upper << 4) | lower, buffer, index, to, true);
}
}
} else if (Character.isWhitespace(b)) {
blanks.append(b);
} else {
index = transfer((int) b & 0xFF, buffer, index, to, true);
}
}
}
return to - from;
}
/**
* Converts '0' => 0, 'A' => 10, etc.
* @param c ASCII character value.
* @return Numeric value of hexadecimal character.
*/
private int convert(int c) {
if (c >= '0' && c <= '9') {
return (c - '0');
} else if (c >= 'A' && c <= 'F') {
return (0xA + (c - 'A'));
} else if (c >= 'a' && c <= 'f') {
return (0xA + (c - 'a'));
} else {
return -1;
}
}
@Override
public int read() throws IOException {
if (closed) {
throw new IOException("Stream has been closed");
}
for (;;) {
int bytes = read(singleByte, 0, 1);
if (bytes == -1) {
return -1;
}
if (bytes == 1) {
return singleByte[0] & 0xff;
}
}
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (closed) {
throw new IOException("Stream has been closed");
}
return read0(b, off, len);
}
}

View File

@ -1,233 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.codec;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Performs Quoted-Printable encoding on an underlying stream.
*/
public class QuotedPrintableOutputStream extends FilterOutputStream {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 3;
private static final byte TB = 0x09;
private static final byte SP = 0x20;
private static final byte EQ = 0x3D;
private static final byte CR = 0x0D;
private static final byte LF = 0x0A;
private static final byte QUOTED_PRINTABLE_LAST_PLAIN = 0x7E;
private static final int QUOTED_PRINTABLE_MAX_LINE_LENGTH = 76;
private static final int QUOTED_PRINTABLE_OCTETS_PER_ESCAPE = 3;
private static final byte[] HEX_DIGITS = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
private final byte[] outBuffer;
private final boolean binary;
private boolean pendingSpace;
private boolean pendingTab;
private boolean pendingCR;
private int nextSoftBreak;
private int outputIndex;
private boolean closed = false;
private byte[] singleByte = new byte[1];
public QuotedPrintableOutputStream(int bufsize, OutputStream out, boolean binary) {
super(out);
this.outBuffer = new byte[bufsize];
this.binary = binary;
this.pendingSpace = false;
this.pendingTab = false;
this.pendingCR = false;
this.outputIndex = 0;
this.nextSoftBreak = QUOTED_PRINTABLE_MAX_LINE_LENGTH + 1;
}
public QuotedPrintableOutputStream(OutputStream out, boolean binary) {
this(DEFAULT_BUFFER_SIZE, out, binary);
}
private void encodeChunk(byte[] buffer, int off, int len) throws IOException {
for (int inputIndex = off; inputIndex < len + off; inputIndex++) {
encode(buffer[inputIndex]);
}
}
private void completeEncoding() throws IOException {
writePending();
flushOutput();
}
private void writePending() throws IOException {
if (pendingSpace) {
plain(SP);
} else if (pendingTab) {
plain(TB);
} else if (pendingCR) {
plain(CR);
}
clearPending();
}
private void clearPending() throws IOException {
pendingSpace = false;
pendingTab = false;
pendingCR = false;
}
private void encode(byte next) throws IOException {
if (next == LF) {
if (binary) {
writePending();
escape(next);
} else {
if (pendingCR) {
// Expect either space or tab pending
// but not both
if (pendingSpace) {
escape(SP);
} else if (pendingTab) {
escape(TB);
}
lineBreak();
clearPending();
} else {
writePending();
plain(next);
}
}
} else if (next == CR) {
if (binary) {
escape(next);
} else {
pendingCR = true;
}
} else {
writePending();
if (next == SP) {
if (binary) {
escape(next);
} else {
pendingSpace = true;
}
} else if (next == TB) {
if (binary) {
escape(next);
} else {
pendingTab = true;
}
} else if (next < SP) {
escape(next);
} else if (next > QUOTED_PRINTABLE_LAST_PLAIN) {
escape(next);
} else if (next == EQ) {
escape(next);
} else {
plain(next);
}
}
}
private void plain(byte next) throws IOException {
if (--nextSoftBreak <= 1) {
softBreak();
}
write(next);
}
private void escape(byte next) throws IOException {
if (--nextSoftBreak <= QUOTED_PRINTABLE_OCTETS_PER_ESCAPE) {
softBreak();
}
int nextUnsigned = next & 0xff;
write(EQ);
--nextSoftBreak;
write(HEX_DIGITS[nextUnsigned >> 4]);
--nextSoftBreak;
write(HEX_DIGITS[nextUnsigned % 0x10]);
}
private void write(byte next) throws IOException {
outBuffer[outputIndex++] = next;
if (outputIndex >= outBuffer.length) {
flushOutput();
}
}
private void softBreak() throws IOException {
write(EQ);
lineBreak();
}
private void lineBreak() throws IOException {
write(CR);
write(LF);
nextSoftBreak = QUOTED_PRINTABLE_MAX_LINE_LENGTH;
}
void flushOutput() throws IOException {
if (outputIndex < outBuffer.length) {
out.write(outBuffer, 0, outputIndex);
} else {
out.write(outBuffer);
}
outputIndex = 0;
}
@Override
public void close() throws IOException {
if (closed)
return;
try {
completeEncoding();
// do not close the wrapped stream
} finally {
closed = true;
}
}
@Override
public void flush() throws IOException {
flushOutput();
}
@Override
public void write(int b) throws IOException {
singleByte[0] = (byte) b;
this.write(singleByte, 0, 1);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (closed) {
throw new IOException("Stream has been closed");
}
encodeChunk(b, off, len);
}
}

View File

@ -1,33 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
/**
* A body containing binary data.
*/
public abstract class BinaryBody extends SingleBody {
/**
* Sole constructor.
*/
protected BinaryBody() {
}
}

View File

@ -1,46 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
/**
* Encapsulates the body of an entity (see RFC 2045).
* <p>
* A body can be a {@link Message}, a {@link Multipart} or a {@link SingleBody}.
* This interface should not be implemented directly by classes other than
* those.
*/
public interface Body extends Disposable {
/**
* 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);
}

View File

@ -1,36 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
/**
* A <tt>Disposable</tt> is an object that should be disposed of explicitly
* when it is no longer needed.
*
* The dispose method is invoked to release resources that the object is
* holding (such as open files).
*/
public interface Disposable {
/**
* Free any resources this object is holding and prepares this object
* for garbage collection. Once an object has been disposed of it can no
* longer be used.
*/
void dispose();
}

View File

@ -1,550 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.james.mime4j.dom.field.ContentDispositionField;
import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
import org.apache.james.mime4j.dom.field.ContentTypeField;
import org.apache.james.mime4j.dom.field.Field;
import org.apache.james.mime4j.dom.field.FieldName;
/**
* MIME entity. An entity has a header and a body (see RFC 2045).
*/
public abstract class Entity implements Disposable {
private Header header = null;
private Body body = null;
private Entity parent = null;
/**
* Creates a new <code>Entity</code>. Typically invoked implicitly by a
* subclass constructor.
*/
protected Entity() {
}
/**
* Gets the parent entity of this entity.
* Returns <code>null</code> if this is the root entity.
*
* @return the parent or <code>null</code>.
*/
public Entity getParent() {
return parent;
}
/**
* Sets the parent entity of this entity.
*
* @param parent the parent entity or <code>null</code> 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.
* @throws IllegalStateException if the body has already been set.
*/
public void setBody(Body body) {
if (this.body != null)
throw new IllegalStateException("body already set");
this.body = body;
body.setParent(this);
}
/**
* Removes and returns the body of this entity. The removed body may be
* attached to another entity. If it is no longer needed it should be
* {@link Disposable#dispose() disposed} of.
*
* @return the removed body or <code>null</code> if no body was set.
*/
public Body removeBody() {
if (body == null)
return null;
Body body = this.body;
this.body = null;
body.setParent(null);
return body;
}
/**
* Sets the specified message as body of this entity and the content type to
* &quot;message/rfc822&quot;. A <code>Header</code> is created if this
* entity does not already have one.
*
* @param message
* the message to set as body.
*/
public void setMessage(Message message) {
setBody(message, "message/rfc822", null);
}
/**
* Sets the specified multipart as body of this entity. Also sets the
* content type accordingly and creates a message boundary string. A
* <code>Header</code> is created if this entity does not already have
* one.
*
* @param multipart
* the multipart to set as body.
*/
public void setMultipart(Multipart multipart) {
String mimeType = "multipart/" + multipart.getSubType();
Map<String, String> parameters = Collections.singletonMap("boundary",
newUniqueBoundary());
setBody(multipart, mimeType, parameters);
}
/**
* Sets the specified multipart as body of this entity. Also sets the
* content type accordingly and creates a message boundary string. A
* <code>Header</code> is created if this entity does not already have
* one.
*
* @param multipart
* the multipart to set as body.
* @param parameters
* additional parameters for the Content-Type header field.
*/
public void setMultipart(Multipart multipart, Map<String, String> parameters) {
String mimeType = "multipart/" + multipart.getSubType();
if (!parameters.containsKey("boundary")) {
parameters = new HashMap<String, String>(parameters);
parameters.put("boundary", newUniqueBoundary());
}
setBody(multipart, mimeType, parameters);
}
/**
* Sets the specified <code>TextBody</code> as body of this entity and the
* content type to &quot;text/plain&quot;. A <code>Header</code> is
* created if this entity does not already have one.
*
* @param textBody
* the <code>TextBody</code> to set as body.
* @see org.apache.james.mime4j.message.BodyFactory#textBody(String)
*/
public void setText(TextBody textBody) {
setText(textBody, "plain");
}
/**
* Sets the specified <code>TextBody</code> as body of this entity. Also
* sets the content type according to the specified sub-type. A
* <code>Header</code> is created if this entity does not already have
* one.
*
* @param textBody
* the <code>TextBody</code> to set as body.
* @param subtype
* the text subtype (e.g. &quot;plain&quot;, &quot;html&quot; or
* &quot;xml&quot;).
* @see org.apache.james.mime4j.message.BodyFactory#textBody(String)
*/
public void setText(TextBody textBody, String subtype) {
String mimeType = "text/" + subtype;
Map<String, String> parameters = null;
String mimeCharset = textBody.getMimeCharset();
if (mimeCharset != null && !mimeCharset.equalsIgnoreCase("us-ascii")) {
parameters = Collections.singletonMap("charset", mimeCharset);
}
setBody(textBody, mimeType, parameters);
}
/**
* Sets the body of this entity and sets the content-type to the specified
* value. A <code>Header</code> is created if this entity does not already
* have one.
*
* @param body
* the body.
* @param mimeType
* the MIME media type of the specified body
* (&quot;type/subtype&quot;).
*/
public void setBody(Body body, String mimeType) {
setBody(body, mimeType, null);
}
/**
* Sets the body of this entity and sets the content-type to the specified
* value. A <code>Header</code> is created if this entity does not already
* have one.
*
* @param body
* the body.
* @param mimeType
* the MIME media type of the specified body
* (&quot;type/subtype&quot;).
* @param parameters
* additional parameters for the Content-Type header field.
*/
public void setBody(Body body, String mimeType,
Map<String, String> parameters) {
setBody(body);
Header header = obtainHeader();
header.setField(newContentType(mimeType, parameters));
}
/**
* Determines the MIME type of this <code>Entity</code>. The MIME type
* is derived by looking at the parent's Content-Type field if no
* Content-Type field is set for this <code>Entity</code>.
*
* @return the MIME type.
*/
public String getMimeType() {
ContentTypeField child =
getContentTypeField();
ContentTypeField parent = getParent() != null
? (ContentTypeField) getParent().getHeader().
getField(FieldName.CONTENT_TYPE)
: null;
return calcMimeType(child, parent);
}
private ContentTypeField getContentTypeField() {
return (ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE);
}
/**
* Determines the MIME character set encoding of this <code>Entity</code>.
*
* @return the MIME character set encoding.
*/
public String getCharset() {
return calcCharset((ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE));
}
/**
* Determines the transfer encoding of this <code>Entity</code>.
*
* @return the transfer encoding.
*/
public String getContentTransferEncoding() {
ContentTransferEncodingField f = (ContentTransferEncodingField)
getHeader().getField(FieldName.CONTENT_TRANSFER_ENCODING);
return calcTransferEncoding(f);
}
/**
* Sets the transfer encoding of this <code>Entity</code> to the specified
* value.
*
* @param contentTransferEncoding
* transfer encoding to use.
*/
public void setContentTransferEncoding(String contentTransferEncoding) {
Header header = obtainHeader();
header.setField(newContentTransferEncoding(contentTransferEncoding));
}
/**
* Return the disposition type of the content disposition of this
* <code>Entity</code>.
*
* @return the disposition type or <code>null</code> if no disposition
* type has been set.
*/
public String getDispositionType() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
if (field == null)
return null;
return field.getDispositionType();
}
/**
* Sets the content disposition of this <code>Entity</code> to the
* specified disposition type. No filename, size or date parameters
* are included in the content disposition.
*
* @param dispositionType
* disposition type value (usually <code>inline</code> or
* <code>attachment</code>).
*/
public void setContentDisposition(String dispositionType) {
Header header = obtainHeader();
header.setField(newContentDisposition(dispositionType, null, -1, null,
null, null));
}
/**
* Sets the content disposition of this <code>Entity</code> to the
* specified disposition type and filename. No size or date parameters are
* included in the content disposition.
*
* @param dispositionType
* disposition type value (usually <code>inline</code> or
* <code>attachment</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
*/
public void setContentDisposition(String dispositionType, String filename) {
Header header = obtainHeader();
header.setField(newContentDisposition(dispositionType, filename, -1,
null, null, null));
}
/**
* Sets the content disposition of this <code>Entity</code> to the
* specified values. No date parameters are included in the content
* disposition.
*
* @param dispositionType
* disposition type value (usually <code>inline</code> or
* <code>attachment</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
* @param size
* size parameter value or <code>-1</code> if the parameter
* should not be included.
*/
public void setContentDisposition(String dispositionType, String filename,
long size) {
Header header = obtainHeader();
header.setField(newContentDisposition(dispositionType, filename, size,
null, null, null));
}
/**
* Sets the content disposition of this <code>Entity</code> to the
* specified values.
*
* @param dispositionType
* disposition type value (usually <code>inline</code> or
* <code>attachment</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
* @param size
* size parameter value or <code>-1</code> if the parameter
* should not be included.
* @param creationDate
* creation-date parameter value or <code>null</code> if the
* parameter should not be included.
* @param modificationDate
* modification-date parameter value or <code>null</code> if
* the parameter should not be included.
* @param readDate
* read-date parameter value or <code>null</code> if the
* parameter should not be included.
*/
public void setContentDisposition(String dispositionType, String filename,
long size, Date creationDate, Date modificationDate, Date readDate) {
Header header = obtainHeader();
header.setField(newContentDisposition(dispositionType, filename, size,
creationDate, modificationDate, readDate));
}
/**
* Returns the filename parameter of the content disposition of this
* <code>Entity</code>.
*
* @return the filename parameter of the content disposition or
* <code>null</code> if the filename has not been set.
*/
public String getFilename() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
if (field == null)
return null;
return field.getFilename();
}
/**
* Sets the filename parameter of the content disposition of this
* <code>Entity</code> to the specified value. If this entity does not
* have a content disposition header field a new one with disposition type
* <code>attachment</code> is created.
*
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should be removed.
*/
public void setFilename(String filename) {
Header header = obtainHeader();
ContentDispositionField field = (ContentDispositionField) header
.getField(FieldName.CONTENT_DISPOSITION);
if (field == null) {
if (filename != null) {
header.setField(newContentDisposition(
ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT,
filename, -1, null, null, null));
}
} else {
String dispositionType = field.getDispositionType();
Map<String, String> parameters = new HashMap<String, String>(field
.getParameters());
if (filename == null) {
parameters.remove(ContentDispositionField.PARAM_FILENAME);
} else {
parameters
.put(ContentDispositionField.PARAM_FILENAME, filename);
}
header.setField(newContentDisposition(dispositionType, parameters));
}
}
/**
* Determines if the MIME type of this <code>Entity</code> matches the
* given one. MIME types are case-insensitive.
*
* @param type the MIME type to match against.
* @return <code>true</code> on match, <code>false</code> otherwise.
*/
public boolean isMimeType(String type) {
return getMimeType().equalsIgnoreCase(type);
}
/**
* Determines if the MIME type of this <code>Entity</code> is
* <code>multipart/*</code>. Since multipart-entities must have
* a boundary parameter in the <code>Content-Type</code> field this
* method returns <code>false</code> if no boundary exists.
*
* @return <code>true</code> on match, <code>false</code> otherwise.
*/
public boolean isMultipart() {
ContentTypeField f = getContentTypeField();
return f != null
&& f.getBoundary() != null
&& getMimeType().startsWith(
ContentTypeField.TYPE_MULTIPART_PREFIX);
}
/**
* Disposes of the body of this entity. Note that the dispose call does not
* get forwarded to the parent entity of this Entity.
*
* Subclasses that need to free resources should override this method and
* invoke super.dispose().
*
* @see org.apache.james.mime4j.dom.Disposable#dispose()
*/
public void dispose() {
if (body != null) {
body.dispose();
}
}
/**
* Obtains the header of this entity. Creates and sets a new header if this
* entity's header is currently <code>null</code>.
*
* @return the header of this entity; never <code>null</code>.
*/
Header obtainHeader() {
if (header == null) {
header = new Header();
}
return header;
}
/**
* Obtains the header field with the specified name.
*
* @param <F>
* concrete field type.
* @param fieldName
* name of the field to retrieve.
* @return the header field or <code>null</code> if this entity has no
* header or the header contains no such field.
*/
<F extends Field> F obtainField(String fieldName) {
Header header = getHeader();
if (header == null)
return null;
@SuppressWarnings("unchecked")
F field = (F) header.getField(fieldName);
return field;
}
protected abstract String newUniqueBoundary();
protected abstract ContentDispositionField newContentDisposition(
String dispositionType, String filename, long size,
Date creationDate, Date modificationDate, Date readDate);
protected abstract ContentDispositionField newContentDisposition(
String dispositionType, Map<String, String> parameters);
protected abstract ContentTypeField newContentType(String mimeType,
Map<String, String> parameters);
protected abstract ContentTransferEncodingField newContentTransferEncoding(
String contentTransferEncoding);
protected abstract String calcMimeType(ContentTypeField child, ContentTypeField parent);
protected abstract String calcTransferEncoding(ContentTransferEncodingField f);
protected abstract String calcCharset(ContentTypeField contentType);
}

View File

@ -1,204 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.james.mime4j.dom.field.Field;
/**
* The header of an entity (see RFC 2045).
*/
public class Header implements Iterable<Field> {
private List<Field> fields = new LinkedList<Field>();
private Map<String, List<Field>> fieldMap = new HashMap<String, List<Field>>();
/**
* Creates a new empty <code>Header</code>.
*/
public Header() {
}
/**
* Creates a new <code>Header</code> from the specified
* <code>Header</code>. The <code>Header</code> instance is initialized
* with a copy of the list of {@link Field}s of the specified
* <code>Header</code>. The <code>Field</code> objects are not copied
* because they are immutable and can safely be shared between headers.
*
* @param other
* header to copy.
*/
public Header(Header other) {
for (Field otherField : other.fields) {
addField(otherField);
}
}
/**
* Adds a field to the end of the list of fields.
*
* @param field the field to add.
*/
public void addField(Field field) {
List<Field> values = fieldMap.get(field.getName().toLowerCase());
if (values == null) {
values = new LinkedList<Field>();
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 <code>Field</code> objects.
*/
public List<Field> getFields() {
return Collections.unmodifiableList(fields);
}
/**
* Gets a <code>Field</code> 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 <code>null</code> if none found.
*/
public Field getField(String name) {
List<Field> l = fieldMap.get(name.toLowerCase());
if (l != null && !l.isEmpty()) {
return l.get(0);
}
return null;
}
/**
* Gets all <code>Field</code>s having the specified field name.
*
* @param name the field name (e.g. From, Subject).
* @return the list of fields.
*/
public List<Field> getFields(final String name) {
final String lowerCaseName = name.toLowerCase();
final List<Field> l = fieldMap.get(lowerCaseName);
final List<Field> results;
if (l == null || l.isEmpty()) {
results = Collections.emptyList();
} else {
results = Collections.unmodifiableList(l);
}
return results;
}
/**
* Returns an iterator over the list of fields of this header.
*
* @return an iterator.
*/
public Iterator<Field> iterator() {
return Collections.unmodifiableList(fields).iterator();
}
/**
* Removes all <code>Field</code>s having the specified field name.
*
* @param name
* the field name (e.g. From, Subject).
* @return number of fields removed.
*/
public int removeFields(String name) {
final String lowerCaseName = name.toLowerCase();
List<Field> removed = fieldMap.remove(lowerCaseName);
if (removed == null || removed.isEmpty())
return 0;
for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext();) {
Field field = iterator.next();
if (field.getName().equalsIgnoreCase(name))
iterator.remove();
}
return removed.size();
}
/**
* Sets or replaces a field. This method is useful for header fields such as
* Subject or Message-ID that should not occur more than once in a message.
*
* If this <code>Header</code> does not already contain a header field of
* the same name as the given field then it is added to the end of the list
* of fields (same behavior as {@link #addField(Field)}). Otherwise the
* first occurrence of a field with the same name is replaced by the given
* field and all further occurrences are removed.
*
* @param field the field to set.
*/
public void setField(Field field) {
final String lowerCaseName = field.getName().toLowerCase();
List<Field> l = fieldMap.get(lowerCaseName);
if (l == null || l.isEmpty()) {
addField(field);
return;
}
l.clear();
l.add(field);
int firstOccurrence = -1;
int index = 0;
for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext(); index++) {
Field f = iterator.next();
if (f.getName().equalsIgnoreCase(field.getName())) {
iterator.remove();
if (firstOccurrence == -1)
firstOccurrence = index;
}
}
fields.add(firstOccurrence, field);
}
/**
* Return Header Object as String representation. Each headerline is
* seperated by "\r\n"
*
* @return headers
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder(128);
for (Field field : fields) {
str.append(field.toString());
str.append("\r\n");
}
return str.toString();
}
}

View File

@ -1,512 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.TimeZone;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.dom.field.AddressListField;
import org.apache.james.mime4j.dom.field.DateTimeField;
import org.apache.james.mime4j.dom.field.Field;
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.MailboxField;
import org.apache.james.mime4j.dom.field.MailboxListField;
import org.apache.james.mime4j.dom.field.UnstructuredField;
public abstract class Message extends Entity implements Body {
/**
* Write the content to the given output stream using the
* {@link org.apache.james.mime4j.message.MessageWriter#DEFAULT default} message writer.
*
* @param out
* the output stream to write to.
* @throws IOException
* in case of an I/O error
* @see org.apache.james.mime4j.message.MessageWriter
*/
public abstract void writeTo(OutputStream out) throws IOException;
/**
* Returns the value of the <i>Message-ID</i> header field of this message
* or <code>null</code> if it is not present.
*
* @return the identifier of this message.
*/
public String getMessageId() {
Field field = obtainField(FieldName.MESSAGE_ID);
if (field == null)
return null;
return field.getBody();
}
/**
* Creates and sets a new <i>Message-ID</i> header field for this message.
* A <code>Header</code> is created if this message does not already have
* one.
*
* @param hostname
* host name to be included in the identifier or
* <code>null</code> if no host name should be included.
*/
public void createMessageId(String hostname) {
Header header = obtainHeader();
header.setField(newMessageId(hostname));
}
protected abstract Field newMessageId(String hostname);
/**
* Returns the (decoded) value of the <i>Subject</i> header field of this
* message or <code>null</code> if it is not present.
*
* @return the subject of this message.
*/
public String getSubject() {
UnstructuredField field = obtainField(FieldName.SUBJECT);
if (field == null)
return null;
return field.getValue();
}
/**
* Sets the <i>Subject</i> header field for this message. The specified
* string may contain non-ASCII characters, in which case it gets encoded as
* an 'encoded-word' automatically. A <code>Header</code> is created if
* this message does not already have one.
*
* @param subject
* subject to set or <code>null</code> to remove the subject
* header field.
*/
public void setSubject(String subject) {
Header header = obtainHeader();
if (subject == null) {
header.removeFields(FieldName.SUBJECT);
} else {
header.setField(newSubject(subject));
}
}
/**
* Returns the value of the <i>Date</i> header field of this message as
* <code>Date</code> object or <code>null</code> if it is not present.
*
* @return the date of this message.
*/
public Date getDate() {
DateTimeField dateField = obtainField(FieldName.DATE);
if (dateField == null)
return null;
return dateField.getDate();
}
/**
* Sets the <i>Date</i> header field for this message. This method uses the
* default <code>TimeZone</code> of this host to encode the specified
* <code>Date</code> object into a string.
*
* @param date
* date to set or <code>null</code> to remove the date header
* field.
*/
public void setDate(Date date) {
setDate(date, null);
}
/**
* Sets the <i>Date</i> header field for this message. The specified
* <code>TimeZone</code> is used to encode the specified <code>Date</code>
* object into a string.
*
* @param date
* date to set or <code>null</code> to remove the date header
* field.
* @param zone
* a time zone.
*/
public void setDate(Date date, TimeZone zone) {
Header header = obtainHeader();
if (date == null) {
header.removeFields(FieldName.DATE);
} else {
header.setField(newDate(date, zone));
}
}
/**
* Returns the value of the <i>Sender</i> header field of this message as
* <code>Mailbox</code> object or <code>null</code> if it is not
* present.
*
* @return the sender of this message.
*/
public Mailbox getSender() {
return getMailbox(FieldName.SENDER);
}
/**
* Sets the <i>Sender</i> header field of this message to the specified
* mailbox address.
*
* @param sender
* address to set or <code>null</code> to remove the header
* field.
*/
public void setSender(Mailbox sender) {
setMailbox(FieldName.SENDER, sender);
}
/**
* Returns the value of the <i>From</i> header field of this message as
* <code>MailboxList</code> object or <code>null</code> if it is not
* present.
*
* @return value of the from field of this message.
*/
public MailboxList getFrom() {
return getMailboxList(FieldName.FROM);
}
/**
* Sets the <i>From</i> header field of this message to the specified
* mailbox address.
*
* @param from
* address to set or <code>null</code> to remove the header
* field.
*/
public void setFrom(Mailbox from) {
setMailboxList(FieldName.FROM, from);
}
/**
* Sets the <i>From</i> header field of this message to the specified
* mailbox addresses.
*
* @param from
* addresses to set or <code>null</code> or no arguments to
* remove the header field.
*/
public void setFrom(Mailbox... from) {
setMailboxList(FieldName.FROM, from);
}
/**
* Sets the <i>From</i> header field of this message to the specified
* mailbox addresses.
*
* @param from
* addresses to set or <code>null</code> or an empty collection
* to remove the header field.
*/
public void setFrom(Collection<Mailbox> from) {
setMailboxList(FieldName.FROM, from);
}
/**
* Returns the value of the <i>To</i> header field of this message as
* <code>AddressList</code> object or <code>null</code> if it is not
* present.
*
* @return value of the to field of this message.
*/
public AddressList getTo() {
return getAddressList(FieldName.TO);
}
/**
* Sets the <i>To</i> header field of this message to the specified
* address.
*
* @param to
* address to set or <code>null</code> to remove the header
* field.
*/
public void setTo(Address to) {
setAddressList(FieldName.TO, to);
}
/**
* Sets the <i>To</i> header field of this message to the specified
* addresses.
*
* @param to
* addresses to set or <code>null</code> or no arguments to
* remove the header field.
*/
public void setTo(Address... to) {
setAddressList(FieldName.TO, to);
}
/**
* Sets the <i>To</i> header field of this message to the specified
* addresses.
*
* @param to
* addresses to set or <code>null</code> or an empty collection
* to remove the header field.
*/
public void setTo(Collection<Address> to) {
setAddressList(FieldName.TO, to);
}
/**
* Returns the value of the <i>Cc</i> header field of this message as
* <code>AddressList</code> object or <code>null</code> if it is not
* present.
*
* @return value of the cc field of this message.
*/
public AddressList getCc() {
return getAddressList(FieldName.CC);
}
/**
* Sets the <i>Cc</i> header field of this message to the specified
* address.
*
* @param cc
* address to set or <code>null</code> to remove the header
* field.
*/
public void setCc(Address cc) {
setAddressList(FieldName.CC, cc);
}
/**
* Sets the <i>Cc</i> header field of this message to the specified
* addresses.
*
* @param cc
* addresses to set or <code>null</code> or no arguments to
* remove the header field.
*/
public void setCc(Address... cc) {
setAddressList(FieldName.CC, cc);
}
/**
* Sets the <i>Cc</i> header field of this message to the specified
* addresses.
*
* @param cc
* addresses to set or <code>null</code> or an empty collection
* to remove the header field.
*/
public void setCc(Collection<Address> cc) {
setAddressList(FieldName.CC, cc);
}
/**
* Returns the value of the <i>Bcc</i> header field of this message as
* <code>AddressList</code> object or <code>null</code> if it is not
* present.
*
* @return value of the bcc field of this message.
*/
public AddressList getBcc() {
return getAddressList(FieldName.BCC);
}
/**
* Sets the <i>Bcc</i> header field of this message to the specified
* address.
*
* @param bcc
* address to set or <code>null</code> to remove the header
* field.
*/
public void setBcc(Address bcc) {
setAddressList(FieldName.BCC, bcc);
}
/**
* Sets the <i>Bcc</i> header field of this message to the specified
* addresses.
*
* @param bcc
* addresses to set or <code>null</code> or no arguments to
* remove the header field.
*/
public void setBcc(Address... bcc) {
setAddressList(FieldName.BCC, bcc);
}
/**
* Sets the <i>Bcc</i> header field of this message to the specified
* addresses.
*
* @param bcc
* addresses to set or <code>null</code> or an empty collection
* to remove the header field.
*/
public void setBcc(Collection<Address> bcc) {
setAddressList(FieldName.BCC, bcc);
}
/**
* Returns the value of the <i>Reply-To</i> header field of this message as
* <code>AddressList</code> object or <code>null</code> if it is not
* present.
*
* @return value of the reply to field of this message.
*/
public AddressList getReplyTo() {
return getAddressList(FieldName.REPLY_TO);
}
/**
* Sets the <i>Reply-To</i> header field of this message to the specified
* address.
*
* @param replyTo
* address to set or <code>null</code> to remove the header
* field.
*/
public void setReplyTo(Address replyTo) {
setAddressList(FieldName.REPLY_TO, replyTo);
}
/**
* Sets the <i>Reply-To</i> header field of this message to the specified
* addresses.
*
* @param replyTo
* addresses to set or <code>null</code> or no arguments to
* remove the header field.
*/
public void setReplyTo(Address... replyTo) {
setAddressList(FieldName.REPLY_TO, replyTo);
}
/**
* Sets the <i>Reply-To</i> header field of this message to the specified
* addresses.
*
* @param replyTo
* addresses to set or <code>null</code> or an empty collection
* to remove the header field.
*/
public void setReplyTo(Collection<Address> replyTo) {
setAddressList(FieldName.REPLY_TO, replyTo);
}
private Mailbox getMailbox(String fieldName) {
MailboxField field = obtainField(fieldName);
if (field == null)
return null;
return field.getMailbox();
}
private void setMailbox(String fieldName, Mailbox mailbox) {
Header header = obtainHeader();
if (mailbox == null) {
header.removeFields(fieldName);
} else {
header.setField(newMailbox(fieldName, mailbox));
}
}
private MailboxList getMailboxList(String fieldName) {
MailboxListField field = obtainField(fieldName);
if (field == null)
return null;
return field.getMailboxList();
}
private void setMailboxList(String fieldName, Mailbox mailbox) {
setMailboxList(fieldName, mailbox == null ? null : Collections
.singleton(mailbox));
}
private void setMailboxList(String fieldName, Mailbox... mailboxes) {
setMailboxList(fieldName, mailboxes == null ? null : Arrays
.asList(mailboxes));
}
private void setMailboxList(String fieldName, Collection<Mailbox> mailboxes) {
Header header = obtainHeader();
if (mailboxes == null || mailboxes.isEmpty()) {
header.removeFields(fieldName);
} else {
header.setField(newMailboxList(fieldName, mailboxes));
}
}
private AddressList getAddressList(String fieldName) {
AddressListField field = obtainField(fieldName);
if (field == null)
return null;
return field.getAddressList();
}
private void setAddressList(String fieldName, Address address) {
setAddressList(fieldName, address == null ? null : Collections
.singleton(address));
}
private void setAddressList(String fieldName, Address... addresses) {
setAddressList(fieldName, addresses == null ? null : Arrays
.asList(addresses));
}
private void setAddressList(String fieldName, Collection<Address> addresses) {
Header header = obtainHeader();
if (addresses == null || addresses.isEmpty()) {
header.removeFields(fieldName);
} else {
header.setField(newAddressList(fieldName, addresses));
}
}
protected abstract AddressListField newAddressList(String fieldName, Collection<Address> addresses);
protected abstract UnstructuredField newSubject(String subject);
protected abstract DateTimeField newDate(Date date, TimeZone zone);
protected abstract MailboxField newMailbox(String fieldName, Mailbox mailbox);
protected abstract MailboxListField newMailboxList(String fieldName, Collection<Mailbox> mailboxes);
}

View File

@ -1,46 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.io.IOException;
import java.io.InputStream;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.codec.DecodeMonitor;
/**
* Defines the API to obtain Message instances from a mime stream.
*/
public abstract class MessageBuilder {
public abstract Message newMessage();
public abstract Message newMessage(Message source);
public abstract Message parse(InputStream source) throws MimeException, IOException;
public abstract void setDecodeMonitor(
DecodeMonitor decodeMonitor);
public abstract void setContentDecoding(boolean contentDecoding);
public abstract void setFlatMode();
}

View File

@ -1,41 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import org.apache.james.mime4j.MimeException;
/**
* A MessageBuilderFactory is used to create EntityBuilder instances.
*
* MessageBuilderFactory.newInstance() is used to get access to an implementation
* of MessageBuilderFactory.
* Then the method newMessageBuilder is used to create a new EntityBuilder object.
*/
public abstract class MessageBuilderFactory {
public abstract MessageBuilder newMessageBuilder() throws MimeException;
public static MessageBuilderFactory newInstance() throws MimeException {
return ServiceLoader.load(MessageBuilderFactory.class);
}
public abstract void setAttribute(String name, Object value) throws IllegalArgumentException;
}

View File

@ -1,238 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* 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.
*/
public abstract class Multipart implements Body {
protected List<Entity> bodyParts = new LinkedList<Entity>();
private Entity parent = null;
private String subType;
/**
* Creates a new empty <code>Multipart</code> instance.
*/
public Multipart(String subType) {
this.subType = subType;
}
/**
* Gets the multipart sub-type. E.g. <code>alternative</code> (the
* default) or <code>parallel</code>. 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. <code>alternative</code> or
* <code>parallel</code>. 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.dom.Body#getParent()
*/
public Entity getParent() {
return parent;
}
/**
* @see org.apache.james.mime4j.dom.Body#setParent(org.apache.james.mime4j.dom.Entity)
*/
public void setParent(Entity parent) {
this.parent = parent;
for (Entity bodyPart : bodyParts) {
bodyPart.setParent(parent);
}
}
/**
* Returns the number of body parts.
*
* @return number of <code>Entity</code> objects.
*/
public int getCount() {
return bodyParts.size();
}
/**
* Gets the list of body parts. The list is immutable.
*
* @return the list of <code>Entity</code> objects.
*/
public List<Entity> getBodyParts() {
return Collections.unmodifiableList(bodyParts);
}
/**
* Sets the list of body parts.
*
* @param bodyParts
* the new list of <code>Entity</code> objects.
*/
public void setBodyParts(List<Entity> bodyParts) {
this.bodyParts = bodyParts;
for (Entity bodyPart : bodyParts) {
bodyPart.setParent(parent);
}
}
/**
* Adds a body part to the end of the list of body parts.
*
* @param bodyPart
* the body part.
*/
public void addBodyPart(Entity bodyPart) {
if (bodyPart == null)
throw new IllegalArgumentException();
bodyParts.add(bodyPart);
bodyPart.setParent(parent);
}
/**
* Inserts a body part at the specified position in the list of body parts.
*
* @param bodyPart
* the body part.
* @param index
* index at which the specified body part is to be inserted.
* @throws IndexOutOfBoundsException
* if the index is out of range (index &lt; 0 || index &gt;
* getCount()).
*/
public void addBodyPart(Entity bodyPart, int index) {
if (bodyPart == null)
throw new IllegalArgumentException();
bodyParts.add(index, bodyPart);
bodyPart.setParent(parent);
}
/**
* Removes the body part at the specified position in the list of body
* parts.
*
* @param index
* index of the body part to be removed.
* @return the removed body part.
* @throws IndexOutOfBoundsException
* if the index is out of range (index &lt; 0 || index &gt;=
* getCount()).
*/
public Entity removeBodyPart(int index) {
Entity bodyPart = bodyParts.remove(index);
bodyPart.setParent(null);
return bodyPart;
}
/**
* Replaces the body part at the specified position in the list of body
* parts with the specified body part.
*
* @param bodyPart
* body part to be stored at the specified position.
* @param index
* index of body part to replace.
* @return the replaced body part.
* @throws IndexOutOfBoundsException
* if the index is out of range (index &lt; 0 || index &gt;=
* getCount()).
*/
public Entity replaceBodyPart(Entity bodyPart, int index) {
if (bodyPart == null)
throw new IllegalArgumentException();
Entity replacedEntity = bodyParts.set(index, bodyPart);
if (bodyPart == replacedEntity)
throw new IllegalArgumentException(
"Cannot replace body part with itself");
bodyPart.setParent(parent);
replacedEntity.setParent(null);
return replacedEntity;
}
/**
* Gets the preamble or null if the message has no preamble.
*
* @return the preamble.
*/
public abstract String getPreamble();
/**
* Sets the preamble with a value or null to remove the preamble.
*
* @param preamble
* the preamble.
*/
public abstract void setPreamble(String preamble);
/**
* Gets the epilogue or null if the message has no epilogue
*
* @return the epilogue.
*/
public abstract String getEpilogue();
/**
* Sets the epilogue value, or remove it if the value passed is null.
*
* @param epilogue
* the epilogue.
*/
public abstract void setEpilogue(String epilogue);
/**
* Disposes of the BodyParts of this Multipart. Note that the dispose call
* does not get forwarded to the parent entity of this Multipart.
*
* @see org.apache.james.mime4j.dom.Disposable#dispose()
*/
public void dispose() {
for (Entity bodyPart : bodyParts) {
bodyPart.dispose();
}
}
}

View File

@ -1,95 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
/**
* Utility class to load Service Providers (SPI).
* This will deprecated as soon as mime4j will be upgraded to Java6
* as Java6 has javax.util.ServiceLoader as a core class.
*/
class ServiceLoader {
private ServiceLoader() {
}
/**
* Loads a Service Provider for the given interface/class (SPI).
*/
static <T> T load(Class<T> spiClass) {
String spiResURI = "META-INF/services/" + spiClass.getName();
ClassLoader classLoader = spiClass.getClassLoader();
Enumeration<URL> resources;
try {
resources = classLoader.getResources(spiResURI);
} catch (IOException e) {
return null;
}
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(resource
.openStream()));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
int cmtIdx = line.indexOf('#');
if (cmtIdx != -1) {
line = line.substring(0, cmtIdx);
line = line.trim();
}
if (line.length() == 0) {
continue;
}
Class<?> implClass;
try {
implClass = classLoader.loadClass(line);
if (spiClass.isAssignableFrom(implClass)) {
Object impl = implClass.newInstance();
return spiClass.cast(impl);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
}
return null;
}
}

View File

@ -1,139 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Abstract implementation of a single message body; that is, a body that does
* not contain (directly or indirectly) any other child bodies. It also provides
* the parent functionality required by bodies.
*/
public abstract class SingleBody implements Body {
private Entity parent = null;
/**
* Sole constructor.
*/
protected SingleBody() {
}
/**
* @see org.apache.james.mime4j.dom.Body#getParent()
*/
public Entity getParent() {
return parent;
}
/**
* @see org.apache.james.mime4j.dom.Body#setParent(org.apache.james.mime4j.dom.Entity)
*/
public void setParent(Entity parent) {
this.parent = parent;
}
/**
* Gets a <code>InputStream</code> which reads the bytes of the body.
*
* @return the stream, transfer decoded
* @throws IOException
* on I/O errors.
*/
public abstract InputStream getInputStream() throws IOException;
/**
* Writes this single body to the given stream. The default implementation copies
* the input stream obtained by {@link #getInputStream()} to the specified output
* stream. May be overwritten by a subclass to improve performance.
*
* @param out
* the stream to write to.
* @throws IOException
* in case of an I/O error
*/
public void writeTo(OutputStream out) throws IOException {
if (out == null)
throw new IllegalArgumentException();
InputStream in = getInputStream();
SingleBody.copy(in, out);
in.close();
}
/**
* Returns a copy of this <code>SingleBody</code> (optional operation).
* <p>
* The general contract of this method is as follows:
* <ul>
* <li>Invoking {@link #getParent()} on the copy returns <code>null</code>.
* That means that the copy is detached from the parent entity of this
* <code>SingleBody</code>. The copy may get attached to a different
* entity later on.</li>
* <li>The underlying content does not have to be copied. Instead it may be
* shared between multiple copies of a <code>SingleBody</code>.</li>
* <li>If the underlying content is shared by multiple copies the
* implementation has to make sure that the content gets deleted when the
* last copy gets disposed of (and not before that).</li>
* </ul>
* <p>
* This implementation always throws an
* <code>UnsupportedOperationException</code>.
*
* @return a copy of this <code>SingleBody</code>.
* @throws UnsupportedOperationException
* if the <code>copy</code> operation is not supported by this
* single body.
*/
public SingleBody copy() {
throw new UnsupportedOperationException();
}
/**
* Subclasses should override this method if they have allocated resources
* that need to be freed explicitly (e.g. cannot be simply reclaimed by the
* garbage collector).
*
* The default implementation of this method does nothing.
*
* @see org.apache.james.mime4j.dom.Disposable#dispose()
*/
public void dispose() {
}
static final int DEFAULT_ENCODING_BUFFER_SIZE = 1024;
/**
* Copies the contents of one stream to the other.
* @param in not null
* @param out not null
* @throws IOException
*/
private static void copy(final InputStream in, final OutputStream out) throws IOException {
final byte[] buffer = new byte[DEFAULT_ENCODING_BUFFER_SIZE];
int inputLength;
while (-1 != (inputLength = in.read(buffer))) {
out.write(buffer, 0, inputLength);
}
}
}

View File

@ -1,53 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom;
import java.io.IOException;
import java.io.Reader;
/**
* Encapsulates the contents of a <code>text/*</code> entity body.
*/
public abstract class TextBody extends SingleBody {
/**
* Sole constructor.
*/
protected TextBody() {
}
/**
* Returns the MIME charset of this text body.
*
* @return the MIME charset.
*/
public abstract String getMimeCharset();
/**
* Gets a <code>Reader</code> which may be used to read out the contents
* of this body.
*
* @return the <code>Reader</code>.
* @throws IOException
* on I/O errors.
*/
public abstract Reader getReader() throws IOException;
}

View File

@ -1,48 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.io.Serializable;
import java.util.List;
/**
* The abstract base for classes that represent RFC2822 addresses. This includes
* groups and mailboxes.
*/
public abstract class Address implements Serializable {
private static final long serialVersionUID = 634090661990433426L;
/**
* Adds any mailboxes represented by this address into the given List. 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(List<Mailbox> results) {
doAddMailboxesTo(results);
}
/**
* Adds any mailboxes represented by this address into the given List. Must
* be overridden by concrete subclasses.
*/
protected abstract void doAddMailboxesTo(List<Mailbox> results);
}

View File

@ -1,98 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* An immutable, random-access list of Address objects.
*/
public class AddressList extends AbstractList<Address> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<? extends Address> addresses;
/**
* @param addresses
* A List that contains only Address objects.
* @param dontCopy
* true iff it is not possible for the addresses list to be
* modified by someone else.
*/
public AddressList(List<? extends Address> addresses, boolean dontCopy) {
if (addresses != null)
this.addresses = dontCopy ? addresses : new ArrayList<Address>(
addresses);
else
this.addresses = Collections.emptyList();
}
/**
* The number of elements in this list.
*/
@Override
public int size() {
return addresses.size();
}
/**
* Gets an address.
*/
@Override
public Address get(int index) {
return 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 (Address addr : addresses) {
if (!(addr instanceof Mailbox)) {
groupDetected = true;
break;
}
}
if (!groupDetected) {
@SuppressWarnings("unchecked")
final List<Mailbox> mailboxes = (List<Mailbox>) addresses;
return new MailboxList(mailboxes, true);
}
List<Mailbox> results = new ArrayList<Mailbox>();
for (Address addr : addresses) {
addr.addMailboxesTo(results);
}
// copy-on-construct this time, because subclasses
// could have held onto a reference to the results
return new MailboxList(results, false);
}
}

View File

@ -1,95 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* An immutable, random-access list of Strings (that are supposedly domain names
* or domain literals).
*/
public class DomainList extends AbstractList<String> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<String> domains;
/**
* @param domains
* A List that contains only String objects.
* @param dontCopy
* true iff it is not possible for the domains list to be
* modified by someone else.
*/
public DomainList(List<String> domains, boolean dontCopy) {
if (domains != null)
this.domains = dontCopy ? domains : new ArrayList<String>(domains);
else
this.domains = Collections.emptyList();
}
/**
* The number of elements in this list.
*/
@Override
public int size() {
return domains.size();
}
/**
* Gets the domain name or domain literal at the specified index.
*
* @throws IndexOutOfBoundsException
* If index is &lt; 0 or &gt;= size().
*/
@Override
public String get(int index) {
return domains.get(index);
}
/**
* Returns the list of domains formatted as a route string (not including
* the trailing ':').
*/
public String toRouteString() {
StringBuilder sb = new StringBuilder();
for (String domain : domains) {
if (sb.length() > 0) {
sb.append(',');
}
sb.append("@");
sb.append(domain);
}
return sb.toString();
}
@Override
public String toString() {
return toRouteString();
}
}

View File

@ -1,113 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* A named group of zero or more mailboxes.
*/
public class Group extends Address {
private static final long serialVersionUID = 1L;
private final String name;
private final MailboxList mailboxList;
/**
* @param name
* The group name.
* @param mailboxes
* The mailboxes in this group.
*/
public Group(String name, MailboxList mailboxes) {
if (name == null)
throw new IllegalArgumentException();
if (mailboxes == null)
throw new IllegalArgumentException();
this.name = name;
this.mailboxList = mailboxes;
}
/**
* @param name
* The group name.
* @param mailboxes
* The mailboxes in this group.
*/
public Group(String name, Mailbox... mailboxes) {
this(name, new MailboxList(Arrays.asList(mailboxes), true));
}
/**
* @param name
* The group name.
* @param mailboxes
* The mailboxes in this group.
*/
public Group(String name, Collection<Mailbox> mailboxes) {
this(name, new MailboxList(new ArrayList<Mailbox>(mailboxes), true));
}
/**
* Returns the group name.
*/
public String getName() {
return name;
}
/**
* Returns the mailboxes in this group.
*/
public MailboxList getMailboxes() {
return mailboxList;
}
@Override
protected void doAddMailboxesTo(List<Mailbox> results) {
for (Mailbox mailbox : mailboxList) {
results.add(mailbox);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append(':');
boolean first = true;
for (Mailbox mailbox : mailboxList) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(' ');
sb.append(mailbox);
}
sb.append(";");
return sb.toString();
}
}

View File

@ -1,204 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.apache.james.mime4j.util.LangUtils;
/**
* Represents a single e-mail address.
*/
public class Mailbox extends Address {
private static final long serialVersionUID = 1L;
private static final DomainList EMPTY_ROUTE_LIST = new DomainList(
Collections.<String> emptyList(), true);
private final String name;
private final DomainList route;
private final String localPart;
private final String domain;
/**
* Creates a named mailbox with a route. Routes are obsolete.
*
* @param name
* the name of the e-mail address. May be <code>null</code>.
* @param route
* The zero or more domains that make up the route. May be
* <code>null</code>.
* @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 name, DomainList route, String localPart,
String domain) {
if (localPart == null || localPart.length() == 0)
throw new IllegalArgumentException();
this.name = name == null || name.length() == 0 ? null : name;
this.route = route == null ? EMPTY_ROUTE_LIST : route;
this.localPart = localPart;
this.domain = domain == null || domain.length() == 0 ? null : domain;
}
/**
* Creates a named mailbox based on an unnamed mailbox. Package private;
* internally used by Builder.
*/
Mailbox(String name, Mailbox baseMailbox) {
this(name, baseMailbox.getRoute(), baseMailbox.getLocalPart(),
baseMailbox.getDomain());
}
/**
* Creates an unnamed 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, null, localPart, domain);
}
/**
* Creates an unnamed mailbox with a route. Routes are obsolete.
*
* @param route
* The zero or more domains that make up the route. May be
* <code>null</code>.
* @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(null, route, localPart, domain);
}
/**
* Creates a named mailbox without a route. Routes are obsolete.
*
* @param name
* the name of the e-mail address. May be <code>null</code>.
* @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 name, String localPart, String domain) {
this(name, null, localPart, domain);
}
/**
* Returns the name of the mailbox or <code>null</code> if it does not
* have a name.
*/
public String getName() {
return name;
}
/**
* Returns the route list. If the mailbox does not have a route an empty
* domain list is returned.
*/
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;
}
/**
* Returns the address in the form <i>localPart@domain</i>.
*
* @return the address part of this mailbox.
*/
public String getAddress() {
if (domain == null) {
return localPart;
} else {
return localPart + '@' + domain;
}
}
@Override
protected final void doAddMailboxesTo(List<Mailbox> results) {
results.add(this);
}
@Override
public int hashCode() {
int hash = LangUtils.HASH_SEED;
hash = LangUtils.hashCode(hash, this.localPart);
hash = LangUtils.hashCode(hash, this.domain != null ?
this.domain.toLowerCase(Locale.US) : null);
return hash;
}
/**
* Indicates whether some other object is "equal to" this mailbox.
* <p>
* An object is considered to be equal to this mailbox if it is an instance
* of class <code>Mailbox</code> that holds the same address as this one.
* The domain is considered to be case-insensitive but the local-part is not
* (because of RFC 5321: <cite>the local-part of a mailbox MUST BE treated
* as case sensitive</cite>).
*
* @param obj
* the object to test for equality.
* @return <code>true</code> if the specified object is a
* <code>Mailbox</code> that holds the same address as this one.
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Mailbox))
return false;
Mailbox that = (Mailbox) obj;
return LangUtils.equals(this.localPart, that.localPart) &&
LangUtils.equalsIgnoreCase(this.domain, that.domain);
}
@Override
public String toString() {
return getAddress();
}
}

View File

@ -1,68 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.address;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* An immutable, random-access list of Mailbox objects.
*/
public class MailboxList extends AbstractList<Mailbox> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<Mailbox> mailboxes;
/**
* @param mailboxes
* A List that contains only Mailbox objects.
* @param dontCopy
* true iff it is not possible for the mailboxes list to be
* modified by someone else.
*/
public MailboxList(List<Mailbox> mailboxes, boolean dontCopy) {
if (mailboxes != null)
this.mailboxes = dontCopy ? mailboxes : new ArrayList<Mailbox>(
mailboxes);
else
this.mailboxes = Collections.emptyList();
}
/**
* The number of elements in this list.
*/
@Override
public int size() {
return mailboxes.size();
}
/**
* Gets an address.
*/
@Override
public Mailbox get(int index) {
return mailboxes.get(index);
}
}

View File

@ -1,165 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.datetime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateTime {
private final Date date;
private final int year;
private final int month;
private final int day;
private final int hour;
private final int minute;
private final int second;
private final int timeZone;
public DateTime(String yearString, int month, int day, int hour, int minute, int second, int timeZone) {
this.year = convertToYear(yearString);
this.date = convertToDate(year, month, day, hour, minute, second, timeZone);
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.second = second;
this.timeZone = timeZone;
}
private int convertToYear(String yearString) {
int year = Integer.parseInt(yearString);
switch (yearString.length()) {
case 1:
case 2:
if (year >= 0 && year < 50)
return 2000 + year;
else
return 1900 + year;
case 3:
return 1900 + year;
default:
return year;
}
}
public static Date convertToDate(int year, int month, int day, int hour, int minute, int second, int timeZone) {
Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
c.set(year, month - 1, day, hour, minute, second);
c.set(Calendar.MILLISECOND, 0);
if (timeZone != Integer.MIN_VALUE) {
int minutes = ((timeZone / 100) * 60) + timeZone % 100;
c.add(Calendar.MINUTE, -1 * minutes);
}
return c.getTime();
}
public Date getDate() {
return date;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getSecond() {
return second;
}
public int getTimeZone() {
return timeZone;
}
public void print() {
System.out.println(toString());
}
@Override
public String toString() {
return getYear() + " " + getMonth() + " " + getDay() + "; " + getHour() + " " + getMinute() + " " + getSecond() + " " + getTimeZone();
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((date == null) ? 0 : date.hashCode());
result = PRIME * result + day;
result = PRIME * result + hour;
result = PRIME * result + minute;
result = PRIME * result + month;
result = PRIME * result + second;
result = PRIME * result + timeZone;
result = PRIME * result + year;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final DateTime other = (DateTime) obj;
if (date == null) {
if (other.date != null)
return false;
} else if (!date.equals(other.date))
return false;
if (day != other.day)
return false;
if (hour != other.hour)
return false;
if (minute != other.minute)
return false;
if (month != other.month)
return false;
if (second != other.second)
return false;
if (timeZone != other.timeZone)
return false;
if (year != other.year)
return false;
return true;
}
}

View File

@ -1,28 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import org.apache.james.mime4j.dom.address.AddressList;
public interface AddressListField extends ParsedField {
AddressList getAddressList();
}

View File

@ -1,117 +0,0 @@
package org.apache.james.mime4j.dom.field;
import java.util.Date;
import java.util.Map;
public interface ContentDispositionField extends ParsedField {
/** The <code>inline</code> disposition type. */
public static final String DISPOSITION_TYPE_INLINE = "inline";
/** The <code>attachment</code> disposition type. */
public static final String DISPOSITION_TYPE_ATTACHMENT = "attachment";
/** The name of the <code>filename</code> parameter. */
public static final String PARAM_FILENAME = "filename";
/** The name of the <code>creation-date</code> parameter. */
public static final String PARAM_CREATION_DATE = "creation-date";
/** The name of the <code>modification-date</code> parameter. */
public static final String PARAM_MODIFICATION_DATE = "modification-date";
/** The name of the <code>read-date</code> parameter. */
public static final String PARAM_READ_DATE = "read-date";
/** The name of the <code>size</code> parameter. */
public static final String PARAM_SIZE = "size";
/**
* Gets the disposition type defined in this Content-Disposition field.
*
* @return the disposition type or an empty string if not set.
*/
String getDispositionType();
/**
* 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 <code>null</code> if not set.
*/
String getParameter(String name);
/**
* Gets all parameters.
*
* @return the parameters.
*/
Map<String, String> getParameters();
/**
* Determines if the disposition type of this field matches the given one.
*
* @param dispositionType
* the disposition type to match against.
* @return <code>true</code> if the disposition type of this field
* matches, <code>false</code> otherwise.
*/
boolean isDispositionType(String dispositionType);
/**
* Return <code>true</code> if the disposition type of this field is
* <i>inline</i>, <code>false</code> otherwise.
*
* @return <code>true</code> if the disposition type of this field is
* <i>inline</i>, <code>false</code> otherwise.
*/
boolean isInline();
/**
* Return <code>true</code> if the disposition type of this field is
* <i>attachment</i>, <code>false</code> otherwise.
*
* @return <code>true</code> if the disposition type of this field is
* <i>attachment</i>, <code>false</code> otherwise.
*/
public abstract boolean isAttachment();
/**
* Gets the value of the <code>filename</code> parameter if set.
*
* @return the <code>filename</code> parameter value or <code>null</code>
* if not set.
*/
String getFilename();
/**
* Gets the value of the <code>creation-date</code> parameter if set and
* valid.
*
* @return the <code>creation-date</code> parameter value or
* <code>null</code> if not set or invalid.
*/
Date getCreationDate();
/**
* Gets the value of the <code>modification-date</code> parameter if set
* and valid.
*
* @return the <code>modification-date</code> parameter value or
* <code>null</code> if not set or invalid.
*/
Date getModificationDate();
/**
* Gets the value of the <code>read-date</code> parameter if set and
* valid.
*
* @return the <code>read-date</code> parameter value or <code>null</code>
* if not set or invalid.
*/
Date getReadDate();
/**
* Gets the value of the <code>size</code> parameter if set and valid.
*
* @return the <code>size</code> parameter value or <code>-1</code> if
* not set or invalid.
*/
long getSize();
}

View File

@ -1,31 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
public interface ContentTransferEncodingField extends ParsedField {
/**
* Gets the encoding defined in this field.
*
* @return the encoding or an empty string if not set.
*/
String getEncoding();
}

View File

@ -1,97 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import java.util.Map;
public interface ContentTypeField extends ParsedField {
/** The prefix of all <code>multipart</code> MIME types. */
public static final String TYPE_MULTIPART_PREFIX = "multipart/";
/** The <code>multipart/digest</code> MIME type. */
public static final String TYPE_MULTIPART_DIGEST = "multipart/digest";
/** The <code>text/plain</code> MIME type. */
public static final String TYPE_TEXT_PLAIN = "text/plain";
/** The <code>message/rfc822</code> MIME type. */
public static final String TYPE_MESSAGE_RFC822 = "message/rfc822";
/** The name of the <code>boundary</code> parameter. */
public static final String PARAM_BOUNDARY = "boundary";
/** The name of the <code>charset</code> parameter. */
public static final String PARAM_CHARSET = "charset";
/**
* Gets the MIME type defined in this Content-Type field.
*
* @return the MIME type or an empty string if not set.
*/
String 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 <code>null</code> if not set.
*/
String getParameter(String name);
/**
* Gets all parameters.
*
* @return the parameters.
*/
Map<String, String> getParameters();
/**
* Determines if the MIME type of this field matches the given one.
*
* @param mimeType
* the MIME type to match against.
* @return <code>true</code> if the MIME type of this field matches,
* <code>false</code> otherwise.
*/
boolean isMimeType(String mimeType);
/**
* Determines if the MIME type of this field is <code>multipart/*</code>.
*
* @return <code>true</code> if this field is has a
* <code>multipart/*</code> MIME type, <code>false</code>
* otherwise.
*/
boolean isMultipart();
/**
* Gets the value of the <code>boundary</code> parameter if set.
*
* @return the <code>boundary</code> parameter value or <code>null</code>
* if not set.
*/
String getBoundary();
/**
* Gets the value of the <code>charset</code> parameter if set.
*
* @return the <code>charset</code> parameter value or <code>null</code>
* if not set.
*/
String getCharset();
}

View File

@ -1,9 +0,0 @@
package org.apache.james.mime4j.dom.field;
import java.util.Date;
public interface DateTimeField extends ParsedField {
Date getDate();
}

View File

@ -1,51 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import java.io.IOException;
import java.io.OutputStream;
/**
* Abstract MIME field.
*/
public interface Field {
/**
* Gets the name of the field (<code>Subject</code>, <code>From</code>, etc).
*
* @return the field name.
*/
String getName();
/**
* Gets the unparsed and possibly encoded (see RFC 2047) field body string.
*
* @return the unparsed field body string.
*/
String getBody();
/**
* Writes the original raw field bytes to an output stream.
* The output is folded, the last CRLF is not included.
* @throws IOException
*/
void writeTo(OutputStream out) throws IOException;
}

View File

@ -1,53 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
/**
* Constants for common header field names.
*/
public class FieldName {
public static final String CONTENT_DISPOSITION = "Content-Disposition";
public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
public static final String CONTENT_TYPE = "Content-Type";
public static final String DATE = "Date";
public static final String MESSAGE_ID = "Message-ID";
public static final String SUBJECT = "Subject";
public static final String FROM = "From";
public static final String SENDER = "Sender";
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_DATE = "Resent-Date";
public static final String RESENT_FROM = "Resent-From";
public static final String RESENT_SENDER = "Resent-Sender";
public static final String RESENT_TO = "Resent-To";
public static final String RESENT_CC = "Resent-Cc";
public static final String RESENT_BCC = "Resent-Bcc";
private FieldName() {
}
}

View File

@ -1,28 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import org.apache.james.mime4j.dom.address.Mailbox;
public interface MailboxField extends ParsedField {
Mailbox getMailbox();
}

View File

@ -1,28 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import org.apache.james.mime4j.dom.address.MailboxList;
public interface MailboxListField extends ParsedField {
MailboxList getMailboxList();
}

View File

@ -1,64 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
import org.apache.james.mime4j.MimeException;
/**
* This exception is thrown when parse errors are encountered.
*/
public class ParseException extends MimeException {
private static final long serialVersionUID = 1L;
/**
* Constructs a new parse exception with the specified detail message.
*
* @param message
* detail message
*/
protected ParseException(String message) {
super(message);
}
/**
* Constructs a new parse exception with the specified cause.
*
* @param cause
* the cause
*/
protected ParseException(Throwable cause) {
super(cause);
}
/**
* Constructs a new parse exception with the specified detail message and
* cause.
*
* @param message
* detail message
* @param cause
* the cause
*/
protected ParseException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,45 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
public interface ParsedField extends Field {
/**
* Returns <code>true</code> if this field is valid, i.e. no errors were
* encountered while parsing the field value.
*
* @return <code>true</code> if this field is valid, <code>false</code>
* otherwise.
* @see #getParseException()
*/
boolean isValidField();
/**
* Returns the exception that was thrown by the field parser while parsing
* the field value. The result is <code>null</code> if the field is valid
* and no errors were encountered.
*
* @return the exception that was thrown by the field parser or
* <code>null</code> if the field is valid.
*/
ParseException getParseException();
}

View File

@ -1,26 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.dom.field;
public interface UnstructuredField extends ParsedField {
String getValue();
}

View File

@ -1,97 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ParseException;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.util.ByteSequence;
/**
* The base class of all field classes.
*/
public abstract class AbstractField implements ParsedField {
private final String name;
private final String body;
private final ByteSequence raw;
protected DecodeMonitor monitor;
protected AbstractField(
final String name,
final String body,
final ByteSequence raw,
final DecodeMonitor monitor) {
this.name = name;
this.body = body;
this.raw = raw;
this.monitor = monitor != null ? monitor : DecodeMonitor.SILENT;
}
/**
* Gets the name of the field (<code>Subject</code>,
* <code>From</code>, etc).
*
* @return the field name.
*/
public String getName() {
return name;
}
/**
* @see org.apache.james.mime4j.dom.field.Field#writeTo(java.io.OutputStream)
*/
public void writeTo(OutputStream out) throws IOException {
out.write(raw.toByteArray());
}
/**
* 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;
}
/**
* @see ParsedField#isValidField()
*/
public boolean isValidField() {
return getParseException() == null;
}
/**
* @see ParsedField#getParseException()
*/
public ParseException getParseException() {
return null;
}
@Override
public String toString() {
return name + ": " + body;
}
}

View File

@ -1,81 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.field.address.parser.AddressBuilder;
import org.apache.james.mime4j.field.address.parser.ParseException;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Address list field such as <code>To</code> or <code>Reply-To</code>.
*/
public class AddressListFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.AddressListField {
private boolean parsed = false;
private AddressList addressList;
private ParseException parseException;
AddressListFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.AddressListField#getAddressList()
*/
public AddressList getAddressList() {
if (!parsed)
parse();
return addressList;
}
/**
* @see org.apache.james.mime4j.dom.field.AddressListField#getParseException()
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
private void parse() {
String body = getBody();
try {
addressList = AddressBuilder.parseAddressList(body, monitor);
} catch (ParseException e) {
parseException = e;
}
parsed = true;
}
static final FieldParser<AddressListFieldImpl> PARSER = new FieldParser<AddressListFieldImpl>() {
public AddressListFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new AddressListFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,253 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.io.StringReader;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.field.contentdisposition.parser.ContentDispositionParser;
import org.apache.james.mime4j.field.contentdisposition.parser.ParseException;
import org.apache.james.mime4j.field.contentdisposition.parser.TokenMgrError;
import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Represents a <code>Content-Disposition</code> field.
*/
public class ContentDispositionFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.ContentDispositionField {
private boolean parsed = false;
private String dispositionType = "";
private Map<String, String> parameters = new HashMap<String, String>();
private ParseException parseException;
private boolean creationDateParsed;
private Date creationDate;
private boolean modificationDateParsed;
private Date modificationDate;
private boolean readDateParsed;
private Date readDate;
ContentDispositionFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* Gets the exception that was raised during parsing of the field value, if
* any; otherwise, null.
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getDispositionType()
*/
public String getDispositionType() {
if (!parsed)
parse();
return dispositionType;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getParameter(java.lang.String)
*/
public String getParameter(String name) {
if (!parsed)
parse();
return parameters.get(name.toLowerCase());
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getParameters()
*/
public Map<String, String> getParameters() {
if (!parsed)
parse();
return Collections.unmodifiableMap(parameters);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#isDispositionType(java.lang.String)
*/
public boolean isDispositionType(String dispositionType) {
if (!parsed)
parse();
return this.dispositionType.equalsIgnoreCase(dispositionType);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#isInline()
*/
public boolean isInline() {
if (!parsed)
parse();
return dispositionType.equals(DISPOSITION_TYPE_INLINE);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#isAttachment()
*/
public boolean isAttachment() {
if (!parsed)
parse();
return dispositionType.equals(DISPOSITION_TYPE_ATTACHMENT);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getFilename()
*/
public String getFilename() {
return getParameter(PARAM_FILENAME);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getCreationDate()
*/
public Date getCreationDate() {
if (!creationDateParsed) {
creationDate = parseDate(PARAM_CREATION_DATE);
creationDateParsed = true;
}
return creationDate;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getModificationDate()
*/
public Date getModificationDate() {
if (!modificationDateParsed) {
modificationDate = parseDate(PARAM_MODIFICATION_DATE);
modificationDateParsed = true;
}
return modificationDate;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getReadDate()
*/
public Date getReadDate() {
if (!readDateParsed) {
readDate = parseDate(PARAM_READ_DATE);
readDateParsed = true;
}
return readDate;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentDispositionField#getSize()
*/
public long getSize() {
String value = getParameter(PARAM_SIZE);
if (value == null)
return -1;
try {
long size = Long.parseLong(value);
return size < 0 ? -1 : size;
} catch (NumberFormatException e) {
return -1;
}
}
private Date parseDate(String paramName) {
String value = getParameter(paramName);
if (value == null) {
monitor.warn("Parsing " + paramName + " null", "returning null");
return null;
}
try {
return new DateTimeParser(new StringReader(value)).parseAll()
.getDate();
} catch (org.apache.james.mime4j.field.datetime.parser.ParseException e) {
monitor.warn("Parsing " + paramName + " '" + value + "': "
+ e.getMessage(), "returning null");
return null;
} catch (org.apache.james.mime4j.field.datetime.parser.TokenMgrError e) {
monitor.warn("Parsing " + paramName + " '" + value + "': "
+ e.getMessage(), "returning null");
return null;
}
}
private void parse() {
String body = getBody();
ContentDispositionParser parser = new ContentDispositionParser(
new StringReader(body));
try {
parser.parseAll();
} catch (ParseException e) {
parseException = e;
} catch (TokenMgrError e) {
parseException = new ParseException(e.getMessage());
}
final String dispositionType = parser.getDispositionType();
if (dispositionType != null) {
this.dispositionType = dispositionType.toLowerCase(Locale.US);
List<String> paramNames = parser.getParamNames();
List<String> paramValues = parser.getParamValues();
if (paramNames != null && paramValues != null) {
final int len = Math.min(paramNames.size(), paramValues.size());
for (int i = 0; i < len; i++) {
String paramName = paramNames.get(i).toLowerCase(Locale.US);
String paramValue = paramValues.get(i);
parameters.put(paramName, paramValue);
}
}
}
parsed = true;
}
static final FieldParser<ContentDispositionFieldImpl> PARSER = new FieldParser<ContentDispositionFieldImpl>() {
public ContentDispositionFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new ContentDispositionFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,65 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
import org.apache.james.mime4j.util.ByteSequence;
import org.apache.james.mime4j.util.MimeUtil;
/**
* Represents a <code>Content-Transfer-Encoding</code> field.
*/
public class ContentTransferEncodingFieldImpl extends AbstractField implements ContentTransferEncodingField {
private String encoding;
ContentTransferEncodingFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
encoding = body.trim().toLowerCase();
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTransferEncodingField#getEncoding()
*/
public String getEncoding() {
return encoding;
}
/**
* Gets the encoding of the given field if. Returns the default
* <code>7bit</code> if not set or if <code>f</code> is
* <code>null</code>.
*
* @return the encoding.
*/
public static String getEncoding(ContentTransferEncodingField f) {
if (f != null && f.getEncoding().length() != 0) {
return f.getEncoding();
}
return MimeUtil.ENC_7BIT;
}
static final FieldParser<ContentTransferEncodingFieldImpl> PARSER = new FieldParser<ContentTransferEncodingFieldImpl>() {
public ContentTransferEncodingFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new ContentTransferEncodingFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,208 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.io.StringReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ContentTypeField;
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;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Represents a <code>Content-Type</code> field.
*/
public class ContentTypeFieldImpl extends AbstractField implements ContentTypeField {
private boolean parsed = false;
private String mimeType = "";
private Map<String, String> parameters = new HashMap<String, String>();
private ParseException parseException;
ContentTypeFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getParseException()
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getMimeType()
*/
public String getMimeType() {
if (!parsed)
parse();
return mimeType;
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getParameter(java.lang.String)
*/
public String getParameter(String name) {
if (!parsed)
parse();
return parameters.get(name.toLowerCase());
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getParameters()
*/
public Map<String, String> getParameters() {
if (!parsed)
parse();
return Collections.unmodifiableMap(parameters);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#isMimeType(java.lang.String)
*/
public boolean isMimeType(String mimeType) {
if (!parsed)
parse();
return this.mimeType.equalsIgnoreCase(mimeType);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#isMultipart()
*/
public boolean isMultipart() {
if (!parsed)
parse();
return mimeType.startsWith(TYPE_MULTIPART_PREFIX);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getBoundary()
*/
public String getBoundary() {
return getParameter(PARAM_BOUNDARY);
}
/**
* @see org.apache.james.mime4j.dom.field.ContentTypeField#getCharset()
*/
public String getCharset() {
return getParameter(PARAM_CHARSET);
}
/**
* Gets the MIME type defined in the child's Content-Type field or derives a
* MIME type from the parent if child is <code>null</code> 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 the <code>charset</code> parameter if set for the
* given field. Returns the default <code>us-ascii</code> if not set or if
* <code>f</code> is <code>null</code>.
*
* @return the <code>charset</code> parameter value.
*/
public static String getCharset(ContentTypeField f) {
if (f != null) {
String charset = f.getCharset();
if (charset != null && charset.length() > 0) {
return charset;
}
}
return "us-ascii";
}
private void parse() {
String body = getBody();
ContentTypeParser parser = new ContentTypeParser(new StringReader(body));
try {
parser.parseAll();
} catch (ParseException e) {
parseException = e;
} catch (TokenMgrError e) {
parseException = new ParseException(e.getMessage());
}
final String type = parser.getType();
final String subType = parser.getSubType();
if (type != null && subType != null) {
mimeType = (type + "/" + subType).toLowerCase();
List<String> paramNames = parser.getParamNames();
List<String> paramValues = parser.getParamValues();
if (paramNames != null && paramValues != null) {
final int len = Math.min(paramNames.size(), paramValues.size());
for (int i = 0; i < len; i++) {
String paramName = paramNames.get(i).toLowerCase();
String paramValue = paramValues.get(i);
parameters.put(paramName, paramValue);
}
}
}
parsed = true;
}
static final FieldParser<ContentTypeFieldImpl> PARSER = new FieldParser<ContentTypeFieldImpl>() {
public ContentTypeFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new ContentTypeFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,86 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.io.StringReader;
import java.util.Date;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
import org.apache.james.mime4j.field.datetime.parser.ParseException;
import org.apache.james.mime4j.field.datetime.parser.TokenMgrError;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Date-time field such as <code>Date</code> or <code>Resent-Date</code>.
*/
public class DateTimeFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.DateTimeField {
private boolean parsed = false;
private Date date;
private ParseException parseException;
DateTimeFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.DateTimeField#getDate()
*/
public Date getDate() {
if (!parsed)
parse();
return date;
}
/**
* @see org.apache.james.mime4j.dom.field.DateTimeField#getParseException()
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
private void parse() {
String body = getBody();
try {
date = new DateTimeParser(new StringReader(body)).parseAll()
.getDate();
} catch (ParseException e) {
parseException = e;
} catch (TokenMgrError e) {
parseException = new ParseException(e.getMessage());
}
parsed = true;
}
static final FieldParser<DateTimeFieldImpl> PARSER = new FieldParser<DateTimeFieldImpl>() {
public DateTimeFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new DateTimeFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,133 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.field.AddressListFieldImpl;
import org.apache.james.mime4j.field.ContentDispositionFieldImpl;
import org.apache.james.mime4j.field.ContentTransferEncodingFieldImpl;
import org.apache.james.mime4j.field.ContentTypeFieldImpl;
import org.apache.james.mime4j.field.DateTimeFieldImpl;
import org.apache.james.mime4j.field.MailboxFieldImpl;
import org.apache.james.mime4j.field.MailboxListFieldImpl;
import org.apache.james.mime4j.field.UnstructuredFieldImpl;
import org.apache.james.mime4j.stream.RawField;
import org.apache.james.mime4j.util.ByteSequence;
import org.apache.james.mime4j.util.ContentUtil;
public class DefaultFieldParser extends DelegatingFieldParser {
private static final DefaultFieldParser PARSER = new DefaultFieldParser();
/**
* Gets the default parser used to parse fields.
*
* @return the default field parser
*/
public static DefaultFieldParser getParser() {
return PARSER;
}
/**
* Parses the given byte sequence and returns an instance of the
* <code>Field</code> class. The type of the class returned depends on the
* field name; see {@link #parse(String)} for a table of field names and
* their corresponding classes.
*
* @param raw the bytes to parse.
* @param monitor a DecodeMonitor object used while parsing/decoding.
* @return a <code>ParsedField</code> instance.
* @throws MimeException if the raw string cannot be split into field name and body.
*/
public static ParsedField parse(
final ByteSequence raw,
final DecodeMonitor monitor) throws MimeException {
RawField rawField = new RawField(raw);
return PARSER.parse(rawField.getName(), rawField.getBody(), raw, monitor);
}
/**
* Parses the given string and returns an instance of the
* <code>Field</code> class. The type of the class returned depends on
* the field name:
* <p>
* <table>
* <tr><th>Class returned</th><th>Field names</th></tr>
* <tr><td>{@link ContentTypeFieldImpl}</td><td>Content-Type</td></tr>
* <tr><td>{@link ContentTransferEncodingFieldImpl}</td><td>Content-Transfer-Encoding</td></tr>
* <tr><td>{@link ContentDispositionFieldImpl}</td><td>Content-Disposition</td></tr>
* <tr><td>{@link DateTimeFieldImpl}</td><td>Date, Resent-Date</td></tr>
* <tr><td>{@link MailboxFieldImpl}</td><td>Sender, Resent-Sender</td></tr>
* <tr><td>{@link MailboxListFieldImpl}</td><td>From, Resent-From</td></tr>
* <tr><td>{@link AddressListFieldImpl}</td><td>To, Cc, Bcc, Reply-To, Resent-To, Resent-Cc, Resent-Bcc</td></tr>
* <tr><td>{@link UnstructuredFieldImpl}</td><td>Subject and others</td></tr>
* </table>
*
* @param rawStr the string to parse.
* @return a <code>ParsedField</code> instance.
* @throws MimeException if the raw string cannot be split into field name and body.
*/
public static ParsedField parse(
final String rawStr,
final DecodeMonitor monitor) throws MimeException {
ByteSequence raw = ContentUtil.encode(rawStr);
return parse(raw, monitor);
}
public static ParsedField parse(final String rawStr) throws MimeException {
ByteSequence raw = ContentUtil.encode(rawStr);
return parse(raw, DecodeMonitor.SILENT);
}
public DefaultFieldParser() {
setFieldParser(FieldName.CONTENT_TRANSFER_ENCODING,
ContentTransferEncodingFieldImpl.PARSER);
setFieldParser(FieldName.CONTENT_TYPE, ContentTypeFieldImpl.PARSER);
setFieldParser(FieldName.CONTENT_DISPOSITION,
ContentDispositionFieldImpl.PARSER);
final FieldParser<DateTimeFieldImpl> dateTimeParser = DateTimeFieldImpl.PARSER;
setFieldParser(FieldName.DATE, dateTimeParser);
setFieldParser(FieldName.RESENT_DATE, dateTimeParser);
final FieldParser<MailboxListFieldImpl> mailboxListParser = MailboxListFieldImpl.PARSER;
setFieldParser(FieldName.FROM, mailboxListParser);
setFieldParser(FieldName.RESENT_FROM, mailboxListParser);
final FieldParser<MailboxFieldImpl> mailboxParser = MailboxFieldImpl.PARSER;
setFieldParser(FieldName.SENDER, mailboxParser);
setFieldParser(FieldName.RESENT_SENDER, mailboxParser);
final FieldParser<AddressListFieldImpl> addressListParser = AddressListFieldImpl.PARSER;
setFieldParser(FieldName.TO, addressListParser);
setFieldParser(FieldName.RESENT_TO, addressListParser);
setFieldParser(FieldName.CC, addressListParser);
setFieldParser(FieldName.RESENT_CC, addressListParser);
setFieldParser(FieldName.BCC, addressListParser);
setFieldParser(FieldName.RESENT_BCC, addressListParser);
setFieldParser(FieldName.REPLY_TO, addressListParser);
}
}

View File

@ -1,56 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.util.HashMap;
import java.util.Map;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.field.UnstructuredFieldImpl;
import org.apache.james.mime4j.util.ByteSequence;
public class DelegatingFieldParser implements FieldParser<ParsedField> {
private static final FieldParser<UnstructuredFieldImpl> DEFAULT_PARSER = UnstructuredFieldImpl.PARSER;
private Map<String, FieldParser<? extends ParsedField>> parsers = new HashMap<String, FieldParser<? extends ParsedField>>();
/**
* Sets the parser used for the field named <code>name</code>.
* @param name the name of the field
* @param parser the parser for fields named <code>name</code>
*/
public void setFieldParser(final String name, final FieldParser<? extends ParsedField> parser) {
parsers.put(name.toLowerCase(), parser);
}
public FieldParser<? extends ParsedField> getParser(final String name) {
final FieldParser<? extends ParsedField> field = parsers.get(name.toLowerCase());
if (field == null) {
return DEFAULT_PARSER;
}
return field;
}
public ParsedField parse(final String name, final String body, final ByteSequence raw, DecodeMonitor monitor) {
final FieldParser<? extends ParsedField> parser = getParser(name);
return parser.parse(name, body, raw, monitor);
}
}

View File

@ -1,30 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.util.ByteSequence;
public interface FieldParser<T extends ParsedField> {
T parse(final String name, final String body, final ByteSequence raw, DecodeMonitor monitor);
}

View File

@ -1,643 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.codec.EncoderUtil;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.field.AddressListField;
import org.apache.james.mime4j.dom.field.ContentDispositionField;
import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
import org.apache.james.mime4j.dom.field.ContentTypeField;
import org.apache.james.mime4j.dom.field.DateTimeField;
import org.apache.james.mime4j.dom.field.Field;
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.MailboxField;
import org.apache.james.mime4j.dom.field.MailboxListField;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.dom.field.UnstructuredField;
import org.apache.james.mime4j.field.AddressListFieldImpl;
import org.apache.james.mime4j.field.ContentDispositionFieldImpl;
import org.apache.james.mime4j.field.ContentTransferEncodingFieldImpl;
import org.apache.james.mime4j.field.ContentTypeFieldImpl;
import org.apache.james.mime4j.field.DateTimeFieldImpl;
import org.apache.james.mime4j.field.MailboxFieldImpl;
import org.apache.james.mime4j.field.MailboxListFieldImpl;
import org.apache.james.mime4j.field.UnstructuredFieldImpl;
import org.apache.james.mime4j.field.address.formatter.AddressFormatter;
import org.apache.james.mime4j.stream.RawField;
import org.apache.james.mime4j.util.MimeUtil;
/**
* Factory for concrete {@link Field} instances.
*/
public class Fields {
private static final Pattern FIELD_NAME_PATTERN = Pattern
.compile("[\\x21-\\x39\\x3b-\\x7e]+");
private Fields() {
}
/**
* Creates a <i>Content-Type</i> field from the specified raw field value.
* The specified string gets folded into a multiple-line representation if
* necessary but is otherwise taken as is.
*
* @param contentType
* raw content type containing a MIME type and optional
* parameters.
* @return the newly created <i>Content-Type</i> field.
*/
public static ContentTypeField contentType(String contentType) {
return parse(ContentTypeFieldImpl.PARSER, FieldName.CONTENT_TYPE,
contentType);
}
/**
* Creates a <i>Content-Type</i> field from the specified MIME type and
* parameters.
*
* @param mimeType
* a MIME type (such as <code>&quot;text/plain&quot;</code> or
* <code>&quot;application/octet-stream&quot;</code>).
* @param parameters
* map containing content-type parameters such as
* <code>&quot;boundary&quot;</code>.
* @return the newly created <i>Content-Type</i> field.
*/
public static ContentTypeField contentType(String mimeType,
Map<String, String> parameters) {
if (!isValidMimeType(mimeType))
throw new IllegalArgumentException();
if (parameters == null || parameters.isEmpty()) {
return parse(ContentTypeFieldImpl.PARSER, FieldName.CONTENT_TYPE,
mimeType);
} else {
StringBuilder sb = new StringBuilder(mimeType);
for (Map.Entry<String, String> entry : parameters.entrySet()) {
sb.append("; ");
sb.append(EncoderUtil.encodeHeaderParameter(entry.getKey(),
entry.getValue()));
}
String contentType = sb.toString();
return contentType(contentType);
}
}
/**
* Creates a <i>Content-Transfer-Encoding</i> field from the specified raw
* field value.
*
* @param contentTransferEncoding
* an encoding mechanism such as <code>&quot;7-bit&quot;</code>
* or <code>&quot;quoted-printable&quot;</code>.
* @return the newly created <i>Content-Transfer-Encoding</i> field.
*/
public static ContentTransferEncodingField contentTransferEncoding(
String contentTransferEncoding) {
return parse(ContentTransferEncodingFieldImpl.PARSER,
FieldName.CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
}
/**
* Creates a <i>Content-Disposition</i> field from the specified raw field
* value. The specified string gets folded into a multiple-line
* representation if necessary but is otherwise taken as is.
*
* @param contentDisposition
* raw content disposition containing a disposition type and
* optional parameters.
* @return the newly created <i>Content-Disposition</i> field.
*/
public static ContentDispositionField contentDisposition(
String contentDisposition) {
return parse(ContentDispositionFieldImpl.PARSER,
FieldName.CONTENT_DISPOSITION, contentDisposition);
}
/**
* Creates a <i>Content-Disposition</i> field from the specified
* disposition type and parameters.
*
* @param dispositionType
* a disposition type (usually <code>&quot;inline&quot;</code>
* or <code>&quot;attachment&quot;</code>).
* @param parameters
* map containing disposition parameters such as
* <code>&quot;filename&quot;</code>.
* @return the newly created <i>Content-Disposition</i> field.
*/
public static ContentDispositionField contentDisposition(
String dispositionType, Map<String, String> parameters) {
if (!isValidDispositionType(dispositionType))
throw new IllegalArgumentException();
if (parameters == null || parameters.isEmpty()) {
return parse(ContentDispositionFieldImpl.PARSER,
FieldName.CONTENT_DISPOSITION, dispositionType);
} else {
StringBuilder sb = new StringBuilder(dispositionType);
for (Map.Entry<String, String> entry : parameters.entrySet()) {
sb.append("; ");
sb.append(EncoderUtil.encodeHeaderParameter(entry.getKey(),
entry.getValue()));
}
String contentDisposition = sb.toString();
return contentDisposition(contentDisposition);
}
}
/**
* Creates a <i>Content-Disposition</i> field from the specified
* disposition type and filename.
*
* @param dispositionType
* a disposition type (usually <code>&quot;inline&quot;</code>
* or <code>&quot;attachment&quot;</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
* @return the newly created <i>Content-Disposition</i> field.
*/
public static ContentDispositionField contentDisposition(
String dispositionType, String filename) {
return contentDisposition(dispositionType, filename, -1, null, null,
null);
}
/**
* Creates a <i>Content-Disposition</i> field from the specified values.
*
* @param dispositionType
* a disposition type (usually <code>&quot;inline&quot;</code>
* or <code>&quot;attachment&quot;</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
* @param size
* size parameter value or <code>-1</code> if the parameter
* should not be included.
* @return the newly created <i>Content-Disposition</i> field.
*/
public static ContentDispositionField contentDisposition(
String dispositionType, String filename, long size) {
return contentDisposition(dispositionType, filename, size, null, null,
null);
}
/**
* Creates a <i>Content-Disposition</i> field from the specified values.
*
* @param dispositionType
* a disposition type (usually <code>&quot;inline&quot;</code>
* or <code>&quot;attachment&quot;</code>).
* @param filename
* filename parameter value or <code>null</code> if the
* parameter should not be included.
* @param size
* size parameter value or <code>-1</code> if the parameter
* should not be included.
* @param creationDate
* creation-date parameter value or <code>null</code> if the
* parameter should not be included.
* @param modificationDate
* modification-date parameter value or <code>null</code> if
* the parameter should not be included.
* @param readDate
* read-date parameter value or <code>null</code> if the
* parameter should not be included.
* @return the newly created <i>Content-Disposition</i> field.
*/
public static ContentDispositionField contentDisposition(
String dispositionType, String filename, long size,
Date creationDate, Date modificationDate, Date readDate) {
Map<String, String> parameters = new HashMap<String, String>();
if (filename != null) {
parameters.put(ContentDispositionFieldImpl.PARAM_FILENAME, filename);
}
if (size >= 0) {
parameters.put(ContentDispositionFieldImpl.PARAM_SIZE, Long
.toString(size));
}
if (creationDate != null) {
parameters.put(ContentDispositionFieldImpl.PARAM_CREATION_DATE,
MimeUtil.formatDate(creationDate, null));
}
if (modificationDate != null) {
parameters.put(ContentDispositionFieldImpl.PARAM_MODIFICATION_DATE,
MimeUtil.formatDate(modificationDate, null));
}
if (readDate != null) {
parameters.put(ContentDispositionFieldImpl.PARAM_READ_DATE, MimeUtil
.formatDate(readDate, null));
}
return contentDisposition(dispositionType, parameters);
}
/**
* Creates a <i>Date</i> field from the specified <code>Date</code>
* value. The default time zone of the host is used to format the date.
*
* @param date
* date value for the header field.
* @return the newly created <i>Date</i> field.
*/
public static DateTimeField date(Date date) {
return date0(FieldName.DATE, date, null);
}
/**
* Creates a date field from the specified field name and <code>Date</code>
* value. The default time zone of the host is used to format the date.
*
* @param fieldName
* a field name such as <code>Date</code> or
* <code>Resent-Date</code>.
* @param date
* date value for the header field.
* @return the newly created date field.
*/
public static DateTimeField date(String fieldName, Date date) {
checkValidFieldName(fieldName);
return date0(fieldName, date, null);
}
/**
* Creates a date field from the specified field name, <code>Date</code>
* and <code>TimeZone</code> values.
*
* @param fieldName
* a field name such as <code>Date</code> or
* <code>Resent-Date</code>.
* @param date
* date value for the header field.
* @param zone
* the time zone to be used for formatting the date.
* @return the newly created date field.
*/
public static DateTimeField date(String fieldName, Date date, TimeZone zone) {
checkValidFieldName(fieldName);
return date0(fieldName, date, zone);
}
/**
* Creates a <i>Message-ID</i> field for the specified host name.
*
* @param hostname
* host name to be included in the message ID or
* <code>null</code> if no host name should be included.
* @return the newly created <i>Message-ID</i> field.
*/
public static UnstructuredField messageId(String hostname) {
String fieldValue = MimeUtil.createUniqueMessageId(hostname);
return parse(UnstructuredFieldImpl.PARSER, FieldName.MESSAGE_ID, fieldValue);
}
/**
* Creates a <i>Subject</i> field from the specified string value. The
* specified string may contain non-ASCII characters.
*
* @param subject
* the subject string.
* @return the newly created <i>Subject</i> field.
*/
public static UnstructuredField subject(String subject) {
int usedCharacters = FieldName.SUBJECT.length() + 2;
String fieldValue = EncoderUtil.encodeIfNecessary(subject,
EncoderUtil.Usage.TEXT_TOKEN, usedCharacters);
return parse(UnstructuredFieldImpl.PARSER, FieldName.SUBJECT, fieldValue);
}
/**
* Creates a <i>Sender</i> field for the specified mailbox address.
*
* @param mailbox
* address to be included in the field.
* @return the newly created <i>Sender</i> field.
*/
public static MailboxField sender(Mailbox mailbox) {
return mailbox0(FieldName.SENDER, mailbox);
}
/**
* Creates a <i>From</i> field for the specified mailbox address.
*
* @param mailbox
* address to be included in the field.
* @return the newly created <i>From</i> field.
*/
public static MailboxListField from(Mailbox mailbox) {
return mailboxList0(FieldName.FROM, Collections.singleton(mailbox));
}
/**
* Creates a <i>From</i> field for the specified mailbox addresses.
*
* @param mailboxes
* addresses to be included in the field.
* @return the newly created <i>From</i> field.
*/
public static MailboxListField from(Mailbox... mailboxes) {
return mailboxList0(FieldName.FROM, Arrays.asList(mailboxes));
}
/**
* Creates a <i>From</i> field for the specified mailbox addresses.
*
* @param mailboxes
* addresses to be included in the field.
* @return the newly created <i>From</i> field.
*/
public static MailboxListField from(Iterable<Mailbox> mailboxes) {
return mailboxList0(FieldName.FROM, mailboxes);
}
/**
* Creates a <i>To</i> field for the specified mailbox or group address.
*
* @param address
* mailbox or group address to be included in the field.
* @return the newly created <i>To</i> field.
*/
public static AddressListField to(Address address) {
return addressList0(FieldName.TO, Collections.singleton(address));
}
/**
* Creates a <i>To</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>To</i> field.
*/
public static AddressListField to(Address... addresses) {
return addressList0(FieldName.TO, Arrays.asList(addresses));
}
/**
* Creates a <i>To</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>To</i> field.
*/
public static AddressListField to(Iterable<Address> addresses) {
return addressList0(FieldName.TO, addresses);
}
/**
* Creates a <i>Cc</i> field for the specified mailbox or group address.
*
* @param address
* mailbox or group address to be included in the field.
* @return the newly created <i>Cc</i> field.
*/
public static AddressListField cc(Address address) {
return addressList0(FieldName.CC, Collections.singleton(address));
}
/**
* Creates a <i>Cc</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Cc</i> field.
*/
public static AddressListField cc(Address... addresses) {
return addressList0(FieldName.CC, Arrays.asList(addresses));
}
/**
* Creates a <i>Cc</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Cc</i> field.
*/
public static AddressListField cc(Iterable<Address> addresses) {
return addressList0(FieldName.CC, addresses);
}
/**
* Creates a <i>Bcc</i> field for the specified mailbox or group address.
*
* @param address
* mailbox or group address to be included in the field.
* @return the newly created <i>Bcc</i> field.
*/
public static AddressListField bcc(Address address) {
return addressList0(FieldName.BCC, Collections.singleton(address));
}
/**
* Creates a <i>Bcc</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Bcc</i> field.
*/
public static AddressListField bcc(Address... addresses) {
return addressList0(FieldName.BCC, Arrays.asList(addresses));
}
/**
* Creates a <i>Bcc</i> field for the specified mailbox or group addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Bcc</i> field.
*/
public static AddressListField bcc(Iterable<Address> addresses) {
return addressList0(FieldName.BCC, addresses);
}
/**
* Creates a <i>Reply-To</i> field for the specified mailbox or group
* address.
*
* @param address
* mailbox or group address to be included in the field.
* @return the newly created <i>Reply-To</i> field.
*/
public static AddressListField replyTo(Address address) {
return addressList0(FieldName.REPLY_TO, Collections.singleton(address));
}
/**
* Creates a <i>Reply-To</i> field for the specified mailbox or group
* addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Reply-To</i> field.
*/
public static AddressListField replyTo(Address... addresses) {
return addressList0(FieldName.REPLY_TO, Arrays.asList(addresses));
}
/**
* Creates a <i>Reply-To</i> field for the specified mailbox or group
* addresses.
*
* @param addresses
* mailbox or group addresses to be included in the field.
* @return the newly created <i>Reply-To</i> field.
*/
public static AddressListField replyTo(Iterable<Address> addresses) {
return addressList0(FieldName.REPLY_TO, addresses);
}
/**
* Creates a mailbox field from the specified field name and mailbox
* address. Valid field names are <code>Sender</code> and
* <code>Resent-Sender</code>.
*
* @param fieldName
* the name of the mailbox field (<code>Sender</code> or
* <code>Resent-Sender</code>).
* @param mailbox
* mailbox address for the field value.
* @return the newly created mailbox field.
*/
public static MailboxField mailbox(String fieldName, Mailbox mailbox) {
checkValidFieldName(fieldName);
return mailbox0(fieldName, mailbox);
}
/**
* Creates a mailbox-list field from the specified field name and mailbox
* addresses. Valid field names are <code>From</code> and
* <code>Resent-From</code>.
*
* @param fieldName
* the name of the mailbox field (<code>From</code> or
* <code>Resent-From</code>).
* @param mailboxes
* mailbox addresses for the field value.
* @return the newly created mailbox-list field.
*/
public static MailboxListField mailboxList(String fieldName,
Iterable<Mailbox> mailboxes) {
checkValidFieldName(fieldName);
return mailboxList0(fieldName, mailboxes);
}
/**
* Creates an address-list field from the specified field name and mailbox
* or group addresses. Valid field names are <code>To</code>,
* <code>Cc</code>, <code>Bcc</code>, <code>Reply-To</code>,
* <code>Resent-To</code>, <code>Resent-Cc</code> and
* <code>Resent-Bcc</code>.
*
* @param fieldName
* the name of the mailbox field (<code>To</code>,
* <code>Cc</code>, <code>Bcc</code>, <code>Reply-To</code>,
* <code>Resent-To</code>, <code>Resent-Cc</code> or
* <code>Resent-Bcc</code>).
* @param addresses
* mailbox or group addresses for the field value.
* @return the newly created address-list field.
*/
public static AddressListField addressList(String fieldName,
Iterable<Address> addresses) {
checkValidFieldName(fieldName);
return addressList0(fieldName, addresses);
}
private static DateTimeField date0(String fieldName, Date date,
TimeZone zone) {
final String formattedDate = MimeUtil.formatDate(date, zone);
return parse(DateTimeFieldImpl.PARSER, fieldName, formattedDate);
}
private static MailboxField mailbox0(String fieldName, Mailbox mailbox) {
String fieldValue = encodeAddresses(Collections.singleton(mailbox));
return parse(MailboxFieldImpl.PARSER, fieldName, fieldValue);
}
private static MailboxListField mailboxList0(String fieldName,
Iterable<Mailbox> mailboxes) {
String fieldValue = encodeAddresses(mailboxes);
return parse(MailboxListFieldImpl.PARSER, fieldName, fieldValue);
}
private static AddressListField addressList0(String fieldName,
Iterable<Address> addresses) {
String fieldValue = encodeAddresses(addresses);
return parse(AddressListFieldImpl.PARSER, fieldName, fieldValue);
}
private static void checkValidFieldName(String fieldName) {
if (!FIELD_NAME_PATTERN.matcher(fieldName).matches())
throw new IllegalArgumentException("Invalid field name");
}
private static boolean isValidMimeType(String mimeType) {
if (mimeType == null)
return false;
int idx = mimeType.indexOf('/');
if (idx == -1)
return false;
String type = mimeType.substring(0, idx);
String subType = mimeType.substring(idx + 1);
return EncoderUtil.isToken(type) && EncoderUtil.isToken(subType);
}
private static boolean isValidDispositionType(String dispositionType) {
if (dispositionType == null)
return false;
return EncoderUtil.isToken(dispositionType);
}
private static <F extends ParsedField> F parse(FieldParser<F> parser,
String fieldName, String fieldBody) {
RawField rawField = new RawField(fieldName, fieldBody);
return parser.parse(rawField.getName(), rawField.getBody(), rawField.getRaw(),
DecodeMonitor.SILENT);
}
private static String encodeAddresses(Iterable<? extends Address> addresses) {
StringBuilder sb = new StringBuilder();
for (Address address : addresses) {
if (sb.length() > 0) {
sb.append(", ");
}
AddressFormatter.encode(sb, address);
}
return sb.toString();
}
}

View File

@ -1,84 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.field.address.parser.AddressBuilder;
import org.apache.james.mime4j.field.address.parser.ParseException;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Mailbox field such as <code>Sender</code> or <code>Resent-Sender</code>.
*/
public class MailboxFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.MailboxField {
private boolean parsed = false;
private Mailbox mailbox;
private ParseException parseException;
MailboxFieldImpl(final String name, final String body, final ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.MailboxField#getMailbox()
*/
public Mailbox getMailbox() {
if (!parsed)
parse();
return mailbox;
}
/**
* @see org.apache.james.mime4j.dom.field.MailboxField#getParseException()
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
private void parse() {
String body = getBody();
try {
MailboxList mailboxList = AddressBuilder.parseAddressList(body, monitor).flatten();
if (mailboxList.size() > 0) {
mailbox = mailboxList.get(0);
}
} catch (ParseException e) {
parseException = e;
}
parsed = true;
}
static final FieldParser<MailboxFieldImpl> PARSER = new FieldParser<MailboxFieldImpl>() {
public MailboxFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new MailboxFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,80 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.field.address.parser.AddressBuilder;
import org.apache.james.mime4j.field.address.parser.ParseException;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Mailbox-list field such as <code>From</code> or <code>Resent-From</code>.
*/
public class MailboxListFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.MailboxListField {
private boolean parsed = false;
private MailboxList mailboxList;
private ParseException parseException;
MailboxListFieldImpl(final String name, final String body, final ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.MailboxListField#getMailboxList()
*/
public MailboxList getMailboxList() {
if (!parsed)
parse();
return mailboxList;
}
/**
* @see org.apache.james.mime4j.dom.field.MailboxListField#getParseException()
*/
@Override
public ParseException getParseException() {
if (!parsed)
parse();
return parseException;
}
private void parse() {
String body = getBody();
try {
mailboxList = AddressBuilder.parseAddressList(body, monitor).flatten();
} catch (ParseException e) {
parseException = e;
}
parsed = true;
}
static final FieldParser<MailboxListFieldImpl> PARSER = new FieldParser<MailboxListFieldImpl>() {
public MailboxListFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new MailboxListFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,62 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.codec.DecoderUtil;
import org.apache.james.mime4j.util.ByteSequence;
/**
* Simple unstructured field such as <code>Subject</code>.
*/
public class UnstructuredFieldImpl extends AbstractField implements org.apache.james.mime4j.dom.field.UnstructuredField {
private boolean parsed = false;
private String value;
UnstructuredFieldImpl(String name, String body, ByteSequence raw, DecodeMonitor monitor) {
super(name, body, raw, monitor);
}
/**
* @see org.apache.james.mime4j.dom.field.UnstructuredField#getValue()
*/
public String getValue() {
if (!parsed)
parse();
return value;
}
private void parse() {
String body = getBody();
value = DecoderUtil.decodeEncodedWords(body, monitor);
parsed = true;
}
static final FieldParser<UnstructuredFieldImpl> PARSER = new FieldParser<UnstructuredFieldImpl>() {
public UnstructuredFieldImpl parse(final String name, final String body,
final ByteSequence raw, DecodeMonitor monitor) {
return new UnstructuredFieldImpl(name, body, raw, monitor);
}
};
}

View File

@ -1,209 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field.address.formatter;
import org.apache.james.mime4j.codec.EncoderUtil;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.Group;
import org.apache.james.mime4j.dom.address.Mailbox;
public class AddressFormatter {
/**
* Formats the address as a human readable string, not including the route.
* The resulting string is intended for display purposes only and cannot be
* used for transport purposes.
*
* For example, if the unparsed address was
*
* <"Joe Cheng"@joecheng.com>
*
* this method would return
*
* <Joe Cheng@joecheng.com>
*
* which is not valid for transport; the local part would need to be
* re-quoted.
*
* @param includeRoute
* <code>true</code> if the route should be included if it
* exists, <code>false</code> otherwise.
* @return a string representation of this address intended to be displayed.
*/
public static void format(final StringBuilder sb, final Address address, boolean includeRoute) {
if (address == null) {
return;
}
if (address instanceof Mailbox) {
format(sb, (Mailbox) address, includeRoute);
} else if (address instanceof Group) {
format(sb, (Group) address, includeRoute);
} else {
throw new IllegalArgumentException("Unsuppported Address class: " + address.getClass());
}
}
/**
* Returns a string representation of this address that can be used for
* transport purposes. The route is never included in this representation
* because routes are obsolete and RFC 5322 states that obsolete syntactic
* forms MUST NOT be generated.
*
* @return a string representation of this address intended for transport
* purposes.
*/
public static void encode(final StringBuilder sb, final Address address) {
if (address == null) {
return;
}
if (address instanceof Mailbox) {
encode(sb, (Mailbox) address);
} else if (address instanceof Group) {
encode(sb, (Group) address);
} else {
throw new IllegalArgumentException("Unsuppported Address class: " + address.getClass());
}
}
public static void format(final StringBuilder sb, final Mailbox mailbox, boolean includeRoute) {
if (sb == null) {
throw new IllegalArgumentException("StringBuilder may not be null");
}
if (mailbox == null) {
throw new IllegalArgumentException("Mailbox may not be null");
}
includeRoute &= mailbox.getRoute() != null;
boolean includeAngleBrackets = mailbox.getName() != null || includeRoute;
if (mailbox.getName() != null) {
sb.append(mailbox.getName());
sb.append(' ');
}
if (includeAngleBrackets) {
sb.append('<');
}
if (includeRoute) {
sb.append(mailbox.getRoute().toRouteString());
sb.append(':');
}
sb.append(mailbox.getLocalPart());
if (mailbox.getDomain() != null) {
sb.append('@');
sb.append(mailbox.getDomain());
}
if (includeAngleBrackets) {
sb.append('>');
}
}
public static String format(final Mailbox mailbox, boolean includeRoute) {
StringBuilder sb = new StringBuilder();
format(sb, mailbox, includeRoute);
return sb.toString();
}
public static void encode(final StringBuilder sb, final Mailbox mailbox) {
if (sb == null) {
throw new IllegalArgumentException("StringBuilder may not be null");
}
if (mailbox == null) {
throw new IllegalArgumentException("Mailbox may not be null");
}
if (mailbox.getName() != null) {
sb.append(EncoderUtil.encodeAddressDisplayName(mailbox.getName()));
sb.append(" <");
}
sb.append(EncoderUtil.encodeAddressLocalPart(mailbox.getLocalPart()));
// domain = dot-atom / domain-literal
// domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
// dtext = %d33-90 / %d94-126
if (mailbox.getDomain() != null) {
sb.append('@');
sb.append(mailbox.getDomain());
}
if (mailbox.getName() != null) {
sb.append('>');
}
}
public static String encode(final Mailbox mailbox) {
StringBuilder sb = new StringBuilder();
encode(sb, mailbox);
return sb.toString();
}
public static void format(final StringBuilder sb, final Group group, boolean includeRoute) {
if (sb == null) {
throw new IllegalArgumentException("StringBuilder may not be null");
}
if (group == null) {
throw new IllegalArgumentException("Group may not be null");
}
sb.append(group.getName());
sb.append(':');
boolean first = true;
for (Mailbox mailbox : group.getMailboxes()) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(' ');
format(sb, mailbox, includeRoute);
}
sb.append(";");
}
public static String format(final Group group, boolean includeRoute) {
StringBuilder sb = new StringBuilder();
format(sb, group, includeRoute);
return sb.toString();
}
public static void encode(final StringBuilder sb, final Group group) {
if (sb == null) {
throw new IllegalArgumentException("StringBuilder may not be null");
}
if (group == null) {
throw new IllegalArgumentException("Group may not be null");
}
sb.append(EncoderUtil.encodeAddressDisplayName(group.getName()));
sb.append(':');
boolean first = true;
for (Mailbox mailbox : group.getMailboxes()) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(' ');
encode(sb, mailbox);
}
sb.append(';');
}
public static String encode(final Group group) {
StringBuilder sb = new StringBuilder();
encode(sb, group);
return sb.toString();
}
}

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTaddr_spec.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTaddr_spec extends SimpleNode {
public ASTaddr_spec(int id) {
super(id);
}
public ASTaddr_spec(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=750ab0a2f6a942d3f4a7a7e076d12a4d (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTaddress.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTaddress extends SimpleNode {
public ASTaddress(int id) {
super(id);
}
public ASTaddress(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=73be0a52ecfe4cf5d5a926be94fbb411 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTaddress_list.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTaddress_list extends SimpleNode {
public ASTaddress_list(int id) {
super(id);
}
public ASTaddress_list(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=6615a805f4abebfcf7252d9aad462299 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTangle_addr.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTangle_addr extends SimpleNode {
public ASTangle_addr(int id) {
super(id);
}
public ASTangle_addr(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=2201bedb23ef9d1b75dd88b2a5571384 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTdomain.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTdomain extends SimpleNode {
public ASTdomain(int id) {
super(id);
}
public ASTdomain(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=0105eb2d00d34d34b0665fd5ced14d52 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTgroup_body.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTgroup_body extends SimpleNode {
public ASTgroup_body(int id) {
super(id);
}
public ASTgroup_body(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=29b09d0a20de5b5f3d7e08c7e325d23f (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTlocal_part.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTlocal_part extends SimpleNode {
public ASTlocal_part(int id) {
super(id);
}
public ASTlocal_part(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=42e77dd54203428772aecd61a95fc01c (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTmailbox.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTmailbox extends SimpleNode {
public ASTmailbox(int id) {
super(id);
}
public ASTmailbox(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=246fe7d146969407e2c7977748e2fc99 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTname_addr.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTname_addr extends SimpleNode {
public ASTname_addr(int id) {
super(id);
}
public ASTname_addr(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=37e69dc07dfc157b3fb2449483ff82b6 (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTphrase.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTphrase extends SimpleNode {
public ASTphrase(int id) {
super(id);
}
public ASTphrase(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=f1c7166e3c5b192d1f6db62b8239b0be (do not edit this line) */

View File

@ -1,21 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTroute.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class ASTroute extends SimpleNode {
public ASTroute(int id) {
super(id);
}
public ASTroute(AddressListParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/* JavaCC - OriginalChecksum=bcec06c89402cfcb3700aefe8d5f14f9 (do not edit this line) */

View File

@ -1,115 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field.address.parser;
import java.io.StringReader;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.dom.address.Group;
import org.apache.james.mime4j.dom.address.Mailbox;
public class AddressBuilder {
/**
* Parses the specified raw string into an address.
*
* @param rawAddressString
* string to parse.
* @param monitor the DecodeMonitor to be used while parsing/decoding
* @return an <code>Address</code> object for the specified string.
* @throws ParseException if the raw string does not represent a single address.
*/
public static Address parseAddress(String rawAddressString, DecodeMonitor monitor) throws ParseException {
AddressListParser parser = new AddressListParser(new StringReader(
rawAddressString));
return Builder.getInstance().buildAddress(parser.parseAddress(), monitor);
}
public static Address parseAddress(String rawAddressString) throws ParseException {
return parseAddress(rawAddressString, DecodeMonitor.STRICT);
}
/**
* 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.
* @param monitor the DecodeMonitor to be used while parsing/decoding
*/
public static AddressList parseAddressList(String rawAddressList, DecodeMonitor monitor)
throws ParseException {
AddressListParser parser = new AddressListParser(new StringReader(
rawAddressList));
try {
return Builder.getInstance().buildAddressList(parser.parseAddressList(), monitor);
} catch (RuntimeException e) {
throw new ParseException(e.getMessage());
}
}
public static AddressList parseAddressList(String rawAddressList) throws ParseException {
return parseAddressList(rawAddressList, DecodeMonitor.STRICT);
}
/**
* Parses the specified raw string into a mailbox address.
*
* @param rawMailboxString
* string to parse.
* @param monitor the DecodeMonitor to be used while parsing/decoding.
* @return a <code>Mailbox</code> object for the specified string.
* @throws ParseException
* if the raw string does not represent a single mailbox
* address.
*/
public static Mailbox parseMailbox(String rawMailboxString, DecodeMonitor monitor) throws ParseException {
AddressListParser parser = new AddressListParser(new StringReader(
rawMailboxString));
return Builder.getInstance().buildMailbox(parser.parseMailbox(), monitor);
}
public static Mailbox parseMailbox(String rawMailboxString) throws ParseException {
return parseMailbox(rawMailboxString, DecodeMonitor.STRICT);
}
/**
* Parses the specified raw string into a group address.
*
* @param rawGroupString
* string to parse.
* @return a <code>Group</code> object for the specified string.
* @throws ParseException
* if the raw string does not represent a single group address.
*/
public static Group parseGroup(String rawGroupString, DecodeMonitor monitor) throws ParseException {
Address address = parseAddress(rawGroupString, monitor);
if (!(address instanceof Group))
throw new ParseException("Not a group address");
return (Group) address;
}
public static Group parseGroup(String rawGroupString) throws ParseException {
return parseGroup(rawGroupString, DecodeMonitor.STRICT);
}
}

View File

@ -1,101 +0,0 @@
/* Generated By:JJTree&JavaCC: Do not edit this line. AddressListParserConstants.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.parser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface AddressListParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int WS = 10;
/** RegularExpression Id. */
int ALPHA = 11;
/** RegularExpression Id. */
int DIGIT = 12;
/** RegularExpression Id. */
int ATEXT = 13;
/** RegularExpression Id. */
int DOTATOM = 14;
/** RegularExpression Id. */
int DOMAINLITERAL = 18;
/** RegularExpression Id. */
int COMMENT = 20;
/** RegularExpression Id. */
int QUOTEDSTRING = 31;
/** RegularExpression Id. */
int QUOTEDPAIR = 32;
/** RegularExpression Id. */
int ANY = 33;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int INDOMAINLITERAL = 1;
/** Lexical state. */
int INCOMMENT = 2;
/** Lexical state. */
int NESTED_COMMENT = 3;
/** Lexical state. */
int INQUOTEDSTRING = 4;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\"\\r\"",
"\"\\n\"",
"\",\"",
"\":\"",
"\";\"",
"\"<\"",
"\">\"",
"\"@\"",
"\".\"",
"<WS>",
"<ALPHA>",
"<DIGIT>",
"<ATEXT>",
"<DOTATOM>",
"\"[\"",
"<token of kind 16>",
"<token of kind 17>",
"\"]\"",
"\"(\"",
"\")\"",
"<token of kind 21>",
"\"(\"",
"<token of kind 23>",
"<token of kind 24>",
"\"(\"",
"\")\"",
"<token of kind 27>",
"\"\\\"\"",
"<token of kind 29>",
"<token of kind 30>",
"\"\\\"\"",
"<QUOTEDPAIR>",
"<ANY>",
};
}

View File

@ -1,969 +0,0 @@
/* Generated By:JJTree&JavaCC: Do not edit this line. AddressListParserTokenManager.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.parser;
/** Token Manager. */
public class AddressListParserTokenManager implements AddressListParserConstants
{
// Keeps track of how many levels of comment nesting
// we've encountered. This is only used when the 2nd
// level is reached, for example ((this)), not (this).
// This is because the outermost level must be treated
// specially anyway, because the outermost ")" has a
// different token type than inner ")" instances.
static int commentNest;
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_0(int pos, long active0)
{
return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
}
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 10:
return jjStopAtPos(0, 2);
case 13:
return jjStopAtPos(0, 1);
case 34:
return jjStopAtPos(0, 28);
case 40:
return jjStopAtPos(0, 19);
case 44:
return jjStopAtPos(0, 3);
case 46:
return jjStopAtPos(0, 9);
case 58:
return jjStopAtPos(0, 4);
case 59:
return jjStopAtPos(0, 5);
case 60:
return jjStopAtPos(0, 6);
case 62:
return jjStopAtPos(0, 7);
case 64:
return jjStopAtPos(0, 8);
case 91:
return jjStopAtPos(0, 15);
default :
return jjMoveNfa_0(1, 0);
}
}
private int jjMoveNfa_0(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 1:
if ((0xa3ffacfa00000000L & l) != 0L)
{
if (kind > 14)
kind = 14;
jjCheckNAdd(2);
}
else if ((0x100000200L & l) != 0L)
{
if (kind > 10)
kind = 10;
jjCheckNAdd(0);
}
break;
case 0:
if ((0x100000200L & l) == 0L)
break;
kind = 10;
jjCheckNAdd(0);
break;
case 2:
if ((0xa3ffecfa00000000L & l) == 0L)
break;
if (kind > 14)
kind = 14;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 1:
case 2:
if ((0x7fffffffc7fffffeL & l) == 0L)
break;
if (kind > 14)
kind = 14;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_2(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_2(int pos, long active0)
{
return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_2()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 22);
case 41:
return jjStopAtPos(0, 20);
default :
return jjMoveNfa_2(0, 0);
}
}
static final long[] jjbitVec0 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_2(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 23)
kind = 23;
break;
case 1:
if (kind > 21)
kind = 21;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 23)
kind = 23;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 21)
kind = 21;
break;
case 2:
if (kind > 23)
kind = 23;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 23)
kind = 23;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 21)
kind = 21;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_4(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_4(int pos, long active0)
{
return jjMoveNfa_4(jjStopStringLiteralDfa_4(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_4()
{
switch(curChar)
{
case 34:
return jjStopAtPos(0, 31);
default :
return jjMoveNfa_4(0, 0);
}
}
private int jjMoveNfa_4(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((0xfffffffbffffffffL & l) == 0L)
break;
if (kind > 30)
kind = 30;
jjCheckNAdd(2);
break;
case 1:
if (kind > 29)
kind = 29;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0xffffffffefffffffL & l) != 0L)
{
if (kind > 30)
kind = 30;
jjCheckNAdd(2);
}
else if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 29)
kind = 29;
break;
case 2:
if ((0xffffffffefffffffL & l) == 0L)
break;
if (kind > 30)
kind = 30;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 30)
kind = 30;
jjCheckNAdd(2);
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 29)
kind = 29;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_3(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_3(int pos, long active0)
{
return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_3()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 25);
case 41:
return jjStopAtPos(0, 26);
default :
return jjMoveNfa_3(0, 0);
}
}
private int jjMoveNfa_3(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 27)
kind = 27;
break;
case 1:
if (kind > 24)
kind = 24;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 27)
kind = 27;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 24)
kind = 24;
break;
case 2:
if (kind > 27)
kind = 27;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 27)
kind = 27;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 24)
kind = 24;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_1(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_1(int pos, long active0)
{
return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_1()
{
switch(curChar)
{
case 93:
return jjStopAtPos(0, 18);
default :
return jjMoveNfa_1(0, 0);
}
}
private int jjMoveNfa_1(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 17)
kind = 17;
break;
case 1:
if (kind > 16)
kind = 16;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0xffffffffc7ffffffL & l) != 0L)
{
if (kind > 17)
kind = 17;
}
else if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 16)
kind = 16;
break;
case 2:
if ((0xffffffffc7ffffffL & l) != 0L && kind > 17)
kind = 17;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 17)
kind = 17;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 16)
kind = 16;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
static final int[] jjnextStates = {
};
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", "\15", "\12", "\54", "\72", "\73", "\74", "\76", "\100", "\56", null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
"INDOMAINLITERAL",
"INCOMMENT",
"NESTED_COMMENT",
"INQUOTEDSTRING",
};
/** Lex State array. */
public static final int[] jjnewLexState = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, 2, 0, -1, 3, -1, -1,
-1, -1, -1, 4, -1, -1, 0, -1, -1,
};
static final long[] jjtoToken = {
0x800443ffL,
};
static final long[] jjtoSkip = {
0x100400L,
};
static final long[] jjtoSpecial = {
0x400L,
};
static final long[] jjtoMore = {
0x7feb8000L,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[3];
private final int[] jjstateSet = new int[6];
private final StringBuilder jjimage = new StringBuilder();
private StringBuilder image = jjimage;
private int jjimageLen;
private int lengthOfMatch;
protected char curChar;
/** Constructor. */
public AddressListParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public AddressListParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 3; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 5 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token specialToken = null;
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
image = jjimage;
image.setLength(0);
jjimageLen = 0;
for (;;)
{
switch(curLexState)
{
case 0:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
break;
case 1:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
break;
case 2:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_2();
break;
case 3:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_3();
break;
case 4:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_4();
break;
}
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
TokenLexicalActions(matchedToken);
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
return matchedToken;
}
else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
if (specialToken == null)
specialToken = matchedToken;
else
{
matchedToken.specialToken = specialToken;
specialToken = (specialToken.next = matchedToken);
}
}
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
continue EOFLoop;
}
MoreLexicalActions();
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
curPos = 0;
jjmatchedKind = 0x7fffffff;
try {
curChar = input_stream.readChar();
continue;
}
catch (java.io.IOException e1) { }
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
}
void MoreLexicalActions()
{
jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
switch(jjmatchedKind)
{
case 16 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 21 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 22 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
commentNest = 1;
break;
case 24 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 25 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
++commentNest;
break;
case 26 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
--commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
break;
case 28 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 1);
break;
case 29 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
default :
break;
}
}
void TokenLexicalActions(Token matchedToken)
{
switch(jjmatchedKind)
{
case 18 :
image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
matchedToken.image = image.toString();
break;
case 31 :
image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
matchedToken.image = image.substring(0, image.length() - 1);
break;
default :
break;
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
}

View File

@ -1,35 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. AddressListParserTreeConstants.java Version 5.0 */
package org.apache.james.mime4j.field.address.parser;
public interface AddressListParserTreeConstants
{
public int JJTVOID = 0;
public int JJTADDRESS_LIST = 1;
public int JJTADDRESS = 2;
public int JJTMAILBOX = 3;
public int JJTNAME_ADDR = 4;
public int JJTGROUP_BODY = 5;
public int JJTANGLE_ADDR = 6;
public int JJTROUTE = 7;
public int JJTPHRASE = 8;
public int JJTADDR_SPEC = 9;
public int JJTLOCAL_PART = 10;
public int JJTDOMAIN = 11;
public String[] jjtNodeName = {
"void",
"address_list",
"address",
"mailbox",
"name_addr",
"group_body",
"angle_addr",
"route",
"phrase",
"addr_spec",
"local_part",
"domain",
};
}
/* JavaCC - OriginalChecksum=e7d2b24000a70a573955cf10036f0056 (do not edit this line) */

View File

@ -1,19 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. AddressListParserVisitor.java Version 5.0 */
package org.apache.james.mime4j.field.address.parser;
public interface AddressListParserVisitor
{
public Object visit(SimpleNode node, Object data);
public Object visit(ASTaddress_list node, Object data);
public Object visit(ASTaddress node, Object data);
public Object visit(ASTmailbox node, Object data);
public Object visit(ASTname_addr node, Object data);
public Object visit(ASTgroup_body node, Object data);
public Object visit(ASTangle_addr node, Object data);
public Object visit(ASTroute node, Object data);
public Object visit(ASTphrase node, Object data);
public Object visit(ASTaddr_spec node, Object data);
public Object visit(ASTlocal_part node, Object data);
public Object visit(ASTdomain node, Object data);
}
/* JavaCC - OriginalChecksum=f57edd9a1eb17afa5907a87b3c51e284 (do not edit this line) */

View File

@ -1,28 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field.address.parser;
public abstract class BaseNode implements Node {
public Token firstToken;
public Token lastToken;
}

View File

@ -1,229 +0,0 @@
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field.address.parser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.codec.DecoderUtil;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.dom.address.DomainList;
import org.apache.james.mime4j.dom.address.Group;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
/**
* Transforms the JJTree-generated abstract syntax tree into a graph of
* org.apache.james.mime4j.dom.address objects.
*/
class Builder {
private static Builder singleton = new Builder();
public static Builder getInstance() {
return singleton;
}
public AddressList buildAddressList(ASTaddress_list node, DecodeMonitor monitor) throws ParseException {
List<Address> list = new ArrayList<Address>();
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
Address address = buildAddress(childNode, monitor);
list.add(address);
}
return new AddressList(list, true);
}
public Address buildAddress(ASTaddress node, DecodeMonitor monitor) throws ParseException {
ChildNodeIterator it = new ChildNodeIterator(node);
Node n = it.next();
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.next();
if (n2 instanceof ASTgroup_body) {
return new Group(name, buildGroupBody((ASTgroup_body) n2, monitor));
} else if (n2 instanceof ASTangle_addr) {
try {
name = DecoderUtil.decodeEncodedWords(name, monitor);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage());
}
Mailbox mb = buildAngleAddr((ASTangle_addr) n2);
return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
mb.getDomain());
} else {
throw new ParseException();
}
} else {
throw new ParseException();
}
}
private MailboxList buildGroupBody(ASTgroup_body node, DecodeMonitor monitor) throws ParseException {
List<Mailbox> results = new ArrayList<Mailbox>();
ChildNodeIterator it = new ChildNodeIterator(node);
while (it.hasNext()) {
Node n = it.next();
if (n instanceof ASTmailbox)
results.add(buildMailbox((ASTmailbox) n, monitor));
else
throw new ParseException();
}
return new MailboxList(results, true);
}
public Mailbox buildMailbox(ASTmailbox node, DecodeMonitor monitor) throws ParseException {
ChildNodeIterator it = new ChildNodeIterator(node);
Node n = it.next();
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, monitor);
} else {
throw new ParseException();
}
}
private Mailbox buildNameAddr(ASTname_addr node, DecodeMonitor monitor) throws ParseException {
ChildNodeIterator it = new ChildNodeIterator(node);
Node n = it.next();
String name;
if (n instanceof ASTphrase) {
name = buildString((ASTphrase) n, false);
} else {
throw new ParseException();
}
n = it.next();
if (n instanceof ASTangle_addr) {
try {
name = DecoderUtil.decodeEncodedWords(name, monitor);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage());
}
Mailbox mb = buildAngleAddr((ASTangle_addr) n);
return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
mb.getDomain());
} else {
throw new ParseException();
}
}
private Mailbox buildAngleAddr(ASTangle_addr node) throws ParseException {
ChildNodeIterator it = new ChildNodeIterator(node);
DomainList route = null;
Node n = it.next();
if (n instanceof ASTroute) {
route = buildRoute((ASTroute) n);
n = it.next();
} else if (n instanceof ASTaddr_spec) {
// do nothing
}
else
throw new ParseException();
if (n instanceof ASTaddr_spec)
return buildAddrSpec(route, (ASTaddr_spec) n);
else
throw new ParseException();
}
private DomainList buildRoute(ASTroute node) throws ParseException {
List<String> results = new ArrayList<String>(node.jjtGetNumChildren());
ChildNodeIterator it = new ChildNodeIterator(node);
while (it.hasNext()) {
Node n = it.next();
if (n instanceof ASTdomain)
results.add(buildString((ASTdomain) n, true));
else
throw new ParseException();
}
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.next(), true);
String domain = buildString((ASTdomain) it.next(), true);
return new Mailbox(route, localPart, domain);
}
private String buildString(SimpleNode node, boolean stripSpaces) {
Token head = node.firstToken;
Token tail = node.lastToken;
StringBuilder out = new StringBuilder();
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(StringBuilder out, Token specialToken) {
if (specialToken != null) {
addSpecials(out, specialToken.specialToken);
out.append(specialToken.image);
}
}
private static class ChildNodeIterator implements Iterator<Node> {
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 Node next() {
return simpleNode.jjtGetChild(index++);
}
}
}

View File

@ -1,123 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. JJTAddressListParserState.java Version 5.0 */
package org.apache.james.mime4j.field.address.parser;
public class JJTAddressListParserState {
private java.util.List<Node> nodes;
private java.util.List<Integer> marks;
private int sp; // number of nodes on stack
private int mk; // current mark
private boolean node_created;
public JJTAddressListParserState() {
nodes = new java.util.ArrayList<Node>();
marks = new java.util.ArrayList<Integer>();
sp = 0;
mk = 0;
}
/* Determines whether the current node was actually closed and
pushed. This should only be called in the final user action of a
node scope. */
public boolean nodeCreated() {
return node_created;
}
/* Call this to reinitialize the node stack. It is called
automatically by the parser's ReInit() method. */
public void reset() {
nodes.clear();
marks.clear();
sp = 0;
mk = 0;
}
/* Returns the root node of the AST. It only makes sense to call
this after a successful parse. */
public Node rootNode() {
return nodes.get(0);
}
/* Pushes a node on to the stack. */
public void pushNode(Node n) {
nodes.add(n);
++sp;
}
/* Returns the node on the top of the stack, and remove it from the
stack. */
public Node popNode() {
if (--sp < mk) {
mk = marks.remove(marks.size()-1);
}
return nodes.remove(nodes.size()-1);
}
/* Returns the node currently on the top of the stack. */
public Node peekNode() {
return nodes.get(nodes.size()-1);
}
/* Returns the number of children on the stack in the current node
scope. */
public int nodeArity() {
return sp - mk;
}
public void clearNodeScope(Node n) {
while (sp > mk) {
popNode();
}
mk = marks.remove(marks.size()-1);
}
public void openNodeScope(Node n) {
marks.add(mk);
mk = sp;
n.jjtOpen();
}
/* A definite node is constructed from a specified number of
children. That number of nodes are popped from the stack and
made the children of the definite node. Then the definite node
is pushed on to the stack. */
public void closeNodeScope(Node n, int num) {
mk = marks.remove(marks.size()-1);
while (num-- > 0) {
Node c = popNode();
c.jjtSetParent(n);
n.jjtAddChild(c, num);
}
n.jjtClose();
pushNode(n);
node_created = true;
}
/* A conditional node is constructed if its condition is true. All
the nodes that have been pushed since the node was opened are
made children of the conditional node, which is then pushed
on to the stack. If the condition is false the node is not
constructed and they are left on the stack. */
public void closeNodeScope(Node n, boolean condition) {
if (condition) {
int a = nodeArity();
mk = marks.remove(marks.size()-1);
while (a-- > 0) {
Node c = popNode();
c.jjtSetParent(n);
n.jjtAddChild(c, a);
}
n.jjtClose();
pushNode(n);
node_created = true;
} else {
mk = marks.remove(marks.size()-1);
node_created = false;
}
}
}
/* JavaCC - OriginalChecksum=e61a7a50ac6b2ea6fa91b5482005b3ce (do not edit this line) */

View File

@ -1,39 +0,0 @@
/* Generated By:JJTree: Do not edit this line. Node.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
/* All AST nodes must implement this interface. It provides basic
machinery for constructing the parent and child relationships
between nodes. */
public
interface Node {
/** This method is called after the node has been made the current
node. It indicates that child nodes can now be added to it. */
public void jjtOpen();
/** This method is called after all the child nodes have been
added. */
public void jjtClose();
/** This pair of methods are used to inform the node of its
parent. */
public void jjtSetParent(Node n);
public Node jjtGetParent();
/** This method tells the node to add its argument to the node's
list of children. */
public void jjtAddChild(Node n, int i);
/** This method returns a child node. The children are numbered
from zero, left to right. */
public Node jjtGetChild(int i);
/** Return the number of children the node has. */
public int jjtGetNumChildren();
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data);
}
/* JavaCC - OriginalChecksum=b3b1bedb94f5dcae7af8d6e02371fe1e (do not edit this line) */

View File

@ -1,220 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.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.james.mime4j.field.address.parser;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* Changes for Mime4J:
* extends org.apache.james.mime4j.field.ParseException
* added serialVersionUID
* added constructor ParseException(Throwable)
* default detail message is "Cannot parse field"
*/
public class ParseException extends org.apache.james.mime4j.dom.field.ParseException {
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set. The boolean
* flag "specialConstructor" is also set to true to indicate that
* this constructor was used to create this object.
* This constructor calls its super class with the empty string
* to force the "toString" method of parent class "Throwable" to
* print the error message in the form:
* ParseException: <result of getMessage>
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super("");
specialConstructor = true;
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super("Cannot parse field");
specialConstructor = false;
}
public ParseException(Throwable cause) {
super(cause);
specialConstructor = false;
}
public ParseException(String message) {
super(message);
specialConstructor = false;
}
/**
* This variable determines which constructor was used to create
* this object and thereby affects the semantics of the
* "getMessage" method (see below).
*/
protected boolean specialConstructor;
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* This method has the standard behavior when this object has been
* created using the standard constructors. Otherwise, it uses
* "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser), then this method is called during the printing
* of the final stack trace, and hence the correct error message
* gets displayed.
*/
public String getMessage() {
if (!specialConstructor) {
return super.getMessage();
}
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += add_escapes(tok.image);
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
protected String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}

View File

@ -1,489 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.address.parser;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=aa11a0881c952a5f8ec0ffbd5648e1c4 (do not edit this line) */

View File

@ -1,96 +0,0 @@
/* Generated By:JJTree: Do not edit this line. SimpleNode.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=org.apache.james.mime4j.field.address.parser.BaseNode,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package org.apache.james.mime4j.field.address.parser;
public
class SimpleNode extends org.apache.james.mime4j.field.address.parser.BaseNode implements Node {
protected Node parent;
protected Node[] children;
protected int id;
protected Object value;
protected AddressListParser parser;
public SimpleNode(int i) {
id = i;
}
public SimpleNode(AddressListParser p, int i) {
this(i);
parser = p;
}
public void jjtOpen() {
}
public void jjtClose() {
}
public void jjtSetParent(Node n) { parent = n; }
public Node jjtGetParent() { return parent; }
public void jjtAddChild(Node n, int i) {
if (children == null) {
children = new Node[i + 1];
} else if (i >= children.length) {
Node c[] = new Node[i + 1];
System.arraycopy(children, 0, c, 0, children.length);
children = c;
}
children[i] = n;
}
public Node jjtGetChild(int i) {
return children[i];
}
public int jjtGetNumChildren() {
return (children == null) ? 0 : children.length;
}
public void jjtSetValue(Object value) { this.value = value; }
public Object jjtGetValue() { return value; }
/** Accept the visitor. **/
public Object jjtAccept(AddressListParserVisitor visitor, Object data)
{
return visitor.visit(this, data);
}
/** Accept the visitor. **/
public Object childrenAccept(AddressListParserVisitor visitor, Object data)
{
if (children != null) {
for (int i = 0; i < children.length; ++i) {
children[i].jjtAccept(visitor, data);
}
}
return data;
}
/* You can override these two methods in subclasses of SimpleNode to
customize the way the node appears when the tree is dumped. If
your output uses more than one line you should override
toString(String), otherwise overriding toString() is probably all
you need to do. */
public String toString() { return AddressListParserTreeConstants.jjtNodeName[id]; }
public String toString(String prefix) { return prefix + toString(); }
/* Override this method if you want to customize how the node dumps
out its children. */
public void dump(String prefix) {
System.out.println(toString(prefix));
if (children != null) {
for (int i = 0; i < children.length; ++i) {
SimpleNode n = (SimpleNode)children[i];
if (n != null) {
n.dump(prefix + " ");
}
}
}
}
}
/* JavaCC - OriginalChecksum=055879471a7647d34de4235b3186aa17 (do not edit this line) */

View File

@ -1,149 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.address.parser;
/**
* Describes the input token stream.
*/
public class Token implements java.io.Serializable {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* An integer that describes the kind of this token. This numbering
* system is determined by JavaCCParser, and a table of these numbers is
* stored in the file ...Constants.java.
*/
public int kind;
/** The line number of the first character of this Token. */
public int beginLine;
/** The column number of the first character of this Token. */
public int beginColumn;
/** The line number of the last character of this Token. */
public int endLine;
/** The column number of the last character of this Token. */
public int endColumn;
/**
* The string image of the token.
*/
public String image;
/**
* A reference to the next regular (non-special) token from the input
* stream. If this is the last token from the input stream, or if the
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular
* token. Otherwise, see below for a description of the contents of
* this field.
*/
public Token next;
/**
* This field is used to access special tokens that occur prior to this
* token, but after the immediately preceding regular (non-special) token.
* If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
* to the last of these special tokens, which in turn refers to the next
* previous special token through its specialToken field, and so on
* until the first special token (whose specialToken field is null).
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there
* is no such token, this field is null.
*/
public Token specialToken;
/**
* An optional attribute value of the Token.
* Tokens which are not used as syntactic sugar will often contain
* meaningful values that will be used later on by the compiler or
* interpreter. This attribute value is often different from the image.
* Any subclass of Token that actually wants to return a non-null value can
* override this method as appropriate.
*/
public Object getValue() {
return null;
}
/**
* No-argument constructor
*/
public Token() {}
/**
* Constructs a new token for the specified Image.
*/
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=a51dc23d1faa88394342107e41df07b3 (do not edit this line) */

View File

@ -1,165 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
/* JavaCCOptions: */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.parser;
/** Token Manager Error. */
public class TokenMgrError extends Error
{
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/*
* Ordinals for various reasons why an Error of this type can be thrown.
*/
/**
* Lexical error occurred.
*/
static final int LEXICAL_ERROR = 0;
/**
* An attempt was made to create a second instance of a static token manager.
*/
static final int STATIC_LEXER_ERROR = 1;
/**
* Tried to change to an invalid lexical state.
*/
static final int INVALID_LEXICAL_STATE = 2;
/**
* Detected (and bailed out of) an infinite loop in the token manager.
*/
static final int LOOP_DETECTED = 3;
/**
* Indicates the reason why the exception is thrown. It will have
* one of the above 4 values.
*/
int errorCode;
/**
* Replaces unprintable characters by their escaped (or unicode escaped)
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
/**
* Returns a detailed message for the Error when it is thrown by the
* token manager to indicate a lexical error.
* Parameters :
* EOFSeen : indicates if EOF caused the lexical error
* curLexState : lexical state in which this error occurred
* errorLine : line number when the error occurred
* errorColumn : column number when the error occurred
* errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method.
*/
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
return("Lexical error at line " +
errorLine + ", column " +
errorColumn + ". Encountered: " +
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
"after : \"" + addEscapes(errorAfter) + "\"");
}
/**
* You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
* of end-users concern, so you can return something like :
*
* "Internal Error : Please file a bug report .... "
*
* from this method for such cases in the release version of your parser.
*/
public String getMessage() {
return super.getMessage();
}
/*
* Constructors of various flavors follow.
*/
/** No arg constructor. */
public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=c00a20fac1340b0977b68c98d352e42d (do not edit this line) */

View File

@ -1,292 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentDispositionParser.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contentdisposition.parser;
import java.util.List;
import java.util.ArrayList;
public class ContentDispositionParser implements ContentDispositionParserConstants {
private String dispositionType;
private List<String> paramNames = new ArrayList<String>();
private List<String> paramValues = new ArrayList<String>();
public String getDispositionType() {
return dispositionType;
}
public List<String> getParamNames() {
return paramNames;
}
public List<String> getParamValues() {
return paramValues;
}
public static void main(String args[]) throws ParseException {
while (true) {
try {
ContentDispositionParser parser = new ContentDispositionParser(
System.in);
parser.parseLine();
} catch (Exception x) {
x.printStackTrace();
return;
}
}
}
final public void parseLine() throws ParseException {
parse();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 1:
jj_consume_token(1);
break;
default:
jj_la1[0] = jj_gen;
;
}
jj_consume_token(2);
}
final public void parseAll() throws ParseException {
parse();
jj_consume_token(0);
}
final public void parse() throws ParseException {
Token dispositionType;
dispositionType = jj_consume_token(ATOKEN);
this.dispositionType = dispositionType.image;
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 3:
;
break;
default:
jj_la1[1] = jj_gen;
break label_1;
}
jj_consume_token(3);
parameter();
}
}
final public void parameter() throws ParseException {
Token attrib;
String val;
attrib = jj_consume_token(ATOKEN);
jj_consume_token(4);
val = value();
paramNames.add(attrib.image);
paramValues.add(val);
}
final public String value() throws ParseException {
Token t;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ATOKEN:
t = jj_consume_token(ATOKEN);
break;
case DIGITS:
t = jj_consume_token(DIGITS);
break;
case QUOTEDSTRING:
t = jj_consume_token(QUOTEDSTRING);
break;
default:
jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return t.image;}
throw new Error("Missing return statement in function");
}
/** Generated Token Manager. */
public ContentDispositionParserTokenManager token_source;
SimpleCharStream jj_input_stream;
/** Current token. */
public Token token;
/** Next token. */
public Token jj_nt;
private int jj_ntk;
private int jj_gen;
final private int[] jj_la1 = new int[3];
static private int[] jj_la1_0;
static {
jj_la1_init_0();
}
private static void jj_la1_init_0() {
jj_la1_0 = new int[] {0x2,0x8,0x1c0000,};
}
/** Constructor with InputStream. */
public ContentDispositionParser(java.io.InputStream stream) {
this(stream, null);
}
/** Constructor with InputStream and supplied encoding */
public ContentDispositionParser(java.io.InputStream stream, String encoding) {
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new ContentDispositionParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Constructor. */
public ContentDispositionParser(java.io.Reader stream) {
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new ContentDispositionParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Constructor with generated Token Manager. */
public ContentDispositionParser(ContentDispositionParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(ContentDispositionParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
if (token.kind == kind) {
jj_gen++;
return token;
}
token = oldToken;
jj_kind = kind;
throw generateParseException();
}
/** Get the next Token. */
final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
jj_gen++;
return token;
}
/** Get the specific Token. */
final public Token getToken(int index) {
Token t = token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
else t = t.next = token_source.getNextToken();
}
return t;
}
private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
private int[] jj_expentry;
private int jj_kind = -1;
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
boolean[] la1tokens = new boolean[23];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
for (int i = 0; i < 3; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
la1tokens[j] = true;
}
}
}
}
for (int i = 0; i < 23; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
jj_expentries.add(jj_expentry);
}
}
int[][] exptokseq = new int[jj_expentries.size()][];
for (int i = 0; i < jj_expentries.size(); i++) {
exptokseq[i] = jj_expentries.get(i);
}
return new ParseException(token, exptokseq, tokenImage);
}
/** Enable tracing. */
final public void enable_tracing() {
}
/** Disable tracing. */
final public void disable_tracing() {
}
}

View File

@ -1,82 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentDispositionParserConstants.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contentdisposition.parser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface ContentDispositionParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int WS = 5;
/** RegularExpression Id. */
int COMMENT = 7;
/** RegularExpression Id. */
int QUOTEDSTRING = 18;
/** RegularExpression Id. */
int DIGITS = 19;
/** RegularExpression Id. */
int ATOKEN = 20;
/** RegularExpression Id. */
int QUOTEDPAIR = 21;
/** RegularExpression Id. */
int ANY = 22;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int INCOMMENT = 1;
/** Lexical state. */
int NESTED_COMMENT = 2;
/** Lexical state. */
int INQUOTEDSTRING = 3;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\"\\r\"",
"\"\\n\"",
"\";\"",
"\"=\"",
"<WS>",
"\"(\"",
"\")\"",
"<token of kind 8>",
"\"(\"",
"<token of kind 10>",
"<token of kind 11>",
"\"(\"",
"\")\"",
"<token of kind 14>",
"\"\\\"\"",
"<token of kind 16>",
"<token of kind 17>",
"\"\\\"\"",
"<DIGITS>",
"<ATOKEN>",
"<QUOTEDPAIR>",
"<ANY>",
};
}

View File

@ -1,857 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentDispositionParserTokenManager.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contentdisposition.parser;
import java.util.List;
import java.util.ArrayList;
/** Token Manager. */
public class ContentDispositionParserTokenManager implements ContentDispositionParserConstants
{
// Keeps track of how many levels of comment nesting
// we've encountered. This is only used when the 2nd
// level is reached, for example ((this)), not (this).
// This is because the outermost level must be treated
// specially anyway, because the outermost ")" has a
// different token type than inner ")" instances.
static int commentNest;
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_0(int pos, long active0)
{
return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
}
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 10:
return jjStartNfaWithStates_0(0, 2, 2);
case 13:
return jjStartNfaWithStates_0(0, 1, 2);
case 34:
return jjStopAtPos(0, 15);
case 40:
return jjStopAtPos(0, 6);
case 59:
return jjStopAtPos(0, 3);
case 61:
return jjStopAtPos(0, 4);
default :
return jjMoveNfa_0(3, 0);
}
}
private int jjStartNfaWithStates_0(int pos, int kind, int state)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return pos + 1; }
return jjMoveNfa_0(state, pos + 1);
}
static final long[] jjbitVec0 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_0(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 3:
if ((0x3ff6cfafffffdffL & l) != 0L)
{
if (kind > 20)
kind = 20;
jjCheckNAdd(2);
}
else if ((0x100000200L & l) != 0L)
{
if (kind > 5)
kind = 5;
jjCheckNAdd(0);
}
if ((0x3ff000000000000L & l) != 0L)
{
if (kind > 19)
kind = 19;
jjCheckNAdd(1);
}
break;
case 0:
if ((0x100000200L & l) == 0L)
break;
kind = 5;
jjCheckNAdd(0);
break;
case 1:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 19)
kind = 19;
jjCheckNAdd(1);
break;
case 2:
if ((0x3ff6cfafffffdffL & l) == 0L)
break;
if (kind > 20)
kind = 20;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 3:
case 2:
if ((0xffffffffc7fffffeL & l) == 0L)
break;
kind = 20;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 3:
case 2:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 20)
kind = 20;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_1(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_1(int pos, long active0)
{
return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_1()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 9);
case 41:
return jjStopAtPos(0, 7);
default :
return jjMoveNfa_1(0, 0);
}
}
private int jjMoveNfa_1(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 10)
kind = 10;
break;
case 1:
if (kind > 8)
kind = 8;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 10)
kind = 10;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 8)
kind = 8;
break;
case 2:
if (kind > 10)
kind = 10;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 10)
kind = 10;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 8)
kind = 8;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_3(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_3(int pos, long active0)
{
return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_3()
{
switch(curChar)
{
case 34:
return jjStopAtPos(0, 18);
default :
return jjMoveNfa_3(0, 0);
}
}
private int jjMoveNfa_3(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((0xfffffffbffffffffL & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(2);
break;
case 1:
if (kind > 16)
kind = 16;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0xffffffffefffffffL & l) != 0L)
{
if (kind > 17)
kind = 17;
jjCheckNAdd(2);
}
else if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 16)
kind = 16;
break;
case 2:
if ((0xffffffffefffffffL & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(2);
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 16)
kind = 16;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_2(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_2(int pos, long active0)
{
return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_2()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 12);
case 41:
return jjStopAtPos(0, 13);
default :
return jjMoveNfa_2(0, 0);
}
}
private int jjMoveNfa_2(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 14)
kind = 14;
break;
case 1:
if (kind > 11)
kind = 11;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 14)
kind = 14;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 11)
kind = 11;
break;
case 2:
if (kind > 14)
kind = 14;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 14)
kind = 14;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 11)
kind = 11;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
static final int[] jjnextStates = {
};
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", "\15", "\12", "\73", "\75", null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
"INCOMMENT",
"NESTED_COMMENT",
"INQUOTEDSTRING",
};
/** Lex State array. */
public static final int[] jjnewLexState = {
-1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, -1, -1, -1, -1, 3, -1, -1, 0, -1, -1, -1, -1,
};
static final long[] jjtoToken = {
0x1c001fL,
};
static final long[] jjtoSkip = {
0xa0L,
};
static final long[] jjtoSpecial = {
0x20L,
};
static final long[] jjtoMore = {
0x3ff40L,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[3];
private final int[] jjstateSet = new int[6];
private final StringBuilder jjimage = new StringBuilder();
private StringBuilder image = jjimage;
private int jjimageLen;
private int lengthOfMatch;
protected char curChar;
/** Constructor. */
public ContentDispositionParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public ContentDispositionParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 3; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 4 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token specialToken = null;
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
image = jjimage;
image.setLength(0);
jjimageLen = 0;
for (;;)
{
switch(curLexState)
{
case 0:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
break;
case 1:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
break;
case 2:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_2();
break;
case 3:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_3();
break;
}
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
TokenLexicalActions(matchedToken);
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
return matchedToken;
}
else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
if (specialToken == null)
specialToken = matchedToken;
else
{
matchedToken.specialToken = specialToken;
specialToken = (specialToken.next = matchedToken);
}
}
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
continue EOFLoop;
}
MoreLexicalActions();
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
curPos = 0;
jjmatchedKind = 0x7fffffff;
try {
curChar = input_stream.readChar();
continue;
}
catch (java.io.IOException e1) { }
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
}
void MoreLexicalActions()
{
jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
switch(jjmatchedKind)
{
case 8 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 9 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
commentNest = 1;
break;
case 11 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 12 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
++commentNest;
break;
case 13 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
--commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
break;
case 15 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 1);
break;
case 16 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
default :
break;
}
}
void TokenLexicalActions(Token matchedToken)
{
switch(jjmatchedKind)
{
case 18 :
image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
matchedToken.image = image.substring(0, image.length() - 1);
break;
default :
break;
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
}

View File

@ -1,220 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.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.james.mime4j.field.contentdisposition.parser;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* Changes for Mime4J:
* extends org.apache.james.mime4j.field.ParseException
* added serialVersionUID
* added constructor ParseException(Throwable)
* default detail message is "Cannot parse field"
*/
public class ParseException extends org.apache.james.mime4j.dom.field.ParseException {
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set. The boolean
* flag "specialConstructor" is also set to true to indicate that
* this constructor was used to create this object.
* This constructor calls its super class with the empty string
* to force the "toString" method of parent class "Throwable" to
* print the error message in the form:
* ParseException: <result of getMessage>
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super("");
specialConstructor = true;
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super("Cannot parse field");
specialConstructor = false;
}
public ParseException(Throwable cause) {
super(cause);
specialConstructor = false;
}
public ParseException(String message) {
super(message);
specialConstructor = false;
}
/**
* This variable determines which constructor was used to create
* this object and thereby affects the semantics of the
* "getMessage" method (see below).
*/
protected boolean specialConstructor;
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* This method has the standard behavior when this object has been
* created using the standard constructors. Otherwise, it uses
* "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser), then this method is called during the printing
* of the final stack trace, and hence the correct error message
* gets displayed.
*/
public String getMessage() {
if (!specialConstructor) {
return super.getMessage();
}
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += add_escapes(tok.image);
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
protected String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}

View File

@ -1,489 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.contentdisposition.parser;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=3a0a96dd40a434f5b242b9ed9202faa4 (do not edit this line) */

View File

@ -1,149 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.contentdisposition.parser;
/**
* Describes the input token stream.
*/
public class Token implements java.io.Serializable {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* An integer that describes the kind of this token. This numbering
* system is determined by JavaCCParser, and a table of these numbers is
* stored in the file ...Constants.java.
*/
public int kind;
/** The line number of the first character of this Token. */
public int beginLine;
/** The column number of the first character of this Token. */
public int beginColumn;
/** The line number of the last character of this Token. */
public int endLine;
/** The column number of the last character of this Token. */
public int endColumn;
/**
* The string image of the token.
*/
public String image;
/**
* A reference to the next regular (non-special) token from the input
* stream. If this is the last token from the input stream, or if the
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular
* token. Otherwise, see below for a description of the contents of
* this field.
*/
public Token next;
/**
* This field is used to access special tokens that occur prior to this
* token, but after the immediately preceding regular (non-special) token.
* If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
* to the last of these special tokens, which in turn refers to the next
* previous special token through its specialToken field, and so on
* until the first special token (whose specialToken field is null).
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there
* is no such token, this field is null.
*/
public Token specialToken;
/**
* An optional attribute value of the Token.
* Tokens which are not used as syntactic sugar will often contain
* meaningful values that will be used later on by the compiler or
* interpreter. This attribute value is often different from the image.
* Any subclass of Token that actually wants to return a non-null value can
* override this method as appropriate.
*/
public Object getValue() {
return null;
}
/**
* No-argument constructor
*/
public Token() {}
/**
* Constructs a new token for the specified Image.
*/
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=b1ee9aaf7cbe47fcd350a0df848362b5 (do not edit this line) */

View File

@ -1,165 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
/* JavaCCOptions: */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contentdisposition.parser;
/** Token Manager Error. */
public class TokenMgrError extends Error
{
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/*
* Ordinals for various reasons why an Error of this type can be thrown.
*/
/**
* Lexical error occurred.
*/
static final int LEXICAL_ERROR = 0;
/**
* An attempt was made to create a second instance of a static token manager.
*/
static final int STATIC_LEXER_ERROR = 1;
/**
* Tried to change to an invalid lexical state.
*/
static final int INVALID_LEXICAL_STATE = 2;
/**
* Detected (and bailed out of) an infinite loop in the token manager.
*/
static final int LOOP_DETECTED = 3;
/**
* Indicates the reason why the exception is thrown. It will have
* one of the above 4 values.
*/
int errorCode;
/**
* Replaces unprintable characters by their escaped (or unicode escaped)
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
/**
* Returns a detailed message for the Error when it is thrown by the
* token manager to indicate a lexical error.
* Parameters :
* EOFSeen : indicates if EOF caused the lexical error
* curLexState : lexical state in which this error occurred
* errorLine : line number when the error occurred
* errorColumn : column number when the error occurred
* errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method.
*/
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
return("Lexical error at line " +
errorLine + ", column " +
errorColumn + ". Encountered: " +
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
"after : \"" + addEscapes(errorAfter) + "\"");
}
/**
* You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
* of end-users concern, so you can return something like :
*
* "Internal Error : Please file a bug report .... "
*
* from this method for such cases in the release version of your parser.
*/
public String getMessage() {
return super.getMessage();
}
/*
* Constructors of various flavors follow.
*/
/** No arg constructor. */
public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=9fa2b884a567f978be9291126c2a21c0 (do not edit this line) */

View File

@ -1,289 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentTypeParser.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contenttype.parser;
import java.util.List;
import java.util.ArrayList;
public class ContentTypeParser implements ContentTypeParserConstants {
private String type;
private String subtype;
private List<String> paramNames = new ArrayList<String>();
private List<String> paramValues = new ArrayList<String>();
public String getType() { return type; }
public String getSubType() { return subtype; }
public List<String> getParamNames() { return paramNames; }
public List<String> getParamValues() { return paramValues; }
public static void main(String args[]) throws ParseException {
while (true) {
try {
ContentTypeParser parser = new ContentTypeParser(System.in);
parser.parseLine();
} catch (Exception x) {
x.printStackTrace();
return;
}
}
}
final public void parseLine() throws ParseException {
parse();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 1:
jj_consume_token(1);
break;
default:
jj_la1[0] = jj_gen;
;
}
jj_consume_token(2);
}
final public void parseAll() throws ParseException {
parse();
jj_consume_token(0);
}
final public void parse() throws ParseException {
Token type;
Token subtype;
type = jj_consume_token(ATOKEN);
jj_consume_token(3);
subtype = jj_consume_token(ATOKEN);
this.type = type.image;
this.subtype = subtype.image;
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 4:
;
break;
default:
jj_la1[1] = jj_gen;
break label_1;
}
jj_consume_token(4);
parameter();
}
}
final public void parameter() throws ParseException {
Token attrib;
String val;
attrib = jj_consume_token(ATOKEN);
jj_consume_token(5);
val = value();
paramNames.add(attrib.image);
paramValues.add(val);
}
final public String value() throws ParseException {
Token t;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ATOKEN:
t = jj_consume_token(ATOKEN);
break;
case DIGITS:
t = jj_consume_token(DIGITS);
break;
case QUOTEDSTRING:
t = jj_consume_token(QUOTEDSTRING);
break;
default:
jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return t.image;}
throw new Error("Missing return statement in function");
}
/** Generated Token Manager. */
public ContentTypeParserTokenManager token_source;
SimpleCharStream jj_input_stream;
/** Current token. */
public Token token;
/** Next token. */
public Token jj_nt;
private int jj_ntk;
private int jj_gen;
final private int[] jj_la1 = new int[3];
static private int[] jj_la1_0;
static {
jj_la1_init_0();
}
private static void jj_la1_init_0() {
jj_la1_0 = new int[] {0x2,0x10,0x380000,};
}
/** Constructor with InputStream. */
public ContentTypeParser(java.io.InputStream stream) {
this(stream, null);
}
/** Constructor with InputStream and supplied encoding */
public ContentTypeParser(java.io.InputStream stream, String encoding) {
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new ContentTypeParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Constructor. */
public ContentTypeParser(java.io.Reader stream) {
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new ContentTypeParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Constructor with generated Token Manager. */
public ContentTypeParser(ContentTypeParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(ContentTypeParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
}
private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
if (token.kind == kind) {
jj_gen++;
return token;
}
token = oldToken;
jj_kind = kind;
throw generateParseException();
}
/** Get the next Token. */
final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
jj_gen++;
return token;
}
/** Get the specific Token. */
final public Token getToken(int index) {
Token t = token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
else t = t.next = token_source.getNextToken();
}
return t;
}
private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
private int[] jj_expentry;
private int jj_kind = -1;
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
boolean[] la1tokens = new boolean[24];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
for (int i = 0; i < 3; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
la1tokens[j] = true;
}
}
}
}
for (int i = 0; i < 24; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
jj_expentries.add(jj_expentry);
}
}
int[][] exptokseq = new int[jj_expentries.size()][];
for (int i = 0; i < jj_expentries.size(); i++) {
exptokseq[i] = jj_expentries.get(i);
}
return new ParseException(token, exptokseq, tokenImage);
}
/** Enable tracing. */
final public void enable_tracing() {
}
/** Disable tracing. */
final public void disable_tracing() {
}
}

View File

@ -1,83 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentTypeParserConstants.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contenttype.parser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface ContentTypeParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int WS = 6;
/** RegularExpression Id. */
int COMMENT = 8;
/** RegularExpression Id. */
int QUOTEDSTRING = 19;
/** RegularExpression Id. */
int DIGITS = 20;
/** RegularExpression Id. */
int ATOKEN = 21;
/** RegularExpression Id. */
int QUOTEDPAIR = 22;
/** RegularExpression Id. */
int ANY = 23;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int INCOMMENT = 1;
/** Lexical state. */
int NESTED_COMMENT = 2;
/** Lexical state. */
int INQUOTEDSTRING = 3;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\"\\r\"",
"\"\\n\"",
"\"/\"",
"\";\"",
"\"=\"",
"<WS>",
"\"(\"",
"\")\"",
"<token of kind 9>",
"\"(\"",
"<token of kind 11>",
"<token of kind 12>",
"\"(\"",
"\")\"",
"<token of kind 15>",
"\"\\\"\"",
"<token of kind 17>",
"<token of kind 18>",
"\"\\\"\"",
"<DIGITS>",
"<ATOKEN>",
"<QUOTEDPAIR>",
"<ANY>",
};
}

View File

@ -1,859 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ContentTypeParserTokenManager.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contenttype.parser;
import java.util.List;
import java.util.ArrayList;
/** Token Manager. */
public class ContentTypeParserTokenManager implements ContentTypeParserConstants
{
// Keeps track of how many levels of comment nesting
// we've encountered. This is only used when the 2nd
// level is reached, for example ((this)), not (this).
// This is because the outermost level must be treated
// specially anyway, because the outermost ")" has a
// different token type than inner ")" instances.
static int commentNest;
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_0(int pos, long active0)
{
return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
}
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 10:
return jjStartNfaWithStates_0(0, 2, 2);
case 13:
return jjStartNfaWithStates_0(0, 1, 2);
case 34:
return jjStopAtPos(0, 16);
case 40:
return jjStopAtPos(0, 7);
case 47:
return jjStopAtPos(0, 3);
case 59:
return jjStopAtPos(0, 4);
case 61:
return jjStopAtPos(0, 5);
default :
return jjMoveNfa_0(3, 0);
}
}
private int jjStartNfaWithStates_0(int pos, int kind, int state)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return pos + 1; }
return jjMoveNfa_0(state, pos + 1);
}
static final long[] jjbitVec0 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_0(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 3:
if ((0x3ff6cfafffffdffL & l) != 0L)
{
if (kind > 21)
kind = 21;
jjCheckNAdd(2);
}
else if ((0x100000200L & l) != 0L)
{
if (kind > 6)
kind = 6;
jjCheckNAdd(0);
}
if ((0x3ff000000000000L & l) != 0L)
{
if (kind > 20)
kind = 20;
jjCheckNAdd(1);
}
break;
case 0:
if ((0x100000200L & l) == 0L)
break;
kind = 6;
jjCheckNAdd(0);
break;
case 1:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 20)
kind = 20;
jjCheckNAdd(1);
break;
case 2:
if ((0x3ff6cfafffffdffL & l) == 0L)
break;
if (kind > 21)
kind = 21;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 3:
case 2:
if ((0xffffffffc7fffffeL & l) == 0L)
break;
kind = 21;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 3:
case 2:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 21)
kind = 21;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_1(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_1(int pos, long active0)
{
return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_1()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 10);
case 41:
return jjStopAtPos(0, 8);
default :
return jjMoveNfa_1(0, 0);
}
}
private int jjMoveNfa_1(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 11)
kind = 11;
break;
case 1:
if (kind > 9)
kind = 9;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 11)
kind = 11;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 9)
kind = 9;
break;
case 2:
if (kind > 11)
kind = 11;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 11)
kind = 11;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 9)
kind = 9;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_3(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_3(int pos, long active0)
{
return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_3()
{
switch(curChar)
{
case 34:
return jjStopAtPos(0, 19);
default :
return jjMoveNfa_3(0, 0);
}
}
private int jjMoveNfa_3(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((0xfffffffbffffffffL & l) == 0L)
break;
if (kind > 18)
kind = 18;
jjCheckNAdd(2);
break;
case 1:
if (kind > 17)
kind = 17;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0xffffffffefffffffL & l) != 0L)
{
if (kind > 18)
kind = 18;
jjCheckNAdd(2);
}
else if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 17)
kind = 17;
break;
case 2:
if ((0xffffffffefffffffL & l) == 0L)
break;
if (kind > 18)
kind = 18;
jjCheckNAdd(2);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
case 2:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 18)
kind = 18;
jjCheckNAdd(2);
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 17)
kind = 17;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_2(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_2(int pos, long active0)
{
return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_2()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 13);
case 41:
return jjStopAtPos(0, 14);
default :
return jjMoveNfa_2(0, 0);
}
}
private int jjMoveNfa_2(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 15)
kind = 15;
break;
case 1:
if (kind > 12)
kind = 12;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 15)
kind = 15;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 12)
kind = 12;
break;
case 2:
if (kind > 15)
kind = 15;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 15)
kind = 15;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 12)
kind = 12;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
static final int[] jjnextStates = {
};
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", "\15", "\12", "\57", "\73", "\75", null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
"INCOMMENT",
"NESTED_COMMENT",
"INQUOTEDSTRING",
};
/** Lex State array. */
public static final int[] jjnewLexState = {
-1, -1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, -1, -1, -1, -1, 3, -1, -1, 0, -1, -1, -1, -1,
};
static final long[] jjtoToken = {
0x38003fL,
};
static final long[] jjtoSkip = {
0x140L,
};
static final long[] jjtoSpecial = {
0x40L,
};
static final long[] jjtoMore = {
0x7fe80L,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[3];
private final int[] jjstateSet = new int[6];
private final StringBuilder jjimage = new StringBuilder();
private StringBuilder image = jjimage;
private int jjimageLen;
private int lengthOfMatch;
protected char curChar;
/** Constructor. */
public ContentTypeParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public ContentTypeParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 3; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 4 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token specialToken = null;
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
image = jjimage;
image.setLength(0);
jjimageLen = 0;
for (;;)
{
switch(curLexState)
{
case 0:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
break;
case 1:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
break;
case 2:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_2();
break;
case 3:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_3();
break;
}
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
TokenLexicalActions(matchedToken);
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
return matchedToken;
}
else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
if (specialToken == null)
specialToken = matchedToken;
else
{
matchedToken.specialToken = specialToken;
specialToken = (specialToken.next = matchedToken);
}
}
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
continue EOFLoop;
}
MoreLexicalActions();
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
curPos = 0;
jjmatchedKind = 0x7fffffff;
try {
curChar = input_stream.readChar();
continue;
}
catch (java.io.IOException e1) { }
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
}
void MoreLexicalActions()
{
jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
switch(jjmatchedKind)
{
case 9 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 10 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
commentNest = 1;
break;
case 12 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 13 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
++commentNest;
break;
case 14 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
--commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
break;
case 16 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 1);
break;
case 17 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
default :
break;
}
}
void TokenLexicalActions(Token matchedToken)
{
switch(jjmatchedKind)
{
case 19 :
image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
matchedToken.image = image.substring(0, image.length() - 1);
break;
default :
break;
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
}

View File

@ -1,220 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.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.james.mime4j.field.contenttype.parser;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* Changes for Mime4J:
* extends org.apache.james.mime4j.field.ParseException
* added serialVersionUID
* added constructor ParseException(Throwable)
* default detail message is "Cannot parse field"
*/
public class ParseException extends org.apache.james.mime4j.dom.field.ParseException {
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set. The boolean
* flag "specialConstructor" is also set to true to indicate that
* this constructor was used to create this object.
* This constructor calls its super class with the empty string
* to force the "toString" method of parent class "Throwable" to
* print the error message in the form:
* ParseException: <result of getMessage>
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super("");
specialConstructor = true;
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super("Cannot parse field");
specialConstructor = false;
}
public ParseException(Throwable cause) {
super(cause);
specialConstructor = false;
}
public ParseException(String message) {
super(message);
specialConstructor = false;
}
/**
* This variable determines which constructor was used to create
* this object and thereby affects the semantics of the
* "getMessage" method (see below).
*/
protected boolean specialConstructor;
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* This method has the standard behavior when this object has been
* created using the standard constructors. Otherwise, it uses
* "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser), then this method is called during the printing
* of the final stack trace, and hence the correct error message
* gets displayed.
*/
public String getMessage() {
if (!specialConstructor) {
return super.getMessage();
}
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += add_escapes(tok.image);
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
protected String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}

View File

@ -1,489 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.contenttype.parser;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=6c6aad23fd4c0ff4139b17758b7e8610 (do not edit this line) */

View File

@ -1,149 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=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.field.contenttype.parser;
/**
* Describes the input token stream.
*/
public class Token implements java.io.Serializable {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* An integer that describes the kind of this token. This numbering
* system is determined by JavaCCParser, and a table of these numbers is
* stored in the file ...Constants.java.
*/
public int kind;
/** The line number of the first character of this Token. */
public int beginLine;
/** The column number of the first character of this Token. */
public int beginColumn;
/** The line number of the last character of this Token. */
public int endLine;
/** The column number of the last character of this Token. */
public int endColumn;
/**
* The string image of the token.
*/
public String image;
/**
* A reference to the next regular (non-special) token from the input
* stream. If this is the last token from the input stream, or if the
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular
* token. Otherwise, see below for a description of the contents of
* this field.
*/
public Token next;
/**
* This field is used to access special tokens that occur prior to this
* token, but after the immediately preceding regular (non-special) token.
* If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
* to the last of these special tokens, which in turn refers to the next
* previous special token through its specialToken field, and so on
* until the first special token (whose specialToken field is null).
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there
* is no such token, this field is null.
*/
public Token specialToken;
/**
* An optional attribute value of the Token.
* Tokens which are not used as syntactic sugar will often contain
* meaningful values that will be used later on by the compiler or
* interpreter. This attribute value is often different from the image.
* Any subclass of Token that actually wants to return a non-null value can
* override this method as appropriate.
*/
public Object getValue() {
return null;
}
/**
* No-argument constructor
*/
public Token() {}
/**
* Constructs a new token for the specified Image.
*/
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=3d41123d7d22080e3366761725b1c1fe (do not edit this line) */

View File

@ -1,165 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
/* JavaCCOptions: */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.contenttype.parser;
/** Token Manager Error. */
public class TokenMgrError extends Error
{
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/*
* Ordinals for various reasons why an Error of this type can be thrown.
*/
/**
* Lexical error occurred.
*/
static final int LEXICAL_ERROR = 0;
/**
* An attempt was made to create a second instance of a static token manager.
*/
static final int STATIC_LEXER_ERROR = 1;
/**
* Tried to change to an invalid lexical state.
*/
static final int INVALID_LEXICAL_STATE = 2;
/**
* Detected (and bailed out of) an infinite loop in the token manager.
*/
static final int LOOP_DETECTED = 3;
/**
* Indicates the reason why the exception is thrown. It will have
* one of the above 4 values.
*/
int errorCode;
/**
* Replaces unprintable characters by their escaped (or unicode escaped)
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
/**
* Returns a detailed message for the Error when it is thrown by the
* token manager to indicate a lexical error.
* Parameters :
* EOFSeen : indicates if EOF caused the lexical error
* curLexState : lexical state in which this error occurred
* errorLine : line number when the error occurred
* errorColumn : column number when the error occurred
* errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method.
*/
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
return("Lexical error at line " +
errorLine + ", column " +
errorColumn + ". Encountered: " +
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
"after : \"" + addEscapes(errorAfter) + "\"");
}
/**
* You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
* of end-users concern, so you can return something like :
*
* "Internal Error : Please file a bug report .... "
*
* from this method for such cases in the release version of your parser.
*/
public String getMessage() {
return super.getMessage();
}
/*
* Constructors of various flavors follow.
*/
/** No arg constructor. */
public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=75c4cf7db7d0ac3344c6bae5c180f189 (do not edit this line) */

View File

@ -1,586 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. DateTimeParser.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.datetime.parser;
import org.apache.james.mime4j.dom.datetime.DateTime;
public class DateTimeParser implements DateTimeParserConstants {
private static final boolean ignoreMilitaryZoneOffset = true;
public static void main(String args[]) throws ParseException {
while (true) {
try {
DateTimeParser parser = new DateTimeParser(System.in);
parser.parseLine();
} catch (Exception x) {
x.printStackTrace();
return;
}
}
}
private static int parseDigits(Token token) {
return Integer.parseInt(token.image, 10);
}
private static int getMilitaryZoneOffset(char c) {
if (ignoreMilitaryZoneOffset)
return 0;
c = Character.toUpperCase(c);
switch (c) {
case 'A': return 1;
case 'B': return 2;
case 'C': return 3;
case 'D': return 4;
case 'E': return 5;
case 'F': return 6;
case 'G': return 7;
case 'H': return 8;
case 'I': return 9;
case 'K': return 10;
case 'L': return 11;
case 'M': return 12;
case 'N': return -1;
case 'O': return -2;
case 'P': return -3;
case 'Q': return -4;
case 'R': return -5;
case 'S': return -6;
case 'T': return -7;
case 'U': return -8;
case 'V': return -9;
case 'W': return -10;
case 'X': return -11;
case 'Y': return -12;
case 'Z': return 0;
default: return 0;
}
}
private static class Time {
private int hour;
private int minute;
private int second;
private int zone;
public Time(int hour, int minute, int second, int zone) {
this.hour = hour;
this.minute = minute;
this.second = second;
this.zone = zone;
}
public int getHour() { return hour; }
public int getMinute() { return minute; }
public int getSecond() { return second; }
public int getZone() { return zone; }
}
private static class Date {
private String year;
private int month;
private int day;
public Date(String year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public String getYear() { return year; }
public int getMonth() { return month; }
public int getDay() { return day; }
}
final public DateTime parseLine() throws ParseException {
DateTime dt;
dt = date_time();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 1:
jj_consume_token(1);
break;
default:
jj_la1[0] = jj_gen;
;
}
jj_consume_token(2);
{if (true) return dt;}
throw new Error("Missing return statement in function");
}
final public DateTime parseAll() throws ParseException {
DateTime dt;
dt = date_time();
jj_consume_token(0);
{if (true) return dt;}
throw new Error("Missing return statement in function");
}
final public DateTime date_time() throws ParseException {
Date d; Time t;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
day_of_week();
jj_consume_token(3);
break;
default:
jj_la1[1] = jj_gen;
;
}
d = date();
t = time();
{if (true) return new DateTime(
d.getYear(),
d.getMonth(),
d.getDay(),
t.getHour(),
t.getMinute(),
t.getSecond(),
t.getZone());} // time zone offset
throw new Error("Missing return statement in function");
}
final public String day_of_week() throws ParseException {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 4:
jj_consume_token(4);
break;
case 5:
jj_consume_token(5);
break;
case 6:
jj_consume_token(6);
break;
case 7:
jj_consume_token(7);
break;
case 8:
jj_consume_token(8);
break;
case 9:
jj_consume_token(9);
break;
case 10:
jj_consume_token(10);
break;
default:
jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return token.image;}
throw new Error("Missing return statement in function");
}
final public Date date() throws ParseException {
int d, m; String y;
d = day();
m = month();
y = year();
{if (true) return new Date(y, m, d);}
throw new Error("Missing return statement in function");
}
final public int day() throws ParseException {
Token t;
t = jj_consume_token(DIGITS);
{if (true) return parseDigits(t);}
throw new Error("Missing return statement in function");
}
final public int month() throws ParseException {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 11:
jj_consume_token(11);
{if (true) return 1;}
break;
case 12:
jj_consume_token(12);
{if (true) return 2;}
break;
case 13:
jj_consume_token(13);
{if (true) return 3;}
break;
case 14:
jj_consume_token(14);
{if (true) return 4;}
break;
case 15:
jj_consume_token(15);
{if (true) return 5;}
break;
case 16:
jj_consume_token(16);
{if (true) return 6;}
break;
case 17:
jj_consume_token(17);
{if (true) return 7;}
break;
case 18:
jj_consume_token(18);
{if (true) return 8;}
break;
case 19:
jj_consume_token(19);
{if (true) return 9;}
break;
case 20:
jj_consume_token(20);
{if (true) return 10;}
break;
case 21:
jj_consume_token(21);
{if (true) return 11;}
break;
case 22:
jj_consume_token(22);
{if (true) return 12;}
break;
default:
jj_la1[3] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
throw new Error("Missing return statement in function");
}
final public String year() throws ParseException {
Token t;
t = jj_consume_token(DIGITS);
{if (true) return t.image;}
throw new Error("Missing return statement in function");
}
final public Time time() throws ParseException {
int h, m, s=0, z;
h = hour();
jj_consume_token(23);
m = minute();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 23:
jj_consume_token(23);
s = second();
break;
default:
jj_la1[4] = jj_gen;
;
}
z = zone();
{if (true) return new Time(h, m, s, z);}
throw new Error("Missing return statement in function");
}
final public int hour() throws ParseException {
Token t;
t = jj_consume_token(DIGITS);
{if (true) return parseDigits(t);}
throw new Error("Missing return statement in function");
}
final public int minute() throws ParseException {
Token t;
t = jj_consume_token(DIGITS);
{if (true) return parseDigits(t);}
throw new Error("Missing return statement in function");
}
final public int second() throws ParseException {
Token t;
t = jj_consume_token(DIGITS);
{if (true) return parseDigits(t);}
throw new Error("Missing return statement in function");
}
final public int zone() throws ParseException {
Token t, u; int z;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OFFSETDIR:
t = jj_consume_token(OFFSETDIR);
u = jj_consume_token(DIGITS);
z=parseDigits(u)*(t.image.equals("-") ? -1 : 1);
break;
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case MILITARY_ZONE:
z = obs_zone();
break;
default:
jj_la1[5] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return z;}
throw new Error("Missing return statement in function");
}
final public int obs_zone() throws ParseException {
Token t; int z;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 25:
jj_consume_token(25);
z=0;
break;
case 26:
jj_consume_token(26);
z=0;
break;
case 27:
jj_consume_token(27);
z=-5;
break;
case 28:
jj_consume_token(28);
z=-4;
break;
case 29:
jj_consume_token(29);
z=-6;
break;
case 30:
jj_consume_token(30);
z=-5;
break;
case 31:
jj_consume_token(31);
z=-7;
break;
case 32:
jj_consume_token(32);
z=-6;
break;
case 33:
jj_consume_token(33);
z=-8;
break;
case 34:
jj_consume_token(34);
z=-7;
break;
case MILITARY_ZONE:
t = jj_consume_token(MILITARY_ZONE);
z=getMilitaryZoneOffset(t.image.charAt(0));
break;
default:
jj_la1[6] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return z * 100;}
throw new Error("Missing return statement in function");
}
/** Generated Token Manager. */
public DateTimeParserTokenManager token_source;
SimpleCharStream jj_input_stream;
/** Current token. */
public Token token;
/** Next token. */
public Token jj_nt;
private int jj_ntk;
private int jj_gen;
final private int[] jj_la1 = new int[7];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
jj_la1_init_0();
jj_la1_init_1();
}
private static void jj_la1_init_0() {
jj_la1_0 = new int[] {0x2,0x7f0,0x7f0,0x7ff800,0x800000,0xff000000,0xfe000000,};
}
private static void jj_la1_init_1() {
jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0xf,0xf,};
}
/** Constructor with InputStream. */
public DateTimeParser(java.io.InputStream stream) {
this(stream, null);
}
/** Constructor with InputStream and supplied encoding */
public DateTimeParser(java.io.InputStream stream, String encoding) {
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new DateTimeParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
/** Constructor. */
public DateTimeParser(java.io.Reader stream) {
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new DateTimeParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
/** Constructor with generated Token Manager. */
public DateTimeParser(DateTimeParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(DateTimeParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 7; i++) jj_la1[i] = -1;
}
private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
if (token.kind == kind) {
jj_gen++;
return token;
}
token = oldToken;
jj_kind = kind;
throw generateParseException();
}
/** Get the next Token. */
final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
jj_gen++;
return token;
}
/** Get the specific Token. */
final public Token getToken(int index) {
Token t = token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
else t = t.next = token_source.getNextToken();
}
return t;
}
private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
private int[] jj_expentry;
private int jj_kind = -1;
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
boolean[] la1tokens = new boolean[49];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
for (int i = 0; i < 7; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
la1tokens[j] = true;
}
if ((jj_la1_1[i] & (1<<j)) != 0) {
la1tokens[32+j] = true;
}
}
}
}
for (int i = 0; i < 49; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
jj_expentries.add(jj_expentry);
}
}
int[][] exptokseq = new int[jj_expentries.size()][];
for (int i = 0; i < jj_expentries.size(); i++) {
exptokseq[i] = jj_expentries.get(i);
}
return new ParseException(token, exptokseq, tokenImage);
}
/** Enable tracing. */
final public void enable_tracing() {
}
/** Disable tracing. */
final public void disable_tracing() {
}
}

View File

@ -1,106 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. DateTimeParserConstants.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.datetime.parser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface DateTimeParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int OFFSETDIR = 24;
/** RegularExpression Id. */
int MILITARY_ZONE = 35;
/** RegularExpression Id. */
int WS = 36;
/** RegularExpression Id. */
int COMMENT = 38;
/** RegularExpression Id. */
int DIGITS = 46;
/** RegularExpression Id. */
int QUOTEDPAIR = 47;
/** RegularExpression Id. */
int ANY = 48;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int INCOMMENT = 1;
/** Lexical state. */
int NESTED_COMMENT = 2;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\"\\r\"",
"\"\\n\"",
"\",\"",
"\"Mon\"",
"\"Tue\"",
"\"Wed\"",
"\"Thu\"",
"\"Fri\"",
"\"Sat\"",
"\"Sun\"",
"\"Jan\"",
"\"Feb\"",
"\"Mar\"",
"\"Apr\"",
"\"May\"",
"\"Jun\"",
"\"Jul\"",
"\"Aug\"",
"\"Sep\"",
"\"Oct\"",
"\"Nov\"",
"\"Dec\"",
"\":\"",
"<OFFSETDIR>",
"\"UT\"",
"\"GMT\"",
"\"EST\"",
"\"EDT\"",
"\"CST\"",
"\"CDT\"",
"\"MST\"",
"\"MDT\"",
"\"PST\"",
"\"PDT\"",
"<MILITARY_ZONE>",
"<WS>",
"\"(\"",
"\")\"",
"<token of kind 39>",
"\"(\"",
"<token of kind 41>",
"<token of kind 42>",
"\"(\"",
"\")\"",
"<token of kind 45>",
"<DIGITS>",
"<QUOTEDPAIR>",
"<ANY>",
};
}

View File

@ -1,869 +0,0 @@
/* Generated By:JavaCC: Do not edit this line. DateTimeParserTokenManager.java */
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.datetime.parser;
import org.apache.james.mime4j.dom.datetime.DateTime;
/** Token Manager. */
public class DateTimeParserTokenManager implements DateTimeParserConstants
{
// Keeps track of how many levels of comment nesting
// we've encountered. This is only used when the 2nd
// level is reached, for example ((this)), not (this).
// This is because the outermost level must be treated
// specially anyway, because the outermost ")" has a
// different token type than inner ")" instances.
static int commentNest;
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0)
{
switch (pos)
{
case 0:
if ((active0 & 0x7fe7cf7f0L) != 0L)
{
jjmatchedKind = 35;
return -1;
}
return -1;
case 1:
if ((active0 & 0x7fe7cf7f0L) != 0L)
{
if (jjmatchedPos == 0)
{
jjmatchedKind = 35;
jjmatchedPos = 0;
}
return -1;
}
return -1;
default :
return -1;
}
}
private final int jjStartNfa_0(int pos, long active0)
{
return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
}
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 10:
return jjStopAtPos(0, 2);
case 13:
return jjStopAtPos(0, 1);
case 40:
return jjStopAtPos(0, 37);
case 44:
return jjStopAtPos(0, 3);
case 58:
return jjStopAtPos(0, 23);
case 65:
return jjMoveStringLiteralDfa1_0(0x44000L);
case 67:
return jjMoveStringLiteralDfa1_0(0x60000000L);
case 68:
return jjMoveStringLiteralDfa1_0(0x400000L);
case 69:
return jjMoveStringLiteralDfa1_0(0x18000000L);
case 70:
return jjMoveStringLiteralDfa1_0(0x1100L);
case 71:
return jjMoveStringLiteralDfa1_0(0x4000000L);
case 74:
return jjMoveStringLiteralDfa1_0(0x30800L);
case 77:
return jjMoveStringLiteralDfa1_0(0x18000a010L);
case 78:
return jjMoveStringLiteralDfa1_0(0x200000L);
case 79:
return jjMoveStringLiteralDfa1_0(0x100000L);
case 80:
return jjMoveStringLiteralDfa1_0(0x600000000L);
case 83:
return jjMoveStringLiteralDfa1_0(0x80600L);
case 84:
return jjMoveStringLiteralDfa1_0(0xa0L);
case 85:
return jjMoveStringLiteralDfa1_0(0x2000000L);
case 87:
return jjMoveStringLiteralDfa1_0(0x40L);
default :
return jjMoveNfa_0(0, 0);
}
}
private int jjMoveStringLiteralDfa1_0(long active0)
{
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(0, active0);
return 1;
}
switch(curChar)
{
case 68:
return jjMoveStringLiteralDfa2_0(active0, 0x550000000L);
case 77:
return jjMoveStringLiteralDfa2_0(active0, 0x4000000L);
case 83:
return jjMoveStringLiteralDfa2_0(active0, 0x2a8000000L);
case 84:
if ((active0 & 0x2000000L) != 0L)
return jjStopAtPos(1, 25);
break;
case 97:
return jjMoveStringLiteralDfa2_0(active0, 0xaa00L);
case 99:
return jjMoveStringLiteralDfa2_0(active0, 0x100000L);
case 101:
return jjMoveStringLiteralDfa2_0(active0, 0x481040L);
case 104:
return jjMoveStringLiteralDfa2_0(active0, 0x80L);
case 111:
return jjMoveStringLiteralDfa2_0(active0, 0x200010L);
case 112:
return jjMoveStringLiteralDfa2_0(active0, 0x4000L);
case 114:
return jjMoveStringLiteralDfa2_0(active0, 0x100L);
case 117:
return jjMoveStringLiteralDfa2_0(active0, 0x70420L);
default :
break;
}
return jjStartNfa_0(0, active0);
}
private int jjMoveStringLiteralDfa2_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(0, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(1, active0);
return 2;
}
switch(curChar)
{
case 84:
if ((active0 & 0x4000000L) != 0L)
return jjStopAtPos(2, 26);
else if ((active0 & 0x8000000L) != 0L)
return jjStopAtPos(2, 27);
else if ((active0 & 0x10000000L) != 0L)
return jjStopAtPos(2, 28);
else if ((active0 & 0x20000000L) != 0L)
return jjStopAtPos(2, 29);
else if ((active0 & 0x40000000L) != 0L)
return jjStopAtPos(2, 30);
else if ((active0 & 0x80000000L) != 0L)
return jjStopAtPos(2, 31);
else if ((active0 & 0x100000000L) != 0L)
return jjStopAtPos(2, 32);
else if ((active0 & 0x200000000L) != 0L)
return jjStopAtPos(2, 33);
else if ((active0 & 0x400000000L) != 0L)
return jjStopAtPos(2, 34);
break;
case 98:
if ((active0 & 0x1000L) != 0L)
return jjStopAtPos(2, 12);
break;
case 99:
if ((active0 & 0x400000L) != 0L)
return jjStopAtPos(2, 22);
break;
case 100:
if ((active0 & 0x40L) != 0L)
return jjStopAtPos(2, 6);
break;
case 101:
if ((active0 & 0x20L) != 0L)
return jjStopAtPos(2, 5);
break;
case 103:
if ((active0 & 0x40000L) != 0L)
return jjStopAtPos(2, 18);
break;
case 105:
if ((active0 & 0x100L) != 0L)
return jjStopAtPos(2, 8);
break;
case 108:
if ((active0 & 0x20000L) != 0L)
return jjStopAtPos(2, 17);
break;
case 110:
if ((active0 & 0x10L) != 0L)
return jjStopAtPos(2, 4);
else if ((active0 & 0x400L) != 0L)
return jjStopAtPos(2, 10);
else if ((active0 & 0x800L) != 0L)
return jjStopAtPos(2, 11);
else if ((active0 & 0x10000L) != 0L)
return jjStopAtPos(2, 16);
break;
case 112:
if ((active0 & 0x80000L) != 0L)
return jjStopAtPos(2, 19);
break;
case 114:
if ((active0 & 0x2000L) != 0L)
return jjStopAtPos(2, 13);
else if ((active0 & 0x4000L) != 0L)
return jjStopAtPos(2, 14);
break;
case 116:
if ((active0 & 0x200L) != 0L)
return jjStopAtPos(2, 9);
else if ((active0 & 0x100000L) != 0L)
return jjStopAtPos(2, 20);
break;
case 117:
if ((active0 & 0x80L) != 0L)
return jjStopAtPos(2, 7);
break;
case 118:
if ((active0 & 0x200000L) != 0L)
return jjStopAtPos(2, 21);
break;
case 121:
if ((active0 & 0x8000L) != 0L)
return jjStopAtPos(2, 15);
break;
default :
break;
}
return jjStartNfa_0(1, active0);
}
private int jjMoveNfa_0(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 4;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0x3ff000000000000L & l) != 0L)
{
if (kind > 46)
kind = 46;
jjCheckNAdd(3);
}
else if ((0x100000200L & l) != 0L)
{
if (kind > 36)
kind = 36;
jjCheckNAdd(2);
}
else if ((0x280000000000L & l) != 0L)
{
if (kind > 24)
kind = 24;
}
break;
case 2:
if ((0x100000200L & l) == 0L)
break;
kind = 36;
jjCheckNAdd(2);
break;
case 3:
if ((0x3ff000000000000L & l) == 0L)
break;
kind = 46;
jjCheckNAdd(3);
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0x7fffbfe07fffbfeL & l) != 0L)
kind = 35;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 4 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_1(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_1(int pos, long active0)
{
return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_1()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 40);
case 41:
return jjStopAtPos(0, 38);
default :
return jjMoveNfa_1(0, 0);
}
}
static final long[] jjbitVec0 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_1(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 41)
kind = 41;
break;
case 1:
if (kind > 39)
kind = 39;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 41)
kind = 41;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 39)
kind = 39;
break;
case 2:
if (kind > 41)
kind = 41;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 41)
kind = 41;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 39)
kind = 39;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_2(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_2(int pos, long active0)
{
return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_2()
{
switch(curChar)
{
case 40:
return jjStopAtPos(0, 43);
case 41:
return jjStopAtPos(0, 44);
default :
return jjMoveNfa_2(0, 0);
}
}
private int jjMoveNfa_2(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 45)
kind = 45;
break;
case 1:
if (kind > 42)
kind = 42;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if (kind > 45)
kind = 45;
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 1;
break;
case 1:
if (kind > 42)
kind = 42;
break;
case 2:
if (kind > 45)
kind = 45;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) != 0L && kind > 45)
kind = 45;
break;
case 1:
if ((jjbitVec0[i2] & l2) != 0L && kind > 42)
kind = 42;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
static final int[] jjnextStates = {
};
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", "\15", "\12", "\54", "\115\157\156", "\124\165\145", "\127\145\144",
"\124\150\165", "\106\162\151", "\123\141\164", "\123\165\156", "\112\141\156",
"\106\145\142", "\115\141\162", "\101\160\162", "\115\141\171", "\112\165\156",
"\112\165\154", "\101\165\147", "\123\145\160", "\117\143\164", "\116\157\166",
"\104\145\143", "\72", null, "\125\124", "\107\115\124", "\105\123\124", "\105\104\124",
"\103\123\124", "\103\104\124", "\115\123\124", "\115\104\124", "\120\123\124",
"\120\104\124", null, null, null, null, null, null, null, null, null, null, null, null, null,
null, };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
"INCOMMENT",
"NESTED_COMMENT",
};
/** Lex State array. */
public static final int[] jjnewLexState = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1,
};
static final long[] jjtoToken = {
0x400fffffffffL,
};
static final long[] jjtoSkip = {
0x5000000000L,
};
static final long[] jjtoSpecial = {
0x1000000000L,
};
static final long[] jjtoMore = {
0x3fa000000000L,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[4];
private final int[] jjstateSet = new int[8];
private final StringBuilder jjimage = new StringBuilder();
private StringBuilder image = jjimage;
private int jjimageLen;
private int lengthOfMatch;
protected char curChar;
/** Constructor. */
public DateTimeParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public DateTimeParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 4; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 3 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token specialToken = null;
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
image = jjimage;
image.setLength(0);
jjimageLen = 0;
for (;;)
{
switch(curLexState)
{
case 0:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
break;
case 1:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
break;
case 2:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_2();
break;
}
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
return matchedToken;
}
else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
if (specialToken == null)
specialToken = matchedToken;
else
{
matchedToken.specialToken = specialToken;
specialToken = (specialToken.next = matchedToken);
}
}
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
continue EOFLoop;
}
MoreLexicalActions();
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
curPos = 0;
jjmatchedKind = 0x7fffffff;
try {
curChar = input_stream.readChar();
continue;
}
catch (java.io.IOException e1) { }
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
}
void MoreLexicalActions()
{
jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
switch(jjmatchedKind)
{
case 39 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 40 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
commentNest = 1;
break;
case 42 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
image.deleteCharAt(image.length() - 2);
break;
case 43 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
++commentNest;
break;
case 44 :
image.append(input_stream.GetSuffix(jjimageLen));
jjimageLen = 0;
--commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
break;
default :
break;
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
}

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