Author: hlship
Date: Sat Jul 19 10:50:21 2008
New Revision: 678192
URL: http://svn.apache.org/viewvc?rev=678192&view=rev
Log:
TAPESTRY-2525: Properties files in a message catalog should be read using UTF-8
encoding, rather than default encoding
Modified:
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/ServicesMessages.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/localization.apt
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=678192&r1=678191&r2=678192&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
Sat Jul 19 10:50:21 2008
@@ -23,7 +23,7 @@
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.LocalizedNameGenerator;
-import java.io.InputStream;
+import java.io.*;
import java.util.*;
/**
@@ -31,6 +31,13 @@
* them, in accordance with extension rules and locale. This represents code
that was refactored out of [EMAIL PROTECTED]
* ComponentMessagesSourceImpl}. This class can be used as a base class,
though the existing code base uses it as a
* utility. Composition trumps inheritance!
+ * <p/>
+ * The message catalog for a component is the combination of all appropriate
properties files for the component, plus
+ * 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
+ * feed that bytestream to Properties.load().
*/
public class MessagesSourceImpl extends InvalidationEventHubImpl implements
MessagesSource
{
@@ -54,6 +61,16 @@
private final Map<String, String> emptyMap = Collections.emptyMap();
+ /**
+ * Charset used when reading a properties file.
+ */
+ private static final String CHARSET = "UTF-8";
+
+ /**
+ * Buffer size used when reading a properties file.
+ */
+ private static final int BUFFER_SIZE = 2000;
+
public MessagesSourceImpl(URLChangeTracker tracker)
{
this.tracker = tracker;
@@ -200,6 +217,10 @@
{
is = resource.openStream();
+ is = readStreamAsUTF8(is);
+
+ // Ok, now we have the content read into memory as UTF-8, not
ASCII.
+
p.load(is);
is.close();
@@ -226,4 +247,27 @@
return result;
}
+
+ private InputStream readStreamAsUTF8(InputStream is) throws IOException
+ {
+ Reader reader = new InputStreamReader(is, CHARSET);
+
+ StringBuilder builder = new StringBuilder(BUFFER_SIZE);
+ char[] buffer = new char[BUFFER_SIZE];
+
+ while (true)
+ {
+ int length = reader.read(buffer);
+
+ if (length < 0) break;
+
+ builder.append(buffer, 0, length);
+ }
+
+ reader.close();
+
+ byte[] resourceContent = builder.toString().getBytes(CHARSET);
+
+ return new ByteArrayInputStream(resourceContent);
+ }
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java?rev=678192&r1=678191&r2=678192&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
Sat Jul 19 10:50:21 2008
@@ -409,4 +409,9 @@
{
return MESSAGES.get("context-value-may-not-be-null");
}
+
+ static String forbidInstantiateComponentClass(String className)
+ {
+ return MESSAGES.format("forbid-instantiate-component-class",
className);
+ }
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties?rev=678192&r1=678191&r2=678192&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
Sat Jul 19 10:50:21 2008
@@ -92,3 +92,4 @@
parameter-binding-must-not-be-empty=Parameter '%s' must have a non-empty
binding.
no-such-method=Class %s does not contain a method named '%s()'.
context-value-may-not-be-null=Context values (which are added to the request
URL) may not be null or blank.
+forbid-instantiate-component-class=Component class %s may not be instantiated
directly. You should use an @InjectPage or @InjectComponent annotation instead.
\ No newline at end of file
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=678192&r1=678191&r2=678192&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
Sat Jul 19 10:50:21 2008
@@ -13,7 +13,8 @@
Component Message Catalogs
Each component class may have a component message catalog. A component
message catalog is a set of files with the extension ".properties".
- These property files are the same format used by java.util.ResourceBundle,
just lines of <<<key=value>>>. These files are packaged with the component's
HTML template.
+ These property files are the same format used by java.util.ResourceBundle,
just lines of <<<key=value>>>.
+ These files are stored on the classpath, in the same package folder as the
page or component's compiled Java class.
So for a class named org.example.myapp.pages.MyPage, you would have a main
properties file as <<<org/example/myapp/pages/MyPage.properties>>>.
@@ -22,10 +23,16 @@
you could create a file <<<MyPage_fr.properties>>>.
Any values in the more language specific file will <override> values from
the main properties file. If you had an even more specific
- localization for just French as spoken in France, you could create
<<<MyPage_fr_FR.properties>>> (thats a language code plus a country code, you
can even go further
+ localization for just French as spoken in France, you could create
<<<MyPage_fr_FR.properties>>> (thats a language code plus a country code,
+ you can even go further
and add variants ... but its unlikely that you'll ever need to go beyond
just language codes in practice).
The messages in the catalog are accessed by keys. Tapestry ignores the case
of the keys when accessing messages in the catalog.
+
+Properties File Charset
+
+ Tapestry uses the <<<UTF-8>>> charset when reading the properties files in a
message catalog. This means that you don't have to use the Java
+ <<<native2ascii>>> tool.
Message Catalog Inheritance
@@ -38,7 +45,8 @@
Application Message Catalog
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. The search
for the file is case sensitive. The properties file may be localized.
+ 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.
Individual pages and components
can override the values defined in this message catalog.