You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/02/26 01:50:33 UTC
cvs commit: jakarta-tapestry/framework/src/descriptor/META-INF tapestry.multipart.xml hivemodule.xml
hlship 2005/02/25 16:50:33
Modified: framework/src/java/org/apache/tapestry/multipart
UploadPart.java ValuePart.java
framework/src/java/org/apache/tapestry/form Upload.java
Upload.jwc
framework/src/java/org/apache/tapestry/request
RequestContext.java
framework/src/java/org/apache/tapestry/services/impl
InvokeEngineTerminator.java
src/documentation/content/xdocs/UsersGuide configuration.xml
framework/src/descriptor/META-INF hivemodule.xml
Added: framework/src/test/org/apache/tapestry/multipart
TestMultipartDecoderFilter.java
TestUploadFormParametersWrapper.java
framework/src/java/org/apache/tapestry/multipart
MultipartDecoderFilter.java
MultipartDecoderImpl.java
MultipartStrings.properties
UploadFormParametersWrapper.java
MultipartDecoder.java MultipartMessages.java
framework/src/descriptor/META-INF tapestry.multipart.xml
Removed: framework/src/java/org/apache/tapestry/multipart IPart.java
DefaultMultipartDecoder.java
Log:
Refactor multipart/form-data support.
Revision Changes Path
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/multipart/TestMultipartDecoderFilter.java
Index: TestMultipartDecoderFilter.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.tapestry.services.RequestServicer;
import org.easymock.MockControl;
/**
* Tests for {@link org.apache.tapestry.multipart.MultipartDecoderFilter}.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestMultipartDecoderFilter extends HiveMindTestCase
{
private static class MockServicer implements RequestServicer
{
HttpServletRequest _request;
public void service(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
_request = request;
}
}
private HttpServletRequest newRequest(String contentType)
{
MockControl control = newControl(HttpServletRequest.class);
HttpServletRequest request = (HttpServletRequest) control.getMock();
request.getContentType();
control.setReturnValue(contentType);
return request;
}
private HttpServletResponse newResponse()
{
return (HttpServletResponse) newMock(HttpServletResponse.class);
}
public void testNormalRequest() throws Exception
{
HttpServletRequest request = newRequest("application/x-www-form-urlencoded");
HttpServletResponse response = newResponse();
MockServicer servicer = new MockServicer();
replayControls();
MultipartDecoderFilter f = new MultipartDecoderFilter();
f.service(request, response, servicer);
assertSame(request, servicer._request);
verifyControls();
}
public void testUploadRequest() throws Exception
{
HttpServletRequest request = newRequest("multipart/form-data");
HttpServletResponse response = newResponse();
HttpServletRequest decoded = (HttpServletRequest) newMock(HttpServletRequest.class);
MockControl control = newControl(MultipartDecoder.class);
MultipartDecoder decoder = (MultipartDecoder) control.getMock();
decoder.decode(request);
control.setReturnValue(decoded);
decoder.cleanup();
MockServicer servicer = new MockServicer();
replayControls();
MultipartDecoderFilter f = new MultipartDecoderFilter();
f.setDecoder(decoder);
f.service(request, response, servicer);
assertSame(decoded, servicer._request);
verifyControls();
}
}
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/multipart/TestUploadFormParametersWrapper.java
Index: TestUploadFormParametersWrapper.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.hivemind.test.HiveMindTestCase;
/**
* Tests for {@link org.apache.tapestry.multipart.UploadFormParametersWrapper}.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestUploadFormParametersWrapper extends HiveMindTestCase
{
private HttpServletRequest newRequest()
{
return (HttpServletRequest) newMock(HttpServletRequest.class);
}
public void testMapIsNotModifiable()
{
HttpServletRequest request = newRequest();
replayControls();
Map map = new HashMap();
map.put("key", new String[]
{ "value" });
HttpServletRequest r = new UploadFormParametersWrapper(request, map);
Map pmap = r.getParameterMap();
assertNotSame(map, pmap);
assertSame(map.get("key"), pmap.get("key"));
try
{
pmap.put("foo", "bar");
unreachable();
}
catch (UnsupportedOperationException ex)
{
// Expected.
}
verifyControls();
}
public void testGetSingleParameterWhenNull()
{
HttpServletRequest request = newRequest();
replayControls();
HttpServletRequest r = new UploadFormParametersWrapper(request, new HashMap());
assertNull(r.getParameter("unknown-key"));
verifyControls();
}
public void testGetSingleParameterWhenEmptyArray()
{
HttpServletRequest request = newRequest();
replayControls();
HashMap params = new HashMap();
params.put("empty-key", new String[0]);
HttpServletRequest r = new UploadFormParametersWrapper(request, params);
assertNull(r.getParameter("empty-key"));
verifyControls();
}
public void testGetParameterValues()
{
String[] values =
{ "fred", "barney" };
HttpServletRequest request = newRequest();
replayControls();
HashMap params = new HashMap();
params.put("key", values);
HttpServletRequest r = new UploadFormParametersWrapper(request, params);
assertSame(values, r.getParameterValues("key"));
verifyControls();
}
public void testGetParameterNames()
{
HttpServletRequest request = newRequest();
replayControls();
HashMap params = new HashMap();
params.put("key", new String[0]);
HttpServletRequest r = new UploadFormParametersWrapper(request, params);
Enumeration e = r.getParameterNames();
assertEquals(true, e.hasMoreElements());
assertEquals("key", e.nextElement());
assertEquals(false, e.hasMoreElements());
verifyControls();
}
}
1.5 +4 -4 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/UploadPart.java
Index: UploadPart.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/UploadPart.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- UploadPart.java 6 Jan 2005 02:17:34 -0000 1.4
+++ UploadPart.java 26 Feb 2005 00:50:32 -0000 1.5
@@ -30,7 +30,7 @@
* @author Joe Panico
* @since 2.0.1
*/
-public class UploadPart extends Object implements IUploadFile, IPart
+public class UploadPart extends Object implements IUploadFile
{
private FileItem _fileItem;
@@ -73,9 +73,9 @@
}
catch (IOException ex)
{
- throw new ApplicationRuntimeException(Tapestry.format(
- "UploadPart.unable-to-open-content-file",
- _fileItem.getName()), ex);
+ throw new ApplicationRuntimeException(MultipartMessages.unableToOpenContentFile(
+ this,
+ ex), ex);
}
}
1.4 +16 -19 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/ValuePart.java
Index: ValuePart.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/ValuePart.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ValuePart.java 6 Jan 2005 02:17:34 -0000 1.3
+++ ValuePart.java 26 Feb 2005 00:50:32 -0000 1.4
@@ -18,17 +18,16 @@
import java.util.List;
/**
- * A portion of a multipart request that stores a value, or values, for
- * a parameter.
- *
- * @author Howard Lewis Ship
- * @since 2.0.1
- *
- **/
+ * A portion of a multipart request that stores a value, or values, for a parameter.
+ *
+ * @author Howard Lewis Ship
+ * @since 2.0.1
+ */
-public class ValuePart implements IPart
+public class ValuePart
{
private int _count;
+
// Stores either String or List of String
private Object _value;
@@ -44,9 +43,8 @@
}
/**
- * Returns the value, or the first value (if multi-valued).
- *
- **/
+ * Returns the value, or the first value (if multi-valued).
+ */
public String getValue()
{
@@ -59,15 +57,15 @@
}
/**
- * Returns the values as an array of strings. If there is only one value,
- * it is returned wrapped as a single element array.
- *
- **/
+ * Returns the values as an array of strings. If there is only one value, it is returned wrapped
+ * as a single element array.
+ */
public String[] getValues()
{
if (_count == 1)
- return new String[] {(String) _value };
+ return new String[]
+ { (String) _value };
List l = (List) _value;
@@ -93,9 +91,8 @@
}
/**
- * Does nothing.
- *
- **/
+ * Does nothing.
+ */
public void cleanup()
{
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/MultipartDecoderFilter.java
Index: MultipartDecoderFilter.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tapestry.services.RequestServicer;
import org.apache.tapestry.services.RequestServicerFilter;
/**
* Checks to see if the request is a file upload and, if so, uses the
* {@link org.apache.tapestry.multipart.MultipartDecoder} to obtain form parameters.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class MultipartDecoderFilter implements RequestServicerFilter
{
private MultipartDecoder _decoder;
public void service(HttpServletRequest request, HttpServletResponse response,
RequestServicer servicer) throws IOException, ServletException
{
String contentType = request.getContentType();
// contentType is occasionally null in testing. The browser tacks on additional
// information onto the contentType to indicate where the boundaries are in
// the stream.
boolean encoded = contentType != null && contentType.startsWith("multipart/form-data");
try
{
HttpServletRequest newRequest = encoded ? _decoder.decode(request) : request;
servicer.service(newRequest, response);
}
finally
{
if (encoded)
_decoder.cleanup();
}
}
public void setDecoder(MultipartDecoder decoder)
{
_decoder = decoder;
}
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/MultipartDecoderImpl.java
Index: MultipartDecoderImpl.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.request.IUploadFile;
/**
* Implementation of {@link org.apache.tapestry.multipart.MultipartDecoder}that is based on <a
* href="http://jakarta.apache.org/commons/fileupload/">Jakarta FileUpload </a>.
*
* @author Howard M. Lewis Ship
* @author Joe Panico
* @since 3.1
*/
public class MultipartDecoderImpl implements MultipartDecoder
{
/**
* Map of UploadPart (which implements IUploadFile), keyed on parameter name.
*/
private Map _uploadParts = new HashMap();
/**
* Map of ValuePart, keyed on parameter name.
*/
private Map _valueParts = new HashMap();
private int _maxSize = 10000000;
private int _thresholdSize = 1024;
private String _repositoryPath = System.getProperty("java.io.tmpdir");
private String _encoding;
public HttpServletRequest decode(HttpServletRequest request)
{
_encoding = request.getCharacterEncoding();
DiskFileUpload upload = createUpload(request);
try
{
List fileItems = upload
.parseRequest(request, _thresholdSize, _maxSize, _repositoryPath);
processFileItems(fileItems);
}
catch (FileUploadException ex)
{
throw new ApplicationRuntimeException(MultipartMessages.unableToDecode(ex), ex);
}
Map parameterMap = buildParameterMap();
return new UploadFormParametersWrapper(request, parameterMap);
}
private Map buildParameterMap()
{
Map result = new HashMap();
Iterator i = _valueParts.entrySet().iterator();
while (i.hasNext())
{
Map.Entry e = (Map.Entry) i.next();
String name = (String) e.getKey();
ValuePart part = (ValuePart) e.getValue();
result.put(name, part.getValues());
}
return result;
}
private void processFileItems(List parts)
{
if (parts == null)
return;
Iterator i = parts.iterator();
while (i.hasNext())
{
FileItem item = (FileItem) i.next();
processFileItem(item);
}
}
private void processFileItem(FileItem item)
{
if (item.isFormField())
{
processFormFieldItem(item);
return;
}
processUploadFileItem(item);
}
private void processUploadFileItem(FileItem item)
{
String name = item.getFieldName();
UploadPart part = new UploadPart(item);
_uploadParts.put(name, part);
}
void processFormFieldItem(FileItem item)
{
String name = item.getFieldName();
String value = extractFileItemValue(item);
ValuePart part = (ValuePart) _valueParts.get(name);
if (part == null)
_valueParts.put(name, new ValuePart(value));
else
part.add(value);
}
private String extractFileItemValue(FileItem item)
{
try
{
return (_encoding == null) ? item.getString() : item.getString(_encoding);
}
catch (UnsupportedEncodingException ex)
{
throw new ApplicationRuntimeException(MultipartMessages.unsupportedEncoding(
_encoding,
ex), ex);
}
}
protected DiskFileUpload createUpload(HttpServletRequest request)
{
DiskFileUpload upload = new DiskFileUpload();
if (_encoding != null)
upload.setHeaderEncoding(_encoding);
return upload;
}
public IUploadFile getFileUpload(String parameterName)
{
return (IUploadFile) _uploadParts.get(parameterName);
}
public void cleanup()
{
Iterator i = _uploadParts.values().iterator();
while (i.hasNext())
{
UploadPart part = (UploadPart) i.next();
part.cleanup();
}
}
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/MultipartStrings.properties
Index: MultipartStrings.properties
===================================================================
# Copyright 2005 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
unable-to-decode=Unable to decode multipart encoded request: {0}
unsupported-encoding=Unsupported character encoding ''{0}'' when decoding multipart encoded request: {1}
write-failure=Unable to write uploaded file content to {0}: {1}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/UploadFormParametersWrapper.java
Index: UploadFormParametersWrapper.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.hivemind.util.Defense;
/**
* {@link javax.servlet.http.HttpServletRequest} wrapper that provides access to the form
* field values uploaded in a multipart request.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class UploadFormParametersWrapper extends HttpServletRequestWrapper
{
/**
* Map of {@link ValuePart} keyed on parameter name.
*/
private Map _parameterMap;
/**
* @param parameterMap
* a map whose keys are parameter names and whose values are arrays of Strings.
*/
public UploadFormParametersWrapper(HttpServletRequest request, Map parameterMap)
{
super(request);
Defense.notNull(parameterMap, "parameterMap");
_parameterMap = Collections.unmodifiableMap(parameterMap);
}
public String getParameter(String name)
{
String[] values = getParameterValues(name);
return (values == null || values.length == 0) ? null : values[0];
}
public Map getParameterMap()
{
return _parameterMap;
}
public Enumeration getParameterNames()
{
return Collections.enumeration(_parameterMap.keySet());
}
public String[] getParameterValues(String name)
{
return (String[]) _parameterMap.get(name);
}
public String toString()
{
return "<UploadFormPartWrapper for " + getRequest() + ">";
}
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/MultipartDecoder.java
Index: MultipartDecoder.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import javax.servlet.http.HttpServletRequest;
import org.apache.tapestry.request.IUploadFile;
/**
* Responsible for detecting and processing file upload requests, using Jakarta Commons FileUpload.
* Implementations of this service typically use the threaded service lifecycle model.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public interface MultipartDecoder
{
/**
* Decodes the request, returning a new {@link javax.servlet.http.HttpServletRequest}
* implementation that will allow access to the form fields submitted in the request (but omits
* uploaded files.
*/
public HttpServletRequest decode(HttpServletRequest request);
/**
* Gets a file upload with the given name, or returns null if no such file upload was in the
* request.
*/
public IUploadFile getFileUpload(String parameterName);
/**
* Cleans up any temporary resources created during the request processing. This typically
* includes temporary files used to contain uploaded file content.
*/
public void cleanup();
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/multipart/MultipartMessages.java
Index: MultipartMessages.java
===================================================================
// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.multipart;
import java.io.File;
import org.apache.hivemind.impl.MessageFormatter;
/**
* @author Howard M. Lewis Ship
* @since 3.1
*/
class MultipartMessages
{
private static final MessageFormatter _formatter = new MessageFormatter(
MultipartMessages.class, "MultipartStrings");
public static String unableToDecode(Throwable cause)
{
return _formatter.format("unable-to-decode", cause);
}
public static String unsupportedEncoding(String encoding, Throwable cause)
{
return _formatter.format("unsupported-encoding", encoding, cause);
}
public static String unableToOpenContentFile(UploadPart part, Throwable cause)
{
return _formatter.format("unable-to-open-content-file", part.getFilePath(), cause);
}
public static String writeFailure(File file, Throwable cause)
{
return _formatter.format("write-failure", file, cause);
}
}
1.4 +20 -15 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Upload.java
Index: Upload.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Upload.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Upload.java 5 Jan 2005 23:17:13 -0000 1.3
+++ Upload.java 26 Feb 2005 00:50:32 -0000 1.4
@@ -17,39 +17,42 @@
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.multipart.MultipartDecoder;
import org.apache.tapestry.request.IUploadFile;
/**
- * Form element used to upload files. For the momement, it is necessary to
- * explicitly set the form's enctype to "multipart/form-data".
+ * Form element used to upload files. For the momement, it is necessary to explicitly set the form's
+ * enctype to "multipart/form-data". [ <a
+ * href="../../../../../ComponentReference/Upload.html">Component Reference </a>]
*
- * [<a href="../../../../../ComponentReference/Upload.html">Component Reference</a>]
- *
- * @author Howard Lewis Ship
- * @since 1.0.8
- *
- **/
+ * @author Howard Lewis Ship
+ * @since 1.0.8
+ */
public abstract class Upload extends AbstractFormComponent
{
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
IForm form = getForm(cycle);
-
+
String name = form.getElementId(this);
if (form.isRewinding())
{
- if (!isDisabled())
- setFile(cycle.getRequestContext().getUploadFile(name));
+ if (!isDisabled())
+ {
+ IUploadFile file = getDecoder().getFileUpload(name);
+
+ setFile(file);
+ }
return;
}
- // Force the form to use the correct encoding type for
- // file uploads.
-
- form.setEncodingType("multipart/form-data");
+ // Force the form to use the correct encoding type for
+ // file uploads.
+
+ form.setEncodingType("multipart/form-data");
writer.beginEmpty("input");
writer.attribute("type", "file");
@@ -68,4 +71,6 @@
public abstract boolean isDisabled();
public abstract void setFile(IUploadFile file);
+
+ public abstract MultipartDecoder getDecoder();
}
\ No newline at end of file
1.4 +2 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Upload.jwc
Index: Upload.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Upload.jwc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Upload.jwc 27 Jan 2005 05:35:51 -0000 1.3
+++ Upload.jwc 26 Feb 2005 00:50:32 -0000 1.4
@@ -38,4 +38,6 @@
<reserved-parameter name="type"/>
<reserved-parameter name="name"/>
+ <inject property="decoder" object="service:tapestry.multipart.MultipartDecoder"/>
+
</component-specification>
1.9 +1 -119 jakarta-tapestry/framework/src/java/org/apache/tapestry/request/RequestContext.java
Index: RequestContext.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/request/RequestContext.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- RequestContext.java 25 Feb 2005 21:26:27 -0000 1.8
+++ RequestContext.java 26 Feb 2005 00:50:32 -0000 1.9
@@ -39,9 +39,6 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRender;
import org.apache.tapestry.IRequestCycle;
-import org.apache.tapestry.Tapestry;
-import org.apache.tapestry.multipart.DefaultMultipartDecoder;
-import org.apache.tapestry.multipart.IMultipartDecoder;
import org.apache.tapestry.spec.IApplicationSpecification;
/**
@@ -93,10 +90,6 @@
private HttpServlet _servlet;
- private IMultipartDecoder _decoder;
-
- private boolean _decoded;
-
private IApplicationSpecification _specification;
/**
@@ -123,40 +116,6 @@
_request = request;
_response = response;
_specification = specification;
-
- // All three parameters may be null if created from
- // AbstractEngine.cleanupEngine().
-
- if (_request != null && DefaultMultipartDecoder.isMultipartRequest(request))
- {
- IMultipartDecoder decoder = obtainMultipartDecoder(servlet, request);
- setDecoder(decoder);
- }
- }
-
- /**
- * Invoked from the constructor to create a {@link DefaultMultipartDecoder}instance.
- * Applications with specific upload needs may need to override this to provide a subclass
- * instance instead. The caller will invoke {@link IMultipartDecoder#decode(HttpServletRequest)}
- * on the returned object.
- * <p>
- * This implementation checks for application extension
- * {@link Tapestry#MULTIPART_DECODER_EXTENSION_NAME}. If that is not defined, a shared instance
- * of {@link DefaultMultipartDecoder}is returned.
- *
- * @see ApplicationServlet#createRequestContext(HttpServletRequest, HttpServletResponse)
- * @since 3.0
- */
-
- protected IMultipartDecoder obtainMultipartDecoder(HttpServlet servlet,
- HttpServletRequest request) throws IOException
- {
- if (_specification.checkExtension(Tapestry.MULTIPART_DECODER_EXTENSION_NAME))
- return (IMultipartDecoder) _specification.getExtension(
- Tapestry.MULTIPART_DECODER_EXTENSION_NAME,
- IMultipartDecoder.class);
-
- return DefaultMultipartDecoder.getSharedInstance();
}
/**
@@ -195,9 +154,6 @@
pair(writer, name, new Date(value));
}
-
-
-
/**
* Builds an absolute URL from the given URI, using the {@link HttpServletRequest}as the source
* for scheme, server name and port.
@@ -255,7 +211,7 @@
buffer.append(scheme);
buffer.append("://");
buffer.append(server);
-
+
if (port > 0)
{
buffer.append(':');
@@ -315,10 +271,6 @@
public String getParameter(String name)
{
- IMultipartDecoder decoder = getDecoder();
- if (decoder != null)
- return decoder.getString(_request, name);
-
return _request.getParameter(name);
}
@@ -342,19 +294,11 @@
public String[] getParameters(String name)
{
- IMultipartDecoder decoder = getDecoder();
- if (decoder != null)
- return decoder.getStrings(_request, name);
-
return _request.getParameterValues(name);
}
public String[] getParameterNames()
{
- IMultipartDecoder decoder = getDecoder();
- if (decoder != null)
- return decoder.getStringParameterNames(_request);
-
Enumeration e = _request.getParameterNames();
List names = new ArrayList();
@@ -369,35 +313,6 @@
}
/**
- * Returns the named {@link IUploadFile}, if it exists, or null if it doesn't. Uploads require
- * an encoding of <code>multipart/form-data</code> (this is specified in the form's enctype
- * attribute). If the encoding type is not so, or if no upload matches the name, then this
- * method returns null.
- */
-
- public IUploadFile getUploadFile(String name)
- {
- IMultipartDecoder decoder = getDecoder();
- if (decoder == null)
- return null;
-
- return decoder.getUploadFile(_request, name);
- }
-
- /**
- * Invoked at the end of the request cycle to cleanup and temporary resources. This is chained
- * to the {@link DefaultMultipartDecoder}, if there is one.
- *
- * @since 2.0.1
- */
-
- public void cleanup()
- {
- if (_decoder != null)
- _decoder.cleanup(_request);
- }
-
- /**
* Returns the request which initiated the current request cycle. Note that the methods
* {@link #getParameter(String)}and {@link #getParameters(String)}should be used, rather than
* obtaining parameters directly from the request (since the RequestContext handles the
@@ -921,39 +836,6 @@
}
/**
- * Returns the multipart decoder and lazily decodes the request parameters. This allows both for
- * this operation to be performed only when really needed and for opening the request for
- * reading much later, so that the Engine can have a chance to set the encoding that the request
- * needs to use.
- *
- * @return the multipart decoder or null if not needed for this request
- * @since 3.0
- */
- private IMultipartDecoder getDecoder()
- {
- if (_decoder != null && !_decoded)
- {
- _decoder.decode(_request);
- _decoded = true;
- }
-
- return _decoder;
- }
-
- /**
- * Sets the multipart decoder to be used for the request.
- *
- * @param decoder
- * the multipart decoder
- * @since 3.0
- */
- public void setDecoder(IMultipartDecoder decoder)
- {
- _decoder = decoder;
- _decoded = false;
- }
-
- /**
* @since 3.1 --- but probably pretty temporary!
*/
public IApplicationSpecification getApplicationSpecification()
1.4 +9 -8 jakarta-tapestry/framework/src/java/org/apache/tapestry/services/impl/InvokeEngineTerminator.java
Index: InvokeEngineTerminator.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/services/impl/InvokeEngineTerminator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- InvokeEngineTerminator.java 5 Jan 2005 23:16:57 -0000 1.3
+++ InvokeEngineTerminator.java 26 Feb 2005 00:50:33 -0000 1.4
@@ -13,6 +13,7 @@
// limitations under the License.
package org.apache.tapestry.services.impl;
+
import java.io.IOException;
import javax.servlet.ServletException;
@@ -29,22 +30,24 @@
import org.apache.tapestry.spec.IApplicationSpecification;
/**
- * The terminatior for the <code>tapestry.RequestProcessor</code> pipeline,
- * this service is responsible for locating the correct engine instance and
- * letting it to the rest of the request.
- *
+ * The terminatior for the <code>tapestry.RequestProcessor</code> pipeline, this service is
+ * responsible for locating the correct engine instance and letting it to the rest of the request.
+ *
* @author Howard Lewis Ship
* @since 3.1
*/
public class InvokeEngineTerminator implements RequestServicer
{
private HttpServlet _servlet;
+
private EngineManager _engineManager;
+
private IApplicationSpecification _specification;
+
private Infrastructure _infrastructure;
public void service(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException
+ throws IOException, ServletException
{
IEngine engine = _engineManager.getEngineInstance();
@@ -59,8 +62,6 @@
finally
{
_engineManager.storeEngineInstance(engine);
-
- context.cleanup();
}
}
@@ -85,4 +86,4 @@
_infrastructure = infrastructure;
}
-}
+}
\ No newline at end of file
1.10 +0 -14 jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/configuration.xml
Index: configuration.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/configuration.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- configuration.xml 8 Feb 2005 21:09:55 -0000 1.9
+++ configuration.xml 26 Feb 2005 00:50:33 -0000 1.10
@@ -694,20 +694,6 @@
(perhaps in a database), or constructed on the fly.
</td></tr>
-
-
-<tr><td>org.apache.tapestry.multipart-decoder </td> <td>&IMultipartDecoder;</td>
-
-<td>
-Allows an alternate object to be responsible for decoding multipart requests (context
-type multipart/form-data, used for file uploads). Generally, this is used to
-configure an instance of &DefaultMultipartDecoder; with non-default values for
-the maximum upload size, threshold size (number of bytes before a temporary file is created
-to store the) and repository directory (where temporary files are stored).
-</td></tr>
-
-
-
<tr><td>org.apache.tapestry.ognl-type-converter</td> <td>ognl.TypeConverter</td>
<td>
1.28 +1 -0 jakarta-tapestry/framework/src/descriptor/META-INF/hivemodule.xml
Index: hivemodule.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/descriptor/META-INF/hivemodule.xml,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- hivemodule.xml 25 Feb 2005 18:01:31 -0000 1.27
+++ hivemodule.xml 26 Feb 2005 00:50:33 -0000 1.28
@@ -40,6 +40,7 @@
<sub-module descriptor="tapestry.asset.xml"/>
<sub-module descriptor="tapestry.persist.xml"/>
<sub-module descriptor="tapestry.state.xml"/>
+ <sub-module descriptor="tapestry.multipart.xml"/>
<service-point id="ClasspathResourceFactory" interface="ClasspathResourceFactory">
1.1 jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.multipart.xml
Index: tapestry.multipart.xml
===================================================================
<?xml version="1.0"?>
<!--
Copyright 2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<module id="tapestry.multipart" version="3.1.0" package="org.apache.tapestry.multipart">
Support for multipart/form-data encoded requests used for file uploads.
<service-point id="MultipartDecoder" interface="MultipartDecoder">
Service responsible for parsing and decoding multipart form submissions.
<create-instance class="MultipartDecoderImpl" model="threaded"/>
</service-point>
<service-point id="MultipartDecoderFilter" interface="org.apache.tapestry.services.RequestServicerFilter">
Identifies upload requests and passes them to the MultipartDecoder service
for decoding.
<invoke-factory>
<construct class="MultipartDecoderFilter">
<set-service property="decoder" service-id="MultipartDecoder"/>
</construct>
</invoke-factory>
</service-point>
<contribution configuration-id="tapestry.request.RequestServicerPipeline">
<filter name="MultipartDecoderFilter" object="service:MultipartDecoderFilter"/>
</contribution>
</module>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org