Search This Blog

Tuesday, December 14, 2010

Struts 2 example

Lets create a simple struts application that would involve a controller , a model and a view. The following structure exists for my project : I have downloaded the struts library and placed the jar files in lib. My codes are under src. The struts only configuration file lies in the src directory. My views are under web. To get started we need to route our incoming requests to our struts dispatcher, we do it in our web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
Once this is done, we can define our controller that will handle our requests. In my case i have named it MyController and contains :

import com.opensymphony.xwork2.ActionSupport;
public class MyController extends ActionSupport {
        private User user;
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    public String execute() throws Exception {
        this.user = new User();
        user.setId(1);
        user.setUsername("user1");
        user.setPassword("password");
        return SUCCESS;
    }
}

The above controller uses User model that i have defined in User.java :

public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

execute() is the method called when request comes to the controller. In MyController we initialize the User object and set its properties. We can also access this user object from jsp rendered by this controller, we'll c that later. Remember Object getters and setters are necessary for this to work. Controller can return different results, based on which it renders different views. For example if success is returned, required view can be rendered else if error is returned error page can be shown. We define all this in struts.xml that lies in my classspath :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">


<struts>
        <package name="test" namespace="/" extends="struts-default">
            <action name="showuser" class="MyController" >
                <result name="success">index.jsp</result>
                <result name="error">error.jsp</result>
            </action>
        </package>
</struts>
In my case i have defined only one action showuser, which will route this request to MyController which will then return a result. In case of success index.jsp will be rendered, error.jsp otherwise. Now lets show the user details which were initialized in MyController in our index.jsp :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head><title>Simple jsp page</title></head>
  <body>
    <s:property value="user.id" />
    <s:property value="user.username" />
    <s:property value="user.password" />
  </body>
</html>
This will print the user id, username, password on the screen when we try to access http://localhost/showuser There is one more interesting thing to see over here, the auto wiring feature of struts. If we define Objects in the controller with its getter and setter and then pass the object as parameter in the url its value is automatically assigned to the object. For example if we add a String variable "message" in MyController and define setter and getter over it, we can use the url http://localhost/showuser?message=HelloWorld it will be printed on the page.

public class MyController extends ActionSupport {
        private User user;
        private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head><title>Simple jsp page</title></head>
  <body>
    <s:property value="message" />
  </body>
</html>

Thursday, December 9, 2010

Struts 2, Spring 3, Hibernate - The Big Picture

Today, we will get a java web application running using these three master frameworks -> Struts, Spring and Hibernate. Each one has its own speciality, that overcome some of the drawbacks of the underlying platform. Spring framework allows you to create and pass objects( java beans) at runtime using constructors or setters rather than doing it implicitly in the host class, the concept being known as Dependency Injection or Inversion of Control (IOC). This makes the classes independent, which indeed helps in testing. Spring also has other components but we wont use it here. Struts provides a Model View Controller (MVC) framework. It helps in separating your logic from the view. The controllers handle the requests, the views generate output and model represents an entity. Hibernate lets us save Persistence Java Objects/POJOs into the database and also retrieve them. All these components have their own configuration xml files. I will break up this topic into 4 parts, in 3 of them we will see how we can get these components running independently and at last using these into one application. ======================================== AN APPLICATION IN SPRING The IDE i prefer for java is IntelliJ Idea, so the initial project settings may differ based on the IDE you use. Download Spring 3 Framework here The structure of the application goes like this : Extract the Spring archive to a folder, import the jar files in dist folder to the lib folder of your project and make sure they are added to the build path. Actually all files are not required, and in Spring you get the freedom to choose only the components you need. The jar file that i have included are : commons-logging, spring-web, spring-webmvc, spring-beans, spring-context, spring-core, spring-asm, spring-expression. commons-logging jar is needed and can be found in projects/spring-build/lib/ivy of the Spring framework extracted folder. Don't forget to include Java EE library. The src folder will contain my source, within which i have defined a package in.codeconnect, my java files will go in here. The web directory contains a sub directory 'pages' where i will keep my views/jsp files. WEB-INF will contain 2 Spring configuration files : applicationContext.xml and dispatcher-servlet.xml and one server config file : web.xml. I have created 2 classes in my package : This is a simple class with getter and setter,that will contain my greeting message :

package in.codeconnect;

public class MessageClass {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
This is the Controller :

package in.codeconnect;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloWorldController implements Controller {
    private MessageClass messageObject;

    public MessageClass getMessageObject() {
        return messageObject;
    }

    public void setMessageObject(MessageClass messageObject) {
        this.messageObject = messageObject;
    }

    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
           ModelAndView modelAndView = new ModelAndView("pages/say_hello.jsp");
           modelAndView.addObject("message",messageObject.getMessage());
           return modelAndView;
    }
}
Note this class has a MessageClass object defined along with its getter and setter. handleRequest() is the function called when request comes to this contoller. Here we create a new view whose jsp is located in /pages with name say_hello.jsp. Then we add a variable that will contain our greeting message using addObject(), whose value will be equal to messageObject's message property. Lets go through the configuration files. web.xml is the main file and this is how it will look :

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> 
<context-param> <param-name>contextConfigLocation</param-name> 
<param-value>/WEB-INF/applicationContext.xml
</param-value> 
</context-param> <listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class> 
</listener> <servlet> <servlet-name>dispatcher</servlet-name> 
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class> 
<load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
<servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
It states that any request coming with .html suffix should be directed to Springs dispatcher, and this is where the action starts. applicationContext.xml can contain all beans definitions except the controller bean definition. dispatcher-servlet.xml should basically contain controller bean definition, but anything can go here. Blank applicationContext.xml :

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
</beans>
dispatcher-servlet.xml :

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
<bean name="messageObject" class="in.codeconnect.MessageClass"> 
<property name="message" value="Hello World" /> </bean> 
<bean name="/sayHello.html" class="in.codeconnect.HelloWorldController"> 
<property name="messageObject" ref="messageObject" /> 
</bean> </beans>
We can see above , we define a bean messageObject of type MessageClass and set its message using "value='Hello World'" (Dependency Injection).Here the setmessage() method of this object will be called to set message value. Next we define another bean, our controller that will be looked upon when request comes to /sayHello.html . We then specify its messageObject to be equal to the previous bean defined above using 'ref' . What is in my say_hello.jsp :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html> <head><title>Simple jsp page</title></head> 
<body>${message}</body> </html>
So When the application starts, the beans are created and then injected in order of dependency. You should see Hello World message when page loads in the browser. ${message} is one that was added using modelAndView.addObject().

Tuesday, October 26, 2010

KML in Google Maps API

There are various ways of loading layers over google maps. One way is creating spatial objects and loading it from within the Java Script. If you you do not wish to touch the Java script code an alternative is using KML (Keyhole Markup language) file. Its basically in XML format and some things need to be taken into consideration when writing one, as a single silly mistake can get on your nerves. In this example i have drawn a polygon across a small area. Below is what you will have in your html :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps KML</title>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script>
    <script type="text/javascript">
    function initialize() {
      if (GBrowserIsCompatible()) {
 var msg = document.getElementById("message");
        var map = new GMap2(document.getElementById("map_canvas"));
 var gx = new GGeoXml("http://testing.codeconnect.in/polygon5.kml");
 map.setCenter(new GLatLng(15.589200424519804, 73.81010591983795), 17);
 map.addControl(new GLargeMapControl());
        map.addOverlay(gx);
        
      }
    }  
    </script>
  </head>

  <body onload="initialize()" onunload="GUnload()">
    <div id="map_canvas" style="width: 500px; height: 300px"></div>
    <div id="message"></div>
  </body>
</html>
Object gx holds this KML file . You just have to add it as an overlay. Remember, your kml files have to on some public server and not localhost. The content of KML is as follows :

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">

<Document>
<name>polygon4.kml</name>

<Placemark>
<name>Test</name>
<Polygon>
<altitudeMode>relativeToGround</altitudeMode>
 <outerBoundaryIs>
  <LinearRing>
   <coordinates>
    73.809323,15.589077,0 
    73.809913,15.589873,0
    73.809913,15.589873,0
    73.809902,15.589858,0
    73.810229,15.589692,0
    73.810503,15.589,0
    73.810202,15.58869,0 
    73.809323,15.589077,0
   </coordinates>
  </LinearRing>
 </outerBoundaryIs>
</Polygon>
</Placemark>
</Document>

</kml>
In The KML file, the first thing that should be taken care of is namespace or xmlns="http://www.opengis.net/kml/2.2" which, if is wrong, Google won't load that kml. Each object can be displayed using Placemark which has a name and the object definition (Polygon in my case). Additionally you can add markers, polyline etc.

Wednesday, September 22, 2010

A simple GPS monitor in j2me with google maps support.

Application without google maps : 
This is a simple application that shows the device's current location coordinates on the screen. It can be built in four easy steps - 
1)Creating a canvas for displaying results. 
2)Starting a new thread so that it doesn't slow down our application. 
3)Using Location Provider object to retrieve the coordinates. 
4)Displaying the coordinates on the canvas. 

MyCanvas a canvas inherited class, which has a paintMe() function that takes 3 parameters, can be called whenever we need to refresh the screen with new data. In this case we are not using google maps so image passed can be anything else or null. LocationProvider is a class that is used to obtain gps data from the device. 
Object of this class is initialized by setting it to LocationProvider.getInstance(Criteria) , where Criteria is a class that holds the options for the LocationProvider object. 
Examples of the options would be horizontal accuracy, vertical accuracy etc. 
See how these objects are initialized below in the GpsTracker() constructor. startApp() is the entry point for the MIDlet where we create and start a new thread. run() contains the code for the thread, where we call getLocation() of Locationprovider object which returns Location object. 
We then retrieve coordinates from the Location object by calling its getQualifiedCoordinates() method. Once we have the coordinates we can call paintMe() method of MyCanvas to refresh the page.

GpsTracker.java code :

import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.location.Coordinates;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationProvider;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.*;

public class GpsTracker extends MIDlet implements CommandListener,Runnable {
 //Create options menu command
 Command exitCommand = new Command("Exit", Command.EXIT, 2);
 Command refreshCommand = new Command("Refresh", Command.OK, 3);
 Criteria cr= new Criteria();
 Display display;
 Displayable screen;
 LocationProvider lp;
 Location l;
 Coordinates c;
 Thread thread;
 Image image;
 MyCanvas canvas;
 byte[] byte_data;
 String url;
 HttpConnection httpConn = null;
 int respCode;

 
 public GpsTracker()  {
  display = Display.getDisplay(this);
  cr.setHorizontalAccuracy(500);
  
  try {
   lp= LocationProvider.getInstance(cr);
  } catch (LocationException e1) {
   e1.printStackTrace();
  }

  image = null;
  //Add options to menu
  canvas = new MyCanvas(image,0,0);
  canvas.addCommand(exitCommand);
  canvas.addCommand(refreshCommand);
  canvas.setCommandListener(this);
 }

 protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
  lp=null;
 }

 protected void pauseApp() {
 }

 protected void startApp() throws MIDletStateChangeException {  
  try {
   thread = new Thread(this);
   thread.start();
  } catch (Exception e) {
   e.printStackTrace();
  }  
 }
 
 public void exitCom() throws MIDletStateChangeException{
  notifyDestroyed();  
  destroyApp(true);
   }

 public void commandAction(Command command, Displayable d) {
  String label = command.getLabel();
     if(label.equals("Exit")){
       try {
   exitCom();
  } catch (MIDletStateChangeException e) {
   e.printStackTrace();
  }
     }
     
     else if(label.equals("Refresh")){
        refreshMap();
      } 
 }

 public void run() {
  try {
  //get location
  l = lp.getLocation(300);
  if(lp.getState()==LocationProvider.AVAILABLE){
  c = l.getQualifiedCoordinates();
  
  }
  } catch (Exception e) {
   e.printStackTrace();
  } 
  display.setCurrent(canvas);
 }
 
public void refreshMap(){
 try {
    l = lp.getLocation(300);
    if(lp.getState()==LocationProvider.AVAILABLE){
    c = l.getQualifiedCoordinates(); 
    coordinates="";
    image = null;
    canvas.paintMe(image,c.getLatitude(), c.getLongitude()); 
    }  
 }  catch (Exception e) {
  e.printStackTrace();
 } 
}
}

class MyCanvas extends Canvas{
   Image image = null; //the image to be set on the screen
   double lat = 0.0; //latitude
   double lon = 0.0; //longitude

   //constructor
   public MyCanvas(Image m,double lat1,double lon1){
     try{
       paintMe(m,lat1,lon1);
     }catch(Exception e){
       e.printStackTrace();
     }
   }

 //paint the screen
 protected void paint(Graphics g) {
  g.setColor(0xffffff);
     g.fillRect(0, 0, getWidth(), getHeight());

     if(image != null){
       g.drawImage(image, getWidth() / 2, getHeight() / 2, Graphics.HCENTER | Graphics.VCENTER);
       g.setColor(0x000000);
       g.drawString("Lat : " + lat + " Lon : " + lon,getWidth() / 2,getHeight() ,Graphics.HCENTER | Graphics.BASELINE);
     } else {
       g.setColor(0x000000);
    g.drawString("Lat : " + lat + " Lon : " + lon,getWidth() / 2,getHeight() ,Graphics.HCENTER | Graphics.BASELINE);
       g.drawString("GPS Monitor", getWidth() / 2, getHeight() / 2,  
       Graphics.HCENTER | Graphics.BASELINE);
     }
  
 }
 
 public void paintMe(Image m, double lat2, double lon2){
  this.image=m;
  this.lat=lat2;
  this.lon=lon2;
  repaint();
 }
}

Adding Google Maps to the Application With one more simple step google map can be displayed on the screen showing your current location. For that you need this GoogleMaps.java file, download it and include it in your project. Next you need to create an object of type GoogleMaps in you MIDlet, and you can call its retrieveStaticImage(height,width,latitude,longitude,zoom_level,image_format) method which will return the map image.

GoogleMaps map;
 Image image;
 image = map.retrieveStaticImage(480, 320, c.getLatitude(), c.getLongitude(), 14, "png");
 canvas.paintMe(image,c.getLatitude(), c.getLongitude());-->
You can pass this image to paintMe() to draw it on the screen. If you want to display additional details like marker, path etc on the map, modify GoogleMaps.java and modify the return url in getMapUrl() method.

Saturday, September 18, 2010

Html revisited, with WRT Applications

WRT (Web RunTime) is a powerful platform for developing applications for your nokia cellphones without compromising the simplicity of programing. It takes the simplicity down to the HTML level! yes, if you know to develop a web page you can also build an application with the same skills and efforts. You can see the power of html today -> wonderful interfaces could be build using Html/Css and robust functionalities can be given using Javascript. WRT applications or widgets contain all these three components, and these applications run on nokia S60 3rd edition and above. Lets create a small WRT application, a Tic Tac Toe game using html,css and standard javascript library. If you wish to add device dependent functionalities like using the camera etc, you have to include additional javascript library provided by nokia. A WRT installation package has '.wgz' extension and includes five files. First decide a name for your application and create a folder with same name. Then open your favorite editor and create four files in that folder. 
1)A html file, can be named anything (index.html in my case). 
2)A css file with name of your choice (style.css in my case). 
3)A Javascript file with name of your choice (jscript.js in mycase). 
4)A Plist file named info.plist where you save the application information. 
If you need an icon for your application create one and name it icon.png or with whatever extension  

The index.html code :

<html>
<head>
<title>Tic Tac Toe</title>
<script language="javascript" type="text/javascript" src="jscript.js"></script>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div id="row1"><button id="1" onclick="change(this)">?</button><button id="2" onclick="change(this)">?</button><button id="3" onclick="change(this)">?</button></div>
<div id="row2"><button id="4" onclick="change(this)">?</button><button id="5" onclick="change(this)">?</button><button id="6" onclick="change(this)">?</button></div>
<div id="row3"><button id="7" onclick="change(this)">?</button><button id="8" onclick="change(this)">?</button><button id="9" onclick="change(this)">?</button></div>
<div id="row4"><label id="label">Turn : Player1</label></div>
<button onclick="reset()">Reset</button>
</body>
</html> 
The style.css code :

button{
height:50px;
width:50px;
}
The jscript.js code :

Array.prototype.contains = function(obj) {
  var i = this.length;
  while (i--) {
    if (this[i] === obj) {
      return true;
    }
  }
  return false;
}

var win= new Array(new Array('1','2','3'),new Array('4','5','6'),new Array('7','8','9'),new Array('1','4','7'),new Array('2','5','8'),new Array('3','6','9'),new Array('1','5','9'),new Array('3','5','7'));
var arrx = new Array();
var arro = new Array();
var count=0,xcount=0,ocount=0,won=0;
function change(button){

         if(count%2==0){
   button.innerHTML="X";
          arrx[xcount]=button.id;
          button.disabled=true;
   document.getElementById("label").innerHTML="Turn : Player 2";
          count++;
          xcount++;
          if(xcount>=3){
          for(var i=0;i<8 arro="" arrx.contains="" button.disabled="true;" button.id="" button.innerhtml="O" count="" document.getelementbyid="" else="" i="" if="" innerhtml="Turn : Player 1" label="" ocount="" stop="" win="" won="1;">=3){
              for(var i=0;i<8 array="" arro.contains="" arro="new" arrx="new" code="" count="0;" disabled="false;" document.getelementbyid="" function="" i="" if="" innerhtml="?" label="" ocount="0;" reset="" stop="" win="" won="0;" xcount="0;">
The style.css code :





  DisplayName
  TicTacToe
  Identifier
  in.co.presentsoft.tictactoe
  Version
  1.0
  MainHTML
  index.html
  MiniViewEnabled
  


--> 
Note : MainHTML entry should contain the html file name as is within the 'string' tag, and DisplayName should be same as the application name and folder that you created. The Icon : The application can be tested by opening the html file in a web browser. Creating the installation package : Just add the folder with all these files to a zip archive with same name (application name), next rename the zip file extension to '.wgz' and your package is ready. Download my package here

Sunday, September 12, 2010

Jquery - Bouncing Box ScreenSaver

This tutorial will show you how to build a jquery screen saver for your site. I got this silly idea when i had to create a 'website offline' or 'website under maintenance' screen and show something more than just some lines of text. 
This Screen saver contains a box that bounces back n forth on the walls while simultaneously changing its color.The code is very simple and needs no explanation. Any elements in the html can be easily animated using a simple function in jquery -> animate(). 
You can change most of the properties of an element, and it will apply a smooth transition to these changes. animate() takes following arguments : properties : specify the new properties here. duration : the time stretch for this animation in miliseconds. easing : type of animation. callback : the function to be called when animation completes. animate(properties,duration,easing,callback) 
In properties you specify the new properties of the element, like height, width, background etc. The duration is the time deadline within which the animation should complete. 
The third argument is easing, which is the type of animation desired and includes options like swing (default, gives accelerated effect), linear (constant effect), easeOutBounce (Bouncing effect). 
In callback we can define what we need to do once the animation is over. So the complete function looks like this : $('#div-id').animate({height:100px;width:100px},2000,'linear',function(){}); 

The code

<html>
<head>
<title>Work In Progress</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script>>
<script type="text/javascript">
//By TJ
$(function(){
 var x,y,limitx,limity,color,current=0;
 limitx = $(window).width()-100; //the horizontal limit minus box width
 limity = $(window).height()-100; // the vertical limit minus box height

 function animatetop(){ //bounce the box on upper wall
  if(current==1){animatebottom();return;} //don't allow subsequent bounce on same wall
  x=Math.floor(Math.random()*limitx); //upper wall coordinates
  y=0;
  color = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')'; //generate random color, requires jquery ui
  $("#box").animate({top: y,left: x,backgroundColor: color},3000,'linear',function(){});
  current=1;
 }
 
 function animatebottom(){  //bounce the box on lower wall
  if(current==2){animatetop();return;}
  x=Math.floor(Math.random()*limitx);
  y=Math.floor(limity);
  color = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
  $("#box").animate({top: y,left: x,backgroundColor: color},3000,'linear',function(){});
  current=2;
 }

 function animateleft(){  //bounce the box on left wall
  if(current==3){animateright();return;}
  x=0;
  y=Math.floor(Math.random()*limity);
  color = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
  $("#box").animate({top: y,left: x,backgroundColor: color},3000,'linear',function(){});
  current=3;
 }

 function animateright(){  //bounce the box on right wall
  if(current==4){animateleft();return;}
  x=Math.floor(limitx);
  y=Math.floor(Math.random()*limity);
  color = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
  $("#box").animate({top: y,left: x,backgroundColor: color},3000,'linear',function(){});
  current=4;
 }

 function animate(){
  var random_num=Math.floor(Math.random()*4);
  switch(random_num){

   case 0: animatetop();
    setTimeout(animate,3000); // next animation after 3 seconds
    break;
   case 1: animatebottom();
    setTimeout(animate,3000)
    break;
   case 2: animateleft();
    setTimeout(animate,3000)
    break;
   case 3: animateright();
    setTimeout(animate,3000)
    break;
   default: animate();
    break;
  }
 }
 
 animate(); //Starting point
 
}); 
</script>
<style>
body{
   overflow:hidden;
   background:url('test.jpg');
}
#launch-date{
   padding-top:250px;
   font-size:20px;
   text-align:center;
   color:white;
}
#not-available{
   font-size:20px;
   text-align:center;
   color:white;
}
#box {
 width:100;
 height:100;
 background:#dddddd;
 position:absolute;
 z-index:-1000;
}
</style>
</head>
<body>
<div id="box"></div>
<div id="launch-date">Bouncing Box</div>
<div id="not-available">Using JQuery</div>
</body>
</html>
Below are some demos : 

 Bounce Effect :  

 Linear Effect :  

 Magnet Effect :

Friday, September 3, 2010

My first Android app - TicTacToe

As you see the market for android phones is expanding, all the major brands have released devices that run Android platform. Android being open source shows a bright future and has lot of scope for development. Today i tried creating an application on Android 2.2 platform and it is so much fun. To start creating your own apps you need to first download Android SDK (and read installation notes). This has a package manager that lets you download all the platforms you want to work on. You can also integrate it with Eclipse The SDK allows you to create virtual devices (Android Virtual Devices or AVD) on which you can test your app.



The app consists of 2 parts, one is the layout or the UI and second, the functionality. The layout is defined in an xml file. Below is the main.xml file code for my TicTacToe application.




The layout structure is similar to html if you see, you have tables, buttons, labels, textfields at your disposal.

The functionality is defined in java language. Below are the contents of my java file.



onCreate() is a function that is called when app starts so you can mark you entry point there. setContentView() lets you set one of the layouts available. findViewById() is used to map the elements in the xml to objects in java (for eg. buttons).

These two components are integrated in a way that allows cross access to resources.
Download the TicTacToe Android source here and the TicTacToe Android application package here.

Sunday, August 29, 2010

LDAP - Creating the root

To start with, we will need a root node under which other nodes will be stored. To store our data we need to dedicate a database to it. In this case we will use Berkley's DB (BDB or HDB).
Creating A Database :
Move to /etc/ldap ,Create a directory 'data' and move into it. Create a file in the current directory and name it db.ldif. Add the following content to it.

# Load dynamic backend modules
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: {0}back_hdb

# Create the database
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=example,dc=com
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: 12345
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn,mail pres,eq,approx,sub
olcDbIndex: objectClass eq

Save it
Here we define our root node called as, and identified by DN (distinguished name) 'dc=example,dc=com'. We also create an admin for that node with password 12345, required for performing any actions on the root. Again, the password used here is plaintext and this password is used when we alter or perform any action within the root. You will see olcDbIndex attribute which tells the server what attributes it has to index.
Run
$sudo ldapadd -W -D 'cn=admin,cn=config' -f db.ldif
This will create your database. It will ask for a password which is the LDAP admin password we defined when creating an admin for the server (1234).

Next we create an entry for our root node. Create a file called root-node.ldif with following code.

dn: dc=example,dc=com
objectClass: dcObject
objectclass: organization
o: example.com
dc: example
description: My LDAP Root

Then run
$sudo ldapadd -W -D 'cn=admin,dc=example,dc=com' -f base.ldif
It will prompt for a password, which now is the password we defined in db.ldif, for the root node (12345).
Now our root is ready. Lets add child nodes to it, say for example, the organization 'example.com' has departments.
Create a new file departments.ldif and add data below to it.

dn: ou=department1,dc=example,dc=com
objectClass: organizationalUnit
ou: department1

dn: ou=department2,dc=example,dc=com
objectClass: organizationalUnit
ou: department2

Then add it.
$sudo ldapadd -W -D 'cn=admin,dc=example,dc=com' -f dept.ldif
Enter password (12345 in my case) and it should be added.
Find it in the root node.
$sudo ldapsearch -W -D 'cn=admin,dc=example,dc=com' -b 'dc=example,dc=com'
You will see entries for department1 and department2

Now lets add employees to the departments
For attributes or employees to be identified we have to add schemas(available in /etc/ldap/schema) to cn=config. Other way is including the path in the ldif file itself.
$sudo ldapadd -W -D 'cn=admin,cn=config' -f /etc/ldap/schema/cosine.ldif
$sudo ldapadd -W -D 'cn=admin,cn=config' -f /etc/ldap/schema/inetorgperson.ldif
Password is 1234 because this is cn=config

In emp.ldif file

dn: uid=johnsmar,ou=department1,dc=example,dc=com
objectClass: inetOrgPerson
sn: Smart
cn: John Smart
mail: john.smart@example.com
postalCode: 31000
mobile: +33 (0)6 654321
title: Supervisor
postalAddress: h23, smart lane

dn: uid=tonygeek,ou=department1,dc=example,dc=com
objectClass: inetOrgPerson
sn: Geek
cn: Tony Geek
mail: tony.geek@example.com
postalCode: 31001
mobile: +33 (0)6 123456
title: Clerk
postalAddress: h26, geek tower

dn: uid=davidlazy,ou=department2,dc=example,dc=com
objectClass: inetOrgPerson
sn: Lazy
cn: David Lazy
mail: david.lazy@example.com
postalCode: 31000
mobile: +33 (0)6 78987
title: Supervisor
postalAddress: h27, lazy street

Then
$sudo ldapadd -W -D 'cn=admin,dc=example,dc=com' -f emp.ldif
This will add 3 employees,2 (john and tony) to department1 and 1 (david) to department2.

$sudo ldapsearch -W -D 'cn=admin,dc=example,dc=com' -b 'dc=example,dc=com'
You should get the entire hierarchy now.

Got my LDAP server finally running and up on Ubuntu.

In some discussion on database performance i came across this term called LDAP. LDAP (Lightweight Directory Access Protocol), yes sounds simple but i almost spent a whole day understanding what it is and getting its server(OpenLDAP) running on Ubuntu. LDAP is a protocol(Not a database or dbms) and from what i understood, its 'like' an interface for data that makes retrieval easy and quick. It represents data in the form of directories (hierarchy,tree). There is a root node under which all your data is stored as child nodes. The fact that its quick is due to its ability to maintain an index for desired attributes. But the performance of LDAP usually depends on where it is been used. For optimal performance, the reads are expected to be huge compared to writes. The reason being the index, which in opposite case will need lots of updates and make it slow.

The form in which the data is represented by LDAP may not be how it is stored. LDAP can use different backends to save its data, like berkleys database (bdb), mysql etc you just need to specify which one to use and not how to use.

Next thing was to run the OpenLDAP server, and was heck of a job. OpenLDAP went a crucial change but its documentation did not. I referred to old documentations initially (readily available) and found most of the things missing in my current server, specially the slapd.conf configuration of the OpenLDAP server slapd. Later i came to know that versions from 2.3 allow dynamically configuring the server and does not use slapd.conf for this purpose. slapd.conf may be still used but any updates to it need server restart.

What i Expected
During installation process it was supposed to ask for a fresh password.
There was supposed to be slapd.conf.

What i found
No password is asked. So there is some other way of configuring your server.
slapd.conf in new versions is replaced by slapd.d or cn=config which holds the ACLs or access control list, backend information and root information.

Installing OpenLDAP on Ubuntu
$sudo apt-get install slapd ldap-utils
The server and utilities will be installed and the slapd server will start.
To completely remove the OpenLDAP for fresh install :
$sudo dpkg --remove slapd ldap-utils
$sudo dpkg --purge slapd ldap-utils
To configure(initial) OpenLDAP :
$sudo dpkg-reconfigure slapd
To start,stop,restart :
$sudo /etc/init.d/slapd start
$sudo /etc/init.d/slapd stop
$sudo /etc/init.d/slapd restart

Creating Admin
Since no password was asked during installation we will have to create one for us.
It is better we create a separate directory to store our ldif files, say initialize created in /etc/ldap. ldif (ldap data interchange format) files are used as a medium for communicating to the server. Move to the initialize directory.
$cd /etc/ldap
$sudo mkdir initialize
$cd /initialize
Create a file called admin-create.ldif which will contain our new password.
$sudo nano admin-create.ldif
Change the password(olcRootPW) and paste this code into above file :

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=admin,cn=config

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: 1234

Save it.
The password used above is in plaintext and not secure. To generate encrypted password use slappasswd utility.
$slappasswd -h {MD5}
$slappasswd -h {SSHA}

Next we have to add that information it to cn=config like this :
$sudo ldapadd -Y EXTERNAL -H ldapi:/// -f admin-create.ldif
Admin has been created.

Trying the admin privileges.
$sudo ldapsearch -W -D 'cn=admin,cn=config' -b 'cn=config'
You will get lots of entries, one showing your password if it is not encrypted.

Please feel free to correct me if i am wrong or my concepts are wrong.
In my next post i will write about creating root node and adding child nodes.
Code Connect

Thursday, August 26, 2010

Connect Java with MySql database

This is a simple Java code which connects to a mysql database, adds and retrieves data from it. For that purpose we will need the mysql driver for java, which can be downloaded here : MysqlConnectorJava
Extract it to a appropriate location (preferably where java is installed)
The folder contains the driver file named mysql-connector-java-5.1.8-bin.jar whose location has to be added to the CLASSPATH so that java finds it.

In windows CLASSPATH can be accessed from My Computer(right click)->properties->Advanced tab->Environment Variables. In system variables if you see a variable named CLASSPATH, edit it and append the driver path for ex. 'C:\j2sdk1.4.2_15\mysql-connector-java-5.1.8\mysql-connector-java-5.1.8-bin.jar' to the existing value with ';' seperating each entry in classpath.

Or open the command prompt and type -> 

set CLASSPATH=%CLASSPATH%;C:\j2sdk1.4.2_15\mysql-connector-java-5.1.8\mysql-connector-java-5.1.8-bin.jar

replacing my path with yours. Type set CLASSPATH to verify if it has been added to CLASSPATH variable.

In linux shell>
setenv CLASSPATH /path/mysql-connector-java-[ver]-bin.jar:$CLASSPATH

The following code is supposed to create a database, add data to it, read the added data and finally drop the database. The database user is 'root' with password 'password'

The Code


Wednesday, August 25, 2010

Show IFrame content in plain-text using javascript/jquery

Today i was working on a html page, wherein another page would be displayed in an iframe and the user gets an option to see the iframe's html. Using raw javascript it became bit confusing and i didn't get the desired result , so i switched over to my favorite jquery. Jquery fulfilled 2 of my requirements at once. First one was retrieving the code and second converting html characters to corresponding html character codes so that it shows up as text and not in rendered form. Next it would display the text in a textarea.

Note: Only content on local domain is accessible for security purpose, so it may not be possible to show html content of pages external to the local domain even though the page loads in iframe.

Key Components :
$.get(url,callback-function) : A get request for retrieving the iframe html page
$('textarea').text(data) : For html conversion

How it works :
On a click of the specified entity, the jquery makes a request for the desired page using $.post() function. The iframe source url is retrieved using $('iframe').attr('src'). $get(url,callback-function) in this case takes 2 arguments, the url will be the iframe location and callback-function is the function called on the event of success. The callback-function gets the received data as argument
In the callback-function we use $('textarea').text(data) to convert the received data to code form and set it as the content of textarea.

The Code :




Wednesday, August 18, 2010

Time for some SEO

This blog is new and not yet been indexed by any search engines. So i will start the experiment of getting my blog indexed by using some of the primary techniques that i learnt while running my previous blogs.
First interesting thing to notice is that google quickly notices new blogs on blogger/blogspot, the reason being simple, google owns it. So if you are planning to start a blog, it is preferred to get one on blogger and later switch (provided domain name remains same).
Next on the list is submitting your blog link to social bookmarking (SB) sites. The reason being, the content of these SB sites frequently change as a result google bot also has to make frequent visits there to keep its data updated. Google will index your pages once it finds your blog link on such sites. I have built up a list of some social bookmarking sites.

Add your sites here :
Twitter
Digg
Mybloglog
Technorati
Blogcatalog

I added my blog to all these, and the quickest one to show my blog in google search was digg (same day), next day result from technorati showed up.

You can use one of the following tools to ping/notify the major search engines.

Ping Tools :
Pingoat
Pingomatic
Ipings

Tuesday, August 17, 2010

Add Settings/Options Page To Wordpress Theme


If you have developed a theme for wordpress and wondering if you could have a settings/options page, here is a quick tutorial. Having a custom theme settings page has its own advantage over hard-coding it. It avoids frequent edits to code, eases and simplifies operation, saves time and has lot many other benefits. Okay so lets move on.



The Logic :
Wordpress is a powerful framework that lets you add so many functionalities to your site. In this case we are concerned about what are called as 'hooks' that wordpress provides. Hooks are of 2 types Action and filter. As the name suggests action hooks are meant to perform some action on occurrence of some event while latter is used to modify the existing functions as per your convenience.

Here we make use of action hooks. I will be creating a settings page that will allow editing a custom content say a marquee somewhere on the page. To start with, we open the functions.php file, which is included on every page as long as your theme is active. Here we get a chance to define our starting or triggering point. We start off by registering our action hooks. We will use 3 hooks :
1)admin_menu : actions to be performed when admin enters the control panel or settings
2)switch_theme : actions to be performed when admin changes the theme
3)wp_head : actions to add something in the head section when header is requested.

Initialization :
Unfortunately there is no hook to define our initialization routine. So we use another method to detect theme change from previous theme to your theme. We analyze the parameters in the url for keyword 'activated' while on 'themes.php' page.
The code :



This code above will go into functions.php anywhere after the initial declarations. It will create a table in database called wp-prefix_mytheme_data where we can store our theme data. Manipulate the query based on your needs.

Registration :
We will use admin_menu hook to add our Theme Settings link to the sidebar.
The Code :



The above hook will call the add_to_menu function which will register the settings page defined in settings_form function.

In action :
We will use wp_head to add data(java scripts) to the head section.
The Code :



The above code will add jquery and jquery code to the head. In my theme i will have a div with id="marque-area", and the marquee with my data will be added within this div.

Unregister :
we will use switch_theme to destroy all the data after theme deactivation
The Code :



We have destroyed everything we had created as user no longer uses our theme.

Combine these codes into one contineous code and add it anywhere in functions.php file(Take care of php open and close tags)
Final Code :


Monday, August 16, 2010

Image preloaders and progress bar : Part 3

Till now we have seen how we can tackle with the images within the html code. But in most cases the number of images in CSS is much greater than the img tags within the html. Also we cannot use our normal element referring for css images. So we have to extract them ourself.



The logic :
First we grab all the css linked to the html document, merge them into one and then search for the images. The images are identified by their extension. So we use a regular expression to get the image url within background-image:Url('') property. We also have to extract all inline image urls using jquery. Next we merge both these lists of css and inline images and start preloading.

The Issues :
The first issue that come up when implementing this technique is the way in which the browser represents the url in css. For eg. Firefox uses a relative url (/images/xyz.jpg) where as chrome uses an absolute url (http://yoursite.com/images/xyz.jpg).
The second issue is the way in which css content is retrieved by browsers. In IE stylesheet content is retrieved by using StylesheetObject.cssRules.cssText whereas in other browsers it is retrieved using StylesheetObject.cssText.

The Code :






Still this code is not 100% compatible and will work only for css images that are referenced using url relative to the root (eg. /images/xyz.jpg). But i guess u must have got an idea of what i am trying to do. If you have any ideas please post them in comments.
This ends up the preloader tutorial. Have a nice day :)

Saturday, August 14, 2010

Image preloaders and progress bar : Part 2

In the previous post we had seen how we can create a simple progress bar, but it did not have any image preloader script and just depended on 2 events. In this post we will see how we can create a progress bar with simple image preloader, this means it will show the actual progress based on the total images loaded.


The Logic :
The basic requirement for this script is the knowledge of how many images exist. So for that purpose we have to count the number of images in the document. In this simple preloader, we will consider only the images in img tags. Jquery provides a powerful function for counting these or any other tags. We just have to say $('img').length() and we get the total count of the given element. Next we find the percentage each image contributes to the total.
Once we have the count we have to find the sources of these images so that they can be loaded one by one. While loading the image we also assign event trigger to the image so that it notifies us that it is loaded and we can proceed with incrementing the progressbar by the smallest percentage.
Once the percentage reaches 100% we can fade out the overlay screen.

The code :




So this was a simple preloader with progress bar which took all the html images into consideration. In our next post we will make our script a bit complex by taking the css images into consideration.

Have a nice day :)

Tuesday, August 10, 2010

Image preloaders and progress bar : Part 1

Are you looking for a preloader that shows a loading screen while your page is been loaded?. Here is a quick tutorial on creating one.


The Theory :
Lets look into the page components that should be taken into consideration while showing the load progress. First is the document itself that is been loaded which is pretty small and also cannot be analyzed as that itself will contain our preloader code. Next components are external stylesheets, scripts and other linked materials. Browser usually loads them before executing any javascript. So this either cannot be counted. The major components are images which are usually large in number and huge as well. In this tutorial we will use jquery for animating the progressbar. We will first make a simple preloader with a progressbar. Lets take a quick look on two functions in javascript/jquery: $(document).ready() and $(window).load() . The first function,as the name suggests, is called by the browser as soon as the script is completely loaded. This marks the start point of our preloader. The second function is called by the browser when all the components on the page are loaded. This marks the end point.

First lets create a simple preloader with progress bar :

The Logic :
We will divide the page contents into 2 parts(50% + 50%) : The text and The images. The point at which our script will start will give an indication that the html text has been loaded. At this point $(document).ready() will be triggered. Hence we can increment the progressbar to 50% of its area. Next the loading of images will occur, and once complete it will call $(window).load(). Now we can increment the progressbar to 100%, following it, a fade out effect.

The code :





This was a simple preloader... in the next post we shall consider counting the total images and then showing the real progress on the progressbar.

Sunday, August 1, 2010

What Programming is all about.

Okay this is my first post on this blog. This post closely relates to my life in the journey of programming. Today most of us are dependent on computers, may be it for work, for leisure or rather most of our work. Its surprising to see the advancement done in this field. There were days when a simple '16 bit' games like Dangerous Dave were favourites and downloading an mp3 used to take an hour. But advancement in hardware has led to even faster advancement in software. So a person entering this field of programming has to cope up with the current speed. The outdated technologies may have been vanished from the software industry but have always served as a base for new ones. Here in this post i am listing the primary languages that a programmer should know in chronological order. I'd like to start off with an overview of kinds of programming a programmer is involved in. I like to classify these kinds based on the following three fields :

1) Embedded Systems Software
2) Computers Software
3) Web applications

The reason behind this classification being, each of them can survive as an independent industry.

The niche of embedded systems deals with programming the microcontrollers. The language used for programming these tiny microcontrollers is Assembly language. Each microcontroller has its own set of instructions (Instruction set) but the basic instructions remain the same. This language is easy to learn and the real deal is watching these programs in action. You could write programs to turn on or off the LEDs, run a stepper motor, do some calculations, communicate to other devices, etc. These microcontrollers are now available at a very low costs. One of the famous 8 bit µC(microcontroller) is 8051, which has 128 bytes RAM and 4Kb of ROM. Since most of the µCs have ROM to store programs, testing becomes a difficult part. Hence the program needs to be finalized first, then tested and once its bug free it is burnt on the ROM. You must be wondering about how one could test the program without burning it on the µC?. The answer is using Simulators. Simulators create an environment similar to the µC on the computer. They have all the features and resources that a µC has (resources being virtual), but also includes extra tools which help in debugging (The primary reason for using simulators). You can actually monitor the running of program and the resources used and once satisfied you can burn the program on the µC. One of the simulator which simulates 8051 µC is EdSim51. Here are some interesting examples of 8051 programs by Mike Predko. Complex embedded systems make use of operating systems like embedded linux, specially designed to take care of limitations of the system(eg. mobile) and use modules to do application specific tasks.

Now lets move on to computer softwares. Usually programmers start with learning languages like C. C is a powerful language which can be used to write programs ranging from simple console applications to applications with GUI(Graphical User Interface). It serves as a strong base to learning the programming techniques. It gives the 1st feeling of what programming is. Once familiar with the syntax and data structures, next stage introduces a new language C++ with new concept. C++ is an object oriented programming (OOP) language where everything is considered as an object. The syntax however remains similar to C. C++ is usually followed by adapting to Java, another powerful OOP language which claims to be platform independent, ie. it can run on any machine unlike C and C++. Syntax is a bit different but influenced by C and C++. Next comes a language which is widely used to create applications with GUI easily and called Visual Basic(VB). It is an event driven programming language by Microsoft i.e. doing a particular task when something occurs. eg. showing a message on button click where button click is an event and showing of message is a task. At this stage, there is also a need felt to efficiently store data, where Databases come into picture. GUI serves as the front end while database serves as the back end. Microsoft provided an Integrated Development Environment (IDE) for developing VB applications. Structured Query Language (SQL) is a common language to query the databases.
VB was followed by VB.NET which added more features and functionality to existing VB.

Web is a very interesting and one of the very advanced field. Today every one is aware of web and taking the full advantage of it. Its members are increasing from the users side as well as developers side. Okay so lets start with the basic element of world wide web, the HTML(Hyper Text Markup Language). Using HTML we could create web pages, but it did not give it a professional look. To make it better CSS (Cascaded Style Sheets) were used which allowed elements in the HTML to be styled and properly arranged, made web pages eye catching. But it still did not make it interactive. DHTML(Dynamic HTML) added features that would make page interactive to some extent. To make it even more interactive JavaScript was used. Since all of the pages with these technologies used to sit on clients machine it was unsafe to supply sensitive data with the pages. Hence server side scripting was in need. ASP (Active server pages),JSP (Java server pages), PHP (Hypertext Pre-processor) are some of the server side scripting languages and used with databases to provide interactive sessions to the users. Among them PHP is the popular one, and my favourite.

This post was not intended to teach any language or any technology, but to give an idea of what a person learns along the time line to the newcomers in this field.

I'll make sure the next posts aren't so dry as these :)