17. Blending Actions with non-generated Java Code

PROBLEM

As described in the Implementing Controller Methods using Actions and Steps recipe, augmenting the application development process with modeling-based automation can significantly improve development productivity and application quality. However it's important to recognize that modeling-based automation should not be an all or nothing proposition. Model-based automation must be complimentary to traditional code-based development. There are occasions where java code may be better suited to implement a portion of an Action. Therefore there needs to be a seemless way of blending java code with generated code.

SOLUTION

Skyway Builder excels at blending models and code. Skyway Builder let's you drop code into your projects that can be used along-side the model-based components. In the event that your functionality cannot be effectively expressed using models (perhaps due to lacking model-based representations of functionality or efficiency/performance considerations), you can use regular java code and java libraries along with your models.

While using java code in conjunction with models is a powerful feature in itself, Skyway Builder goes the extra step of adapting (blending) code-based resources to appear as model-based resources in the modeling environment. For example, if you define POJO's in your project, they can be used just like POJO's derived from models.

Another capability afforded by the Skyway Builder application generation engine is that the generated logic/code can be used directly from the developer's custom code. The code generated by Skyway is concise and human-readable, and it's organized and packaged according to the developers preference. This makes it very easy for developers to find and use the generated functionality from within their custom code.

The bottom line is that Skyway Builder makes it easy for your model-based and code-based artifacts to co-exist and interact. Java developers can now implement the data, service, and web layers of their solution entirely in models or through the blending of models and java code. Custom Java code can be authored along side models, and both can be fully leveraged by one another.

The Invoke Java step lets you invoke pre-written JAVA code from your Action. (For Spring integration see Blending Actions with non-generated Spring Beans) As a developer is sequencing various Skyway steps to implement an Action, the developer can incorporate pre-existing JAVA logic into the flow. The JAVA code may be contained in JAVA libraries (jar) or a source files within the project.

HOW IT WORKS

In order for a JAVA class to be used by the Invoke Java step, the class must have a PUBLIC constructor that doesn't require any arguments. The following figure shows a very basic JAVA class that will be leveraged from an Action.

Example 2.9. Blending Java Code with Actions - MyJavaClass.java

package example.web.mycontroller.mymodel;

public class MyJavaClass {

   public MyJavaClass(){
   }

   public String doThis(String x, Integer y){
     //...
     return x;
   }

   public void doThat(String z){
     //...
     return;
   }

}

Steps for calling JAVA code using Invoke Java Step:

  1. From an Action, open the Java drawer in the Skyway Step Palette.

  2. Click on the Invoke Java step in the palette and click on the Action Canvas. The step will be placed at the location you click.

  3. Switch to the Java panel on the Steps properties.

  4. Select an invocation type

    • Inline - this invocation type is for invoking java source code that is embedded directly into the step (Source)

    • Variable - this invocation type is for invoking methods on variables defined in either the Model or Project

    • Instance - this invocation type is for creating an instance of a specified class prior to invoking a java method

    • Static - this invocation type is for invoking static methods without creating an instance of a class

  5. After the invocation type is selected, the Java panel will show the fields that need to be configured. Configure the remaining fields to invoke the MyJavaClass.

  6. Based on the method signature, the Parameters panel will list any input parameters. The input parameters must be mapped to variables

The following examples will show the generated code for the various invocation types.

Inline Invocation

In order to use inline invocation, you must specify the code in the source window of the Invoke Java Step using the Inline invocation option. The code will be generated verbatim into the operation method.

Variable Invocation

In order to use variable invocation, you must create an instance of the class using an Operation variable. Next configure the Invoke Java step using the Variable invocation option and specify the variable, method name and return variable.

Figure 2.13. Creating an instance of MyJavaClass using Variables

Creating an instance of MyJavaClass using Variables

Example 2.10. Invoke Java Step - Variable Invocation (Generated Code)

  // InvokeJavaStep: Invoke Java
  MyJavaClass instanceVariable = getVariableStorage().getMyclassVar();1
  String inputString = ((String) getVariableContext().get("inputString"));2
  Integer inputInteger = ((Integer) getVariableContext().get("inputInteger"));

  String result_1 = instanceVariable.doThis(inputString, inputInteger);3
  getVariableContext().set("outputString", result_1);4

1

A reference to MyJavaClass is being obtained from model variables.

2

Input parameters are being obtained from model variables.

3

The doThis() method is being called, and input parameters are being passed.

4

The return parameter is being assigned to model variable.

Instance Invocation

In order to use instance invocation, configure the Invoke Java step using the Instance invocation option and specify the class name, method name and return variable.

Example 2.11. Invoke Java Step - Instance Invocation (Generated Code)

  // InvokeJavaStep: Invoke Java
  MyJavaClass instanceVariable = new MyJavaClass();1
  String inputString = ((String) getVariableContext().get("inputString"));2
  Integer inputInteger = ((Integer) getVariableContext().get("inputInteger"));

  String result_1 = instanceVariable.doThis(inputString, inputInteger);3
  getVariableContext().set("outbean", result_1);4

1

A new reference to MyJavaClass is being instantiated.

2

Input parameters are being obtained from model variables.

3

The doThis() method is being called, and input parameters are being passed.

4

The return parameter is being assigned to model variable.

Static Invocation

In order to use static invocation, configure the Invoke Java step using the Static invocation option and specify the class name, method name and return variable.

Example 2.12. Invoke Java Step - Static Invocation (Generated Code)

  // InvokeJavaStep: Invoke Java
  String inputString = ((String) getVariableContext().get("inputString"));1

  void result_1 = MyJavaClass.doFoo(inputString);2
  getVariableContext().set("outputString", result);3

1

Input parameters are being obtained from model variables.

2

The doFoo() method is being statically invoked, and input parameters are being passed.

3

The return parameter is being assigned to model variable.

RELATED RECIPES

  1. Implementing Controller Methods using Actions and Steps

  2. Blending Actions with non-generated Spring Beans