classes/hirondelle/web4j/ui/translate/Translator.java
author Tomas Zeman <tzeman@volny.cz>
Wed, 04 Dec 2013 17:00:31 +0100
changeset 0 3060119b1292
permissions -rw-r--r--
Imported web4j 4.10.0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     1
package hirondelle.web4j.ui.translate;
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     2
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     3
import hirondelle.web4j.request.LocaleSource;
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     4
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     5
import java.util.Locale;
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     6
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     7
/**
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     8
 Translate base text into a localized form. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     9
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    10
 <P>See {@link hirondelle.web4j.BuildImpl} for important information on how this item is configured. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    11
 {@link hirondelle.web4j.BuildImpl#forTranslator()} returns the configured implementation of this interface.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    12
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    13
 <P>Here, "<b>base text</b>" refers to either :
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    14
 <ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    15
 <li>a snippet of user-presentable text in the language being used to build the application
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    16
 <li>a "coder key", such as <tt>"image.title"</tt> or <tt>"button.label"</tt>. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    17
 Coder keys are never presented to the end user, and serve as an alias or shorthand 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    18
 for something else. They are intended for the exclusive use of the programmer, and may 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    19
 be thought of as being in a special "language" understood only by the programmer.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    20
 </ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    21
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    22
 <P><span class="highlight">In code, it is likely best to use user-presentable text 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    23
 instead of coder keys, whenever possible - since lookups are never needed, it makes 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    24
 code clearer at the point of call.</span>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    25
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    26
 <P>Please see the package <a href="package-summary.html">overview</a> for an interesting way of 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    27
 evolving the implementation of this interface during development, allowing applications to assist in their 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    28
 own translation.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    29
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    30
 <P>One might validly object to a framework which requires an implementation of this 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    31
 interface even for single-language applications. However, arguments in favor of 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    32
 such a style include : 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    33
<ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    34
 <li>providing a do-nothing implementation for a single-language application is trivial.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    35
 <li>changing from a single language to multiple languages is a common requirement for 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    36
 web applications. The presence of this implementation makes it clear to the maintainer 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    37
 where such changes are made, if they become necessary. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    38
 <li>some programmers might prefer to name items as <tt>'emailAddr'</tt> instead of 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    39
 <tt>'Email Address'</tt>, for instance. In this case, a {@link Translator} can also  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    40
 be used, even in a single-language application, to translate from such 'coder keys' 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    41
 to user-presentable text. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    42
</ul> 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    43
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    44
 <P>The recommended style is to implement this interface with a database, and to 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    45
 <a href="http://www.javapractices.com/Topic208.cjp">avoid <tt>ResourceBundle</tt></a>.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    46
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    47
 <P><b>Guidance For Implementing With A Database</b><br>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    48
 Example of a web application with the following particular requirements 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    49
 (see the example application for further illustration): 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    50
 <ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    51
 <li>English is the base development language, used by the programmers and development team
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    52
 <li>the user interface needs to be in both English and French
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    53
 <li>in source code, the programmers use both regular text snippets in  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    54
 user-presentable English, and (occasionally) 'coder keys', according to the needs of each particular case 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    55
 </ul> 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    56
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    57
 Here is a style of <tt>ResultSet</tt> that can be used to implement this interface :
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    58
 <P><table border=1 cellspacing=0 cellpadding=3>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    59
  <tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    60
   <th>BaseText</th><th>Locale</th><th>Translation</th> 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    61
  </tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    62
  <tr><td>Fish And Chips</td><td>en</td><td>Fish And Chips</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    63
  <tr><td>Fish And Chips</td><td>fr</td><td>Poisson et Frites</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    64
  <tr><td>delete</td><td>en</td><td>delete</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    65
  <tr><td>delete</td><td>fr</td><td>supprimer</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    66
  <tr><td>add.edit.button</td><td>en</td><td>Add/Edit</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    67
  <tr><td>add.edit.button</td><td>fr</td><td>Ajouter/Changer</td></tr>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    68
 </table> 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    69
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    70
 <P>Only the last two rows use a "coder key".
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    71
 The <tt>BaseText</tt> column holds either the coder key, or the user-presentable English. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    72
 The <tt>BaseText</tt> is the lookup key. The fact that there is 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    73
 repetition of data between the <tt>BaseText</tt> and <tt>English</tt> columns is not a real duplication problem, 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    74
 since <em>this is a <tt>ResultSet</tt>, not a table</em> - the underlying tables will not have such 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    75
 repetition (if designed properly, of course). 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    76
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    77
 <P>For example, such a <tt>ResultSet</tt> can be constructed from three underlying tables - 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    78
 <tt>BaseText</tt>, <tt>Locale</tt>, and <tt>Translation</tt>. <tt>Translation</tt> is a cross-reference 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    79
 table, with foreign keys to both <tt>BaseText</tt> and <tt>Locale</tt>. When such a scheme is 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    80
 normalized, it will have no repeated data. (In underlying queries, however, the base 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    81
 language will be necessarily treated differently than the other languages.)
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    82
 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    83
 <P>Upon startup, the tables are read, the above <tt>ResultSet</tt> is created and  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    84
 stored in a <tt>private static Map</tt>, represented schematically as 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    85
 <tt>Map[BaseText, Map[Locale, Translation]]</tt>. When a translation is required, 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    86
 this <tt>Map</tt> is used as an in-memory lookup table. This avoids 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    87
 repeated fetching from the database of trivial data that rarely changes. 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    88
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    89
 <P><b>Note on Thread Safety</b>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    90
 <br>In the suggested implementation style, the <tt>private static Map</tt> that stores translation data is 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    91
 <tt>static</tt>, and thus shared by multiple threads. Implementations are free to implement 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    92
 any desired policy regarding thread safety, from relaxed to strict. A relaxed implementation 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    93
 might completely ignore the possibility of a mistaken read/write, since no writes are expected in 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    94
 production, or simply because the consequences are usually trivial. A strict implementation would 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    95
 take the opposite approach, and demand that the <tt>private static Map</tt> be used in an fully 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    96
 thread-safe manner.   
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    97
*/
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    98
public interface Translator {
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    99
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   100
  /**
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   101
   Translate <tt>aBaseText</tt> into text appropriate for <tt>aLocale</tt>.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   102
   
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   103
   <P><tt>aBaseText</tt> is either user-presentable text in the base language of 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   104
   development, or a "coder key" known only to the programmer.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   105
   
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   106
   <P>If <tt>aBaseText</tt> is unknown, then the implementation is free to define 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   107
   any desired behavior. For example, this method might return  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   108
  <ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   109
   <li><tt>aBaseText</tt> passed to this method, in its raw, untranslated form
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   110
   <li><tt>aBaseText</tt> with special surrounding text, such as <tt>???some text???</tt>, with 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   111
   leading and trailing characters
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   112
   <li>a fixed <tt>String</tt> such as <tt>'???'</tt> or <tt>'?untranslated?'</tt>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   113
   <li>it is also possible for an implementation to throw a {@link RuntimeException} when 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   114
   an item is missing, but this is not recommended for applications in production
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   115
  </ul>
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   116
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   117
   <P>If <tt>aBaseText</tt> is known, but there is no explicit translation for the 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   118
   given {@link Locale}, then an implementation might choose to mimic the behavior of 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   119
   {@link java.util.ResourceBundle}, and choose a translation from the "nearest available" 
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   120
   {@link Locale} instead.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   121
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   122
   @param aBaseText is not <tt>null</tt>, but may be empty
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   123
   @param aLocale comes from the configured {@link LocaleSource}.
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   124
  */
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   125
  String get(String aBaseText, Locale aLocale);
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   126
  
3060119b1292 Imported web4j 4.10.0
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   127
}