Monday, December 26, 2011

How does servlet instances share variable instances in a servlet container

On my post about Java class loader and static variable, I was asked if a static member shared for all user of a web application?

The quick answer is Yes. A static variable in a class used in a Servlet will be shared by all users who access the same application. However, to be precisely, A static member of class used in Servlet class will be shared by all instances of that servlet class. It is not just all user (or user's request). One servlet can be configured to have multiple instances in servlet engine.

If we only want to share variable among different user access to one servlet instance, we do not need to declare it as static. We can simply put it as global variable in our servlet class. This is actually topic about thread safe servlet programming.

We can also store variable in ServletContext if we want to share variable among different instances of servlet and it does not matter for other servlets in same context to see it.

Below is code to determine how static variable act inside servlet.

Step 1, Create a dummy class having static field.
/**
 *
 * @author Yiyu Jia
 */
public class DummyClass {
    //declare a static member.
    //This variable will be used as counter.
    static int jia = 0;    
}

Step 2, Create a servlet to validate variable values.
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Yiyu Jia
 */
public class TestStaticServlet extends HttpServlet {

    static int classCount = 0;  // shared by all servlet instances
    int count = 0;              // separate for each servlet
    static Hashtable instances = new Hashtable();  // also shared

    DummyClass jia = new DummyClass();

    /** 
     * Processes requests for both HTTP GET and POST methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

            jia.jia++;
            count++;
            out.println("Since loading, this servlet instance has been accessed "
                    + count + " times.
" );

            // Keep track of the instance count by putting a reference to this
            // instance in a Hashtable. Duplicate entries are ignored.
            // The size() method returns the number of unique instances stored.
            instances.put(this, this);
            out.println("There are currently "
                    + instances.size() + " instances.
");

            classCount++;
            out.println("Across all instances, this servlet class has been "
                    + "accessed " + classCount + " times.
");

            out.println("jia static value:  " + jia.jia + "
");

        } finally {
            out.close();
        }
    }

    // 
    /** 
     * Handles the HTTP GET method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP POST method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// 
}

Step 3: Configure two instance for one servlet in web.xml

    
        TestStaticServlet
        TestStaticServlet
    
    
        TestStaticServlet
        /TestStaticServlet
    
    
        TestStaticServlet2
        TestStaticServlet
    
    
        TestStaticServlet2
        /TestStaticServlet2
    
    
        
            30
        
    
    
        index.jsp
    


Step 4: Now, we can deploy and access two different instance throw web browser.
URL one: http://localhost:8080/ServletStatic/TestStaticServlet

URL two: http://localhost:8080/ServletStatic/TestStaticServlet2

Step 5: We see something like below as result in web browser

Monday, December 19, 2011

Seven ways to stored data in local through Web application.

To develop Web application, especially for mobile web application, one question is often asked is how can I store data in local. Particularly, how can we store large size of data in local disk? My answer is there should be no problem to do this. There must be technique to solve this issue as there are demand from market. This post is a collection of local storage methods, which I can think so far.

  1. HTTP cookies All developers know that HTTP cookies is designed to allow Web developer to store some data on browser side. But, it is also well know that its size limitation is small. The very cookies' maximum size could be different among different browsers. Maximum number of cookies may be different among different browsers. Using the number limitation of cookies per domain, we may find way to enlarge the imitation by deploy Web application among several servers having different Sub domain name.
  2. Flah player Because of mean of cookie, web developer go to Flah player for larger local storage size. By default, Flash player embedded in a Browser has 1MB limitation of local storage. But, user can adjust it until unlimited. Ext JS 3.x uses Flash local storage too.
  3. bookmarklet Since bookmarklet store javascript code locally, I can think that we can use it to pursue certain degree of local storage capability.
  4. Web Cache By configure Web server, we can ask browser to cache certain content on client side. Here is an example from Sencha web site:
    Taking Sencha Touch Apps Offline
  5. HTML 5 local storage A good news from HTML 5 is that HTML 5 compatible browser may support HTML 5 local storage. Its W3C recommended size limitation is 5M but some browser allow it be expandable.
  6. Web SQL database To have even larger local storage, we can use Web SQL database. Here is a list of When can I use Web SQL Database?. Here is an example usage: http://rem.im/html5-tweet-time-range.html
  7. Using Web browser wrapper Titanium and phoneGap are two popular web browser wrapper on mobile devices. Using this kind technology, the local storage space goes to almost unlimited.


Thursday, December 8, 2011

java vs php benchmark (cited from The Computer Language Benchmarks Game )

I saw a benchmark between Java 7 and PHP. I do not know how precisely the benchmark is. But, I will believe this result. Besides running speed and memory usage, there are many other factors affect us to choose Java or PHP as programming language. But, it is always interesting and valuable to be able to have a rough idea about this kind comparison.

Below is cited from http://shootout.alioth.debian.org/ . Interested can go there for detail.

This chart shows 3 comparisons - Time-used, Memory-used and Code-used ~ speed and size.
Each chart bar shows, for one unidentified benchmark, how much the fastest Java 7 -server program used compared to the fastest PHP program.

Saturday, November 26, 2011

Mapping SQL terminology with IBM i terminology

As a IBMi developer coming with background of modern SQL RDBMS, I was always try to "translate" iSerience term like "physical file", "logical file" into SQL terms. Here, I found a table, which maps these terms.

Mapping SQL terminology with IBM i terminology
SQL termIBM i term
TABLE PHYSICAL FILE
ROW RECORD
COLUMN FIELD
INDEX KEYED LOGICAL FILE
VIEW NON-KEYED LOGICAL FILE
SCHEMA LIBRARY
LOG JOURNAL
ISOLATION LEVEL COMMITMENT CONTROLE LEVEL
PARTITION MEMBER


The table is cited from document IBM DB2 for i indexing methods and strategies

Friday, November 18, 2011

IBM DB2 extension has no limitation on number of opened persistent PHP DB2 connection.

To further study how to optimize PHP DB2 connection, I looked into PHP DB2 extension again recently. I want to find out the best way to use persist connection with considering about ODP reusing.

After reading the source code of PHP DB2 extension, I noticed that there is no limitation of maximum number of pconnection from PHP DB2 extension. In the C code, we can see only UserID, password, and Database name are used to compose hash code. You locate the place by search following code in the source code.

sprintf(hKey, "__db2_%s.%s.%s", uid, database, password);

This is interesting as it implies that I should avoid allowing huge number of different user profile to be used inside one Zend Server.

I am thinking that we will have difficult to reuse ODP when only userId, password, and database name are used to generate hash code for pconnect because ODP will be reused based on not only user name and password. For example, I think the ODP will be rebuilt if different requests use same User Name and password but different library list to get pconnection. PHP Db2 extension allows us to pass in library list. So, if developers, for some reason, happen to pass in different library list to run query on same library, the ODP will be rebuilt for sure.

Some other things I do not have answers are,

1) What happens to pconnection if its associated QSQSRVR job is terminated for some reason?

2) I saw something about ODBC version occur in C code. Does PHP DB2 extension works with ODBC in any way?

Tuesday, November 8, 2011

A simple example about creating DB2 SQL stored procedure to return multiple Result Set

There are plenty of examples showing how to get multiple result sets in languages like Java or php. But, there are not so many simple stored procedure examples, which return multiple result sets. Here is a very simple DB2 stored procedure, which return two result set. Just following the steps, you will have a multiple results DB2 stored procedure for testing.

Step 1: Create a table:
CREATE TABLE DEPT
     (DEPTNO   CHAR(3)     NOT NULL,
      DEPTNAME VARCHAR(36) NOT NULL,
      PRIMARY KEY(DEPTNO))

Step 2: Populate data into table:
INSERT INTO DEPT (DEPTNO, DEPTNAME)
     VALUES ('B11', 'PURCHASING'),
            ('E41', 'DATABASE ADMINISTRATION') ;

Step 3: Create SQL store procedure:
CREATE PROCEDURE TESTMULTIRS
--We do not use this input parameter.
(IN i_cmacct CHARACTER(5)) 
RESULT SETS 2
LANGUAGE SQL
BEGIN 

DECLARE csnum INTEGER;

--Declare serial cursors as serial cursor consume less resources
--and we do not need rollable cursor.
DECLARE getDeptNo CHAR(50); --Be careful about estimated length here.
DECLARE getDeptName CHAR(200);
DECLARE c1 CURSOR WITH RETURN FOR s1; 
DECLARE c2 CURSOR WITH RETURN FOR s2;

SET getDeptNo = 'SELECT DEPTNO FROM DEPT';
SET getDeptName = 'SELECT DEPTNAME FROM DEPT'; 

PREPARE s1 FROM getDeptNo;
OPEN c1;

PREPARE s2 FROM getDeptName;
OPEN c2;

END;

Step 4: Call stored procedure in iNavigator:
call testmultirs('jia');

Then we can see outpu as below in inavigator:
and

Wednesday, October 26, 2011

A simple tutorial about Exception handling in Jersey 1.1.5

There are at least three ways for us to deal with Exception in Jersey RESTful framework.

  1. Create a WebApplicationException instance and throw it in code.
  2. Extending your own Exception from WebApplicationException and throw your own exception in code
  3. creating an ExceptionMapper to have chance to further customize response upon exception.

This simple tutorial shows how to map our own defined exception in Jersey. Code has been created and tested in netbeans 6.9.1 with Jersey version 1.1.5 and Tomcat 6.

creating our dummy runtime exception class

package jia.blog;

public class JiaAppException extends RuntimeException{

    public JiaAppException( String message ) {
        super( message );
    }

}

Create our testing Web service

package jia.blog;

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;

/**
 * REST Web Service
 *
 * @author Yiyu Jia
 */

@Path("generic")
public class WSTester {
    @Context
    private UriInfo context;

    /** Creates a new instance of WSTester */
    public WSTester() {
    }

    /**
     * Retrieves representation of an instance of jia.blog.WSTester
     * @return an instance of java.lang.String
     */
    @GET
    @Produces("application/xml")
    public String getXml() {        
         throw new JiaAppException("Sorry. You are not allowed to access this resource.");
    }

}

Creating Exception Mapper class

package jia.blog;

import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

/**
 *
 * @author Yiyu Jia
 */

@Provider
public class JiaExceptionMapper implements ExceptionMapper< jiaappexception > {

    @Override
    public Response toResponse(JiaAppException jiaException) {
        
        GenericEntity ge = new GenericEntity < string > ( jiaException.getMessage ( ) ) { };

        return Response.status(Response.Status.FORBIDDEN).
                entity(ge).build();
    }
}


The web.xml file

Note: no servlet init param 'com.sun.jersey.config.property.packages'

    
        ServletAdaptor
        com.sun.jersey.spi.container.servlet.ServletContainer       
        1
    
    
        ServletAdaptor
        /resources/*
    
    
        
            30
        
    
    
        index.jsp
    


Test it

If you deploy web app on tomcat running on localhost and listen on port 8080, you test by pointing web browser to access URL http://localhost:8080/JerseyTest/resources/generic .

Wednesday, October 19, 2011

Why does DB2 not use Index I created?!

Recently, I heard a guy cried that the DB2 for iSeriese does not use index he created. Then, I asked him if he has check the size of table. The answer is NO!

So, it seems that some developers do not aware that a RDBMS' query optimizer may not use index though indexes are created to optimize SQL query speed. In fact, DBMS normally have its own algorithm to decide when to use index scan or table scan in a SQL query. In general, DBMS should use index scan instead of full table scan only when size of index is smaller than size of table. Otherwise, there is no point for DBMS to use index. This is true for DB2, MySQL, Oracle, MS SQL etc.

How to create index or combined index and how many index should be created for a table is big topic. But, we shall know that index may not be always used when SQL query optimizer thinks it is not worthy. This is most likely true for a new launched application, which has not received/created many data in tables. So, do not cry that DBMS is suck that it does not use indexes. Check your table size first. Then, check your DBMS configuration. For example, MySQL has configurable threshold value, which determine when query optimizer can use index instead of full table scan. But, you can not force SQL query optimizer to use index. The most we can do is configuring table to prefer index scan than table scan.

Here is a more detailed discussion about "magic number".

Tuesday, October 18, 2011

Java Class loader and static variable and JVM memory management.

We always say that there is only one copy of static fields of a class in JVM memory. This is incorrect. At least, it is not precise. The precise statement should be "there is only one copy of static fields of class for each class loader in one JVM". In other words, we will have multiple copies of static fields in one JVM memory if we use different ClassLoaders to load same class into one JVM.

Different JVM vendor may have different ways to do JVM memory management. But, I think it will be common for JVM to have class initializer and instance initializer. static fields in class is initialized in class initializer. Using hotspot as example, "instanceKlass" in JVM contains static fields. To understand more about java memory management, these articles may be helpful. Presenting the Permanent Generation , OpenJDK Storage management, and JVM spec.

But, we are not guys who are able to create JVM. So, let's use our ways to determine this. What we will do here are
  1. Create our own class loader.
  2. Create a simple Java class which has static field for testing.
  3. Create two instances of our own class loader and let them to load class.
  4. Changing static field value in one loaded class instance and see if the rest one has changed field or not. 
  5. We will say that static fields defined in same class have different copies in memory if their containing class is loaded into memory by different classloader.

getting a class loader from JavaBlogging and slightly modified it as below.

package jia.blog;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * Our custom implementation of the ClassLoader.
 * For any of classes from "javablogging" package
 * it will use its {@link CustomClassLoader#getClass()}
 * method to load it from the specific .class file. For any
 * other class it will use the super.loadClass() method
 * from ClassLoader, which will eventually pass the
 * request to the parent.
 *
 */
public class JiaClassLoader extends ClassLoader {

    /**
     * Parent ClassLoader passed to this constructor
     * will be used if this ClassLoader can not resolve a
     * particular class.
     *
     * @param parent Parent ClassLoader
     *              (may be from getClass().getClassLoader())
     */
    public JiaClassLoader() {
        super(JiaClassLoader.class.getClassLoader());
    }

    /**
     * Loads a given class from .class file just like
     * the default ClassLoader. This method could be
     * changed to load the class over network from some
     * other server or from the database.
     *
     * @param name Full class name
     */
    private synchronized  Class getClass(String name)
        throws ClassNotFoundException {

        // is this class already loaded?
        Class cls = findLoadedClass(name);
        if (cls != null) {
            System.out.println("class " + name + "has been loaded.");
            return cls;
        } else {
            System.out.println("class " + name + " has not been loaded. Loading now.");
        }


        // We are getting a name that looks like
        // javablogging.package.ClassToLoad
        // and we have to convert it into the .class file name
        // like javablogging/package/ClassToLoad.class
        String file = name.replace('.', File.separatorChar)
            + ".class";
        byte[] b = null;
        try {
            // This loads the byte code data from the file
            b = loadClassData(file);
            // defineClass is inherited from the ClassLoader class
            // and converts the byte array into a Class
            cls = defineClass(name, b, 0, b.length);
            resolveClass(cls);
            return cls;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Every request for a class passes through this method.
     * If the requested class is in "javablogging" package,
     * it will load it using the
     * {@link CustomClassLoader#getClass()} method.
     * If not, it will use the super.loadClass() method
     * which in turn will pass the request to the parent.
     *
     * @param name
     *            Full class name
     */
    @Override
    public Class loadClass(String name)
        throws ClassNotFoundException {
        System.out.println("loading class '" + name + "'");
        if (name.startsWith("jia.")) {
            return getClass(name);
        }
        return super.loadClass(name);
    }

    /**
     * Loads a given file (presumably .class) into a byte array.
     * The file should be accessible as a resource, for example
     * it could be located on the classpath.
     *
     * @param name File name to load
     * @return Byte array read from the file
     * @throws IOException Is thrown when there
     *               was some problem reading the file
     */
    private byte[] loadClassData(String name) throws IOException {
        // Opening the file
        InputStream stream = getClass().getClassLoader()
            .getResourceAsStream(name);
        int size = stream.available();
        byte buff[] = new byte[size];
        DataInputStream in = new DataInputStream(stream);
        // Reading the binary data
        in.readFully(buff);
        in.close();
        return buff;
    }
}

Create a very simple class having static field.

package jia.blog;

/**
 *
 * @author Yiyu Jia
 */
public class AStatic {

    public static int yiyu = -1;

    public static int getYiyu() {
        return yiyu;
    }

    public static void setYiyu(int yiyu) {
        AStatic.yiyu = yiyu;
    }

    public static void printYiyu(String instanceName){
        System.out.println("The static member yiyu's value in " 
                + instanceName + " is " + AStatic.yiyu);
    }

}

Now, we write a testing class


package jia.blog;

/**
 *
 * @author Yiyu Jia
 */

public class TestStatic  {
    public static void main(String[] args) throws Exception {
        
        JiaClassLoader loader1 = new JiaClassLoader();
        JiaClassLoader loader2 = new JiaClassLoader();
        if(loader1.equals(loader2)){
            System.out.println("two classloaders are same");
        }
        else {
            System.out.println("two classloaders are different");
        }

        Class clsA = Class.forName("jia.blog.AStatic", true, loader1);
        Class clsB = Class.forName("jia.blog.AStatic", true, loader2);

        System.out.println("jia.blog.AStatic class: " + clsA);

        Object instanceA = clsA.newInstance();
        Object instanceB = clsB.newInstance();


        if (clsA.equals(clsB)) {
            System.out.println("class loaded in different customer classloader are same");
        }
        else {
            System.out.println("class loaded in different customer classloader are different.");
        }

        clsA.getMethod("setYiyu",int.class).invoke(instanceA, 1);
        clsA.getMethod("printYiyu", String.class).invoke(instanceA, "instanceA");
        clsB.getMethod("printYiyu", String.class).invoke(instanceB, "instanceB");
       
    }
}

Running testing code, we get result as below

two classloaders are different
loading class 'jia.blog.AStatic'
class jia.blog.AStatic has not been loaded. Loading now.
loading class 'java.lang.Object'
loading class 'jia.blog.AStatic'
class jia.blog.AStatic has not been loaded. Loading now.
loading class 'java.lang.Object'
jia.blog.AStatic class: class jia.blog.AStatic
class loaded in different customer classloader are different.
loading class 'java.lang.String'
loading class 'java.lang.System'
loading class 'java.lang.StringBuilder'
loading class 'java.io.PrintStream'
The static member yiyu's value in instanceA is 1
loading class 'java.lang.String'
loading class 'java.lang.System'
loading class 'java.lang.StringBuilder'
loading class 'java.io.PrintStream'
The static member yiyu's value in instanceB is -1

Having this knowledge in mind, we can explore more about how to use static and thread safe issue. In real world, we can see customized class loader in java application server, loading class from network, Web application is a born multi thread environment. It will be necessary to have a clear view about class loader architecture, thread safe, and static members.

Also, there are more interesting discussion on this link.

Thursday, October 6, 2011

Ext JS 4 reCAPTCHA widget

After password strength meter widget, I am asked to give a Captcha verify widget too. Well, it is not so difficult, below is a ReCaptcha widget for Ext JS 4.x. On ExtJS 2.x forum, there are detailed description about how to apply for ReCaptcha account.


Source code:

//define a reCaptcha widget.
Ext.define('yiyu.util.ReCaptcha', 
 { 
 extend : 'Ext.Component',
  alias : 'widget.recaptcha',
    

    onRender : function(ct, position){
     var me = this;
     me.callParent(arguments);
     
     me.recaptcha = me.el.createChild({
   tag : "div",
   'id' : me.recaptchaId
  });
     
     Recaptcha.create(me.publickey, me.recaptcha.id, {
            theme: me.theme,
            lang: me.lang,
            callback: Recaptcha.focus_response_field
     });
     
     //me.recaptcha.setWidth(me.el.getWidth(true));
        
    },
    
    getChallenge: function(){
     return Recaptcha.get_challenge();
    }, 
    
    getResponse: function(){
     return Recaptcha.get_response();
    }

});

//create a ReCaptcha instance and we can use it as item in Form.
var recaptcha = Ext.create('yiyu.util.ReCaptcha',{
  name: 'recaptcha',
        recaptchaId: 'recaptcha',
        publickey: 'Your public Key from ReCaptcha',
        theme: 'white',
        lang: 'en'
 });

Wednesday, September 28, 2011

How to model RESTful Web Service

I see somebody lost way when he/she tries to model RESTful Web service. The issues I noticed are,
  • Not always keep in mind that RESTful Web Service is CRUD on "resources".
  • Put verbs in URI. Therefore, the concept about resources is messy up. 
  • Not think that URI is a hierarchy structure to help on organizing "resources"
 So, I made below picture to help on modeling RESTful Web Service.



Simplicity should be one of major reasons for us to adopt RESTful Web service. So, I think it is unnecessary to make RESTful model to be complicate. Another major reason to use RESTful Web Service is that the motivation of project is to "share resources" over the Internet/Intranet (or should say in Cloud? :) ). With these concepts in mind, we can divide the modeling process into four steps as below,
  1. Tell myself that I am going to make software to share "resource" as sharing HTML pages.
  2. Making a sheet to list/add resources into it.
  3. Check each resource and see if it need to be further categorized, Or, we will think if we need to have a reserved category for future. These categories will be mapped into URL. 
  4. For each classified resource, we can do CRUD operations, which maps to HTTP verbs POST, GET, PUT, or DELETE.
Using the Customer in above picture as an example, it is a kind of Resource. Customers are under different categories, silver and gold. For each customer, we can do CRUD operation. Then, the URI for getting a customer may like this: /resources/customer/silver/customerID/

It is better to avoid putting verbs in URI because we are going to share resource and verbs (operation) will be indicated by HTML verbs. Of course, it will still work if we put verbs in URI. It is just string. There is no standard spec for RESTful Web Service. We can define our own languge/protocl in URI. But, what I introduce here should be helpful for organizing analysts' thoughts and make models to be neat and SIMPLE.

Sunday, September 18, 2011

Ext JS 4 password strength meter

One of my friends wants me to help him on putting a password strength meter on his registration page. Inspired by a post on Ext JS 1.x forum, I created a Ext JS 4 compatible one as shown below,


To do this, what you need is 1) the following Ext JS widget extends from Ext.form.field.Text. 2) do not forget the CSS file and images used in CSS. To change the appearance of password meter, you can simply change images used in CSS.

JavaScript code:
Ext.define('yiyu.util.PasswordMeter',
    {
     extend : 'Ext.form.field.Text',
     alias : 'widget.passwordMeter',
     inputType : 'password',

     reset : function() {
      this.callParent();
      this.updateMeter(this);
     },
     
     //private
     onRender : function(container, position) {
      var me = this;
      me.callParent(arguments);
      this.objMeter = me.el.createChild({
       tag : "div",
       'class' : "strengthMeter"
      });
      me.objMeter.setWidth(me.el.getWidth(true) - 17);
      me.scoreBar = me.objMeter.createChild({
       tag : "div",
       'class' : "scoreBar"
      });
      me.scoreBar.setWidth(me.objMeter.getWidth(true));

      if (Ext.isIE6) { // Fix style for IE6
       this.objMeter.setStyle('margin-left', '3px');
      }
     },

     // private
     initEvents : function() {
      var me = this, el = me.inputEl;
      me.callParent();
      me.mon(el, {
       scope : me,
       keyup : me.updateMeter
      });
     },
     /**
      * Sets the width of the meter, based on the score
      * 
      * @param {Object} e
      * Private function 
      */
     updateMeter : function() {
      var score, p, maxWidth, nScore, scoreWidth;
      score = 0;
      p = this.getValue();
      
      maxWidth = this.objMeter.getWidth() - 2;

      nScore = this.calcStrength(p);

      scoreWidth = maxWidth - (maxWidth / 100) * nScore;
      
      this.scoreBar.setWidth(scoreWidth, true);
     },

     /**
      * Calculates the strength of a password
      * 
      * @param {Object} p
      *   The password that needs to be calculated
      * @return {int} intScore The strength score of the password
      */
     calcStrength : function(p) {
      var intScore = 0;

      // PASSWORD LENGTH
      intScore += p.length;

      if (p.length > 0 && p.length <= 4) { // length 4 or
                // less
       intScore += p.length;
      } else if (p.length >= 5 && p.length <= 7) { 
       // length between 5 and 7
       intScore += 6;
      } else if (p.length >= 8 && p.length <= 15) { 
       // length between 8 and 15
       intScore += 12;       
      } else if (p.length >= 16) { // length 16 or more
       intScore += 18;       
      }

      // LETTERS (Not exactly implemented as dictacted above
      // because of my limited understanding of Regex)
      if (p.match(/[a-z]/)) { 
       // [verified] at least one lower case letter
       intScore += 1;
      }
      if (p.match(/[A-Z]/)) { // [verified] at least one upper
            // case letter
       intScore += 5;
      }
      // NUMBERS
      if (p.match(/\d/)) { // [verified] at least one
            // number
       intScore += 5;
      }
      if (p.match(new RegExp(".*\\d.*\\d.*\\d"))) {
       // [verified] at least three numbers
       intScore += 5;
      }

      // SPECIAL CHAR
      if (p.match(new RegExp("[!,@,#,$,%,^,&,*,?,_,~]"))) {
       // [verified] at least one special character
       intScore += 5;
      }
      // [verified] at least two special characters
      if (p.match(new RegExp(
          ".*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]"
        ))) {
       intScore += 5;
      }

      // COMBOS
      if (p.match(new RegExp("(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both upper and lower case
       intScore += 2;
      }
      if (p.match(new RegExp(
        "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both letters and numbers
       intScore += 2;
      }
      // [verified] letters, numbers, and special characters
      if (p
        .match(new RegExp(
          "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])"
          ))) {
       intScore += 2;
      }

      var nRound = Math.round(intScore * 2);

      if (nRound > 100) {
       nRound = 100;
      }

      return nRound;
     }
    })


CSS code:
.strengthMeter {
 border: 1px solid #B5B8C8;
 margin: 3px 0 3px 0;
 background-image: url(images/meter.gif);
 height: 10px;
 background-size: 100%; 
}

.scoreBar {
 background-image: url(images/meter_background.gif);
 height: 10px;
 background-size: 100%; 
 line-height: 1px;
 font-size: 1px;
 float: right;
}


Edit: Here is a better implementation crated by osnoek.

Friday, September 9, 2011

A simple tutorial about creating Jersey RESTful web service in Netbean 7.0

I believe that new technologies should make things simpler instead of more complex. RESTful Web service is one of them. But, it seems there is no very simple tutorial about how to create RESTful Web service in Netbean. So, here is a extremely simple tutorial about how to create a Servlet based only RESTful web service in Netbeans 7.0.

There are several different RESTful web service frameworks on the market. Jersey is one of them. Jersey is reference implementation of JSR 311: JAX-RS: The JavaTM API for RESTful Web Services . The follows steps will show how easy it is to create a RESTful Web Service in Netbeans 7.0.

1)Create a Web application






2) Create our first RESTful Web service in Netbeans 7.0 with Jersey.








3) Test it.

Once we successfully did above steps, we see a new Restful Web Service folder in project as shown below.

We modify and add hello world string into GenericResource.java as shown below,
/**
* Retrieves representation of an instance of jia.blog.rest.GenericResource
* @return an instance of java.lang.String
*/
@GET
@Produces("text/html")
public String getHtml() {
   //TODO return proper representation object
   return "

Hello World!

"; }

Then we compile and deploy the project. Once we successful deployed it. We can test our hello world example by using the following URL:

http://localhost:8080/jerseyRest/firstREST/generic

I purposely use different string "jerseyRest", "fristREST", "generic" in URL as this way can help you to map string in URL into the place where we input in netbeans 7.0.

Also, this simple hello world example has been successfully tested on JDK 1.5 and Tomcat 6.0 environment. So, it works on i5/OS V5R4 platform too.

Here is the link to source code jiaRest.zip

Sunday, August 28, 2011

install xdebug with Zend Server CE and Netbeans 7.0.x

Go to Fedora "Application -> System Tools -> Add/Remove Software" and make sure PHP PEAR and PHP PECL and XDebug are installed already. Then, run the following commands to add xdebug into Zend Server.

#  edit debugger.ini file to disable zend debugger.
#  ; register the extension to be loaded by Zend Extension Manager
# ;zend_extension_manager.dir.debugger=/usr/local/zend/lib/debugger
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/conf.d/debugger.ini

#find where is xdebug.so
[root@jiaFedora14 /]# find /usr/ -name 'xdebug.so'
/usr/lib64/php/modules/xdebug.so

#  Make zend server to load xdegug.so before extension manager is loaded.
#  zend_extension=/usr/lib64/php/modules/xdebug.so
#  zend_extension=/usr/local/zend/lib/ZendExtensionManager.so
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/conf.d/extension_manager.ini

# edit php.ini or other configuration files to have xdebug settings
# [xdebug]
# xdebug.remote_enable=on
# xdebug.remote_handler=dbgp
# xdebug.remote_mode=req
# ;xdebug.remote_connect_back=1
# xdebug.remote_host=192.168.1.190
# xdebug.remote_port=9001
# xdebug.idekey="netbeans-xdebug"
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/php.ini

# Fedora has SELinux enabled by default. I open the port 9001.
[root@jiaFedora14 yyjia]# semanage port -a -t http_port_t -p tcp 9001

# restart Zend Server
[root@jiaFedora14 yyjia]# service zend-server restart

# check xdebug configuration.
[root@jiaFedora14 yyjia]# php -i | grep xdebug

After running all above command and see every thing is correct as expected, we do a simple configuration in Netbeans as shown in figure below,




Some notes:
1) The above steps only install xdebug for one developer. For a team developing environment, we need to install DBGp proxy.

2) I tried "xdebug.remote_connect_back=1" and hope I do not need to specify a fix hostname/ipaddress in php.ini. But, I failure on it. I have not dig deep into it.

Thursday, August 18, 2011

i5/OS job status help file

Below is job status help file exactly copied from i5/OS R5V4 help menu. I copy it here to study them in detail later. Especially for status of prestart job on i5/OS.




The status of the initial thread of the job. Only one status is
displayed per job. A blank status field represents an initial thread
that is in transition. Possible values are:

BSCA
The initial thread of the job is waiting for the completion of an
I/O operation to a binary synchronous device in the activity level.

BSCW
The initial thread of the job is waiting for the completion of an
I/O operation to a binary synchronous device.

CMNA
The initial thread of the job is waiting for the completion of an
I/O operation to a communications device in the activity level.

CMNW
The initial thread of the job is waiting for the completion of an
I/O operation to a communications device.

CMTW
The initial thread of the job is waiting for the completion of
save-while-active checkpoint processing in another job. This wait
is necessary to prevent a partial commitment control transaction
from being saved to the media.

CNDW
The initial thread of the job is waiting for the handle-based
condition.

CPCW
The initial thread of the job is waiting for the completion of a
CPI Communications call.

DEQA
The initial thread of the job is waiting for completion of a
dequeue operation in the pool activity level.

DEQW
The initial thread of the job is waiting for completion of a
dequeue operation. For example, QSYSARB and subsystem monitors
generally wait for work by waiting for a dequeue operation.

DKTA
The initial thread of the job is waiting for the completion of an
I/O operation to a diskette device in the activity level.

DKTW
The initial thread of the job is waiting for the completion of an
I/O operation to a diskette device.

DLYW
Due to the Delay Job (DLYJOB) command, the initial thread of the
job is delayed while it waits for a time interval to end, or for a
specific delay end time. The function field shows either the
number of seconds the job is to delay (999999), or the specific
time when the job is to resume running.

DSC
The job has been disconnected from a work station display.

DSPA
The initial thread of the job is waiting for input from a work
station display in the activity level.

DSPW
The initial thread of the job is waiting for input from a work
station display.

END
The job has been ended with the *IMMED option, or delay time has
ended with the *CNTRLD option.

EOFA
The initial thread of the job is waiting in the activity level to
try a read operation again on a database file after the end-of-file
has been reached.

EOFW
The initial thread of the job is waiting to try a read operation
again on a database file after the end-of-file has been reached.

EOJ
The job is ending for a reason other than End Job (ENDJOB) or End
Subsystem (ENDSBS). For example, SIGNOFF, End Group Job
(ENDGRPJOB), or an exception that is not being handled.

EVTW
The initial thread of the job is waiting for an event. For
example, QLUS and SCPF generally wait for work by waiting for an
event.

GRP
The job is suspended due to a Transfer to Group Job (TFRGRPJOB)
command.

HLD
The job is being held.

HLDT
The initial thread of the job is held.

ICFA
The initial thread of the job is waiting, in an activity level, for
the completion of an I/O operation to an intersystem communications
function file.

ICFW
The initial thread of the job is waiting for the completion of an
I/O operation to an intersystem communications function file.

INEL
The initial thread of the job is ineligible and not currently in
the pool activity level.

JVAA
The initial thread of the job is waiting for completion of a Java
program operation in the pool activity level.

JVAW
The initial thread of the job is waiting for completion of a Java
program operation.

LCKW
The initial thread of the job is waiting for a lock.

LSPA
The initial thread of the job is waiting for a lock space to be
attached in the pool activity level.

LSPW
The initial thread of the job is waiting for a lock space to be
attached.

MLTA
The initial thread of the job is waiting, in an activity level, for
the completion of an I/O operation to multiple files.

MLTW
The initial thread of the job is waiting for the completion of an
I/O operation to multiple files.

MSGW
The initial thread of the job is waiting for a message from a
message queue.

MTXW
The initial thread of the job is in a mutex wait. A mutex is a
synchronization function that is used to allow multiple jobs or
processes to serialize their access to shared data.

MXDW
The initial thread of the job is waiting for the completion of an
I/O operation to a mixed device file. Details are in the Remote
Work_Station_Support book.

OPTA
The initial thread of the job is waiting, in an activity level, for
the completion of an I/O operation to an optical device.

OPTW
The initial thread of the job is waiting for the completion of an
I/O operation to an optical device.

OSIW
The initial thread of the job is waiting for the completion of an
OSI Communications Subsystem OSLISN, OSRACS, OSRACA, OSRCV, or
OSRCVA operation.

PRTA
The initial thread of the job is waiting for output to a printer to
complete in the activity level.

PRTW
The initial thread of the job is waiting for output to a printer to
be completed.

PSRW
The initial thread of the job is a prestart job waiting for a
program start request.

RUN
The initial thread of the job is currently running in the activity
level.

SELW
The initial thread of the job is in a select wait. More
information on the select() function is in the Sockets APIs chapter
in the System API Reference information in the iSeries Information
Center at http://www.ibm.com/eserver/iseries/infocenter.

SEMW
The initial thread of the job is waiting for a semaphore. A
semaphore is a synchronization function that is used to allow
multiple jobs or threads to serialize their access to shared data.

SIGS
The initial thread of the job is stopped by a signal.

SIGW
The initial thread of the job is waiting for a signal.

SRQ
The initial thread of the job is the suspended half of a system
request job pair.

SVFA
The initial thread of the job is waiting for completion of a Save
File operation in the activity level.

SVFW
The initial thread of the job is waiting for completion of a Save
File operation.

TAPA
The initial thread of the job is waiting for completion of an I/O
operation to a tape device in the activity level.

TAPW
The initial thread of the job is waiting for completion of an I/O
operation to a tape device.

THDW
The initial thread is waiting for another thread to complete an
operation.

TIMA
The initial thread of the job is waiting, in the activity level,
for a time interval to end.

TIMW
The initial thread of the job is waiting for a time interval to
end.

Monday, August 8, 2011

upgrade Fedora 14 to Fedora 15

Since Fedora 15 was released for some time already, I upgraded my development server from Fedora 14 to Fedora 15 recently. Below is the command set I used to upgrade to Fedora 15. Before run those commands, I backup my virtual machine files in case.

# change account to Root account
[yyjia@jiaFedora14 ~]$ su
Password: 

# upgrade to latest rpm version
[root@jiaFedora14 yyjia]# yum upgrade rpm
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
Zend                                       |  951 B     00:00     
Zend_noarch                                |  951 B     00:00     
fedora/metalink                            |  21 kB     00:00     
jenkins                                    |  951 B     00:00     
jenkins/primary                            | 1.3 kB     00:00     
jenkins                                                                     1/1
updates/metalink                           |  13 kB     00:00     
updates                                    | 4.7 kB     00:00     
updates/primary_db                         | 6.5 MB     00:07     
Setting up Upgrade Process
No Packages marked for Update
[root@jiaFedora14 yyjia]# 

#make sure I have latest packages installed.
[root@jiaFedora14 yyjia]# yum -y update

#clean up yum cache.
[root@jiaFedora14 yyjia]# yum clean all

#insall preupgrade package.
[root@jiaFedora14 yyjia]# yum install preupgrade

#running preupgrade
[root@jiaFedora14 yyjia]# preupgrade

After running preupgrade, we have below screen. I don't want to try Fedora 16 beta version. So, I selected Fedora 15.

I followed instructions shown on the screen. Then, I have a below screen to ask for reboot.

After reboot, the upgrade process starts.


Here is upgrade manual from Fedora web site: http://fedoraproject.org/wiki/YumUpgradeFaq

Thursday, July 28, 2011

how Ext JS 4 deals with postprocessors and preprocessors?

I looked into source code of Ext.ClassManager recently. But, I found that I can not understand it. Actually, I think it is a bug?

According to the signature of Ext.ClassManager.create function, It seems that developer can pass in postprocessors in configuration data. However, I think the postprocessors in configuration data will overwrite ClassManager's default postProcessors.

I put sample code to show what happen once we apply "||" operator to two JavaScript arrays. I cited the source code as below and add several lines comments there. Similar things happen to preprocessors in Class.js .

code snippet to show || operator on JavaScript arrays

The output of above code is:
Array is:
0
1
Another array is:
2
3
4
Now, let's see what happens in ClassManager.js: Code snippet cited from ClassManager.js
return new Class(data, function() {
                //If I pass in data having postprocessors,
                //all default postprocessors is going to ignored? 
                var postprocessorStack = data.postprocessors || manager.defaultPostprocessors,
                    registeredPostprocessors = manager.postprocessors,
                    index = 0,
                    postprocessors = [],
                    postprocessor, postprocessors, process, i, ln;

                delete data.postprocessors;

                //if my data has just one postprocessor, 
                //doesn't postprocessorStack.length only equal to 1?  
                for (i = 0, ln = postprocessorStack.length; i < ln; i++) {
                    postprocessor = postprocessorStack[i];

                    if (typeof postprocessor === 'string') {
                        postprocessor = registeredPostprocessors[postprocessor];

                        if (!postprocessor.always) {
                            if (data[postprocessor.name] !== undefined) {
                                postprocessors.push(postprocessor.fn);
                            }
                        }
                        else {
                            postprocessors.push(postprocessor.fn);
                        }
                    }
                    else {
                        postprocessors.push(postprocessor);
                    }
                }

                process = function(clsName, cls, clsData) {
                    postprocessor = postprocessors[index++];

                    if (!postprocessor) {
                        manager.set(className, cls);

                        Ext.Loader.historyPush(className);

                        if (createdFn) {
                            createdFn.call(cls, cls);
                        }

                        return;
                    }

                    if (postprocessor.call(this, clsName, cls, clsData, process) !== false) {
                        process.apply(this, arguments);
                    }
                };

                process.call(manager, className, this, data);
            }

I reported a bug here to see if I am right or it is just because I do not understand the code. Please feel free to make comments below if I am wrong.

Thursday, July 7, 2011

Java memory leak caused by String object

For some reason, I recall that Java String can easily cause memory leak. Since it has not been fixed in JVM, I write this note to keep it in mind. Next time, I will write down C/C++ and C# memory leak on pocket PC, which I was experienced.

We all know that Java has garbage collector, which automatically release memory of object if there is refernece points to it any more. However, something strange from String class happens in at least Sun and IBM's JVM. String is definietly frequently used Object in Java program. So, it will be significant if its function causes memory leak. The souce of the issue is from substring function of String class in JVM implementations from Sun and IBM at least. Speak in simple way, substring() function will not create a new String object having its own memory block and return it. It will only create a String object, which points to part of original String object. Therefore, the memory block occupied by original String object will be refered by new sub String object too. This will cause siginificant memory leak problem if original String is very long and the sub String object will be used outside scope where original String object residents. Below figure gives a clear view of this statement.


To workaround this issue, we can use new operator to force the sub String object has its own memory block. In fact, this is reported as a bug in Sun microsystem. But, it has low priority and has not been fixed. There is an interesting discussion about Java memory leak here: Creating a memory leak with Java

Friday, July 1, 2011

ExtJS 4 REST proxy and Zend framework Zend_Rest_Route are incompatible.

I noticed a very strange thing when I worked on Ext JS 4 v4.0.2 and Zend Framework. I find that every time when Ext JS grid sends new created Record to the server through its REST proxy, the POST method was teated as PUT method in Zend_Rest_Route. This cause troublesome because my code have to know if the incoming record a new one for insert or exsiting one for update. Otherwise, I have to use some UPSERT SQL statement to UPDATE or INSERT record into Database table. Unfortunately, I use DB2 for i5/OS V5R4, which does not have built-in UPSERT command and it even does nor support MERGE statement.

I do not want to walkaround this by doing SELECT first and judging if the code need to run INSERT or UPDATE statement. So, I traced the Ext JS 4 code and Zend Framework 1.11 code. I found that these two are not compatiable. I am not sure if we can say it is BUG as this wont happen if either side change their code. Or, both side can change the code to avoid the confilicaton if we say bugs are from both sides.

The key for this issue is that Ext JS 4 append record's id at the end of base URL, which points to RESTful service. Below is a psuedo POST URL create by Ext JS 4 REST proxy. I highlight the unexpected friend in red color.

http://hostname/yourRestServiceURI/yourRecordId/?dc=randomNum


We understand that adding record id as part of URI can allow server side script easily find it. But, why this design is implemented in a general SDK like Ext JS? Especially, I do not see good reason for a POST request to have it as record in POST are suppoe not to have been existing on server side. Therefore, the ID of the new record might not have been generated if it will be generated on the server side only.

In Ext JS 4 source code \src\data\proxyRest.js, we can see what happens,
/**
     * Specialized version of buildUrl that incorporates the {@link #appendId} and {@link #format} options into the
     * generated url. Override this to provide further customizations, but remember to call the superclass buildUrl
     * so that additional parameters like the cache buster string are appended
     */
    buildUrl: function(request) {
        var me        = this,
            operation = request.operation,
            records   = operation.records || [],
            record    = records[0],
            format    = me.format,
            url       = me.getUrl(request),
            id        = record ? record.getId() : operation.id;
        
        if (me.appendId && id) {
            if (!url.match(/\/$/)) {
                url += '/';
            }
            
            url += id; //Why add ID here even for POST? Yiyu Jia
        }
        
        if (format) {
            if (!url.match(/\.$/)) {
                url += '.';
            }
            
            url += format;
        }
        
        request.url = url;
        
        return me.callParent(arguments);
    }
}

Now, people will ask why adding id in URL cause the problem in Zend Framework? Well, let's trace Zend Framework code now.

On Zend Framework API document about Zend_Rest_Route, we can see Zend clearly described their design how RESTful URI should looks like,
Zend_Rest_Route Behavior
MethodURIModule_Controller::action
GET/product/ratings/Product_RatingsController::indexAction()
GET/product/ratings/:idProduct_RatingsController::getAction()
POST/product/ratingsProduct_RatingsController::postAction()
PUT/product/ratings/:idProduct_RatingsController::putAction()
DELETE/product/ratings/:idProduct_RatingsController::deleteAction()
POST/product/ratings/:id?_method=PUTProduct_RatingsController::putAction()
POST/product/ratings/:id?_method=DELETEProduct_RatingsController::deleteAction()

As we can see, Zend Framework does not expect any thing attached to method URI when PHP programmer intend to use POST method. In Zend_Rest_Route source code, we can see a case switch statement as below. You will see when the POST method will be "magically" routed to PUT method if pathElementCount is larger than zero.

switch( $values[$this->_actionKey] ){
                    case 'post':
                        if ($pathElementCount > 0) {
                            $values[$this->_actionKey] = 'put';
                        } else {
                            $values[$this->_actionKey] = 'post';
                        }
                        break;
                    case 'put':
                        $values[$this->_actionKey] = 'put';
                        break;
                }


But, where is the $pathElementCount set? In the same source code file, we can see below statement,

//Store path count for method mapping
$pathElementCount = count($path);

So, where is value of $path populated? Still, in the same source code, there is a function call match. Part of it is cited as below.

/**
     * Matches a user submitted request. Assigns and returns an array of variables
     * on a successful match.
     *
     * If a request object is registered, it uses its setModuleName(),
     * setControllerName(), and setActionName() accessors to set those values.
     * Always returns the values as an array.
     *
     * @param Zend_Controller_Request_Http $request Request used to match against this routing ruleset
     * @return array An array of assigned values or a false on a mismatch
     */
    public function match($request, $partial = false)
    {
        if (!$request instanceof Zend_Controller_Request_Http) {
            $request = $this->_front->getRequest();
        }
        $this->_request = $request;
        $this->_setRequestKeys();

        $path   = $request->getPathInfo();
        $params = $request->getParams();
        $values = array();
        $path   = trim($path, self::URI_DELIMITER);

Ok, now, it is not the end of code tracing yet. Where is the getPathInfo() function? It is in Zend_Controller_Request_Http. The following code citation will show us that getPathInfo() eeturns everything between the BaseUrl and QueryString and deos something special.

/**
     * Returns everything between the BaseUrl and QueryString.
     * This value is calculated instead of reading PATH_INFO
     * directly from $_SERVER due to cross-platform differences.
     *
     * @return string
     */
    public function getPathInfo()
    {
        if (empty($this->_pathInfo)) {
            $this->setPathInfo();
        }

        return $this->_pathInfo;
    }

/**
     * Set the PATH_INFO string
     *
     * @param string|null $pathInfo
     * @return Zend_Controller_Request_Http
     */
    public function setPathInfo($pathInfo = null)
    {
        if ($pathInfo === null) {
            $baseUrl = $this->getBaseUrl(); // this actually calls setBaseUrl() & setRequestUri()
            $baseUrlRaw = $this->getBaseUrl(false);
            $baseUrlEncoded = urlencode($baseUrlRaw);
        
            if (null === ($requestUri = $this->getRequestUri())) {
                return $this;
            }
        
            // Remove the query string from REQUEST_URI
            if ($pos = strpos($requestUri, '?')) {
                $requestUri = substr($requestUri, 0, $pos);
            }
            
            if (!empty($baseUrl) || !empty($baseUrlRaw)) {
                if (strpos($requestUri, $baseUrl) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrl));
                } elseif (strpos($requestUri, $baseUrlRaw) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlRaw));
                } elseif (strpos($requestUri, $baseUrlEncoded) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlEncoded));
                } else {
                    $pathInfo = $requestUri;
                }
            } else {
                $pathInfo = $requestUri;
            }
        
        }

        $this->_pathInfo = (string) $pathInfo;
        return $this;
    }

So, what is the conclusion? The conclusion is that both Ext JS and Zend framework has their own design of RESTful URI pattern. Unfortunately, they are not compatible with each other. They are too nice to do more than developer expected. As libraries vendor, they maybe should do less sometimes in order to make their library as general as possible. Ext JS, as a pure client side JavaScript library, should not guide server side script designer how to implement RESTful Web service. Zend Framework, as a pure server side script library, should not make design for client side application either. In fact, RESTful Web service is a set of guide lines for developer to make scalable application over HTTP methods. But, it does not define how the URI pattern must be.

Thursday, June 23, 2011

Managing Grid CRUD In ExtJS 4

I read a discussion on Sencha forum (here). Obviously, ExtJS 4 make user to be frustrating because of the lack of well organized document and lack of well commented sample code. Probably, it is just because ExtJS 4 is too new that developers have not catch up. However, since ExtJS is partially commercial product instead of a pure open source project, its quality should be well controlled before it announce final release. Here is a little bit experiece on how to make a CRUD grid with ExtJS 4.

To successfully use Grid, auto sync store, and rowediting plugin in ExtJS 4, there are several points need to be highlighted. I listed them as below,


  1. In your Model class, you have to either define a hardcoded 'id' property or use 'idProperty' to specify one column as 'id'.
  2. You server side code need to return processed records back to browser. I tried only send back "id" in "data" part. But, it is not successful.
  3. Be aware that the format of record in the "data" has JSON format.
  4. Be sure to implemented at least one Validator in your Model class because, in ExtJS source code AbstractStore.js, you can find the following code, which may always return true for a new created record in RowEditing plugin when the store is set as autoSync = true

/**
     * @private
     * Filter function for new records.
     */
    filterNew: function(item) {
        // only want phantom records that are valid
        return item.phantom === true && item.isValid();
    },

Most likely, we wont use auto sync store in real product. But, this example could be a good start.

Sunday, June 12, 2011

Web application i18n programming

How to do i18n programming is a big topic. I do not think I should try to describe it in a short blog post. I post this because I was asked with this question.

In my recent project, I created a JavaScript function as shown below,
/*
 * Translates $text
 */
function __i18n($text)
{
    //extend to each module has its own language file.
    // If we don't have the language set.
    if (undefined === Module.namespace.UI.lang) {
        return $text;
    }
    // If we don't have a translation for the $text.
    if (undefined === Module.namespace.UI.lang[$text]) {
        return $text;
    }
    return Module.namespace.UI.lang[$text];
}
The above simple JavaScript code is used to translate text into another UTF-8 encoded text, which is most likely written in another language. BTW, one thing I want to emphasize is that UTF-8 and unicode are different stuff. I often heard people just use them as if they were exchangeable.

Above sample is just small part in the whole i18n enabled system. We can use a traditional three-tie Web application as sample (traditional desktop app has different concern, I believe). Let's assume that we have just one centralized Web server. That is, we do not consider the situation in which we have distributed Web server located in different host server and those server have different system locale settings. We will have concern about i18 in each layers including presentation layer, business logical layer, and database layer. Let's have a brief review on each layer as below,

  1. Presentation layer. First of all, let's know what is involved in this layer. Obviously, JavaScript, HTML is involved in this layer. But, we should not forgot that Web browser and Web server are included as well.
    In HTML, we can specify language info not only in HTML page wide, but also in each FORM scope.
    In JavaScript, as we see in the sample code, a language resource file can be well designed and used.
    In CSS, we probably need to create seperated CSS files for different locale as different language may have different text width.
    About Web browser and Web server, some people just ignore this part. But, in fact, in HTTP header specification, some field like Accept-Encoding, Accept-Language has been defined for your convenience. But, using this feature also cause potential problem if end user happens to change their browser settings.
  2. Business layer. Most of talking about resource bundle, locale object happens in this layer. According to my experience in Java, we only need to keep in mind that the internal encode used in JVM is UTF-8. That is, we need a base line. Then, from there, we convert to any encoded schema if the specific language is installed on the system.In terms of programming, coder need to be carefully to avoid use functions which only support ASCII characters. In language like PHP, C/C++, you can always find there are two set of string functions, one is only for ASCII characters. The other is used for "wider" unicode characters.
  3. Persistent storage layer. Using MySQL RDBMS as an example, database designer can specify storage schema and transmission schema for database or table. I always use UTF-8 so far. Of course, you can still support multilingual if you treat all string as just binary array.

A well designed i18n architecture is very important to a world wide used software as it may cause painful redesign and recoding effort later if it is not well designed at the very beginning. Also, it will be helpful to understand i18n programming by starting to learn i18n from a specific language. For example, IBM instead of Sun Microsystem contributes i18n into Core Java from the beginning. It will be good to use Java language to learn i18n.

Wednesday, June 8, 2011

how to convert TIMESTAMP format to different date format

It is very often that we need to get specific format of date from TIMESTAMP column. We can certainly get timestamp as string and do some string operation on it to compose a new string with desired formated. However, it will be just nice to be able to get what I want directly from SQL query output. Here is a brief conclusion on how to get formated Date string from TIMESTAMP.

Basically, two DB2 functions are used. DATE scalar function and CHAR scalar function. In CHAR function, we can specify five different format: iso, usa, eur, jis, local.

Below is sample output for different format,

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), eur) 
  FROM SYSIBM.SYSDUMMY1; 
Output EUR format: 
2011-05-28 15:36:12.178455 28.05.2011

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), usa) 
  FROM SYSIBM.SYSDUMMY1; 
Output USA format: 
2011-05-28 15:38:57.487165 05/28/2011

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), jis) 
  FROM SYSIBM.SYSDUMMY1; 
Output JIS format: 
2011-05-28 15:40:00.455681 2011-05-28

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), iso) 
  FROM SYSIBM.SYSDUMMY1; 
Output ISO format: 
2011-05-28 15:41:12.159374 2011-05-28


SELECT CURRENT_TIMESTAMP, 
char(date (CURRENT_TIMESTAMP), local)
  FROM SYSIBM.SYSDUMMY1; 
Output LOCAL format: 
2011-05-28 15:42:41.802835 05/28/11

Saturday, May 28, 2011

Using dynamic class loading feature in ExtJS 4

ExtJS 4 introduces a new feature about dynamical class loading. It is not recommended in a product environment. However, it will be very useful when you want to debug your application. Especially, it is extremely helpful when you have to debug into source code of ExtJS 4 as it is still buggy now. Here is a template that I use in my project.

First of all, in HTML HEADER, I include ExtJS file ext-dev.js instead of ext-all-debug.js . And, ext-dev.js is the only JavaScript file I need to included there.

Then, in the first page of ExtJS app, I have code like below,



Wednesday, May 18, 2011

DB2 for i5/OS V5R4 have no buit-in UPSERT support.

Recently, I need to do UPDATE_or_INSERT (UPSERT) in DB2 for i5/OS V5R4. But, this version DB2 does not have built-in UPSERT function.

In MySQL, I have two ways to implement UPSERT. One is using REPLACE INTO. The other is using ON DUPLICATE KEY UPDATE

It seems that MERGE statement can be used for UPSERT purpose though it is designed for different purpose. But, MERGE statement is not support DB2 v8 for i5/OS V5. It requires 6.1 of the OS.

The following is an article about how to write SQL for both DB2 and MySQL. I bookmark it here as reference: Writing SQL for both MySQL and DB2

Wednesday, May 4, 2011

Implementing Singleton object in JavaScript

I read a discussion in ExtJS forum about how to implement private methods (see here). It let me think what the guy wants is a modularization design, which is discussed in "A modular architecture based approach for Single Page Web application development". In order to implement the design, we need to use JavaScript closure concept. Here, I am going to further discuss a little about Singleton in JavaScript.

Singleton in Javascript is a little bit tough to be understood by Java developer because JavaScript does not use "class" to pursue OOP capability. Instead, it uses prototype to implement object inheriting.So, JavaScript has no "class". It only has Object. Each function is an Object in the memory.

Therefore, if you are just developing a project by yourself only, you can certainly implement your singleton as simple as below,
var singleton = {
   method1: function(){},
   method2: function(){}
}
However, if we want to have a more complex singleton object, which has private variable and method, we may employee below code,
var Singleton = (function() {
   //a private variable pointing to singleton object.
    var _instance = null; 
    
    //a private construction function, which is actually
    //the singleton object itself.
    function PrivateConstructor() {
        var publicVar = ``Hello '';
        this.publicMethod = function(name) {
            alert(publicVar + para);
        }
    }
    
    //This function return caller an object used
    //for getting singleton instance.
    return new function() {
        this.getInstance = function() {
            if (_instance == null) {
                _instance = new PrivateConstructor();
                _instance.constructor = null; //no more constructor!.
            }
            return _instance;
        }
    }
})();
var singletonInstance = Singleton.getInstance();
var singletonInstance2 = Singleton.getInstance();
alert(singletonInstance == singletonInstance2); //display true!
Or, this code give you true singleton too,
function singleton() {
 
  var instance = (function() {
  var privateVar = "Hello ";
  function privateMethod (param) {
    alert(privateVar + param);
  }
   return { // public interface
    publicMethod1: function (name) {
       privateMethod(name);
    }
   };
})();
singleton = function () { // re-define the function for subsequent calls
   return instance;
};
return new singleton; // call the new function
};
var singletonInstance = new singleton;
var singletonInstance2 = new singleton;
alert(singletonInstance == singletonInstance2); //display true!

In above examples, we used techniques like self-invoking, constructor function, javaScript closures etc.

Different from other language, JavaScript has no block scope. But, it has function scope. So, we use self-invoking function to add extra layer of scope.

Singpleton is useful to implement Factory design pattern. And, it can be useful if we want to implement function module as singleton.

Friday, April 29, 2011

Remove and reconfigure SSHD setting after running Zend Studio 8.0 repair installation.

I happened to run Zend Studio 8.0 installer to "repair" my zend studio 8.0 for IBMi. However, I got below error message after I click the folder under Sftp files and My Home directory in the Remote Systems View window.
ProxyHTTP:java.ioException: proxy error: Forbidden

It is strange because a dialogue was pop up and asked me to input password. So, that means studio can see the sshd server running on i5/OS.

I tried many ways. But, the final solution is simple: deleting the exsiting SSHD server setting from the Remote Systems window and create a new one. Then, a new key is generated for remote sshd server and connection works just well now.

Sunday, April 24, 2011

Using Abstract class and Interface in ExtJS 4.x programming.

I was driven to think about how to implement Interface and Abstract class when I review a project using Ext JS as front GUI library. It is good to see they try to do OOP and design the GUI component as reusable.

However, I saw that there was no clear idea about Interface and Abstract class design in the code. I say this because I saw some empty function in parent classes. Obviously, the programmer of parent classes wish subclass programmer to implement those empty functions. But, I did not see any code there to force subclass programmer to implement the function. The way to solve this is very simple, we only need to add a throw statement in parent class.

Ext.define('jia.blog.ParentClass', {
    greeting : function(){
                  throw "Unimplemented method.";
               }
}

Ext.define('jia.blog.ChildClass', {
    extend: 'jia.blog.ParentClass',

    greeting : function(){
                  alert('I implemented a abstract method');
               }
}

About using Interface in Ext JS, I think the new feature mixins introduced in Ext JS 4.0 can be good candidate as it is invented to solve multiple inherent. In Java, we know that one class can only extends from one and only one parent class. But, it can implement multiple Interfaces. So, for my opinion, I will declare my interface as mixins as below,

//a mixins class to be used as Interface
Ext.define('jia.blog.TechnicalManager', {
    level : 'manager',
    meetingWithPM : function() {
        throw "unimplemented method";
    }
});

//a mixins class to be used as Interface
Ext.define('jia.blog.Mother', {
    sex : 'female',
    feedChild : function() {
        throw "unimplemented method";
    }
});

Ext.define('jia.blog.WorkingMom', {
    
    mixins: {
        inWork: 'jia.blog.TechnicalManager',
        atHome: 'jia.blog.Mother'
    }

    meetingWithPM : function() {
        alert('I am meeting with project manager');
    }

    feedChild : function() {
        alert('I am feeding my kids');
    }

});


Of course, you can put "abstract" method in mixins too. I did not do it here just because I want to show how I use mixins as Interface in OOP manner. Actually, Javascript has no class at all. Class here should be called as Ext JS class as Ext JS 4.0 create the infrastructure of Class and Object. extend and mixins are both preprocessors in ExtJS 4.0. I list default preprocessors and postprocessors as below.

  • default preprocessors (defined in Class.js):
    'extend', 'statics', 'inheritableStatics', 'mixins', 'config'
  • default postprocessors (defined in ClassManager.js):
    'alias', 'singleton', 'alternateClassName'

Although ExtJS tries to implement a Class infrastructure for OOP, it is not a sophisticated OOP environment after all. For example, the throw statement we used above does not really force subclass developer to implement methods. Subclass developer will not know until he run the code. This happens there is no something like ExtJS compiler or interpreter. But, we can apply certain OO design concept with it. Also, we need to be careful not to make same properties or function names in different preprocessors or postprocessors as, obviously, ExtJS class functions will deal with these processors in sequence.