Author: jochen Date: Tue Mar 27 13:30:53 2007 New Revision: 523066 URL: http://svn.apache.org/viewvc?view=rev&rev=523066 Log: Adding the ability to get any header from the FileItem and FileItemStream interfaces. PR: FILEUPLOAD-130 Submitted-By: Michael Macaluso <[EMAIL PROTECTED]>
Added: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeaders.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeadersSupport.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.java jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/FileItemHeadersTest.java Modified: jakarta/commons/proper/fileupload/trunk/.classpath jakarta/commons/proper/fileupload/trunk/.project jakarta/commons/proper/fileupload/trunk/pom.xml jakarta/commons/proper/fileupload/trunk/src/changes/changes.xml jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemStream.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileUploadBase.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java Modified: jakarta/commons/proper/fileupload/trunk/.classpath URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.classpath?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/.classpath (original) +++ jakarta/commons/proper/fileupload/trunk/.classpath Tue Mar 27 13:30:53 2007 @@ -1,8 +1,8 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry path="src/java" kind="src"/> - <classpathentry path="src/test" kind="src"/> - <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/> - <classpathentry path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" kind="con"/> - <classpathentry path="target/classes" kind="output"/> -</classpath> +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/java"/> + <classpathentry kind="src" path="src/test"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> Modified: jakarta/commons/proper/fileupload/trunk/.project URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.project?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/.project (original) +++ jakarta/commons/proper/fileupload/trunk/.project Tue Mar 27 13:30:53 2007 @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>commons-fileupload</name> - <comment>The FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications.</comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.maven.ide.eclipse.maven2Builder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - <nature>org.maven.ide.eclipse.maven2Nature</nature> - </natures> -</projectDescription> +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>commons-fileupload</name> + <comment>The FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications.</comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.maven.ide.eclipse.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.maven.ide.eclipse.maven2Nature</nature> + </natures> +</projectDescription> Modified: jakarta/commons/proper/fileupload/trunk/pom.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/pom.xml?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/pom.xml (original) +++ jakarta/commons/proper/fileupload/trunk/pom.xml Tue Mar 27 13:30:53 2007 @@ -104,6 +104,10 @@ <name>Henry Yandell</name> <email>[EMAIL PROTECTED]</email> </contributor> + <contributor> + <name>Michael Macaluso</name> + <email>[EMAIL PROTECTED]</email> + </contributor> </contributors> <scm> Modified: jakarta/commons/proper/fileupload/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/changes/changes.xml?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/changes/changes.xml (original) +++ jakarta/commons/proper/fileupload/trunk/src/changes/changes.xml Tue Mar 27 13:30:53 2007 @@ -41,7 +41,7 @@ </properties> <body> - <release version="1.2" date="2007-02-13"> + <release version="1.3" date="Not yet released"> <action dev="jochen" type="fix"> Upgrade to commons-io-1.4-SNAPSHOT, in order to use the new FileCleaningTracker and fix issues with FileCleaner. @@ -50,6 +50,10 @@ Made the MockHttpServletRequest comply to the servlet 2.4 specification by applying http://www.sourcelabs.com/dashboards/sash-1.2/patches/commons-fileupload-1.1-1/SUP-520.diff + </action> + <action dev="jochen" type="add" issue="FILEUPLOAD-130" + due-to="Michael Macaluso" due-to-email="[EMAIL PROTECTED]"> + Added support for accessing the file item headers. </action> </release> Added: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeaders.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeaders.java?view=auto&rev=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeaders.java (added) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeaders.java Tue Mar 27 13:30:53 2007 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload; + +import java.io.Serializable; +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders extends Serializable { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} Added: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeadersSupport.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeadersSupport.java?view=auto&rev=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeadersSupport.java (added) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemHeadersSupport.java Tue Mar 27 13:30:53 2007 @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload; + +/** + * Interface that will indicate that [EMAIL PROTECTED] FileItem} or [EMAIL PROTECTED] FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the [EMAIL PROTECTED] FileItemHeaders} present for this item. + * @since 1.3 + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * [EMAIL PROTECTED] FileItem} or [EMAIL PROTECTED] FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + * @since 1.3 + */ + void setHeaders(FileItemHeaders headers); +} Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemStream.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemStream.java?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemStream.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileItemStream.java Tue Mar 27 13:30:53 2007 @@ -32,7 +32,7 @@ * [EMAIL PROTECTED] java.util.Iterator#hasNext()} on the iterator, you discard all data, * which hasn't been read so far from the previous data.</p> */ -public interface FileItemStream { +public interface FileItemStream extends FileItemHeadersSupport { /** * This exception is thrown, if an attempt is made to read * data from the [EMAIL PROTECTED] InputStream}, which has been returned Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileUploadBase.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileUploadBase.java?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileUploadBase.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/FileUploadBase.java Tue Mar 27 13:30:53 2007 @@ -21,6 +21,7 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -30,6 +31,7 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.commons.fileupload.util.Closeable; +import org.apache.commons.fileupload.util.FileItemHeadersImpl; import org.apache.commons.fileupload.util.LimitedInputStream; import org.apache.commons.fileupload.util.Streams; @@ -360,6 +362,9 @@ "Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); } + if (fileItem instanceof FileItemHeadersSupport) { + ((FileItemHeadersSupport) fileItem).setHeaders(item.getHeaders()); + } items.add(fileItem); } return items; @@ -409,17 +414,33 @@ * @param headers A <code>Map</code> containing the HTTP request headers. * * @return The file name for the current <code>encapsulation</code>. + * @deprecated Use [EMAIL PROTECTED] #getFileName(FileItemHeaders)}. */ protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + /** + * Retrieves the file name from the <code>Content-disposition</code> + * header. + * + * @param headers The HTTP headers object. + * + * @return The file name for the current <code>encapsulation</code>. + */ + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { String fileName = null; - String cd = getHeader(headers, CONTENT_DISPOSITION); - if (cd != null) { - String cdl = cd.toLowerCase(); + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input - Map params = parser.parse(cd, ';'); + Map params = parser.parse(pContentDisposition, ';'); if (params.containsKey("filename")) { fileName = (String) params.get("filename"); if (fileName != null) { @@ -445,15 +466,17 @@ * * @return The field name for the current <code>encapsulation</code>. */ - protected String getFieldName(Map /* String, String */ headers) { - String fieldName = null; - String cd = getHeader(headers, CONTENT_DISPOSITION); - if (cd != null && cd.toLowerCase().startsWith(FORM_DATA)) { + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input - Map params = parser.parse(cd, ';'); + Map params = parser.parse(pContentDisposition, ';'); fieldName = (String) params.get("name"); if (fieldName != null) { fieldName = fieldName.trim(); @@ -462,6 +485,19 @@ return fieldName; } + /** + * Retrieves the field name from the <code>Content-disposition</code> + * header. + * + * @param headers A <code>Map</code> containing the HTTP request headers. + * + * @return The field name for the current <code>encapsulation</code>. + * @deprecated Use [EMAIL PROTECTED] #getFieldName(FileItemHeaders)}. + */ + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + /** * Creates a new [EMAIL PROTECTED] FileItem} instance. @@ -486,7 +522,6 @@ getFileName(headers)); } - /** * <p> Parses the <code>header-part</code> and returns as key/value * pairs. @@ -499,9 +534,9 @@ * * @return A <code>Map</code> containing the parsed HTTP request headers. */ - protected Map /* String, String */ parseHeaders(String headerPart) { + protected FileItemHeaders getParsedHeaders(String headerPart) { final int len = headerPart.length(); - Map headers = new HashMap(); + FileItemHeadersImpl headers = newFileItemHeaders(); int start = 0; for (;;) { int end = parseEndOfLine(headerPart, start); @@ -533,6 +568,42 @@ } /** + * Creates a new instance of [EMAIL PROTECTED] FileItemHeaders}. + * @return The new instance. + */ + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + /** + * <p> Parses the <code>header-part</code> and returns as key/value + * pairs. + * + * <p> If there are multiple headers of the same names, the name + * will map to a comma-separated list containing the values. + * + * @param headerPart The <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * @return A <code>Map</code> containing the parsed HTTP request headers. + * @deprecated Use [EMAIL PROTECTED] #getParsedHeaders(String)} + */ + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext(); ) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + /** * Skips bytes until the end of the current line. * @param headerPart The headers, which are being parsed. * @param end Index of the last byte, which has yet been @@ -560,25 +631,16 @@ * @param headers String with all headers. * @param header Map where to store the current header. */ - private void parseHeaderLine(Map headers, String header) { + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { final int colonOffset = header.indexOf(':'); if (colonOffset == -1) { // This header line is malformed, skip it. return; } - String headerName = header.substring(0, colonOffset) - .trim().toLowerCase(); + String headerName = header.substring(0, colonOffset).trim(); String headerValue = header.substring(header.indexOf(':') + 1).trim(); - if (getHeader(headers, headerName) != null) { - // More that one heder of that name exists, - // append to the list. - headers.put(headerName, - getHeader(headers, headerName) + ',' - + headerValue); - } else { - headers.put(headerName, headerValue); - } + headers.addHeader(headerName, headerValue); } /** @@ -590,6 +652,7 @@ * * @return The value of specified header, or a comma-separated list if * there were multiple headers of that name. + * @deprecated Use [EMAIL PROTECTED] FileItemHeaders#getHeader(String)}. */ protected final String getHeader(Map /* String, String */ headers, String name) { @@ -623,6 +686,9 @@ /** Whether the file item was already opened. */ private boolean opened; + /** The headers, if any. + */ + private FileItemHeaders headers; /** * CReates a new instance. @@ -713,6 +779,14 @@ void close() throws IOException { stream.close(); } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } } /** @@ -856,13 +930,12 @@ currentFieldName = null; continue; } - Map headers = parseHeaders(multi.readHeaders()); + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); if (currentFieldName == null) { // We're parsing the outer multipart String fieldName = getFieldName(headers); if (fieldName != null) { - String subContentType - = getHeader(headers, CONTENT_TYPE); + String subContentType = headers.getHeader(CONTENT_TYPE); if (subContentType != null && subContentType.toLowerCase() .startsWith(MULTIPART_MIXED)) { @@ -875,7 +948,7 @@ } String fileName = getFileName(headers); currentItem = new FileItemStreamImpl(fileName, - fieldName, getHeader(headers, CONTENT_TYPE), + fieldName, headers.getHeader(CONTENT_TYPE), fileName == null); notifier.noteItem(); itemValid = true; @@ -886,7 +959,7 @@ if (fileName != null) { currentItem = new FileItemStreamImpl(fileName, currentFieldName, - getHeader(headers, CONTENT_TYPE), + headers.getHeader(CONTENT_TYPE), false); notifier.noteItem(); itemValid = true; Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java?view=diff&rev=523066&r1=523065&r2=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java Tue Mar 27 13:30:53 2007 @@ -36,6 +36,8 @@ import org.apache.commons.io.output.DeferredFileOutputStream; import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemHeaders; +import org.apache.commons.fileupload.FileItemHeadersSupport; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ParameterParser; @@ -75,7 +77,7 @@ * @version $Id$ */ public class DiskFileItem - implements FileItem { + implements FileItem, FileItemHeadersSupport { // ----------------------------------------------------- Manifest constants @@ -175,6 +177,11 @@ */ private FileCleaningTracker fileCleaningTracker; + /** + * The file items headers. + */ + private FileItemHeaders headers; + // ----------------------------------------------------------- Constructors @@ -762,4 +769,17 @@ cachedContent = null; } + /** + * Returns the file item headers. + */ + public FileItemHeaders getHeaders() { + return headers; + } + + /** + * Sets the file item headers. + */ + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } } Added: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.java?view=auto&rev=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.java (added) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.java Tue Mar 27 13:30:53 2007 @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.fileupload.FileItemHeaders; + +/** + * Default implementation of the [EMAIL PROTECTED] FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + /* (non-Javadoc) + * @see org.apache.commons.fileupload.FileItemHeaders#getHeader(java.lang.String) + */ + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) + { + return null; + } + return (String) headerValueList.get(0); + } + + /* (non-Javadoc) + * @see org.apache.commons.fileupload.FileItemHeaders#getHeaderNames() + */ + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + /* (non-Javadoc) + * @see org.apache.commons.fileupload.FileItemHeaders#getHeaders(java.lang.String) + */ + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) + { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) + { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} Added: jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/FileItemHeadersTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/FileItemHeadersTest.java?view=auto&rev=523066 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/FileItemHeadersTest.java (added) +++ jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/FileItemHeadersTest.java Tue Mar 27 13:30:53 2007 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload; + +import java.util.Iterator; + +import org.apache.commons.fileupload.util.FileItemHeadersImpl; + +import junit.framework.TestCase; + +/** + * Unit tests [EMAIL PROTECTED] FileItemHeaders} and + * [EMAIL PROTECTED] FileItemHeadersImpl}. + * + * @author Michael C. Macaluso + */ +public class FileItemHeadersTest extends TestCase { + /** + * @throws Exception + */ + public void testFileItemHeaders() throws Exception { + FileItemHeadersImpl aMutableFileItemHeaders = new FileItemHeadersImpl(); + aMutableFileItemHeaders.addHeader("Content-Disposition", "form-data; name=\"FileItem\"; filename=\"file1.txt\""); + aMutableFileItemHeaders.addHeader("Content-Type", "text/plain"); + + aMutableFileItemHeaders.addHeader("TestHeader", "headerValue1"); + aMutableFileItemHeaders.addHeader("TestHeader", "headerValue2"); + aMutableFileItemHeaders.addHeader("TestHeader", "headerValue3"); + aMutableFileItemHeaders.addHeader("testheader", "headerValue4"); + + Iterator headerNameEnumeration = aMutableFileItemHeaders.getHeaderNames(); + assertEquals("content-disposition", (String) headerNameEnumeration.next()); + assertEquals("content-type", (String) headerNameEnumeration.next()); + assertEquals("testheader", (String) headerNameEnumeration.next()); + assertFalse(headerNameEnumeration.hasNext()); + + assertEquals(aMutableFileItemHeaders.getHeader("Content-Disposition"), "form-data; name=\"FileItem\"; filename=\"file1.txt\""); + assertEquals(aMutableFileItemHeaders.getHeader("Content-Type"), "text/plain"); + assertEquals(aMutableFileItemHeaders.getHeader("content-type"), "text/plain"); + assertEquals(aMutableFileItemHeaders.getHeader("TestHeader"), "headerValue1"); + assertNull(aMutableFileItemHeaders.getHeader("DummyHeader")); + + Iterator headerValueEnumeration; + + headerValueEnumeration = aMutableFileItemHeaders.getHeaders("Content-Type"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "text/plain"); + assertFalse(headerValueEnumeration.hasNext()); + + headerValueEnumeration = aMutableFileItemHeaders.getHeaders("content-type"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "text/plain"); + assertFalse(headerValueEnumeration.hasNext()); + + headerValueEnumeration = aMutableFileItemHeaders.getHeaders("TestHeader"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "headerValue1"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "headerValue2"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "headerValue3"); + assertTrue(headerValueEnumeration.hasNext()); + assertEquals(headerValueEnumeration.next(), "headerValue4"); + assertFalse(headerValueEnumeration.hasNext()); + + headerValueEnumeration = aMutableFileItemHeaders.getHeaders("DummyHeader"); + assertFalse(headerValueEnumeration.hasNext()); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]