Package com.isomorphic.js

# Class JSTranslater

java.lang.Object
com.isomorphic.base.Base
com.isomorphic.js.JSTranslater

All Implemented Interfaces:
  `com.isomorphic.base.IAutoConfigurable`

public class JSTranslater extends com.isomorphic.base.Base
`JSTranslater` provides translation of Java objects to JavaScript equivalents. The translation is robust, intuitive, high performance and extensible. Generally speaking, any non-trivial Java data that you would like to make available to the browser should go through JSTranslater.

The JSTranslater is used automatically by the SmartClient RPCManager to provide Java to JavaScript translation of data provided to a RPCResponse or DSResponse. See JSTranslater.toJS() for the general rules of Java to JavaScript translation, and how to customize translation.

The JSTranslater may also be used directly, for uses such as outputting Java-derived data into a .jsp as JavaScript variables. For example, the following Java code, called from a .jsp, would produce a global JavaScript variable "myJavaData" whose value would be the translated form of "myJavaObj":

        JSTranslater.get().toJSVariable(myJavaObj, "myJavaData", out);

Use JSTranslater to deliver various kinds of data, including:

- a database-derived or XML dataset
- dynamically generated XML component definitions
- metadata such as DataSource fields
- information that allows client-side authorization checks

Warning: always use "get()" to retrieve a JSTranslater. Attempting to use "new JSTranslater()" will produce unexpected results.

See Also:
  - `get()`
  - `toJS(Object, Writer)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `alwaysToString()`
  Sets the translater to output the Java objects that aren't specifically handled by the translater as strings, using the `toString` method on those objects.
  `JSTranslater`
  `collapseSmallContainers(boolean value)`
  Enables or disables the option to print the contents of containers (maps or collections) on one line if they don't contain other containers.
  `JSTranslater`
  `enablePrettyPrinting()`
  Turns pretty printing on.
  `JSTranslater`
  `enablePrettyPrinting(boolean value)`
  Turns pretty printing on if `value` is true, otherwise turns pretty printing off.
  `static JSTranslater`
  `get()`
  Retrieve a JSTranslater instance.
  `Locale`
  `getLocale()`
  Sets the Locale to use when processing `<fmt:message>` tags in DataSource definitions.
  `JSTranslater`
  `omitNullMapValues(boolean value)`
  If enabled, key/value pairs in maps encountered by the JSTranslater that have null values are omitted in the output.
  `void`
  `preserveLiteralNulls(boolean b)`
  If true, causes the parser to preserve literal null values in the incoming Javascript object, such that the resulting Java Map contains a key with a null value.
  `void`
  `quoteForTextArea()`
  Sets the translater to output the Javascript object with escaping/quoting suitable for the contents of a TEXTAREA HTML tag.
  `void`
  `quoteForXML()`
  Sets the translater to output the Javascript object with escaping/quoting suitable for embedding in XML.
  `JSTranslater`
  `setCurrentIndentDepth(int depth)`
  Sets the indent depth so JS can be pretty-printed inside manually emitted indented blocks, and still look perfect.
  `void`
  `setEnumTranslateStrategy(String newValue)`
  Sets the strategy this JSTranslater uses to translate enumerated types (objects of type "enum").
  `JSTranslater`
  `spaceAfterColon(boolean value)`
  Adds a space after the colon in key:value pairs, producing `"key": "value"` instead of `"key":"value"`.
  `JSTranslater`
  `strictJSONMode()`
  Sets the translater to output the Javascript object using a strict interpretation of the JSON rules.
  `String`
  `toJS(Object javaObj)`
  Returns a string containing the Javascript equivalent of `javaObj`.
  `void`
  `toJS(Object javaObj, Writer out)`
  Writes the Javascript equivalent of `javaObj` to the output stream `out`.
  `void`
  `toJSVariable(Object javaObj, String variableName, Writer out)`
  Writes JavaScript code to define a variable with the JavaScript-converted value of the passed Java object.
  `void`
  `toJSVariableInScript(Object javaObj, String variableName, Writer out)`
  Writes JavaScript code to define a variable with the JavaScript-converted value of the passed Java object, enclosed in HTML SCRIPT tags.

- ## Method Details

  - ### get

    public static JSTranslater get()
    Retrieve a JSTranslater instance.

    Warning: always use "get()" to retrieve a JSTranslater. Attempting to use "new JSTranslater()" will produce unexpected results.

  - ### enablePrettyPrinting

    public JSTranslater enablePrettyPrinting()
    Turns pretty printing on. With this option on, the Javascript output is indented for better readability. You can set the default behaviour to be pretty printing by setting the jsTranslater.prettyPrint property to true in the properties file. (Default is false)

    Warning: pretty printing drastically slows down translation speed, and should not be used for high-load production servers.

  - ### enablePrettyPrinting

    public JSTranslater enablePrettyPrinting(boolean value)
    Turns pretty printing on if `value` is true, otherwise turns pretty printing off. With this option on, the Javascript output is indented for better readability. You can set the default behaviour to be pretty printing by setting the jsTranslater.prettyPrint property to true in the properties file. (Default is false)

    Warning: pretty printing drastically slows down translation speed, and should not be used for high-load production servers.

    Parameters:
      `value` - if true, pretty printing is turned on, otherwise it's turned off

  - ### omitNullMapValues

    public JSTranslater omitNullMapValues(boolean value)
    If enabled, key/value pairs in maps encountered by the JSTranslater that have null values are omitted in the output.
    Parameters:
      `value` - true to omit null valued keys

  - ### spaceAfterColon

    public JSTranslater spaceAfterColon(boolean value)
    Adds a space after the colon in key:value pairs, producing `"key": "value"` instead of `"key":"value"`. Useful for matching external JSON formatting conventions. Default can be set via `jsTranslater.spaceAfterColon` in the properties file. (Default is false)
    Parameters:
      `value` - if true, a space is written after the colon

  - ### collapseSmallContainers

    public JSTranslater collapseSmallContainers(boolean value)
    Enables or disables the option to print the contents of containers (maps or collections) on one line if they don't contain other containers. This option only has an effect when pretty printing is turned on. Default behaviour can be set with the jsTranslater.prettyPrint.collapseSmallContainers property. (Default is false)

    Warning: container collapsing significantly slows translation speed (100x in some cases), and should not be used for very high load production servers.

    Parameters:
      `value` - if true, and pretty printing is on, then output container contents on one line
    See Also:
      - `enablePrettyPrinting(boolean)`

  - ### quoteForTextArea

    public void quoteForTextArea()
    Sets the translater to output the Javascript object with escaping/quoting suitable for the contents of a TEXTAREA HTML tag. Specifically, ampersands (the '&' character) are never escaped and `</TEXTAREA>` is escaped so that the browser doesn't interpret it as the closing TEXTAREA tag.

    This can be used to deliver a data structure to the browser without actually creating JavaScript objects until a subsequent eval().

    Mutually exclusive with quoteForXML().

  - ### quoteForXML

    public void quoteForXML()
    Sets the translater to output the Javascript object with escaping/quoting suitable for embedding in XML. Specifically, '<', '>' and '&' are written as entity references (eg '<').

    This can be used to embed a JavaScript data structure inside an XML document, for subsequent evaluation in the browser (via eval()).

    Mutually exclusive with quoteForTextArea().

  - ### strictJSONMode

    public JSTranslater strictJSONMode()
    Sets the translater to output the Javascript object using a strict interpretation of the JSON rules. Practically, this means that object keys are always quoted strings - so we generate `{ "propName":"value" }` instead of `{ propName:"value" }`. The latter is valid Javascript, but strictly speaking is not valid JSON.

  - ### setCurrentIndentDepth

    public JSTranslater setCurrentIndentDepth(int depth)
    Sets the indent depth so JS can be pretty-printed inside manually emitted indented blocks, and still look perfect. One level of indenting consists of four spaces.

  - ### getLocale

    public Locale getLocale()
    Sets the Locale to use when processing `<fmt:message>` tags in DataSource definitions. Defaults to the value of the server.properties setting "defaultLocale", which should be an underscore-delimited locale designator in the accepted format - for example, "fr" or "en_US". See the discussion on DataSource internationalization in the client-side docs for details.

  - ### alwaysToString

    public void alwaysToString()
    Sets the translater to output the Java objects that aren't specifically handled by the translater as strings, using the `toString` method on those objects.
    See Also:
      - `toJS(Object, Writer)`

  - ### preserveLiteralNulls

    public void preserveLiteralNulls(boolean b)
    If true, causes the parser to preserve literal null values in the incoming Javascript object, such that the resulting Java Map contains a key with a null value. If false (the default), null values are simply omitted from the Java Map.

  - ### toJS

    public String toJS(Object javaObj) throws UnconvertableException
    Returns a string containing the Javascript equivalent of `javaObj`.
    Parameters:
      `javaObj` - the object to be written out as a Javascript object
    Returns:
      the Javascript equivalent of `javaObj`, as a string
    Throws:
      `UnconvertableException`
    See Also:
      - `toJS(Object, Writer)`

  - ### toJS

    public void toJS(Object javaObj, Writer out) throws UnconvertableException, IOException
    Writes the Javascript equivalent of `javaObj` to the output stream `out`.

    Any Java object or nested structure of Java Objects can be translated to JavaScript. The general rules are:

    - Basic types such as String, Integer, Float, Boolean and Date become the same-named JavaScript built-in type.
    - Enumerated types (objects of type enum)
    - Collections become JavaScript Arrays. This includes List and Set, and also other Array-like structures such as Iterator, Enumeration and native Java Arrays.
    - Maps become JavaScript Objects, where each key-value pair becomes a JavaScript property.
    - XML Elements (org.w3c.dom.Element) and XML Documents (org.w3c.dom.Document) are treated identically to XML found in <isomorphic:XML> tags in .jsps, that is, component definitions like <ListGrid .. /> become live SmartClient components, and any other Elements become JavaScript Objects, where each attribute or subelement becomes a JavaScript property.
    - Any other Java object is treated as a Java Bean, and becomes a JavaScript Object where each Bean property becomes a JavaScript property.
    - Joda-Time types (org.joda.time.DateTime, DateMidnight, LocalDateTime, LocalDate, LocalTime) and Java 8 Date/Time API types (java.time.LocalDate, LocalDateTime, LocalTime) are supported in the same way as basic Date type.

    Note that for handling JDBC ResultSets, the SQLTransform class can be used to transform a ResultSet into Collections that the JSTranslator accepts.

    There are a few ways to customize this translation:

    - translate your objects to collections of basic types before calling toJS().
    - implement a Collections interface (such as Iterator or Map) either directly on your object or as a wrapper for your object. Since you really only have to implement the read methods from the Collection interface, this is straightforward.
    - provide a `JSONFilter` for your object(s)
    - implement the `com.isomorphic.js.IToJSON` interface to do completely custom translation.

    This example shows a simple way to customize Bean translation by implementing the IToJSON interface.

         class MyBean implements IToJSON {
            public void toJSON (Writer out, JSTranslater jsTrans) {
               try {
                  Map beanProps = DataTools.getProperties(this);
                  // here, remove any properties you don't want to send
                  // (or add or modify any others)
                  jsTrans.toJS(beanProps, out);
               } catch (Exception ignored) {}
            }
         }

    In this example we use DataTools.getProperties() to get all of the Bean's public properties as a Map. This Map can be modified arbitrarily, then the JSTranslater is invoked to transform the Map to a JavaScript Object. The same approach can be used externally to an object if you can't add the IToJSON interface.

    Alternatively, if you simply want to filter your bean down to a set of properties, you can use the `JSONFilter` class.

    NOTE: if the default translation yields a structure that contains all the right information but isn't arranged correctly, it is often better to re-arrange the dataset on the client. This reduces server load, providing a tremendous scalability advantage.

    Parameters:
      `javaObj` - the object to be written out as a Javascript object
      `out` - the output stream for the Javascript equivalent of `javaObj`
    Throws:
      `UnconvertableException`
      `IOException`
    See Also:
      - `SQLTransform`
      - `JSONFilter`
      - `IToJSON`
      - `DataTools.getProperties(java.lang.Object)`

  - ### toJSVariableInScript

    public void toJSVariableInScript(Object javaObj, String variableName, Writer out) throws UnconvertableException, IOException
    Writes JavaScript code to define a variable with the JavaScript-converted value of the passed Java object, enclosed in HTML SCRIPT tags.
    Parameters:
      `javaObj` - the object to be written out as a Javascript object
      `variableName` - the Javascript variable name
      `out` - the output stream for the Javascript equivalent of `javaObj`
    Throws:
      `UnconvertableException`
      `IOException`
    See Also:
      - `toJS(Object, Writer)`

  - ### toJSVariable

    public void toJSVariable(Object javaObj, String variableName, Writer out) throws UnconvertableException, IOException
    Writes JavaScript code to define a variable with the JavaScript-converted value of the passed Java object.
    Parameters:
      `javaObj` - the object to be written out as a Javascript object
      `variableName` - the Javascript variable name
      `out` - the output stream for the Javascript equivalent of `javaObj`
    Throws:
      `UnconvertableException`
      `IOException`
    See Also:
      - `toJS(Object, Writer)`

  - ### setEnumTranslateStrategy

    public void setEnumTranslateStrategy(String newValue)
    Sets the strategy this JSTranslater uses to translate enumerated types (objects of type "enum"). Valid values are: "string" Translates to a String matching the constant name "ordinal" Translates to an integer matching the ordinal number of the constant within the enumeration "bean" Translates to a JS object containing one property for each property defined within the enum. The constant itself and the ordinal number are included in the JS object. By default they are called "_constant" and "_ordinal", but this can be overridden on both JSTranslater and DataSource with the enumOrdinalProperty and enumConstantProperty properties (which have setters named using normal bean semantics)