##### General Information

- Overview
- Features
- Specification
- Getting Started
- Howto Build Turbine
- Changes

##### Documentation

- Services
  - Assembler Broker Service
  - Avalon Component Service
  - Crypto Service
  - Cache Service
  - Factory Service
  - Intake Service
  - JSON-RPC Service
  - JSP Service
  - Localization Service
  - MimeType Service
  - Naming Service
  - Parser Service
  - Pool Service
  - Pull Service
  - RunData Service
  - Scheduler Service
  - Security Service
  - Servlet Service
  - Session Service
  - Template Service
  - UI Service
  - Unique ID Service
  - Upload Service
  - Velocity Service
  - XML-RPC Service
  - XSLT Service
- Howtos
- Wiki
- JavaDocs

##### Development

- Proposals
- How To Help
- Todo

##### Project Documentation

- Project Information
- Project Reports

##### Apache

- Apache Website
- License
- How the ASF works
- Sponsorship
- Thanks
- Security

## JSON-RPC Service

The JSON-RPC Service supports JavaScript to Java AJAX communications using JSON-RPC-Java (Jabsorb replaced project oss.metaparadigm.com/jsonrpc/. As of March 2015 Google Code projects are only read-only and this project is archived too, though GIT exports are allowed probably until Jan 2016, e.g. https://github.com/gmkll/jabsorb).

## Configuration

    # -------------------------------------------------------------------
    #
    #  S E R V I C E S
    #
    # -------------------------------------------------------------------
    ...
    services.JsonRpcService.classname=org.apache.turbine.services.jsonrpc.TurbineJsonRpcService
    ...

## Usage

There are a number of things you need to do in order to add AJAX functionality to your webapp. First you implement the functions:

    public class MyJsonFunctions
    {
        public String getHello(String clientParameter)
        {
            return "Hello " + clientParameter;
        }
        public String getGoodbye(String clientParameter)
        {
            return "Goodbye " + clientParameter;
        }
    }

Next you implement your Screen class to make your functions available:

    public class MyJsonScreen extends JSONScreen
    {
        public void doOutput(RunData data) throws Exception
        {
            MyJsonFunctions myFunctions = new MyJsonFunctions();

            // Session specific
            TurbineJsonRpc.registerObject(data.getSession(), "myFunctions", myFunctions);

            // Global
            //TurbineJsonRpc.registerObjectGlobal("testGlobal", testObject);

            super.doOutput(data);
        }
    }

### Client Side: Synchronous AJAX Calls

Now we shift focus to your template classes. Firstly, there are a few useful utility functions that you need to make sure are available to the pages that will include AJAX functionality:

    // Body onload utility (supports multiple onload functions)
    function SafeAddOnload(func) {
      var oldonload = window.onload;
      if (typeof window.onload != 'function') {
        window.onload = func;
      } else {
        window.onload = function() {
          oldonload();
          func();
        };
      }
    }

    // Prepare for possible JSON-RPC requests.
    // jsonurl must be set before calling this function.
    // First example synchronous call
    function jsonOnLoadSync() {
      try {
        jsonrpc = new JSONRpcClient(jsonurl);
      }
      catch(e) {
        if(e.message) {
          alert(e.message);
        }
        else {
          alert(e);
        }
      }
    }

    // Process a JSON-RPC request.
    function jsonEval(evalStr) {
      try	{
        return eval(evalStr);
      }
      catch(e) {
        if(e.javaStack) {
          alert("Exception: \n\n" + e.javaStack);
        }
        else {
          alert("Exception: \n\n" + e);
        }
      }
      return null;
    }

In these pages you also need to include the JavaScript necessary to process the JSON calls - this file is available as part of the JSON-RPC Java distribution (it is included in the `webapps\jsonrpc` directory):

    $page.addScript($content.getURI('scripts/jsonrpc.js'))

Then you need to set up the specific handler for the page (synchronous example):

    <script type="text/javascript">
    <!--
      ## Set up the JSON-RPC handler.
      var jsonurl = '$link.setScreen("MyJsonScreen")';
      SafeAddOnload(jsonOnLoad);
      ## myArg below would be provided when you call this function from your
      ## web page (usually you would retrieve something via the DOM or your
      ## favorite JavaScript DOM wrapper library).
      function retrieveHello(myArg) {
        ## This is a synchronous call.
        var helloResult = jsonEval("jsonrpc.myFunctions.getHello(" + myArg + ")");
        if(null == helloResult) {
          alert('Something went wrong!');
          return;
        }
        ## Here you would again use the DOM to include the result somewhere on your
        ## page.
      }
    -->
    </script>

### Client Side: Asynchronous AJAX Call

Alternatively, asynchronous calls require handling of the deferred objects, which could be done by using some kind of Promise) library. As an example a JQuery Promise Object model (supported since version 1.5) is shown. Usage of asynchronous calls conforms more to XMLHttpRequest specification.

    // Prepare for possible JSON-RPC requests.
    // jsonurl must be set before calling this function.
    // Second example asynchronous call
    var deferred;
    function jsonOnLoad() {
      try {
          // This feature is available since jabsorb 1.1 release, cft. webapps/jaxrpc/CHANGES.txt.
          // JQuery Promises are available since jQuery 1.5/1.8 (with major changes).
          // This is just an example, any other Promise handling will do it.
           if (deferred != undefined) {
                return deferred;
            } else {
                deferred =  jQuery.Deferred(function(defer) {
          // Add a default function as first parameter to enable asynchronous call.
                      jsonrpc = new JSONRpcClient(function(result, e) {
                            defer.resolve(result,e);
                        }, jsonurl);
                }).promise();
                return deferred;
            }
      }
      catch(e) {
        if(e.message) {
          alert(e.message);
        }
        else {
          alert(e);
        }
      }
    }

In these pages you also need to include the JavaScript necessary to process the JSON calls - this file is available as part of the JSON-RPC-Java distribution (it is included in the `webapps\jsonrpc` directory):

    $page.addScript($content.getURI('scripts/jsonrpc.js'))

Then you need to set up the specific handler for the page (in this case a asynchronous handler):

    <script type="text/javascript">
    <!--
      ## Set up the JSON-RPC handler.
      var jsonurl = '$link.setScreen("MyJsonScreen")';

      ## myArg below would be provided when you call this function from your
      ## web page (usually you would retrieve something via the DOM or your
      ## favorite JavaScript DOM wrapper library).
      function retrieveHello(myArg) {
        ## This is a an ansynchronous call as you provide as first parameter a callback function to getHello
        ## (Jabsorb JSON-RPC library expects it this way).
        var promiseA = jsonOnLoad();
        var promiseB = jQuery.Deferred();
        promiseA.done(
           function() {
             jQuery.Deferred(function(deferred) {
               jsonrpc.myFunctions.getHello( function(res,e) {
                        deferred.resolve(); // not used
                        promiseB.resolve(res);
                      }, " + myArg + ")" );
                }).promise();
            }
        );
        return jQuery.when(promiseA, promiseB);
        }

      # call function
      var helloResult;
      var promise = retrieveHello(myArg);
      promise.done(
          function(resultA,resultB) {
            helloResult = resultB;
            ## Here or in another dependent Promise you would again use the DOM to include the result somewhere on your
            ## page.
        }
      );
    -->
    </script>

The above code is executable by users that are not logged into your application. Your Screen class can extend JSONSecureScreen to require that users be logged in before allowing execution.