Flexible, efficient Java web applications

The StrataCode webFramework is built with components, properties, data binding and templates. The same code runs on both client and server with a Java to Javascript converter built with Parselets. Web applications are built with the readable schtml file format for fast initial page loads, and efficient, incremental refresh.

Java to Javascript converter

Java is converted to readable, debugging Javascript that looks a lot like the original.

Java selection sort:

file: example/simple/SortTest.scj
public class SortTest {
   public static void doSort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
         int index = i;
         for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[index])
               index = j;
         }
         int toMove = arr[index]; 
         arr[index] = arr[i];
         arr[i] = toMove;
       }
   }
     
   @sc.obj.MainSettings
   public static void main(String args[]) {
       int[] arr = {5, 8, 0, 13, 21, 1, 2, 34, 3, 1}; 
       doSort(arr);

       for (int i : arr) {
           System.out.print(i + ", ");
       }
       System.out.println();
   }
}
converted to Javascript:
file: example/simple/js/types/example/simple/SortTest.js
// Generated JS from Java: example.simple.SortTest -----
function example_simple_SortTest() {
   jv_Object.call(this);
}

var example_simple_SortTest_c = sc_newClass("example.simple.SortTest", example_simple_SortTest, jv_Object, null);

example_simple_SortTest_c.doSort = function (arr)  {
   for (var i = 0; i < arr.length - 1; i++) {
      var index = i;
      for (var j = i + 1; j < arr.length; j++) {
         if (arr[j] < arr[index])
            index = j;
      }
      var toMove = arr[index];
      arr[index] = arr[i];
      arr[i] = toMove;
   }
};
example_simple_SortTest_c.main = function (args)  {
   var arr = sc_initArray(Number_c, 1, [ 5, 8, 0, 13, 21, 1, 2, 34, 3, 1 ]);
   example_simple_SortTest_c.doSort(arr);
   {
      var _lv = arr;
      for (var _i = 0; _i < _lv.length; _i++) {
         var i = arr[_i];
         jv_System_c.out.print(i + ", ");
      }
   }
   jv_System_c.out.println();
};

Template language

Static-typed web pages and components from HTML tag objects:

A login form from the site builder:

file: user/html/core/user/LoginView.schtml
<div visible=":= currentUserView.loginStatus==LoginStatus.NotLoggedIn"
     class="loginView">
   <div class="formTitle">Login</div>
   <div class="formField">
      <label for="userNameField">User name</label>
      <input id="userNameField" type="text" value=":=: currentUserView.userName"
             class="wideTextField" placeholder="user name">
   </div>
   <div class="formField">
      <label for="passwordField">Password</label>
      <input id="passwordField" type="password" value=":=: currentUserView.password"
             keyUpEvent="=: keyUpEvent.key.equals("Enter") ? currentUserView.login() : null"
             class="wideTextField" placeholder="password">
   </div>
   <div class="formField confirmButtons">
      <input id="loginButton" type="submit" value="Log in"
             clickEvent="=: currentUserView.login()">
   </div>
   <div class="formError"><%= currentUserView.userViewError %></div>
   <div id="alt" class="loginView">
      <div>
         <label for="logoutButton">Logged in as <%= currentUserView.user.userName %></label>
         <input id="logoutButton" type="submit" value="Log out"
                clickEvent="=: currentUserView.logout()">
      </div>
   </div>
</div>

A hierarchical tree widget from the program editor:

file: editor/html/core/TreeView.schtml
<%@
   @sc.obj.CompilerSettings(constructorProperties="tree")
%>
<li class=':= "sctTreeNode " + (tree.hasChildren ?
       (tree.ent.open ? "sctParentOpen" : "sctParentClosed") : "sctLeaf")'>
   <%! TypeTree.TreeNode tree; %>

   <span class=':= tree.ent.selected ? "selectedItem" : ""'>
      <a href="#" clickEvent="=: tree.ent.toggleOpen()">
         <img height="18" width="18"
              src=':= tree.ent.open ? "/images/listClose.png" : "/images/listOpen.png"'
              visible=':= tree.needsOpenClose' style="vertical-align:-4px">
      </a>
      <a href="#" clickEvent="=: tree.ent.selectType(false)">
         <img src='= tree.ent.icon == null ? "" : tree.ent.icon.path'
              visible=":= tree.ent.icon != null"
              style="vertical-align:-3px">
         <%= tree.ent.nodeDisplayName %>
      </a>
   </span>
   <ol visible=":= tree.hasChildren" class=':= tree.ent.open ? "sctOpen" : "sctClosed"'>
      <li repeat=":= tree.children" extends="TreeView"
          repeatVarName="childTree" tree=":= childTree"/>
   </ol>
</li>

The repeated childTree extends this TreeView component recursively.

Tags are converted to tag objects, then to Java classes. One tag object can extend or modify another for flexible, customizable web components. JSP-like operators allow Java code to be mixed in as needed. Attributes of the tag set properties of the tagObject and can use data binding expressions.

Flexible deployment

The same APIs and interfaces work in three different ways:

  • Serverless apps where the application code runs entirely in the browser
  • Client/server apps where application code runs in both
  • Server-only apps where the application code only runs on the server, sending snippets of HTML across the wire for fast, incremental refreshes.

Isomorphic Java

Layers allow shared parts of classes to be used on both browser and server, and even to be automatically synchronized for more declarative apps.

In client/server mode, the first request from the browser generates HTML on the server, the browser draws it quickly, then downloads Javascript to do further updates incrementally on the client.

Read more in the documentation.

Status

See the status page.