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 2008/07/29 22:01:55 UTC
svn commit: r680819 - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry5/
tapestry-core/src/main/java/org/apache/tapestry5/annotations/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/
tapestry-core/src/main/...
Author: hlship
Date: Tue Jul 29 13:01:53 2008
New Revision: 680819
URL: http://svn.apache.org/viewvc?rev=680819&view=rev
Log:
TAPESTRY-2543: Simplify Tapestry to use UTF-8 (or another, configurable character set) across the entire application
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ResponseEncoding.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestEncodingInitializerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ResponseEncodingWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestEncodingInitializerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ResponseEncodingWorkerTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/MetaDataConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/StreamResponse.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ContentType.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/Autocomplete.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientPersistentFieldStorageImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventDispatcher.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONObjectEventResultProcessor.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterFactoryImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MessagesSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventRequestFilter.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventDispatcherTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java
tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImpl.java
tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/ParametersServletRequestWrapper.java
tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java Tue Jul 29 13:01:53 2008
@@ -14,6 +14,7 @@
package org.apache.tapestry5;
+import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
@@ -53,6 +54,17 @@
}
/**
+ * Creates a new content type with the given MIME type and charset
+ */
+ public ContentType(String contentType, String charset)
+ {
+ this(contentType);
+
+ setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, charset);
+ }
+
+
+ /**
* Returns true only if the other object is another instance of ContentType, and has the ssame baseType, subType and
* set of parameters.
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/MetaDataConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/MetaDataConstants.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/MetaDataConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/MetaDataConstants.java Tue Jul 29 13:01:53 2008
@@ -1,3 +1,17 @@
+// Copyright 2008 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.tapestry5;
/**
@@ -12,14 +26,9 @@
* "text/html" when not overridden.
*/
public static final String RESPONSE_CONTENT_TYPE = "tapestry.response-content-type";
+
/**
* Meta data key applied to pages that may only be accessed via secure methods (HTTPS).
*/
public static final String SECURE_PAGE = "tapestry.secure-page";
- /**
- * Meta data key applied to pages that sets the response encoding. A factory default provides the value "UTF-8" when
- * not overriden. Content type may also be specified in the {@link #RESPONSE_CONTENT_TYPE content type} as parameter
- * "charset", i.e., "text/html;charset=UTF-8".
- */
- public static final String RESPONSE_ENCODING = "tapestry.response-encoding";
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/StreamResponse.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/StreamResponse.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/StreamResponse.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/StreamResponse.java Tue Jul 29 13:01:53 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -39,8 +39,8 @@
/**
- * Prepare response before it is sent to the client. This is the place to set any response headers (e.g.
- * content-disposition)
+ * Prepares the response before it is sent to the client. This is the place to set any response headers (e.g.
+ * content-disposition).
*
* @param response Response that will be sent.
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java Tue Jul 29 13:01:53 2008
@@ -26,34 +26,41 @@
* exceptions are reported.
*/
public static final String PRODUCTION_MODE = "tapestry.production-mode";
+
/**
* Symbol which may be set to "true" to force the use of absolute URIs (not relative URIs) exclusively.
*/
public static final String FORCE_ABSOLUTE_URIS = "tapestry.force-absolute-uris";
+
/**
* If set to true, then action requests will render a page markup response immediately, rather than sending a
* redirect to render the response.
*/
public static final String SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS = "tapestry.suppress-redirect-from-action-requests";
+
/**
* The list of locales supported by the application; locales identified in the incoming request are "narrowed" to
* one of these values.
*/
public static final String SUPPORTED_LOCALES = "tapestry.supported-locales";
+
/**
* Controls whether whitespace is compressed by default in templates, or left as is. The factory default is to
* compress whitespace. This can be overridden using the xml:space attribute inside template elements.
*/
public static final String COMPRESS_WHITESPACE = "tapestry.compress-whitespace";
+
/**
* Time interval defining how often Tapestry will check for updates to local files (including classes). This number
* can be raised in a production environment.
*/
public static final String FILE_CHECK_INTERVAL = "tapestry.file-check-interval";
+
/**
* Time interval that sets how long Tapestry will wait to obtain the exclusive lock needed to check local files.
*/
public static final String FILE_CHECK_UPDATE_TIMEOUT = "tapestry.file-check-update-timeout";
+
/**
* The version number of the core Tapestry framework, or UNKNOWN if the version number is not available (which
* should only occur when developing Tapestry).
@@ -65,4 +72,10 @@
* will normally be <code>WEB-INF/app.properties</code>.
*/
public static final String APPLICATION_CATALOG = "tapestry.app-catalog";
+
+ /**
+ * The charset used when rendering page markup; the charset is also used as ther request encoding when handling
+ * incoming requests. The default is "UTF-8".
+ */
+ public static final String CHARSET = "tapestry.charset";
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ContentType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ContentType.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ContentType.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/ContentType.java Tue Jul 29 13:01:53 2008
@@ -21,10 +21,8 @@
* An annotation on a page component used to identify the content type the page returns. An alternative to the {@link
* org.apache.tapestry5.annotations.Meta} annotation with the {@link org.apache.tapestry5.MetaDataConstants#RESPONSE_CONTENT_TYPE}
* key.
- *
- * @see org.apache.tapestry5.annotations.ResponseEncoding
*/
-@Target({ ElementType.TYPE })
+@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ContentType
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/Autocomplete.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/Autocomplete.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/Autocomplete.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/Autocomplete.java Tue Jul 29 13:01:53 2008
@@ -188,7 +188,7 @@
}
};
- resources.triggerEvent("providecompletions", new Object[] { input }, callback);
+ resources.triggerEvent("providecompletions", new Object[]{input}, callback);
ContentType contentType = responseRenderer.findContentType(this);
@@ -196,7 +196,7 @@
generateResponseMarkup(writer, matchesHolder.get());
- return new TextStreamResponse(contentType.getMimeType(), writer.toString());
+ return new TextStreamResponse(contentType.toString(), writer.toString());
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java Tue Jul 29 13:01:53 2008
@@ -16,7 +16,10 @@
import org.apache.tapestry5.ContentType;
import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.MarkupWriterFactory;
import org.apache.tapestry5.services.PartialMarkupRenderer;
@@ -36,13 +39,24 @@
private final PartialMarkupRenderer partialMarkupRenderer;
- public AjaxPartialResponseRendererImpl(MarkupWriterFactory factory, Request request,
- Response response, PartialMarkupRenderer partialMarkupRenderer)
+ private final String outputEncoding;
+
+ public AjaxPartialResponseRendererImpl(MarkupWriterFactory factory,
+
+ Request request,
+
+ Response response,
+
+ PartialMarkupRenderer partialMarkupRenderer,
+
+ @Inject @Symbol(SymbolConstants.CHARSET)
+ String outputEncoding)
{
this.factory = factory;
this.request = request;
this.response = response;
this.partialMarkupRenderer = partialMarkupRenderer;
+ this.outputEncoding = outputEncoding;
}
public void renderPartialPageMarkup() throws IOException
@@ -51,12 +65,10 @@
// seperated, and trying to keep stateless and stateful (i.e., perthread scope) services
// seperated. So we inform the stateful queue service what it needs to do here ...
- ContentType pageContentType = (ContentType) request.getAttribute(
- InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME);
- String charset = pageContentType.getParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER);
+ ContentType pageContentType =
+ (ContentType) request.getAttribute(InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME);
- ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE);
- contentType.setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, charset);
+ ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE, outputEncoding);
MarkupWriter writer = factory.newMarkupWriter(pageContentType);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientPersistentFieldStorageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientPersistentFieldStorageImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientPersistentFieldStorageImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientPersistentFieldStorageImpl.java Tue Jul 29 13:01:53 2008
@@ -117,6 +117,9 @@
public ClientPersistentFieldStorageImpl(Request request)
{
+ // This, here, is the problem of TAPESTRY-2501; this call can predate
+ // the check to set the character set based on meta data of the page.
+
String value = request.getParameter(PARAMETER_NAME);
// MIME can encode to a '+' character; the browser converts that to a space; we convert it
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventDispatcher.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventDispatcher.java Tue Jul 29 13:01:53 2008
@@ -51,19 +51,19 @@
private final ContextValueEncoder contextValueEncoder;
- private final RequestEncodingInitializer requestEncodingInitializer;
-
private final EventContext emptyContext = new EmptyEventContext();
- public ComponentEventDispatcher(@Traditional ComponentEventRequestHandler componentEventRequestHandler,
- ComponentClassResolver componentClassResolver,
- ContextValueEncoder contextValueEncoder,
- RequestEncodingInitializer requestEncodingInitializer)
+ public ComponentEventDispatcher(
+ @Traditional
+ ComponentEventRequestHandler componentEventRequestHandler,
+
+ ComponentClassResolver componentClassResolver,
+
+ ContextValueEncoder contextValueEncoder)
{
this.componentEventRequestHandler = componentEventRequestHandler;
this.componentClassResolver = componentClassResolver;
this.contextValueEncoder = contextValueEncoder;
- this.requestEncodingInitializer = requestEncodingInitializer;
}
// A beast that recognizes all the elements of a path in a single go.
@@ -109,11 +109,6 @@
EventContext eventContext = decodeContext(matcher.group(CONTEXT));
- // Initialize the request encoding BEFORE accessing any query parameters
- // (TAPESTRY-1605)
-
- requestEncodingInitializer.initializeRequestEncoding(activePageName);
-
EventContext activationContext = decodeContext(request.getParameter(InternalConstants.PAGE_CONTEXT_NAME));
// The event type is often omitted, and defaults to "action".
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java Tue Jul 29 13:01:53 2008
@@ -76,7 +76,6 @@
binder.bind(PageElementFactory.class, PageElementFactoryImpl.class);
binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class);
binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class);
- binder.bind(RequestEncodingInitializer.class, RequestEncodingInitializerImpl.class);
binder.bind(PageRenderQueue.class, PageRenderQueueImpl.class);
binder.bind(AjaxPartialResponseRenderer.class, AjaxPartialResponseRendererImpl.class);
binder.bind(PageContentTypeAnalyzer.class, PageContentTypeAnalyzerImpl.class);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONObjectEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONObjectEventResultProcessor.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONObjectEventResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONObjectEventResultProcessor.java Tue Jul 29 13:01:53 2008
@@ -14,7 +14,11 @@
package org.apache.tapestry5.internal.services;
+import org.apache.tapestry5.ContentType;
+import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.ComponentEventResultProcessor;
import org.apache.tapestry5.services.Response;
@@ -32,14 +36,22 @@
{
private final Response response;
- public JSONObjectEventResultProcessor(Response response)
+ private final String outputEncoding;
+
+ public JSONObjectEventResultProcessor(Response response,
+
+ @Inject @Symbol(SymbolConstants.CHARSET)
+ String outputEncoding)
{
this.response = response;
+ this.outputEncoding = outputEncoding;
}
public void processResultValue(JSONObject value) throws IOException
{
- PrintWriter pw = response.getPrintWriter(InternalConstants.JSON_MIME_TYPE);
+ ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE, outputEncoding);
+
+ PrintWriter pw = response.getPrintWriter(contentType.toString());
pw.print(value.toString());
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterFactoryImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterFactoryImpl.java Tue Jul 29 13:01:53 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -19,6 +19,7 @@
import org.apache.tapestry5.dom.DefaultMarkupModel;
import org.apache.tapestry5.dom.MarkupModel;
import org.apache.tapestry5.dom.XMLMarkupModel;
+import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.services.MarkupWriterFactory;
public class MarkupWriterFactoryImpl implements MarkupWriterFactory
@@ -36,7 +37,7 @@
// The charset parameter sets the encoding attribute of the XML declaration, if
// not null and if using the XML model.
- return new MarkupWriterImpl(model, contentType.getParameter("charset"));
+ return new MarkupWriterImpl(model, contentType.getParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER));
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MessagesSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MessagesSourceImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MessagesSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MessagesSourceImpl.java Tue Jul 29 13:01:53 2008
@@ -36,7 +36,7 @@
* any keys inherited form base components and, ultimately, the application global message catalog. At some point we
* should add support for per-library message catalogs.
* <p/>
- * Message catalogs are read using the utf-8 character set. This is tricky in JDK 1.5; we read the file into memory then
+ * Message catalogs are read using the UTF-8 character set. This is tricky in JDK 1.5; we read the file into memory then
* feed that bytestream to Properties.load().
*/
public class MessagesSourceImpl extends InvalidationEventHubImpl implements MessagesSource
@@ -215,9 +215,7 @@
try
{
- is = resource.openStream();
-
- is = readStreamAsUTF8(is);
+ is = readStreamAsUTF8(resource.openStream());
// Ok, now we have the content read into memory as UTF-8, not ASCII.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java Tue Jul 29 13:01:53 2008
@@ -17,17 +17,25 @@
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.ContentType;
import org.apache.tapestry5.MetaDataConstants;
-import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.services.MetaDataLocator;
public class PageContentTypeAnalyzerImpl implements PageContentTypeAnalyzer
{
private final MetaDataLocator metaDataLocator;
- public PageContentTypeAnalyzerImpl(MetaDataLocator metaDataLocator)
+ private final String outputCharset;
+
+ public PageContentTypeAnalyzerImpl(MetaDataLocator metaDataLocator,
+
+ @Inject @Symbol(SymbolConstants.CHARSET)
+ String outputCharset)
{
this.metaDataLocator = metaDataLocator;
+ this.outputCharset = outputCharset;
}
public ContentType findContentType(Page page)
@@ -36,19 +44,9 @@
String contentTypeString = metaDataLocator.findMeta(MetaDataConstants.RESPONSE_CONTENT_TYPE, pageResources,
String.class);
- ContentType contentType = new ContentType(contentTypeString);
-
- // Make sure thre's always a charset specified.
-
- String encoding = contentType.getParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER);
- if (encoding == null)
- {
- encoding = metaDataLocator
- .findMeta(MetaDataConstants.RESPONSE_ENCODING, pageResources, String.class);
- contentType.setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, encoding);
- }
+ // Draconian but necessary: overwrite the content type they selected with the application-wide output charset.
- return contentType;
+ return new ContentType(contentTypeString, outputCharset);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java Tue Jul 29 13:01:53 2008
@@ -36,13 +36,20 @@
private final HttpServletRequest request;
- public RequestImpl(HttpServletRequest request)
+ private final String requestEncoding;
+
+ private boolean encodingSet;
+
+ public RequestImpl(HttpServletRequest request, String requestEncoding)
{
this.request = request;
+ this.requestEncoding = requestEncoding;
}
public List<String> getParameterNames()
{
+ setupEncoding();
+
return InternalUtils.toList(request.getParameterNames());
}
@@ -53,11 +60,15 @@
public String getParameter(String name)
{
+ setupEncoding();
+
return request.getParameter(name);
}
public String[] getParameters(String name)
{
+ setupEncoding();
+
return request.getParameterValues(name);
}
@@ -100,8 +111,10 @@
return request.getDateHeader(name);
}
- public void setEncoding(String requestEncoding)
+ private void setupEncoding()
{
+ if (encodingSet) return;
+
try
{
request.setCharacterEncoding(requestEncoding);
@@ -110,8 +123,11 @@
{
throw new RuntimeException(ex);
}
+
+ encodingSet = true;
}
+
public boolean isXHR()
{
return XML_HTTP_REQUEST.equals(request.getHeader(REQUESTED_WITH_HEADER));
@@ -141,4 +157,5 @@
{
return request.getServerName();
}
+
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventRequestFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventRequestFilter.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventRequestFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventRequestFilter.java Tue Jul 29 13:01:53 2008
@@ -20,8 +20,8 @@
* Filter interface for {@link ComponentEventRequestHandler}.
*
* @see org.apache.tapestry5.services.TapestryModule#contributeComponentEventRequestHandler(org.apache.tapestry5.ioc.OrderedConfiguration,
- * org.apache.tapestry5.internal.services.RequestEncodingInitializer, ComponentEventRequestHandler ,
- * org.apache.tapestry5.ioc.ObjectLocator) }
+ * org.apache.tapestry5.internal.services.RequestSecurityManager, ComponentEventRequestHandler,
+ * org.apache.tapestry5.ioc.ObjectLocator)
*/
public interface ComponentEventRequestFilter
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java Tue Jul 29 13:01:53 2008
@@ -93,13 +93,6 @@
String getHeader(String name);
/**
- * Sets the encoding of the request, which must occur before any parameters for the request are read.
- *
- * @param requestEncoding charset used when parsing parameters
- */
- void setEncoding(String requestEncoding);
-
- /**
* Returns true if the request originated on the client using XmlHttpRequest (the core of any Ajax behavior). Ajax
* action requests may behave quite differently than ordinary, page-based requests. This implementation currently
* depends on the client side setting a header: <strong>X-Requested-With=XMLHttpRequest</strong> (this is what
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Tue Jul 29 13:01:53 2008
@@ -286,8 +286,7 @@
* {@link org.apache.tapestry5.internal.InternalComponentResources#postRenderCleanup()} is invoked after a component
* finishes rendering</dd> <dt>Secure</dt> <dd>Checks for the {@link org.apache.tapestry5.annotations.Secure}
* annotation</dd> <dt>ContentType</dt> <dd>Checks for {@link org.apache.tapestry5.annotations.ContentType}
- * annotation</dd> <dt>ResponseEncoding</dt> <dd>Checks for the {@link org.apache.tapestry5.annotations.ResponseEncoding}
- * annotation</dd> <dt>GenerateAccessors</dt> <dd>Generates accessor methods if {@link
+ * annotation</dd> <dt>GenerateAccessors</dt> <dd>Generates accessor methods if {@link
* org.apache.tapestry5.annotations.Property} annotation is present </dd> <dt>Cached</dt> <dd>Checks for the {@link
* org.apache.tapestry5.annotations.Cached} annotation</dd><dt>Log</dt> <dd>Checks for the {@link
* org.apache.tapestry5.annotations.Log} annotation</dd></dl>
@@ -360,7 +359,6 @@
configuration.add("InvokePostRenderCleanupOnResources", new InvokePostRenderCleanupOnResourcesWorker());
configuration.add("ContentType", new ContentTypeWorker());
- configuration.add("ResponseEncoding", new ResponseEncodingWorker());
configuration.add("Property", new PropertyWorker());
@@ -898,10 +896,14 @@
}
public HttpServletRequestHandler buildHttpServletRequestHandler(Logger logger,
+
List<HttpServletRequestFilter> configuration,
@Primary
- final RequestHandler handler)
+ final RequestHandler handler,
+
+ @Inject @Symbol(SymbolConstants.CHARSET)
+ final String applicationCharset)
{
HttpServletRequestHandler terminator = new HttpServletRequestHandler()
{
@@ -910,7 +912,7 @@
{
requestGlobals.storeServletRequestResponse(servletRequest, servletResponse);
- Request request = new RequestImpl(servletRequest);
+ Request request = new RequestImpl(servletRequest, applicationCharset);
Response response = new ResponseImpl(servletResponse);
// Transition from the Servlet API-based pipeline, to the Tapestry-based pipeline.
@@ -1268,7 +1270,7 @@
{
configuration.add(RenderCommand.class, locator.autobuild(RenderCommandComponentEventResultProcessor.class));
configuration.add(Component.class, locator.autobuild(AjaxComponentInstanceEventResultProcessor.class));
- configuration.add(JSONObject.class, new JSONObjectEventResultProcessor(response));
+ configuration.add(JSONObject.class, locator.autobuild(JSONObjectEventResultProcessor.class));
configuration.add(StreamResponse.class, new StreamResponseResultProcessor(response));
}
@@ -1743,7 +1745,8 @@
configuration.add(PersistentFieldManagerImpl.META_KEY, PersistentFieldManagerImpl.DEFAULT_STRATEGY);
configuration.add(MetaDataConstants.RESPONSE_CONTENT_TYPE, "text/html");
- configuration.add(MetaDataConstants.RESPONSE_ENCODING, "UTF-8");
+
+ configuration.add(SymbolConstants.CHARSET, "UTF-8");
configuration.add(SymbolConstants.APPLICATION_CATALOG, "WEB-INF/${tapestry.app-name}.properties");
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt Tue Jul 29 13:01:53 2008
@@ -46,10 +46,9 @@
If the file <<<WEB-INF/>>><AppName><<<.properties>>> exists in the context, it will be used as an application-wide message catalog. The <AppName>
is derived from the name of the filter inside the web.xml file; this is most often just "app", thus <<<WEB-INF/app.properties>>>.
- The search for the file is case sensitive. The properties file may be localized.
+ The search for the file is case sensitive. The properties files may be localized.
- Individual pages and components
- can override the values defined in this message catalog.
+ Individual pages and components can override the values defined in the message catalog.
Localized Component Templates
@@ -169,10 +168,16 @@
This information is obtained from meta data on the page itself. Meta data is specified using the
{{{../../apidocs/org/apache/tapestry5/annotations/Meta.html}Meta}} annotation.
- First, the response content type is obtained via meta-data key "tapestry.response-content-type". This value defaults to "text/html".
+ The response content type is obtained via meta-data key "tapestry.response-content-type". This value defaults to "text/html".
+
+ As a convienence, the {{{../../apidocs/org/apache/tapestry5/annotations/ContentType.html}ContentType}} annotation can be used to specify the response
+ content type. The value attribute of the annotation is the content type.
+
+ The character set for all outgoing markup and all incoming requests is "UTF-8". UTF-8 is a version of Unicode where individual characters are encoded as one
+ or more bytes. Most western language characters (that is, typical ASCII characters) are encoded in a single byte. Accented characters or
+ non-western characters (such as Japanese, Arabic, etc.) may be encoded as two or more bytes.
+
- Next, the encoding is obtained via meta-data key "tapestry.response-encoding". This value defaults to "UTF-8". This is only necessary if
- the content type does not provide a charset parameter (i.e., "text/html;charset=ISO-8559-1"). The encoding becomes the charset.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventDispatcherTest.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventDispatcherTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventDispatcherTest.java Tue Jul 29 13:01:53 2008
@@ -41,24 +41,18 @@
ComponentEventRequestHandler handler = newComponentEventRequestHandler();
Request request = mockRequest();
Response response = mockResponse();
- RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
train_getPath(request, "/foo/bar/baz");
replay();
- Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, null, requestEncodingInitializer);
+ Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, null);
assertFalse(dispatcher.dispatch(request, response));
verify();
}
- protected final RequestEncodingInitializer mockRequestEncodingInitializer()
- {
- return newMock(RequestEncodingInitializer.class);
- }
-
protected final ComponentEventRequestHandler newComponentEventRequestHandler()
{
return newMock(ComponentEventRequestHandler.class);
@@ -138,16 +132,14 @@
Request request = mockRequest();
Response response = mockResponse();
ComponentClassResolver resolver = mockComponentClassResolver();
- RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
-
ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("mypage", "mypage", "",
"eventname",
new URLEventContext(
contextValueEncoder,
- new String[] {
+ new String[]{
"alpha",
- "beta" }),
+ "beta"}),
new EmptyEventContext());
train_getPath(request, "/mypage:eventname");
@@ -158,14 +150,12 @@
train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, null);
- requestEncodingInitializer.initializeRequestEncoding("mypage");
-
handler.handle(expectedParameters);
replay();
- Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
- requestEncodingInitializer);
+ Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder
+ );
assertTrue(dispatcher.dispatch(request, response));
@@ -179,7 +169,6 @@
Request request = mockRequest();
Response response = mockResponse();
ComponentClassResolver resolver = mockComponentClassResolver();
- RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("activepage", "mypage",
"", "eventname",
@@ -190,8 +179,6 @@
train_isPageName(resolver, "activepage", true);
- requestEncodingInitializer.initializeRequestEncoding("activepage");
-
train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, "mypage");
@@ -200,8 +187,8 @@
replay();
- Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
- requestEncodingInitializer);
+ Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder
+ );
assertTrue(dispatcher.dispatch(request, response));
@@ -215,7 +202,6 @@
Request request = mockRequest();
Response response = mockResponse();
ComponentClassResolver resolver = mockComponentClassResolver();
- RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
train_getPath(request, "/mypage.foo");
@@ -223,7 +209,7 @@
replay();
- Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, null, requestEncodingInitializer);
+ Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, null);
assertFalse(dispatcher.dispatch(request, response));
@@ -237,7 +223,6 @@
Request request = mockRequest();
Response response = mockResponse();
ComponentClassResolver resolver = mockComponentClassResolver();
- RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters(containerPageName,
containerPageName,
@@ -256,14 +241,12 @@
train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, null);
- requestEncodingInitializer.initializeRequestEncoding(containerPageName);
-
handler.handle(expectedParameters);
replay();
- Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
- requestEncodingInitializer);
+ Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder
+ );
assertTrue(dispatcher.dispatch(request, response));
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java Tue Jul 29 13:01:53 2008
@@ -23,9 +23,12 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
+import java.util.Collections;
public class RequestImplTest extends InternalBaseTestCase
{
+ public static final String CHARSET = "UTF-8";
+
@Test
public void get_session_doesnt_exist()
{
@@ -35,7 +38,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
assertNull(request.getSession(false));
@@ -54,7 +57,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
Session session = request.getSession(true);
assertEquals(session.getAttribute("foo"), "bar");
@@ -71,9 +74,11 @@
sr.setCharacterEncoding(encoding);
+ expect(sr.getParameterNames()).andReturn(Collections.enumeration(Collections.EMPTY_LIST));
+
replay();
- new RequestImpl(sr).setEncoding(encoding);
+ new RequestImpl(sr, encoding).getParameterNames();
verify();
}
@@ -93,7 +98,7 @@
try
{
- new RequestImpl(sr).setEncoding(encoding);
+ new RequestImpl(sr, encoding).getParameterNames();
unreachable();
}
catch (RuntimeException ex)
@@ -113,7 +118,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
assertEquals(request.isXHR(), expected);
@@ -139,7 +144,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
assertEquals(request.getPath(), path);
@@ -160,7 +165,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
assertEquals(request.getPath(), path);
@@ -178,7 +183,7 @@
replay();
- Request request = new RequestImpl(sr);
+ Request request = new RequestImpl(sr, CHARSET);
assertEquals(request.getPath(), "/");
Modified: tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImpl.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImpl.java Tue Jul 29 13:01:53 2008
@@ -19,6 +19,7 @@
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -48,6 +49,8 @@
private final long maxFileSize;
+ private final String requestEncoding;
+
public MultipartDecoderImpl(
@Inject @Symbol(UploadSymbols.REPOSITORY_LOCATION)
@@ -60,12 +63,16 @@
long maxRequestSize,
@Symbol(UploadSymbols.FILESIZE_MAX)
- long maxFileSize)
+ long maxFileSize,
+
+ @Inject @Symbol(SymbolConstants.CHARSET)
+ String requestEncoding)
{
this.repositoryLocation = repositoryLocation;
this.repositoryThreshold = repositoryThreshold;
this.maxRequestSize = maxRequestSize;
this.maxFileSize = maxFileSize;
+ this.requestEncoding = requestEncoding;
}
public UploadedFile getFileUpload(String parameterName)
@@ -75,6 +82,15 @@
public HttpServletRequest decode(HttpServletRequest request)
{
+ try
+ {
+ request.setCharacterEncoding(requestEncoding);
+ }
+ catch (UnsupportedEncodingException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
List<FileItem> fileItems = parseRequest(request);
return processFileItems(request, fileItems);
@@ -122,8 +138,6 @@
ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);
- String encoding = request.getCharacterEncoding();
-
for (FileItem item : fileItems)
{
if (item.isFormField())
@@ -133,12 +147,11 @@
try
{
- fieldValue = encoding == null ? item.getString() : item.getString(encoding);
+ fieldValue = item.getString(requestEncoding);
}
- catch (UnsupportedEncodingException e)
+ catch (UnsupportedEncodingException ex)
{
- // TODO maybe log exception with level warn
- fieldValue = item.getString();
+ throw new RuntimeException(ex);
}
wrapper.addParameter(item.getFieldName(), fieldValue);
Modified: tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/ParametersServletRequestWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/ParametersServletRequestWrapper.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/ParametersServletRequestWrapper.java (original)
+++ tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry5/upload/internal/services/ParametersServletRequestWrapper.java Tue Jul 29 13:01:53 2008
@@ -15,7 +15,6 @@
package org.apache.tapestry5.upload.internal.services;
import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
-import org.apache.tapestry5.services.Dispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@@ -92,9 +91,10 @@
}
/**
- * Ignores any attempt to set the character encoding. Tapestry attempts to set the encoding <em>after</em> the page
- * name has been identified by the correct {@link Dispatcher}, and that's too late from the perspective of the
- * Servlet API as HttpServlet.getInputStream() will already have been called.
+ * Ignores any attempt to set the character encoding, as it already has been set before the request content was
+ * parsed.
+ *
+ * @see org.apache.tapestry5.SymbolConstants#CHARSET
*/
@Override
public void setCharacterEncoding(String enc) throws UnsupportedEncodingException
Modified: tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImplTest.java?rev=680819&r1=680818&r2=680819&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry5/upload/internal/services/MultipartDecoderImplTest.java Tue Jul 29 13:01:53 2008
@@ -28,10 +28,12 @@
public class MultipartDecoderImplTest extends TapestryTestCase
{
+ private static final String CHARSET = "UTF-8";
+
@Test
public void create_file_upload_gets_configuration_from_symbols() throws Exception
{
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, 7777, 6666);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, 7777, 6666, CHARSET);
replay();
@@ -48,7 +50,7 @@
public void process_file_items_does_nothing_when_null_file_items() throws Exception
{
HttpServletRequest request = mockHttpServletRequest();
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
replay();
@@ -63,7 +65,7 @@
public void process_file_items_does_nothing_when_empty_file_items() throws Exception
{
HttpServletRequest request = mockHttpServletRequest();
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
List<FileItem> fileItems = Collections.emptyList();
replay();
@@ -82,7 +84,7 @@
train_getCharacterEncoding(request, "UTF-8");
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
List<FileItem> fileItems = Arrays.asList(createValueItem("one", "first"), createValueItem("two", "second"));
replay();
@@ -104,7 +106,7 @@
train_getCharacterEncoding(request, null);
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
List<FileItem> fileItems = Arrays.asList(createValueItem("one", "first"), createValueItem("two", "second"));
@@ -124,7 +126,7 @@
public void process_file_items_set_file_parameters_with_file_name() throws Exception
{
HttpServletRequest request = mockHttpServletRequest();
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
List<FileItem> fileItems = Arrays.asList(createFileItem("one", "first.txt"),
createFileItem("two", "second.txt"));
@@ -146,7 +148,7 @@
public void uploaded_file_stored() throws Exception
{
HttpServletRequest request = mockHttpServletRequest();
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
List<FileItem> fileItems = Arrays.asList(createFileItem("one", "first.txt"),
createFileItem("two", "second.txt"));
@@ -168,7 +170,7 @@
public void file_items_cleaned_up() throws Exception
{
HttpServletRequest request = mockHttpServletRequest();
- MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);
+ MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1, CHARSET);
StubFileItem firstItem = new StubFileItem("one");
firstItem.setFormField(false);
StubFileItem secondItem = new StubFileItem("two");