james-mime4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mwiederk...@apache.org
Subject svn commit: r738651 - in /james/mime4j/trunk/src: main/java/org/apache/james/mime4j/field/ main/javacc/org/apache/james/mime4j/field/contentdisposition/ test/java/org/apache/james/mime4j/field/ test/java/org/apache/james/mime4j/field/contentdisposition/
Date Wed, 28 Jan 2009 22:35:39 GMT
Author: mwiederkehr
Date: Wed Jan 28 22:35:38 2009
New Revision: 738651

URL: http://svn.apache.org/viewvc?rev=738651&view=rev
Log:
MIME4J-108: added ContentDispositionField

Added:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java
    james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/
    james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ContentDispositionParser.jj
    james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ParseException.java
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/ContentDispositionTest.java
Modified:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Field.java

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java?rev=738651&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java
(added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java
Wed Jan 28 22:35:38 2009
@@ -0,0 +1,326 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.field.contentdisposition.parser.ContentDispositionParser;
+import org.apache.james.mime4j.field.contentdisposition.parser.TokenMgrError;
+import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
+import org.apache.james.mime4j.field.ParseException;
+
+/**
+ * Represents a <code>Content-Disposition</code> field.
+ */
+public class ContentDispositionField extends Field {
+    private static Log log = LogFactory.getLog(ContentDispositionField.class);
+
+    /** 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";
+
+    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;
+
+    ContentDispositionField(String name, String body, String raw) {
+        super(name, body, raw);
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * Gets the disposition type defined in this Content-Disposition field.
+     * 
+     * @return the disposition type or an empty string if not set.
+     */
+    public String getDispositionType() {
+        if (!parsed)
+            parse();
+
+        return dispositionType;
+    }
+
+    /**
+     * 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.
+     */
+    public String getParameter(String name) {
+        if (!parsed)
+            parse();
+
+        return parameters.get(name.toLowerCase());
+    }
+
+    /**
+     * Gets all parameters.
+     * 
+     * @return the parameters.
+     */
+    public Map<String, String> getParameters() {
+        if (!parsed)
+            parse();
+
+        return Collections.unmodifiableMap(parameters);
+    }
+
+    /**
+     * 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.
+     */
+    public boolean isDispositionType(String dispositionType) {
+        if (!parsed)
+            parse();
+
+        return this.dispositionType.equalsIgnoreCase(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.
+     */
+    public boolean isInline() {
+        if (!parsed)
+            parse();
+
+        return dispositionType.equals(DISPOSITION_TYPE_INLINE);
+    }
+
+    /**
+     * 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 boolean isAttachment() {
+        if (!parsed)
+            parse();
+
+        return dispositionType.equals(DISPOSITION_TYPE_ATTACHMENT);
+    }
+
+    /**
+     * 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.
+     */
+    public String getFilename() {
+        return getParameter(PARAM_FILENAME);
+    }
+
+    /**
+     * 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.
+     */
+    public Date getCreationDate() {
+        if (!creationDateParsed) {
+            creationDate = parseDate(PARAM_CREATION_DATE);
+            creationDateParsed = true;
+        }
+
+        return creationDate;
+    }
+
+    /**
+     * 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.
+     */
+    public Date getModificationDate() {
+        if (!modificationDateParsed) {
+            modificationDate = parseDate(PARAM_MODIFICATION_DATE);
+            modificationDateParsed = true;
+        }
+
+        return modificationDate;
+    }
+
+    /**
+     * 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.
+     */
+    public Date getReadDate() {
+        if (!readDateParsed) {
+            readDate = parseDate(PARAM_READ_DATE);
+            readDateParsed = true;
+        }
+
+        return readDate;
+    }
+
+    /**
+     * 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.
+     */
+    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) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parsing " + paramName + " null");
+            }
+            return null;
+        }
+
+        try {
+            return new DateTimeParser(new StringReader(value)).parseAll()
+                    .getDate();
+        } catch (ParseException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parsing " + paramName + " '" + value + "': "
+                        + e.getMessage());
+            }
+            return null;
+        } catch (org.apache.james.mime4j.field.datetime.parser.TokenMgrError e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parsing " + paramName + " '" + value + "': "
+                        + e.getMessage());
+            }
+            return null;
+        }
+    }
+
+    private void parse() {
+        String body = getBody();
+
+        ContentDispositionParser parser = new ContentDispositionParser(
+                new StringReader(body));
+        try {
+            parser.parseAll();
+        } catch (ParseException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parsing value '" + body + "': " + e.getMessage());
+            }
+            parseException = e;
+        } catch (TokenMgrError e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parsing value '" + body + "': " + e.getMessage());
+            }
+            parseException = new ParseException(e.getMessage());
+        }
+
+        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;
+    }
+
+    public static class Parser implements FieldParser {
+        public Field parse(final String name, final String body,
+                final String raw) {
+            return new ContentDispositionField(name, body, raw);
+        }
+    }
+}

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java?rev=738651&r1=738650&r2=738651&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java
(original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java
Wed Jan 28 22:35:38 2009
@@ -24,6 +24,7 @@
     public DefaultFieldParser() {
         setFieldParser(Field.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
         setFieldParser(Field.CONTENT_TYPE, new ContentTypeField.Parser());
+        setFieldParser(Field.CONTENT_DISPOSITION, new ContentDispositionField.Parser());
         
         final DateTimeField.Parser dateTimeParser = new DateTimeField.Parser();
         setFieldParser(Field.DATE, dateTimeParser);

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Field.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Field.java?rev=738651&r1=738650&r2=738651&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Field.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Field.java Wed Jan 28 22:35:38
2009
@@ -47,9 +47,10 @@
     public static final String RESENT_DATE = "Resent-Date";
 
     public static final String SUBJECT = "Subject";
+
     public static final String CONTENT_TYPE = "Content-Type";
-    public static final String CONTENT_TRANSFER_ENCODING = 
-                                        "Content-Transfer-Encoding";
+    public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
+    public static final String CONTENT_DISPOSITION = "Content-Disposition";
 
     public static final String MESSAGE_ID = "Message-ID";
 
@@ -79,6 +80,7 @@
      *   <tr><th>Class returned</th><th>Field names</th></tr>
      *   <tr><td>{@link ContentTypeField}</td><td>Content-Type</td></tr>
      *   <tr><td>{@link ContentTransferEncodingField}</td><td>Content-Transfer-Encoding</td></tr>
+     *   <tr><td>{@link ContentDispositionField}</td><td>Content-Disposition</td></tr>
      *   <tr><td>{@link DateTimeField}</td><td>Date, Resent-Date</td></tr>
      *   <tr><td>{@link MailboxField}</td><td>Sender, Resent-Sender</td></tr>
      *   <tr><td>{@link MailboxListField}</td><td>From, Resent-From</td></tr>

Added: james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ContentDispositionParser.jj
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ContentDispositionParser.jj?rev=738651&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ContentDispositionParser.jj
(added)
+++ james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ContentDispositionParser.jj
Wed Jan 28 22:35:38 2009
@@ -0,0 +1,231 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+/**
+ * RFC2183 Content-Disposition parser.
+ */
+
+options {
+	STATIC=false;
+	LOOKAHEAD=1;
+	JDK_VERSION = "1.5";
+	OUTPUT_DIRECTORY = "../../../../../../../../../target/generated-sources/javacc";
+	//DEBUG_PARSER=true;
+	//DEBUG_TOKEN_MANAGER=true;
+}
+
+PARSER_BEGIN(ContentDispositionParser)
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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 {
+
+    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;
+            }
+        }
+    }
+}
+
+PARSER_END(ContentDispositionParser)
+
+void parseLine() :
+{}
+{
+	parse() ["\r"] "\n"
+}
+
+void parseAll() :
+{}
+{
+	parse() <EOF>
+}
+
+void parse() :
+{
+	Token dispositionType;
+}
+{
+	dispositionType=<ATOKEN>
+	{
+		this.dispositionType = dispositionType.image;
+	}
+	( ";" parameter() )*
+}
+
+void parameter() :
+{
+	Token attrib;
+	String val;
+}
+{
+	attrib=<ATOKEN> "=" val=value()
+	{
+		paramNames.add(attrib.image);
+		paramValues.add(val);
+	}
+}
+
+String value() :
+{Token t;}
+{
+(	t=<ATOKEN>
+|   t=<DIGITS>
+|	t=<QUOTEDSTRING>
+)
+	{ return t.image; }
+}
+
+
+
+SPECIAL_TOKEN :
+{
+ 	< WS: ( [" ", "\t"] )+ >
+}
+
+TOKEN_MGR_DECLS :
+{
+	// 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;
+}
+
+MORE :
+{
+	// starts a comment
+	"(" : INCOMMENT
+}
+
+<INCOMMENT>
+SKIP :
+{
+	// ends a comment
+	< COMMENT: ")" > : DEFAULT
+	// if this is ever changed to not be a SKIP, need
+	// to make sure matchedToken.token = token.toString()
+	// is called.
+}
+
+<INCOMMENT>
+MORE :
+{
+	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+|	"(" { commentNest = 1; } : NESTED_COMMENT
+|	< <ANY>>
+}
+
+<NESTED_COMMENT>
+MORE :
+{
+	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+|	"(" { ++commentNest; }
+|	")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
+|	< <ANY>>
+}
+
+
+
+// QUOTED STRINGS
+
+MORE :
+{
+	"\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
+}
+
+<INQUOTEDSTRING>
+MORE :
+{
+	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+|	< (~["\"", "\\"])+ >
+}
+
+<INQUOTEDSTRING>
+TOKEN :
+{
+	< QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() -
1); } : DEFAULT
+}
+
+
+TOKEN :
+{
+	< DIGITS: ( ["0"-"9"] )+ >
+}
+
+TOKEN :
+{
+	< ATOKEN: ( ~[" ", "\t", "(", ")", "<", ">", "@", ",", ";", ":", "\\", "\"", "/",
"[", "]", "?", "="] )+ >
+}
+
+
+// GLOBALS
+
+<*>
+TOKEN :
+{
+	< #QUOTEDPAIR: "\\" <ANY> >
+|	< #ANY: ~[] >
+}

Added: james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ParseException.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ParseException.java?rev=738651&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ParseException.java
(added)
+++ james/mime4j/trunk/src/main/javacc/org/apache/james/mime4j/field/contentdisposition/ParseException.java
Wed Jan 28 22:35:38 2009
@@ -0,0 +1,220 @@
+/* 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.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();
+   }
+
+}

Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java?rev=738651&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java
(added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java
Wed Jan 28 22:35:38 2009
@@ -0,0 +1,209 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.Date;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.BasicConfigurator;
+
+public class ContentDispositionFieldTest extends TestCase {
+
+    @Override
+    public void setUp() {
+        BasicConfigurator.resetConfiguration();
+        BasicConfigurator.configure();
+    }
+
+    public void testDispositionTypeWithSemiColonNoParams() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline;");
+        assertEquals("inline", f.getDispositionType());
+    }
+
+    public void testGetDispositionType() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertEquals("attachment", f.getDispositionType());
+
+        f = (ContentDispositionField) Field
+                .parse("content-disposition:   InLiNe   ");
+        assertEquals("inline", f.getDispositionType());
+
+        f = (ContentDispositionField) Field
+                .parse("CONTENT-DISPOSITION:   x-yada ;" + "  param = yada");
+        assertEquals("x-yada", f.getDispositionType());
+
+        f = (ContentDispositionField) Field.parse("CONTENT-DISPOSITION:   ");
+        assertEquals("", f.getDispositionType());
+    }
+
+    public void testGetParameter() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("CONTENT-DISPOSITION:   inline ;"
+                        + "  filename=yada yada");
+        assertEquals("yada", f.getParameter("filename"));
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: x-yada;"
+                        + "  fileNAme= \"ya:\\\"*da\"; " + "\tSIZE\t =  1234");
+        assertEquals("ya:\"*da", f.getParameter("filename"));
+        assertEquals("1234", f.getParameter("size"));
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: x-yada;  "
+                        + "fileNAme= \"ya \\\"\\\"\tda \\\"\"; "
+                        + "\tx-Yada\t =  \"\\\"hepp\\\"  =us\t-ascii\"");
+        assertEquals("ya \"\"\tda \"", f.getParameter("filename"));
+        assertEquals("\"hepp\"  =us\t-ascii", f.getParameter("x-yada"));
+    }
+
+    public void testIsDispositionType() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field.parse("Content-Disposition:INline");
+        assertTrue(f.isDispositionType("InLiNe"));
+        assertFalse(f.isDispositionType("NiLiNe"));
+        assertTrue(f.isInline());
+        assertFalse(f.isAttachment());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertTrue(f.isDispositionType("ATTACHMENT"));
+        assertFalse(f.isInline());
+        assertTrue(f.isAttachment());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: x-something");
+        assertTrue(f.isDispositionType("x-SomeThing"));
+        assertFalse(f.isInline());
+        assertFalse(f.isAttachment());
+    }
+
+    public void testGetFilename() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; filename=yada.txt");
+        assertEquals("yada.txt", f.getFilename());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; filename=yada yada.txt");
+        assertEquals("yada", f.getFilename());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; filename=\"yada yada.txt\"");
+        assertEquals("yada yada.txt", f.getFilename());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline");
+        assertNull(f.getFilename());
+    }
+
+    public void testGetCreationDate() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "creation-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
+        assertEquals(new Date(0), f.getCreationDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "creation-date=Tue, 01 Jan 1970 00:00:00 +0000");
+        assertNull(f.getCreationDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertNull(f.getCreationDate());
+    }
+
+    public void testGetModificationDate() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "modification-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
+        assertEquals(new Date(0), f.getModificationDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\"");
+        assertEquals(new Date(855782991000l), f.getModificationDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "modification-date=yesterday");
+        assertNull(f.getModificationDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertNull(f.getModificationDate());
+    }
+
+    public void testGetReadDate() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; "
+                        + "read-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
+        assertEquals(new Date(0), f.getReadDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: inline; read-date=");
+        assertNull(f.getReadDate());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertNull(f.getReadDate());
+    }
+
+    public void testGetSize() throws Exception {
+        ContentDispositionField f = null;
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment; size=0");
+        assertEquals(0, f.getSize());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment; size=matters");
+        assertEquals(-1, f.getSize());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment");
+        assertEquals(-1, f.getSize());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment; size=-12");
+        assertEquals(-1, f.getSize());
+
+        f = (ContentDispositionField) Field
+                .parse("Content-Disposition: attachment; size=12");
+        assertEquals(12, f.getSize());
+    }
+
+}

Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/ContentDispositionTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/ContentDispositionTest.java?rev=738651&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/ContentDispositionTest.java
(added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/field/contentdisposition/ContentDispositionTest.java
Wed Jan 28 22:35:38 2009
@@ -0,0 +1,15 @@
+package org.apache.james.mime4j.field.contentdisposition;
+
+import junit.framework.TestCase;
+
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.field.contentdisposition.parser.ParseException;
+
+public class ContentDispositionTest extends TestCase {
+
+    public void testExceptionTree() {
+        // make sure that our ParseException extends MimeException.
+        assertTrue(MimeException.class.isAssignableFrom(ParseException.class));
+    }
+    
+}



Mime
View raw message