610 likes | 684 Views
Web 2.0 and Java. The Zen of jMaki. Greg Murray Ajax Architect Sun Microsystems. December 12, 2006. Agenda. Web 2.0 and Java What is jMaki jMaki Widget Model jMaki Templates jMaki Injector jMaki Glue XmlHttpProxy for Mashups Building Applications with jMaki. Web 2.0.
E N D
Web 2.0 and Java The Zen of jMaki Greg Murray Ajax Architect Sun Microsystems December 12, 2006
Agenda • Web 2.0 and Java • What is jMaki • jMaki Widget Model • jMaki Templates • jMaki Injector • jMaki Glue • XmlHttpProxy for Mashups • Building Applications with jMaki
What developers want... http://www.isoma.net/games/goggles.html
Realities • We don't always have the skill sets • We don't have an infinite budget • We don't have infinite time
End Result We copy something a web application out there or go with a technology we know. Or we go over the top and over-reach our skill set.
Ajax options in Java • Frameworks • Direct Web Remoting (DWR) • Java Server Faces • Use all Java Google Web Toolkit • Use JavaScript toolkit on client with: • Servlets • JSP
Dojo Toolkit • Why Dojo? • Package/build system - Load what you need • dojo.event - Cross browser event handling • dojo.ally - Accessibility • dojo.18n - Internationalization • dojo.lfx Effects • dojo.gfx - SVG/VML abstraction • dojo.io - Common abstraction to Ajax IO • dojo.storage - Storage
There are other Options • Dynamic Faces – Ajax with existing and future JSF * • Phobos – Scripting on the server* • jMaki – Framework for creating JavaScript centric web applications * jMaki is supported in both Project Dyanmic Faces and Phobos
jMaki • jMaki - Not jMonkey • ‘j’ is for JavaScript • Maki is to Wrap (Japanese) • jMaki == JavaScript Wrappers
jMaki Birthplace Kumamoto, Japan
What is jMaki? jMaki is a Client/Server Framework that provides: • On the Client • Styles and templates • Widget Model • Client Runtime • Client Services • On the Server • Server Runtime • XMLHttpProxy https://ajax.dev.java.net/about.html
jMaki • jMaki - Not jMonkey • jMaki is not an all or nothing framework • ‘j’ is for JavaScript • BSD License • Supports • JavaServer Pages • JavaServer Faces • Embedded JavaScript (Phobos) • PHP 5.x
jMaki target Audience • Java, PHP, and Phobos developers want to use JavaScript but may want one level of indirection between the script and themselves. • JavaScript developers who want a simple re-usable framework to tie applications together. • Designers who want access to CSS
jMaki Styles and Templates • We are a cut and paste generation • Give you a place to put your widgets • Uses standard approach • Web Designer friendly • Easy to customizing https://ajax.dev.java.net/source/browse/*checkout*/ajax/ws/lib/css/index.html
WYSIRWYG What You See Is REALY What You Get
Template HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <link rel="stylesheet" href="jmaki-standard-footer.css" type="text/css"></link> <html> ... <div class="header"> <div class="banner">Application Name</div> </div> <!-- header --> ... </body> </html>
Template CSS .header { height:100px; border: 1px solid #000000; } .main { position: relative; width: 100%; height:auto; margin-top: 5px; } .content { margin: 0 0 0 200px; height: auto; border: 1px solid #000000; } ...
Hello World Widget component.htm <div id="${uuid}"></div> component.js jmaki.hello = {}; jmaki.hello.Widget = function(wargs) { var mydiv = document.getElementById(wargs.uuid); mydiv.innerHTML = "Hello " + wargs.args.name; } index.jsp <%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %> <a:ajax name="hello" args="{name: 'world'}" />
jMaki in Dynamic Faces <%@ taglib prefix="a" uri="http://java.sun.com/jmaki-jsf" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%> <f:view> <jsfExt:scripts/> <h:form prependId="false"> <a:ajax name="hello" args="{name: 'Greg'}" /> </h:form> </f:view>
Multi-Server support JSP - index.jsp <%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %> <a:ajax name="hello" args="{name: 'Greg'}" /> PHP - index.php <?php require_once 'Jmaki.php'; ?> <?php addWidget("hello", null, "{name: 'Greg'}"); ?> Phobos index.ejs <% library.jmaki.insert({ component:"hello", args: {name: 'Greg'} }); %>
jMaki Widget Model // define the namespaces for foo and bar if (typeof jmaki.foo == 'undefined') { jmaki.foo = {}; } jmaki.foo.bar = {}; jmaki.foo.bar.Widget = function(wargs) { // widget code here }
Wrapping other Widgets dojo.require("dojo.widget.Editor"); // define namespace jmaki.dojo.editor jmaki.dojo.editor.Widget = function(wargs) { var container = document.getElementById(wargs.uuid); this.editor = dojo.widget.createWidget("Editor2", { shareToolbar: false, toolbarAlwaysVisible: true, focusOnLoad: false }, container); this.getValue = function() { return this.editor.getEditorContent(); } }
jMaki config.json A central place for defining jMaki configuration information which includes JavaScript library dependencies including API keys, CSS dependencies, and jMaki Glue handler mappings.
Adding Dojo in the config.json {"config": { "version": "1.2", "types": [ {"id": "dojo", "version": ".4.1", "libs": ["/resources/libs/dojo/version.4.1/dojo.js" ], "preload" : "if (typeof djConfig == 'undefined') djConfig = { parseWidgets: false, searchIds: [] };" } ] }
Google Maps in config.json {"config": {"version": "1.2", "types": [ {"id": "google.map", "libs": ["http://maps.google.com/maps? file=api&v=2&key="], "apikey" : "google" ], "apikeys" : [ {"id": "google", "keys": [ {"url": "http://localhost:8080/jmaki/", "key": "xoxoxoxo" } ] } ] } }
jMaki Publish/Subscribe A means for one or more jMaki widgets to communicate with each other in a page using topics. Publish/Subscribe is much like a server side messaging system by it runs in the scope of an HTML page. https://ajax.dev.java.net/publishsubscribe.html
Publish/Subscribe Usecases • You don't want to put application specific code in a specific widget • You have an application controller that drives application behavior • More than one widget needs be acted upon
Publishing Events icon.onClick = function (){ jmaki.publish("/dojo/fisheye", this); }
Subscribing to Events <script> function fisheyeListener(item) { var targetDiv = document.getElementById("newpage"); var responseText = ""; var index = Number(item.index); switch(index){ case 1: // Set responseText equal to Jayashri's bio break; case 2: // Set responseText equal to Roberto's bio default: responseText += 'Click on one of the photos above'; break; } targetDiv.innerHTML = responseText; } jmaki.subscribe("/dojo/fisheye", fisheyeListener); </script>
jMaki Injector A JavaScript Utility for loading content from a URL (same domain) and properly loading scripts and CSS styles into the document and the contents a into a target element.
jMaki Injector Use Cases • Build Composite Widgets • Tabbed Views • Accordions • Do partial page refresh • Support page as an application pattern
Injector : Page Developer View index.jsp <%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %> <a:ajax name="dojo.tabbedview" value="{tabs:[{label:'My Tab', content: 'Some static content'}, {label:'My Tab 2', url: 'tab2.jsp'} ]}" /> tab2.jsp <%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %> <a:ajax name="yahoo.calendar" /> <a:ajax name="flickr.favorites" args="{tags:'thekt', size:50, columns:2, count:4}"/>
jMaki API Injector Useage var divId = widget.uuid + "_tab" + i; var _c = dojo.widget.createWidget("ContentPane", {label: _row.label, selected: i==1}); _c.setContent("<div style='widget:100%;height:323px' id='" + divId +"'>Loading " + divId + "</div>"); tabbedview.addChild(_c); var _i = new jmaki.Injector(); _i.inject({url:_row.url, injectionPoint: divId}); https://ajax.dev.java.net/injector.html
jMaki Glue jMaki Glue lets you wire together jMaki widgets together using JavaScript action handlers which is called on a publish subscribe events.
Glue Mapping - config.json {"config": { "version": "1.2", "glue" : { "includes": ["glue.js"], "listeners": [ {"topic" : "/debug", "action": "call", "target": { "object": "jmaki.listeners", "functionName": "debug" } } ] } }
Glue JavaScript Action handler glue.js jmaki.listeners = function() { this.debug = function(args) { alert("debug: " + args); } }
jMaki XMLHttpProxy A generic proxy that allows you to access external content including RESTful web services. The proxy provides both session and token based security to prevent miss-use and un-authorized access. https://ajax.dev.java.net/xmlhttpproxy.html
XMLHttpProxy Use Case • I want to cache common coordinates locally • I want to format the data in a JavaScript Object Notation (JSON) • I want only my clients to access the service • I want to use Yahoo’s Geocoder API • It’s provided as a RESTful web service • I can’t access a domain from the browser Requirements:
jMaki XMLHttpProxy http://weblogs.java.net/blog/gmurray71/archive/2006/08/restricting_acc.html
JavaScript View var location = dojo.io.bind({ url: "xhp, mimetype: "text/json", content: { key: “yahoogeocoder”, urlparams: “location=milpitas ca” }, load : function(type, data) { alert("latitude=" + data.coordinates[0].latitude); } });
XMLHttpProxy xhp.json { "id": "yahoogeocoder", "url": "http://api.local.yahoo.com/MapsService/V1/geocode", "apikey" : "appid=jmaki-key", "xslStyleSheet": "yahoo-geocoder.xsl", "defaultURLParams": "location=milpitas,+ca" } http://weblogs.java.net/blog/gmurray71/archive/2006/08/restricting_acc.html