--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+public class BooleanVariable extends Variable {
+
+ private boolean value = true;
+
+ public BooleanVariable(Component owner, String name, String id) {
+ super(owner, name, id);
+ }
+
+
+ void update() {
+ owner.getClient().updateVariable(this);
+ if(immediate)
+ owner.getClient().flushVariables();
+
+ }
+
+ public boolean getValue() {
+ return value;
+ }
+
+ public void setValue(boolean value) {
+ this.value = value;
+ }
+
+
+ public String getEncodedValue() {
+ return ( value ? "true" : "false" );
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.Node;
+
+public abstract class Component {
+
+ private ContainerComponent parent;
+ protected GwtClient client;
+ private final int id;
+
+ public Component(int id, GwtClient c) {
+ client = c;
+ this.id = id;
+ }
+
+ public abstract void updateFromUidl(Node n);
+
+ public abstract Widget getWidget();
+
+ public static boolean isComponent(String nodeName) {
+ if(
+ nodeName.equals("label") ||
+ nodeName.equals("button") ||
+ nodeName.equals("textfield") ||
+ nodeName.equals("select") ||
+ nodeName.equals("orderedlayout")
+ ) return true;
+ return false;
+ }
+
+ public static Component createComponent(Node uidl, GwtClient cli) {
+ Component c = null;
+ String nodeName = uidl.getNodeName();
+ if(nodeName.equals("label")) {
+ c = new TkLabel(uidl, cli);
+ } else if(nodeName.equals("orderedlayout")) {
+ c = new TkOrderedLayout(uidl, cli);
+ } else if(nodeName.equals("button")) {
+ c = new TkButton(uidl, cli);
+ } else if(nodeName.equals("textfield")) {
+ c = new TkTextField(uidl, cli);
+ } else if(nodeName.equals("select")) {
+ c = new TkLegacyComponent(uidl, cli);
+ } else {
+ c = new TkUnknown(uidl, cli);
+ }
+ return c;
+ }
+
+ public void appendTo(ContainerComponent cont) {
+ this.parent = cont;
+ getClient().registerComponent(this);
+ cont.appendChild(this);
+ }
+
+ public ContainerComponent getParent() {
+ return parent;
+ }
+
+ public GwtClient getClient() {
+ if(client == null)
+ client = parent.getClient();
+ return client;
+ }
+
+ public static int getIdFromUidl(Node uidl) {
+ Node pid = uidl.getAttributes().getNamedItem("id");
+ return Integer.parseInt(pid.getNodeValue().substring(3));
+ }
+
+ public int getId() {
+ return id;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
+
+public final class Console {
+
+ private RootPanel rp;
+
+ public Console(RootPanel rp) {
+ this.rp = rp;
+ }
+
+ public void log(String msg) {
+ rp.add(new Label(msg));
+ }
+
+ public void error(String msg) {
+ rp.add((new Label(msg)));
+ }
+
+ public void printObject(Object msg) {
+ rp.add((new Label(msg.toString())));
+ }
+
+
+// public native void log(String msg)
+///*-{
+// console.log(msg);
+//}-*/;
+//
+// public native void warn(String msg)
+// /*-{
+// console.warn(msg);
+// }-*/;
+//
+// public native void error(String msg)
+// /*-{
+// console.error(msg);
+// }-*/;
+//
+// public native void printObject(Object msg)
+// /*-{
+// console.dir(msg);
+// }-*/;
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+
+abstract class ContainerComponent extends Component {
+
+ public ContainerComponent(int id, GwtClient c) {
+ super(id, c);
+ }
+
+ abstract void appendChild(Component c);
+
+ public void renderChildNodes(Node n, GwtClient cli) {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if(Component.isComponent(child.getNodeName())) {
+ Component c = Component.createComponent(child, cli);
+ c.appendTo(this);
+ }
+ }
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.RequestException;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.xml.client.Document;
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+import com.google.gwt.xml.client.XMLParser;
+
+/**
+ * Entry point classes define <code>onModuleLoad()</code>.
+ */
+public class GwtClient implements EntryPoint {
+
+ private String appUri = "http://localhost:8080/tk/HelloWorld";
+
+ // TODO remove repaintAll things start to pile up
+ private RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, appUri + "/UIDL/?repaintAll=1&");
+
+ private Console console;
+
+ private RootWindow rw;
+
+ private Vector pendingVariables = new Vector();
+
+ private HashMap components = new HashMap();
+
+ private int requestCount = 0;
+
+ private LegacyClientWrapper lClient;
+
+ /**
+ * This is the entry point method.
+ */
+ public void onModuleLoad() {
+
+ console = new Console(RootPanel.get("itmtk-loki"));
+
+ console.log("muutos");
+
+ console.log("Starting app");
+
+ console.log("Makin fake UIDL Request to fool servlet of an app init");
+ RequestBuilder rb2 = new RequestBuilder(RequestBuilder.GET, appUri);
+ try {
+ rb2.sendRequest("", new RequestCallback() {
+
+ public void onResponseReceived(Request request, Response response) {
+ console.log("Got fake response... sending initial UIDL request");
+ makeUidlRequest("repaintAll=1");
+ }
+
+ public void onError(Request request, Throwable exception) {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+ } catch (RequestException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ }
+
+ private void makeUidlRequest(String requestData) {
+ console.log("Making UIDL Request");
+ rb = new RequestBuilder(RequestBuilder.GET, appUri + "/UIDL/?requestId=" + (++requestCount) + "&" + requestData);
+ try {
+ rb.sendRequest(requestData, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ console.error("Got error");
+ }
+ public void onResponseReceived(Request request, Response response) {
+ console.log("Got response:");
+ Document doc = XMLParser.parse(response.getText());
+ console.log(doc.toString());
+ handleUIDL(doc);
+ }
+ });
+ console.log("Request sent");
+
+ } catch (RequestException e) {
+ console.error(e.getMessage());
+ }
+ }
+
+ private void handleUIDL(Document doc) {
+ NodeList changes = doc.getElementsByTagName("change");
+
+ for(int i = 0; i < changes.getLength(); i++) {
+ applyChange(changes.item(i).getFirstChild());
+ }
+ }
+
+ private void applyChange(Node n) {
+ if(n.getNodeName().equals("window")) {
+ console.log("Rendering main window");
+ rw = new RootWindow(n, this);
+ rw.setClient(this);
+ } else {
+ int pid = Component.getIdFromUidl(n);
+ console.log("Updating node: " + n.getNodeName() + ", PID:"+pid);
+ Component c = getPaintable(pid);
+ c.updateFromUidl(n);
+ }
+ }
+
+ /**
+ * Queues a changed variable to be sent to server
+ *
+ * @param variable
+ */
+ public void updateVariable(Variable variable) {
+ // remove variable first so we will maintain the correct order (in case of "double change")
+ pendingVariables.remove(variable);
+ pendingVariables.add(variable);
+ }
+
+ /**
+ * Sends queued variables to server
+ *
+ */
+ public void flushVariables() {
+
+ StringBuffer sb = new StringBuffer();
+
+ int i = 0;
+ while (!pendingVariables.isEmpty()) {
+ Variable v = (Variable) pendingVariables.lastElement();
+ pendingVariables.removeElement(v);
+
+ if (i > 0) {
+ sb.append("&");
+ }
+ // encode the characters in the name
+ String encodedName = URL.encodeComponent(v.getId());
+ sb.append(encodedName);
+ sb.append("=");
+
+ // encode the characters in the value
+ String encodedValue = URL.encodeComponent(v.getEncodedValue());
+ sb.append(encodedValue);
+ }
+
+ String buf = sb.toString();
+
+ console.log("Making following request to server:");
+ console.log(buf);
+
+ makeUidlRequest(buf);
+ }
+
+ public void registerComponent(Component component) {
+ components.put(""+component.getId(), component );
+ }
+
+ public Component getPaintable(int pid) {
+ return (Component) components.get(""+pid);
+ }
+
+ public LegacyClientWrapper getLegacyClient() {
+ if(lClient == null)
+ lClient = new LegacyClientWrapper();
+ return lClient;
+ }
+}
+
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.xml.client.Node;
+
+public class LegacyClientWrapper {
+
+ JavaScriptObject lClient;
+
+ LegacyClientWrapper() {
+ instantiateLegacyClient();
+ }
+
+ private native void instantiateLegacyClient()/*-{
+ var client = new $wnd.itmill.Client();
+ client.start();
+ this.@com.itmill.gwtclient.client.LegacyClientWrapper::lClient = client;
+ debugger;
+
+ }-*/;
+
+ public native void renderUidl(Element e, Node n)/*-{
+// var uidlNode = n.hE; //sneeked obf. reference to DOM-node, changes on almost every change
+ // should fork GWT and make method for getting jsObject
+// var uidlNode = cQ.gE;
+ eval('var uidlNode = cQ.gE;');
+
+ //ok so in eval compiler don't look
+ var client = this.@com.itmill.gwtclient.client.LegacyClientWrapper::lClient;
+
+ debugger;
+
+ client.renderUIDL(uidlNode,e);
+
+
+}-*/;
+
+}
--- /dev/null
+
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.Node;
+
+public class RootWindow extends ContainerComponent {
+
+ private RootPanel rp;
+ private GwtClient client;
+
+ public RootWindow(Node uidl, GwtClient c) {
+ super(0,c);
+ // root panel must be attached to client before childs can be rendered
+ setClient(c);
+ rp = RootPanel.get("itmtk-ajax-window");
+ rp.clear();
+ renderChildNodes(uidl, client);
+ }
+
+ void appendChild(Component c) {
+ rp.add(c.getWidget());
+ }
+
+ public void updateFromUidl(Node n) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Widget getWidget() {
+ return rp;
+ }
+
+ public void setClient(GwtClient client) {
+ this.client = client;
+ }
+
+ public GwtClient getClient() {
+ return this.client;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.NamedNodeMap;
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+
+public class TkButton extends Component {
+
+ private Button b;
+ private BooleanVariable state;
+
+ public TkButton(Node uidl, GwtClient c) {
+ super(getIdFromUidl(uidl), c);
+ b = new Button();
+ updateFromUidl(uidl);
+ b.addClickListener(new ButtonClickListener());
+ }
+
+ public void updateFromUidl(Node n) {
+
+ String text = "";
+ String description = null;
+ NamedNodeMap attributes = n.getAttributes();
+ Node caption = attributes.getNamedItem("caption");
+ if(caption != null)
+ text = caption.getNodeValue();
+
+ NodeList children = n.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ String nName = child.getNodeName();
+ if(nName.equals("description"))
+ description = child.getFirstChild().toString();
+ if(nName.equals("boolean")) {
+ state = (BooleanVariable) VariableFactory.getVariable(child,this);
+ state.setImmediate(true); // button always immediate
+ }
+ }
+ b.setText(text);
+ if(description != null)
+ b.setTitle(description);
+ }
+
+ public Widget getWidget() {
+ return b;
+ }
+
+ public class ButtonClickListener implements ClickListener {
+
+ public void onClick(Widget sender) {
+ TkButton.this.state.setValue(true);
+ TkButton.this.state.update();
+ }
+
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.NamedNodeMap;
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+
+public class TkLabel extends Component {
+
+ private Label l;
+
+ public TkLabel(Node uidl, GwtClient cli) {
+ super(getIdFromUidl(uidl), cli);
+
+ l = new Label();
+ updateFromUidl(uidl);
+ }
+
+ public void updateFromUidl(Node n) {
+ NodeList children = n.getChildNodes();
+ String text = "";
+ String description = null;
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if(child.getNodeName().equals("description"))
+ description = child.getNodeValue();
+ else if(child.getNodeType() == Node.TEXT_NODE)
+ text = child.toString();
+ }
+ NamedNodeMap attributes = n.getAttributes();
+ Node caption = attributes.getNamedItem("caption");
+ if(caption != null)
+ text = caption.getNodeValue();
+ l.setText(text);
+ if(description != null)
+ l.setTitle(description);
+ }
+
+ public Widget getWidget() {
+ return l;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.Node;
+
+public class TkLegacyComponent extends Component {
+
+ private Label l;
+
+ public TkLegacyComponent(Node uidl, GwtClient cli) {
+ super(getIdFromUidl(uidl), cli);
+
+ // TODO Check if client has legacy client instantiated
+
+ l = new Label();
+// updateFromUidl(uidl);
+ }
+
+ public void updateFromUidl(Node n) {
+ LegacyClientWrapper lc = client.getLegacyClient();
+
+ Element e = l.getElement();
+
+ lc.renderUidl(e,n);
+ }
+
+ public Widget getWidget() {
+ return l;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.Node;
+
+public class TkOrderedLayout extends ContainerComponent {
+
+ private FlowPanel p;
+
+ public TkOrderedLayout(Node uidl, GwtClient cli) {
+ super(getIdFromUidl(uidl), cli);
+
+ p = new FlowPanel();
+ updateFromUidl(uidl);
+ }
+
+ void appendChild(Component c) {
+ p.add(c.getWidget());
+ }
+
+ public Widget getWidget() {
+ return p;
+ }
+
+ public void updateFromUidl(Node n) {
+ p.clear();
+ renderChildNodes(n, getClient());
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.NamedNodeMap;
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+
+public class TkTextField extends Component {
+
+
+ private TextBox tb;
+
+ public TkTextField(Node uidl, GwtClient cli) {
+ super(getIdFromUidl(uidl),cli);
+
+ tb = new TextBox();
+ updateFromUidl(uidl);
+ }
+
+ public void updateFromUidl(Node n) {
+ NodeList children = n.getChildNodes();
+ String text = "";
+ String description = null;
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if(child.getNodeName().equals("description"))
+ description = child.getNodeValue();
+ else if(child.getNodeType() == Node.TEXT_NODE)
+ text = child.toString();
+ }
+ NamedNodeMap attributes = n.getAttributes();
+ Node caption = attributes.getNamedItem("caption");
+ if(caption != null)
+ text = caption.getNodeValue();
+ tb.setText(text);
+ if(description != null)
+ tb.setTitle(description);
+ }
+
+ public Widget getWidget() {
+ return tb;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.xml.client.Node;
+
+public class TkUnknown extends Component {
+
+ private Label l;
+
+ public TkUnknown(Node uidl, GwtClient cli) {
+ super(getIdFromUidl(uidl),cli);
+
+ l = new Label("No client side component found for " + uidl.getNodeName());
+ }
+
+ public void updateFromUidl(Node n) {
+ }
+
+ public Widget getWidget() {
+ return l;
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+public abstract class Variable {
+
+ protected Component owner;
+ protected boolean immediate = false;
+ protected String name;
+ protected String id;
+
+ public Variable(Component owner, String name, String id) {
+ this.owner = owner;
+ this.name = name;
+ this.id = id;
+ }
+
+ abstract void update();
+
+ public boolean isImmediate() {
+ return immediate;
+ }
+
+ public void setImmediate(boolean immediate) {
+ this.immediate = immediate;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public abstract String getEncodedValue();
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+import java.util.HashMap;
+
+import com.google.gwt.xml.client.NamedNodeMap;
+import com.google.gwt.xml.client.Node;
+import com.google.gwt.xml.client.NodeList;
+
+public class VariableFactory {
+
+ public static Variable getVariable(Node n, Component owner) {
+ String nName = n.getNodeName();
+ NamedNodeMap attr = n.getAttributes();
+ if(nName.equals("boolean")) {
+ String name = attr.getNamedItem("name").getNodeValue();
+ String id = attr.getNamedItem("id").getNodeValue();
+ boolean b = attr.getNamedItem("value").getNodeValue().equals("true");
+ BooleanVariable v = new BooleanVariable(owner,name,id);
+ v.setValue(b);
+ return v;
+ } else {
+ return null;
+ }
+ }
+
+ public static HashMap getAllVariables(Node n, Component owner) {
+ HashMap v = new HashMap();
+ NodeList children = n.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Variable var = getVariable(children.item(i), owner);
+ if(var != null)
+ v.put(var.getName(), var);
+ }
+ return v;
+ }
+
+}