Pages

Monday, August 1, 2011

HTML5 - Sliding Tile Puzzle Game


Presented below is the HTML5 source code for a puzzle game called Sliding Tile puzzle or Mystic Square puzzle. Numbers 1 to 15 are jumbled in a 4x4 board. You have to arrange the numbers in order by moving the blank tile or magic square.
At the bottom of the board, you can see images in shuffled position. With each move on the board, the images will get re-aligned. Once the puzzle is solved, you can see the complete picture in the Canvas Area.
HTML5's Drag And Drop, Offline Storage, Canvas features are used. It is tested on Chrome 12.0 and Firefox 5.0 and NOT compatible with mobile devices.

Screen Shot:



HTML Code
<!DOCTYPE HTML>
<html manifest="cache.manifest">
<head>

<link rel=StyleSheet href="slidetile.css" TYPE="text/css">

<script src="jquery-1.6.2.min.js"></script>
<script src="slidetile.js"></script>
</head>
<body onload="initialize();">

<div id="row1" class="row">
<div id="1" class="tile" draggable="true"></div>
<div id="2" class="tile" draggable="true"></div>
<div id="3" class="tile" draggable="true"></div>
<div id="4" class="tile" draggable="true"></div>
</div>

<div id="row2" class="row">
<div id="5" class="tile" draggable="true"></div>
<div id="6" class="tile" draggable="true"></div>
<div id="7" class="tile" draggable="true"></div>
<div id="8" class="tile" draggable="true"></div>
</div>

<div id="row3" class="row">
<div id="9" class="tile" draggable="true"></div>
<div id="10" class="tile" draggable="true"></div>
<div id="11" class="tile" draggable="true"></div>
<div id="12" class="tile" draggable="true"></div>
</div>

<div id="row4" class="row">
<div id="13" class="tile" draggable="true"></div>
<div id="14" class="tile" draggable="true"></div>
<div id="15" class="tile" draggable="true"></div>
<div id="16" class="tile" draggable="true"></div>
</div>

<div id="moveStatus" class="row">
<div id="status">Ready to start?</div>
</div>

<canvas id="myCanvas" width="200" height="200" class="canvas">
</canvas>

<div id="buttons" class="row">
<input type="button" id="newGameButton" class="button" value="New"
onclick="clearStorage();initialize();"></input> <input type="button"
id="saveGameButton" class="button" value="Save"></input>
</div>

<div id="rules" class="rules">
<div id="rulesInfo" class="infoTitle">
<strong>Rules:</strong>
</div>
<div class="row">1. Arrange the numbers on the board from 1 to
15.</div>
<div class="row">2. Move the tiles around by moving only the
blank tile.</div>
<div class="row">3. The blank tile can be swapped only with the
adjacent tiles.</div>
<div class="row">4. Drag and Drop the tiles using the mouse.
Images are not draggable.</div>

<div class="infoTitle">
<strong>About:</strong>
</div>
<div class="row" id="AboutInfo">Sliding tile puzzle is also called Gem Puzzle or Mystic Square puzzle. If you can solve within 80 moves,well, you are lucky. The algorithm is complex to solve and sometimes impossible. Wish you patience and good luck. </div>

<div class="infoTitle">
<strong>Note:</strong>
</div>
<div class="row" id="NoteInfo">This version of game is NOT compatible with mobile. Offline caching enabled for modern browsers. Tested for Chrome 12.0 and Firefox 5.0</div>

<div class="infoTitle">
<strong>Best Finish:</strong>
</div>
<div class="row" id="bestMove"></div>
</div>

<div class="flashMessage" id="flashMessage"></div>

</body>
</html>


CSS:
.button {
color: white;
padding: 5px 20px;
text-shadow: 1px 1px 0 #145982;
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
font-weight: bold;
text-align: center;
border: 1px solid #60b4e5;
margin-right: 20px;
margin-top: 20px;
float: left;
position: relative;
right: -35%;
width: 100px;

/*
CSS3 gradients for webkit and mozilla browsers fallback color for the rest:
*/
background-color: #59aada;
background: -moz-linear-gradient(left center, rgb(200, 0, 0),
rgb(79, 79, 79), rgb(21, 21, 21) );
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgb(200, 0,
0) ), color-stop(0.50, rgb(79, 79, 79) ),
color-stop(1, rgb(21, 21, 21) ) ); to (#FFA4E6) );
box-shadow: 3px 3px 3px #000000;
-moz-box-shadow: 3px 3px 3px #000000;
-webkit-box-shadow: 3px 3px 3px #000000;
border: 1px solid #F902B6;
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
background-color: #59aada
}


.button:hover { /* Lighter gradients for the hover effect */
text-decoration: none;
background-color: #F902B6;
background-image: -moz-linear-gradient(#6bbbe9, #57a5d4);
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#6bbbe9),
to(#57a5d4) );
box-shadow: 3px 3px 3px #333;
-moz-box-shadow: 3px 3px 3px #333;
-webkit-box-shadow: 3px 3px 3px #333;
}
/* Prevent the text contents of draggable elements from being selectable. */
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}

.row {
width: 100 %;
clear: both;
}

.infoTitle {
width: 100 %;
clear: both;
margin-top: 20px;
text-shadow: 1px 0px 0 #145982;
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
font-weight: bold;
}

.rules {
position: absolute;
top: 0;
right: 0;
width: 200px;
text-align: left;
color: #800000;
font-size: small;
font-family: Arial, Helvetica, sans-serif;
}

.flashMessage {
position: absolute;
top: 50px;
left: 50px;
width: 220px;
height: 60px;
text-align: left;
margin-right: 10px;
margin-leftt: 15px;
line-height: 1.5em;
color: #fff;
font-size: large;
font-family: Arial, Helvetica, sans-serif;
clear: both;
margin-top: 20px;
background: -moz-linear-gradient(left center, rgb(100, 0, 0),
rgb(179, 79, 79), rgb(121, 21, 21) );
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgb(100, 0,
0) ), color-stop(0.50, rgb(179, 79, 79) ),
color-stop(1, rgb(121, 21, 21) ) );
}

#moveStatus {
clear: both;
float: left;
position: relative;
right: -35%;
text-align: left;
margin-top: 20px;
width: 215px;
background: -moz-linear-gradient(left center, rgb(200, 0, 0),
rgb(79, 79, 79), rgb(21, 21, 21) );
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgb(200, 0,
0) ), color-stop(0.50, rgb(79, 79, 79) ),
color-stop(1, rgb(21, 21, 21) ) );
color: #fff;
text-shadow: 1px 1px 0 #145982;
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
font-weight: bold;
box-shadow: 3px 3px 3px #000000;
-moz-box-shadow: 3px 3px 3px #000000;
-webkit-box-shadow: 3px 3px 3px #000000;
}

.tile {
height: 50px;
width: 50px;
float: left;
position: relative;
right: -35%;
border: 2px solid #666666;
background-color: #ccc;
margin-right: 1px;
line-height: 2em;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: inset 0 0 3px #000;
box-shadow: inset 0 0 3px #000;
text-align: center;
cursor: move;
background: -moz-linear-gradient(left center, rgb(0, 0, 0),
rgb(79, 79, 79), rgb(21, 21, 21) );
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgb(0, 0, 0)
), color-stop(0.50, rgb(79, 79, 79) ), color-stop(1, rgb(21, 21, 21) )
);
color: #fff;
font-size: x-large;
}

.canvas {
clear: both;
height: 200px;
width: 215px;
float: left;
position: relative;
right: -35%;
border: 2px solid #666666;
background-color: #ccc;
margin-right: 1px;
margin-top: 10px;
line-height: 2em;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: inset 0 0 3px #000;
box-shadow: inset 0 0 3px #000;
background: -moz-linear-gradient(left center, rgb(0, 0, 0),
rgb(79, 79, 79), rgb(21, 21, 21) );
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgb(0, 0, 0)
), color-stop(0.50, rgb(79, 79, 79) ), color-stop(1, rgb(21, 21, 21) )
);
color: #fff;
font-size: x-large;
height: 200px;
}

.over {
border: 2px dashed #000;
}

Javascript Code:
// Global Variable
var myarray = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
"12", "13", "14", "15", "" ];
var gameStatus = 0;
var moveCount = 0;
var positionDifference = 0;

// If you have 10 number of 200x200 images, use 9.
var imageNumber = Math.floor(Math.random()*9);
var sourceDiv = null;
var bestMove;
var bestTime;

$(document)
.ready(

function () {

Element.prototype.hasClassName = function(name) {
return new RegExp("(?:^|\\s+)" + name
+ "(?:\\s+|$)").test(this.className);
};

Element.prototype.addClassName = function(name) {
if (!this.hasClassName(name)) {
this.className = this.className ? [
this.className, name ].join(' ') : name;
}
};

Element.prototype.removeClassName = function(name) {
if (this.hasClassName(name)) {
var c = this.className;
this.className = c.replace(
new RegExp("(?:^|\\s+)" + name
+ "(?:\\s+|$)", "g"), "");
}
};



function handleDragStart(e) {
// Target (this) element is the source node.
sourceDiv = this;
this.style.opacity = '0.7';
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}

function handleDragEnter(e) {
// this / e.target is the current hover target.
this.addClassName('over');
}

function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to
// drop.
}

e.dataTransfer.dropEffect = 'move'; // See the
// section on
// the
// DataTransfer
// object.
this.addClassName('over');
return false;
}

function handleDragLeave(e) {
this.removeClassName('over'); // this / e.target
// is previous
// target element.
}

function handleDrop(e) {
// this/e.target is current target element.
this.style.opacity = '1.0';
sourceDiv.style.opacity = '1.0';

if (e.stopPropagation) {
e.stopPropagation(); // Stops some browsers
// from redirecting.
}

// Stop Game when it is over
if (!gameStatus)
{

// Don't do anything if dropping the same column
// we're dragging.
if (sourceDiv != this) {

// Swap boxes only if one of them is BLANK
if (sourceDiv.innerHTML == ""
|| this.innerHTML == "") {

// Restrict box movements to one level (up,
// down, left, right)
positionDifference = Math.abs(sourceDiv.id
- this.id);

if (positionDifference == 1
|| positionDifference == 4) {

if (positionDifference == 4 || (!((sourceDiv.id%4==0 && this.id%4==1) || (sourceDiv.id%4==1 && this.id%4==0))))
{
// Set the source column's HTML to the
// HTML of the column we dropped on.
sourceDiv.innerHTML = this.innerHTML;
if (e.dataTransfer.getData('text/html') == null) {
this.innerHTML = "";
} else {
this.innerHTML = e.dataTransfer
.getData('text/html');
}

moveCount = moveCount + 1;

// Check Game Status
gameStatus = checkGameStatus();

if (gameStatus) {
if (bestMove == null || (bestMove > moveCount))
{
bestMove = moveCount;
localStorage.setItem('BEST_MOVE',bestMove);
document.getElementById("bestMove").innerHTML = bestMove + " moves";
}
document.getElementById("status").innerHTML = "You are Awesome!!. You took " + moveCount + " moves";
document.getElementById("flashMessage").innerHTML = "Game Over";
$('#flashMessage').slideDown('1000');
$('#flashMessage').delay('3000');
$('#flashMessage').slideUp('1000');
} else {
document.getElementById("status").innerHTML = "Number Of Moves :: "
+ moveCount;
}

drawCanvas();

}
else {
displayNotification();
}
}
else {
displayNotification();
}
} else {
displayNotification();
}

}
}
return false;
}

function handleDragEnd(e) {
// this/e.target is the source node.
var cols = document.querySelectorAll('.tile');
[].forEach.call(cols, function(col) {
col.removeClassName('over');
});

toggleFlashMessage();

}


$('#saveGameButton').click(function() {

if (!gameStatus)
{
for ( var i = 0; i < 16; i++) { myarray[i] = document.getElementById(i + 1).innerHTML; } localStorage.setItem('MY_ARRAY', myarray.toString()); localStorage.setItem('MOVE_COUNT', moveCount); localStorage.setItem('IMAGE_NUMBER',imageNumber); localStorage.setItem('GAME_STATUS',gameStatus); console.log("Move Count" +localStorage.getItem('MOVE_COUNT')); console.log("Image Number" +localStorage.getItem('IMAGE_NUMBER')); document.getElementById("flashMessage").innerHTML = "Game saved successfully"; $('#flashMessage').slideDown('1000'); $('#flashMessage').delay('1000'); $('#flashMessage').slideUp('1000'); } }); var cols = document.querySelectorAll('.tile'); [].forEach.call(cols, function(col) { col.addEventListener('dragstart', handleDragStart, false); col.addEventListener('dragenter', handleDragEnter, false); col.addEventListener('dragover', handleDragOver, false); col.addEventListener('dragleave', handleDragLeave, false); col.addEventListener('drop', handleDrop, false); col.addEventListener('dragend', handleDragEnd, false); }); }); function toggleFlashMessage() { $('#flashMessage').slideUp('1000'); } function initialize() { $('#notificationMessage').hide(); $('#flashMessage').hide(); if ((imageNumber = localStorage.getItem('IMAGE_NUMBER')) == null) { imageNumber = Math.floor(Math.random()*5); } if ((moveCount = localStorage.getItem('MOVE_COUNT')) == null) { moveCount = 0; document.getElementById("status").innerHTML = "Ready to start?"; } else { moveCount = parseInt(moveCount); if (moveCount != 0) { document.getElementById("status").innerHTML = "Number Of Moves :: " + moveCount; } else { document.getElementById("status").innerHTML = "Ready to start?"; } } if ((gameStatus = localStorage.getItem('GAME_STATUS')) == null) { gameStatus = 0; } else { gameStatus = parseInt(gameStatus); } if ((bestMove = localStorage.getItem('BEST_MOVE')) == null) { document.getElementById("bestMove").innerHTML = ""; } else { document.getElementById("bestMove").innerHTML = bestMove + " moves"; } if (localStorage.getItem('MY_ARRAY') == null) { // Shuffle Array Contents myarray.sort(function() { return 0.5 - Math.random(); }); } else { myarray = localStorage.getItem('MY_ARRAY').split(','); document.getElementById("flashMessage").innerHTML = "Game restored from previous session"; $('#flashMessage').slideDown('1000'); $('#flashMessage').delay('1000'); $('#flashMessage').slideUp('1000'); } // Populate Boxes with Numbers for ( var i = 0; i < myarray.length; i++) { document.getElementById(i + 1).innerHTML = myarray[i]; } drawCanvas(); } function clearStorage() { localStorage.removeItem('MOVE_COUNT'); localStorage.removeItem('MY_ARRAY'); localStorage.removeItem('IMAGE_NUMBER'); localStorage.removeItem('GAME_STATUS'); } function saveGame() { for ( var i = 0; i < 16; i++) { myarray[i] = document.getElementById(i + 1).innerHTML; } localStorage.setItem('MY_ARRAY', myarray.toString()); localStorage.setItem('MOVE_COUNT', moveCount); localStorage.setItem('IMAGE_NUMBER',imageNumber); localStorage.setItem('GAME_STATUS',gameStatus); console.log("Move Count" +localStorage.getItem('MOVE_COUNT')); console.log("Image Number" +localStorage.getItem('IMAGE_NUMBER')); } function checkGameStatus() { for ( var i = 1; i < myarray.length; i++) { var currentElement = document.getElementById(i); if (currentElement.innerHTML != i) { return 0; } } return 1; } function displayNotification() { document.getElementById("flashMessage").innerHTML = "Move not allowed"; $('#flashMessage').fadeIn('slow'); $('#flashMessage').delay(2000); $('#flashMessage').fadeOut('slow'); } function drawCanvas() { var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); canvas.width = 200; canvas.height = 200; context.clearRect(0,0,200,200); var imageObj = new Image(); imageObj.onload = function(){ // draw cropped image var x = 0; var y = 0; var x1 = 0; var y1 = 0; var width = 50; var height = 50; var element; var elementValue; var elementId; for (var i=0;i<16;i++) { element = document.getElementById(i+1); elementValue = element.innerHTML; elementId = element.id; // Handle blank box if (elementValue == null || elementValue == "") { elementValue = "16"; } x = ((elementValue-1)%4) * 50; y = parseInt(((elementValue-1)/4)) * 50; x1 = ((elementId-1)%4) * 50; y1 = parseInt(((elementId-1)/4)) * 50; context.drawImage(imageObj, x, y, width, height, x1, y1, width, height); } }; imageObj.src = imageNumber+".jpg"; }



Instructions: Create .html, .css, .js files with the above code. Download JQuery 1.6.2 to the same folder. Add 10 (jpg) images of exact size 200x200px. Have all the 14 files in the same folder.


Reference: http://www.html5rocks.com/en/tutorials/dnd/basics/

Tuesday, June 21, 2011

Java Obfuscation


Introduction
Obfuscation is the process of making a readable code difficult to understand by concealing its purpose. Obfuscated code deters reverse engineering to some extent. Obfuscator is a program that converts readable code into obfuscated code. In this article, we will see about ‘yguard’ which is an Open Source Java obfuscator and shrinking software.

Yguard Obfuscator
yguard requires Java2 SDK 1.4 or above and ANT 1.5 or greater. Yguard integrates with your deployment process (build.xml). You need to add a separate task for obfuscation in your build.xml. The yguard task contains two nested elements that perform the name obfuscation and code shrinking separately:
The shrink element removes all code elements that are not reachable from the entry points given in the nested keep element.
The rename element performs name-obfuscation, renaming all packages, classes, methods and fields according to a selectable name-mapping scheme. Elements can be excluded from the renaming process using a nested keep element.

Get Started:
Download yguard and copy the jar file ‘yguard.jar’ into the project directory.

In the above example, it is assumed that the java source files are compiled to a JAR file and that jar is the input. Yguard obfuscates the input jar and creates a new jar.

Shrink & Rename:
The shrink task removes all classes, fields and methods that are not reachable or unused. You can see the number of classes, methods or fields removed from the jar in the log file ‘shrink.log’.  The rename task does the actual obfuscation by renaming the classes, methods and fields. The details will be available in rename.xml. Using the nested keep element, you can specify all classes, methods, fields, and attributes that should be excluded from name obfuscation or shrinking. The obfuscation will fail, if yguard detects any problems during the process. The error-checking attribute with value ‘pedantic’ will make the obfuscation fail.

Adjust Element
If the class names are referred in properties/config files, yguard can replace the plain-text class names in the properties files as well via adjust element.


Known Challenges:
In Java, Obfuscation does not support Reflection API. Simple bean introspection will not work, if you decide to obfuscate your public accessor methods, since it makes use of reflection.
The customized serialization mechanism will not work if you obfuscated or shrinked the writeObject and readObject methods as well as the serializationUID field.
If you do not set the -Xmx property for the Java virtual machine, the yguard Ant task might fail due to a java.lang.OutOfMemoryError. Set export ANT_OPTS="-Xmx512M"

Is Obfuscation Important?
Obfuscation does not mean security. Still, some people believe in security through obscurity. You can think of obfuscation, if you are exposing a critical or important logic as a JAR to public. Otherwise, it will just be an extra step in deployment process. Obfuscation can't stop a determined hacker. Yet, it can save your code from newbies. It would still be better to get appropriate license and enforce law through copyrights.

References:
Yguard download link - ‘http://www.yworks.com/en/products_download.php?file=yguard-2.3.0.1.zip’.
Java Decompiler download link - http://java.decompiler.free.fr/?q=jdgui
Yguard documentation html that comes in yguard-2.3.0.1.zip.

Thursday, March 24, 2011

JSON Vs XML


An article without an introduction is like hitting on the head. It gets all fuzzy. JSON stands for JavaScript Object Notation which is a built in feature of JavaScript. It is based out of ECMA standards. XML stands for Extended Markup Language. It is W3C supported standard. JSON and XML are common data interchange format. They are mainly used to send/receive data between applications running on same or different platforms. They are well supported by open source libraries for almost all programming languages like C, C++, Java, ASP, Ruby, VB, Python, PHP, Perl, Adobe Cold Fusion. They are handy and important for mobile application developments as well. Apple's Objective C, Google's Android, RIM's Blackberry, Symbian OS they all support both JSON and XML.

Though both JSON and XML are fairly easy to understand, programmers choose JSON for its simplicity. JSON gives a Deja Vu to programmers, reminding them of their first love, The powerful C Language. The data structure format of JSON is similar to C. Web programmers prefer XML for its HTML like structure. Let's assume, your requirement is to send fire to the sun or to receive darkness from your shadow. How would you choose between JSON and XML? Someone, somewhere makes a bold move everyday. It's your turn, boss. So, What differentiates JSON and XML?

From the data exchange perspective, JSON is light weight when compared to XML. JSON is beautiful without a makeup. JSON carries no unwanted tags like namespace, unicode, internationalizations and it represents the object as it is. This makes serialization/deserialization of an object to JSON  faster than XML. This is a crucial point for Mobile Applications. Extra data transfer means extra processing, which means extra CPU, which means extra battery usage, which means unhappy users. JSON libraries are available for conversion between JSON to Java, JSON to CSV, JSON to HttpHeaders, JSON to Cookies, JSON to XML etc. GSON (Google JSON) library helps converting data between JSON and Java. It is as easy as you get a Grinder or Mixie or a TV. This conversion needs no schema. Gson's toJson(), fromJson() methods does all the conversions. It creates only one java object or JSON string. GSON library can be used on .class files when the source java file is not available (assuming the class does not have an inner class). Customized representation of objects are possible with GSON. JSON needs special attention when the object contains generics like List of objects, Maps etc.

XML is everywhere. The kingdom of XML is much more bigger than JSON. Most of the enterprise applications serve their business as Webservices (Soap Based) where XML is widely used. With RESTFul based webservices, JSON is slowly gaining popularity. Reading data from a stream or downloading a file is lot easier with XML than JSON. XML can handle data streaming with SOAP based webservices. The binary content of an entire file can be encoded as a base64 string and embedded in the XML message (for bigger files, use HTTP or FTP and don't use web services). RSS, Atom, XHTML, WSDL are all based out of XML. Apart from data interchange, XML is also used for configurations, settings replacing the traditional properties files. Spring Framework's IOC, JSF's faces-config, Strut's struts-config, Web Server's deployment descriptor, Hibernate's HBM files, Ibatis's SQL maps are all based out of XML. With such wide usage and flexibility, XML has become developer's reliable bet and is blindly used in most of the applications for data interchange as well. JAXB (Java API for XML Binding) library helps convering data between XML and Java. This conversion needs the XML schema to be known.  No conventional parsing is required. The 'marshall' / 'unmarshall' method call does all the conversion for you both ways. Understanding a Genius (JAXB) is a complex thing. I guess, you agree.

An article without a conclusion is like ending a movie at the interval. The audiences don't get a damn. With technologies evolving wisely, it becomes important to chose them wisely too. While designing enterprise applications, consider JSON to support faster data transfer, which means a lot for tablets, netbooks and mobile devices. At the same time, consider XML because most of your voters are still using the XML band and looking out for data to be transferred magically. If the amount of data to be transferred is big or for fairly complex objects, choose XML. You would not want to lose your customers. So, without rationalizations, without regrets, provide support for both JSON and XML. While developing applications for handsets like mobiles, consider JSON. Your users won't care about the beauty inside but will still be happy with your application's performance.

Saturday, December 18, 2010

HTML5 Editors

HTML5
When something new comes along, the old has to give away. Do you believe so? HTML5 is evolving and is already well supported by most of the smart phones and leading browsers. Ipad/IPhone enabled websites are all powered with HTML5. With increasing usage of Smart Phones, there is a compulsory need for every website to have a mobile friendly version. With the promising features like Offline support, enhanced multimedia, graphics, interactive Drag & Drop and advanced UI forms, HTML5 will eventually become the standard of the web.



Editors for HTML5:
The specification for this major version of HTML is not finalized yet. Probably because of this reason, there are not much HTML5 editors available for developers. Till HTML4, W3C would finalize the specification first and then the browsers and editors would start to implement them. With Google and Apple heavily backing up HTML5, browsers have started implementing the draft version of HTML5 and kept moving forward on their browse race. Developers are left with only a few options to choose their favorite editor for HTML5. The editors available on markets like Dreamweaver CS5, Aloha Editor (WYSIWYG based) are licensed and heavily priced. Web developers are forced to use Text Editors like Textpad, Editplus, Notepad++ or Eclipse IDE without any additional help for quick reference.



Eclipse & HTML5:
With the support of third party plug-in like Aptana Studio 3.0 beta, Eclipse (Version 3.4 or above) is able to provide HTML5 support for developers to some extent. The good thing about this plug-in is that, it supports code assistant for JQuery (Version 1.4.2). For web developers, this is a great boon, I would bet. The code assistant tool recognizes HTML4 tags well but eclipse will flag a compilation error for new HTML5 tags. Even the latest version of Eclipse 3.6 does not have a built in support of HTML5. Aptana has little support for CSS3 and built in Preview option for HTML files.. To install the plugin,


Netbeans & HTML5:
Netbeans.org has recently released their Beta version of IDE 7.0 with HTML5, Javascript, CSS, AJAX, JSON and JavaFX formatting support. The interesting feature about this release is that the code assistant tool is able to identify most of the HTML5 tags supported by leading browsers like Chrome, Firefox, Opera and Safari. The code assistant tool briefs the HTML5 tag syntax, attributes and the browsers that currently support the tag. It also shows example code with appropriate syntax and suggestions. The code assistant works out well for Javascript and CSS files as well but there is no support for JQuery. It also has an option to view the HTML5 specification (draft specification as of September 2010) in a separate browser. There is no need to update or install plug-ins for HTML5 support on it.












It would be great if we have the power of Aptana on Netbeans. But they themselves are competitors on Ruby and PHP front. We have to wait for Aptana Studio to fully support HTML5 or Netbeans to support JQuery. When something new comes along, it doesn’t mean that the old has to fail. They can live in harmony with one another and generate greater results. Agree?

Tuesday, December 7, 2010

Web Services - An Introduction

Hello there,
This article is for the beginners and people who are new to Web Services. I have compiled the things you need to know when you get started with Web Service. Screenshots are available in the attached document.

Web Services Introduction:
Web Services help in exposing the available services in your application to the Web thereby making your application a web application. With web services exchange of data between different applications on different platforms becomes simple. Web Services are application components that communicate using XML + HTTP. Web Services use XML to encode and decode data. It uses SOAP to transport the data.

It is composed of three elements
• SOAP – Simple Object Access Protocol (Platform independent, XML Based)
• UDDI – Universal Description, Discovery and Integration
• WSDL – Web Services Description Language

SOAP – Platform independent, XML based protocol for accessing a web service.
UDDI - A directory service where companies can register and search for Web services.
WSDL - XML based language that describes Web Services message formats and protocols.

Creating Web Services:
Web Services can be created in two ways.
• Top Down Approach (WSDL  Coding)
• Bottom Up Approach (Coding  WSDL)

Top down Approach:
In this method, the WSDL is created first using the WSDL editor. The web service wizard on eclipse can be used to create skeleton Java Classes and the desired implementation can be done on or based out of those classes. Creating the WSDL first gives more control over the web service and hence this is the recommended way of implementing a web service.

Bottom up Approach:
In this method, the desired implementation is done through coding and the service class (Java Bean or EJB) is exposed as Web Service. Web Service wizard in eclipse can help in creating the WSDL file and web service configurations corresponding to the Service class that is exposed. This method is easier and faster and used by developers who are new to Web Service.


IDE / JDK requirement:
  1. Get Eclipse 3.2 or above.
  2. Install JDK 1.4 or above.
  3. Install Tomcat 5.5 or above.
The example project here uses Eclipse 36 (Helios, Java EE IDE for Web Developers), JDK 1.6 and Tomcat 6.0.1.2

Getting Started with Web Service:
Let’s build a web service that accepts a name and says Hello. i.e. If you pass “John”, the web service will return a string “Hello John” as response. The method exposed to web here is “sayHello”.
Top Down Approach:

Create a Workspace with a dynamic web project (2.5).
Copy axis.jar, saaj.jar, jaxrpc.jar to the lib folder of WEB-INF.
Create a folder named “wsdl” inside your WEB-INF. Copy/Paste your wsdl file to that.






















Right Click on the WSDL file (Hello.wsdl), Select Web Services and Create Java Bean Skeleton.






















Web Service Wizard will pop up. Carefully note down the text fields and values. Do not change anything here. Click Next.



































Click Next



































Now your Java Bean classes are created. Click on Start Server. This will add the Web Project (Hello_Web) to the Tomcat server and start the server. You can also see the Web Service Descriptor files created inside Web Project (deploy.wsdd and undeploy.wsdd).





















Bottom Up Approach:

Create a new dynamic web project (Hello_WebWS) .
Copy axis.jar, saaj.jar, jaxrpc.jar to the lib folder inside WEB-INF.
Create a Java Class (com.webservice.sample.Hello.java) with a public method with signature “public String sayHello (String name)”. Let the method return the string “Hello + name”.






















Right Click on Hello.java Web Services Create Web Service






















Web Service Wizard will show up with Web Service type as “Bottom Up” Approach. No changes here. Click Next.


































All your public methods in Hello.java should come here. Select the methods you want to be exposed as Web Service. Click Next.


































You do not want to publish your web service now. So, click finish button here.
Your WSDL file, Web Service Descriptors (deploy.wsdd, undeploy.wsdd) are created on Web Project, and web project added to server and should be in STARTED status now.



Testing Web Services:
Testing the web service is easy and is same for both the development approaches. Right click on the WSDL, Select Test with Web Services Explorer.



































Click on the sayHello method. It will show a text field to accept the input (name). Type in “John” and click on GO. You will see the response printed on the explorer.





















Hope it helps... :)