Thursday, December 31, 2009

Coupling and Cohesion

Time spent on software design process takes the most significant part of the software development life cycle. Taken design decision affects the whole product positively or negatively so at this point, coupling and cohesion come into play.
Coupling is defined as a measure of intermodule connectivity. There are different forms of coupling such as data,stamp,control and common-environment coupling.
Cohesion helps to determine how functionally the intramodule components are related. Principal forms of cohesion are listed as functional, sequential, communicational, procedural, temporal, logical and coincidental.
General design approach includes generating highly cohesive and loosely coupled modules. Highly cohesive modules contain logically related operations together into the same structure and that helps to define responsibility at a specific location. Designing loosely coupled modules decreases dependencies to other modules so a small change in one dependent module does not break other parts.

Monday, November 23, 2009

Set JAVA_HOME and PATH on ubuntu 9.10

Instead of installing JDK from synaptic package manager, you can manually download JDK 6 Update 17 from http://java.sun.com/javase/downloads/index.jsp. After downloading "jdk-6u17-linux-i586.bin", make it executable by changing its mode and run to install by issuing following commands.

$ chmod 777 jdk-6u17-linux-i586.bin
$ ./java_ee_sdk-5_08-jdk-6u17-linux.bin

After that point edit your /etc/profile file to add lines below:
$ sudo gedit /etc/profile

PATH=(yourJDKInstallationFolder)/bin:${PATH}
export PATH
JAVA_HOME=(yourJDKInstallationFolder)
export JAVA_HOME

Save /etc/profile and logout. To test your JAVA_HOME location and installed java version type from the console:
$ java -version

$ echo $JAVA_HOME

Friday, October 9, 2009

Shutdown Remote Ubuntu Machine

SSH protocol is used to exchange data between two networked devices using a secure channel. Ubuntu server machines with ssh installed on them can be reached from other computers on the network. Ubuntu's synaptic package manager easily installs ssh for your server machine. In order to reach remote ubuntu server machines with ssh installed on them, type the following command from command line of the client machine:
$ ssh remoteUserName@remoteMachineIPAddress
replace remoteUserName and remoteMachineIPAddress with appropriate values. Then you will see that it is asking for adding to the list of known hosts. write 'yes' for confirmation. Then type following from the console window and press enter, the remote machine will shutdown.
$ sudo shutdown -h now

Tuesday, September 29, 2009

equals(Object obj) and hashCode() methods in Java

Comparing two different objects is one of the mostly achieved tasks for object oriented Java developers. In order to handle this requirement, it is important to understand what makes two different objects in Java equals to each other. For this purpose java.lang.Object class includes equals(Object obj) and hashCode() methods. Main criteria for determining whether different two objects are equal to each other depends actually upon the application's business logic. So it depends on the significance of fields in your Java classes.

Implementation details for the equals(Object obj) method of java.lang.Object class involve deciding about firstly for the types of objects being compared. If two objects are of different types, then the equals(Object obj) method returns false. Else if the compared object can be casted to the current object, it becomes the time for checking the equality of fields in objects.

Another method which is helpful for object comparison in Java is the hashCode() method of java.lang.Object class. hashCode() and equals(Object obj) methods of java.lang.object class are related to each other because if two objects are equal so they are required to generate the same hash code for their common fields. It is suggested to also override hashCode() method of java.lang.Object class whenever you override equals(Object obj) method of java.lang.Object class.

If you are using eclipse for Java development, then ide generates equals(Object obj) and hashCode() methods for you automatically. In order to generate equals(Object obj) and hashCode() methods for your Java classes in eclipse ide, right click in your .java source file and choose from context menu "Source --> Generate hashCode() and equals()" so ide generates hashCode() and equals(Object obj) methods for you.

package util;

public class Person {

 private int id;
 private String name;
 
 public Person(int id,String name){
    this.id = id;
    this.name = name;
 }
 
 @Override
 public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + id;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
 }
 
 @Override
 public boolean equals(Object obj) {
    if (this == obj)
       return true;
    if (obj == null)
       return false;
    if (!(obj instanceof Person))
       return false;
    Person other = (Person) obj;
    if (id != other.id)
       return false;
    if (name == null) {
       if (other.name != null)
          return false;
    } else if (!name.equals(other.name))
      return false;
      return true;
    }
 
    public static void main(String[] args) {
    Person personOne = new Person(1,"Alice");
    Person personTwo = new Person(1,"Alice");
    Person personThree = new Person(1,"Jack");
  
    if(personOne.equals(personTwo)){
      System.out.println("personOne and personTwo are equal!");
    }

    if (personOne.equals(personThree)) {
      System.out.println("personOne and personThree are equal!");
    } else {
      System.out.println("personOne and personThree are not equal!");
    }  
  } 
}

When you run this java class, console output becomes:

personOne and personTwo are equal!
personOne and personThree are not equal!

Saturday, July 25, 2009

Implementing CommandListener Interface in J2ME Applications

Classes that implement CommandListener interface, which has a single method: commandAction(Command com, Displayable dis), have the abilitiy to trace command click actions. In order to transfer command information to a listener, the listener is registered with the method setCommandListener(CommandListener listener). In the sample code at below, the command listener in this case is the form class itself which is implementing the commandAction() method.
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;

public class ConfirmationPopUpForm extends Form implements CommandListener {
 private Command cmdPreviousPage;
 private Command cmdExit; 
 public ConfirmationPopUpForm(){
  this("Confirmation Form");
 } 
 public ConfirmationPopUpForm(String title){
  super(title);  
  cmdPreviousPage = new Command("Return",Command.CANCEL, 0);
  addCommand(cmdPreviousPage);
  cmdExit = new Command("Exit",Command.OK, 1);
  addCommand(cmdExit);
  this.setCommandListener(this);
 }
 public void commandAction(Command cmd, Displayable display) {
  if(cmd == cmdExit){
   exitAction();
  }
  else if(cmd == cmdPreviousPage){
   showPreviousFormAction();
  }
 }
 private void showPreviousFormAction() {
  MainMenuForm.show();
 }
 private void exitAction() {
  StarterForm.show();
 } 
}

Thursday, July 23, 2009

Unicode Characters Corresponding to Turkish Letters

In order to use Turkish characters/letters ç,ğ,ı,ş,ö,ü,Ç,Ğ,İ,Ş,Ö,Ü in applications, their corresponding unicode character codes can be helpful.



Turkish Unicode Characters/Letters :


     ç    -->   \u00E7
     ğ    -->   \u011F
     ı     -->   \u0131
     ş    -->   \u015F
     ö    -->   \u00F6
     ü    -->   \u00FC
     Ç   -->   \u00C7
     Ğ   -->   \u011E
     İ     -->   \u0130
     Ş    -->   \u015E
     Ö   -->   \u00D6
     Ü   -->   \u00DC




Wednesday, July 22, 2009

Creating Buttons on J2ME Forms

StringItem can be used in order to create buttons on J2ME forms. Define a new Command variable in your Form and set it as defaultCommand for StringItem variable.

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;
import javax.microedition.lcdui.StringItem;

public class FormWithButton extends Form implements ItemCommandListener{

private StringItem btnLogin;
private Command cmdLogin;
public FormWithButton(String str) {
super(str);
btnLogin = new StringItem(null, "Login");
cmdLogin = new Command("", Command.OK, 1);
btnLogin.setDefaultCommand(cmdLogin);
btnLogin.setItemCommandListener(this);
append(btnLogin);
}
public void commandAction(Command cmd, Item item) {
LoginForm.show();
}
}

Thursday, July 16, 2009

Singleton Java ME Forms

Some of the mobile forms contain only static elements, which are not interacting with the user. That kind of forms are usually aimed to provide a list of command items on them, which are redirecting users to other forms. So, it is reasonable to design that classess in singleton pattern. Aim of creating a form in singleton pattern is to ensure that a class has only one instance at a time. Instead of creating an instance of that kind of mobile forms each time, you can hide the constructor from global access and make it protected.
The instance that will represent the class is placed as a static field in the class and initialized when it is not created before.
import javax.microedition.lcdui.Form;

public class SingletonForm extends Form {

 private static SingletonForm instance;

 public static SingletonForm createNew() {
  if(instance == null){
   instance = new SingletonForm(""); 
  }
  return instance;
 }
 
 public void showNew() {
  MainMidlet.getInstance().getDisplay().setCurrent(this);
 }
 
 protected SingletonForm(String str){
  super(str);
  append("SingletonForm!");
 }
}


This is the 'not-thread-safe' version of singleton pattern. If you want it to be thread-safe then use locking. In order to call an instance of the above class you can type in your caller:
SingletonForm.createNew().showNew();

Friday, June 12, 2009

Character Frequency Checker in Ruby

Character frequency checker which is implemented in Ruby, can be used to find the number of occurrences of each consecutive series of the same character in a given string. In the inspected string, that consecutive series of the each character is replaced by a two element array where the first element is a string containing the character, and the second element is the number of repetitions. For example,if the method receives a parameter like "aaassssddddfgh", then the result will be stored in an array where its elements are:
[[a,3],[s,4],[d,4],f,g,h]
class CharacterFrequency

  def char_frequency(sequence)
    return_array = Array.new
    if (!sequence.eql?(nil) && sequence.size>0)
      puts "String to check for character frequency is : "+sequence
      last_checked_char_index = 0
      for i in 0...sequence.size
        next_char_index = last_checked_char_index + 1
        repeating_char_count = 1
        if(i >= last_checked_char_index)
          for j in i...sequence.size
            if(sequence[j].eql?(sequence[next_char_index]))
              repeating_char_count = repeating_char_count + 1
              next_char_index = next_char_index + 1
              last_checked_char_index = next_char_index
            else
              last_checked_char_index = next_char_index
              arr = Array.new
              if repeating_char_count > 1
                arr = sequence[i].chr.to_s+","+repeating_char_count.to_s
              elsif repeating_char_count == 1
                arr = sequence[i].chr.to_s
              end
              return_array.push(arr)
            break
          end
        end        
      end      
    end
    if(!return_array.empty? && return_array.length >0)
      for indice in 0...return_array.size
        puts return_array[indice]
      end
    end
    else
      puts "Empty or null sequence!"
  end
  end
end

app = CharacterFrequency.new
app.char_frequency("laaamburtiiifikasssssyon")
app.char_frequency("aaassssddddfgh")
app.char_frequency("abcdeee")
app.char_frequency("a")
app.char_frequency("ab")
app.char_frequency("abBgGvV122")
app.char_frequency("asdadddssf")
app.char_frequency("")
app.char_frequency(nil)


Save your script into frequency.rb file and run as follows. It will loop through the created array and display elements at console. Tested with ruby 1.8.7 on ubuntu9.04.
$ ruby frequency.rb

Saturday, May 23, 2009

Passing Complex Types Between TCP Client and Server

Matrix Transpose with Readn&Writen:

In order to pass an array between a TCP client and server, it is suitable to place your array in a structure.

For this sample which is aimed to pass a 5X10 integer array from client to server and return back the transpose of that 5X10 array back to the client; define one structure for the 5X10 integer array you pass to the server, and another structure for the result 10X5 integer array that you return back to the client.

Place both structure definitions and Readn&Writen functions in a matrix.h file.Writen is used to send the structure to the server by client.Readn is used to read the reply, and then print the result at client side by using printf function as defined by Stevens code.

Server reads the arguments by calling Readn,takes the transpose of the 5X10 array passed to the server-side and by using Writen, 10X5 matrix is returned back to the client.

In addition to client and server source code files an extra header file is used to hold 2 structures and Readn&Writen method implementations.

client-source.c file is as follows:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "matrix.h"

int main(int argc,char **argv)
{
    int clientfd;
    short int port_no;
    char msg[1000];
    struct sockaddr_in servaddr;
    char *server_ip_address;
    struct matrices matrix;
    struct matriceresult matriceresult;
    if(argc!=5){
       printf("Usage Format: ./client -a <IPAddress> -p <PortNumber>\n");
       printf("Sample Run: ./client -a 127.0.0.1 -p 2000\n");
       exit(1);
    }
    server_ip_address=(char *)argv[2];
    port_no = atoi(argv[4]);
    printf("Client will connect to the server at IP %s, port #%d\n", server_ip_address, port_no);
   
    // Create client socket.
    if((clientfd = socket(AF_INET, SOCK_STREAM, 0))<0 br="">      printf("Socket could not be created\n");
      printf("errno %i: %s\n",errno,strerror(errno));
      exit(1);
    }
    printf("Client socket created\n");
    errno=0;
    // Connect to the server client
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port_no);
    if((inet_pton(AF_INET, server_ip_address, &servaddr.sin_addr))<=0){
      printf("inet_pton error for %s\n",server_ip_address);
      printf("errno %d: %s\n",errno,strerror(errno));
      exit(1);
    }
    errno=0;
    if((connect(clientfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))<0 br="">       printf("Connect error\n");
       printf("errno %d: %s\n",errno,strerror(errno));
       exit(1);
    }
    printf("Client socket connected\n");

    //fill initial matrice to be sent from the client to the server. 
    int i,j;
    for(i=0;i<5 br="" i="">      for(j=0;j<10 br="" j="">        matrix.matrice[i][j]=rand()%100;
    //print matrice
    printf("Printing initial 5X10 matrice at client side\n");
    int k,l;
    for(k=0;k<5 br="" k="">      for(l=0;l<10 br="" l="">        printf("%d\t",matrix.matrice[k][l]);
      printf("\n"); 
    }
    writen(clientfd,&matrix,sizeof(matrix));
    readn(clientfd,&matriceresult,sizeof(matriceresult));
    printf("Client received 10X5 matrix from server! Printing Transposed New Matrix at Client\n");
    int m,n;
    for(m=0;m<10 br="" m="">       for(n=0;n<5 br="" n="">         printf("%d\t",matriceresult.resultmatrice[m][n]);
       printf("\n"); 
    }
    close(clientfd);
    return 0;
}

server-source.c file is as follows:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "matrix.h"

extern int errno;

int main(int argc,char **argv)
{
    int clientaddrlen, listenfd, connectfd, bytes_rcvd, listen_queue_size=1;
    short int port_no;
    char buffer[1000];
    struct sockaddr_in servaddr, clientaddr;
    pid_t  childpid;
    int status;
    struct matrices matrix;
    struct matriceresult matriceresult;
    
    if(argc!=3){
       printf("Usage Format: ./server -p <PortNumber>\n");
       printf("Sample Run: ./server -p 2000\n");
       exit(1);
    }
    port_no = atoi(argv[argc-1]);
    printf("Server running at port #%d\n", port_no);

    // Create server socket.
    if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        fprintf(stderr, "Cannot create server socket! errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server socket created\n");

    // Bind (attach) this process to the server socket.
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(port_no);
    errno = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
    if(errno < 0)
    {
        printf("Server bind failure errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server socket is bound to port #%d\n", port_no);

    // Turn 'listenfd' to a listening socket. Listen queue size is 1.
    errno=listen(listenfd,listen_queue_size);
    if(errno < 0)
    {
        printf("Server listen failure errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server listening with a queue of size %d. \n", listen_queue_size);

    // Wait for connection(s) from client(s).
    while (1)
    {
        clientaddrlen = sizeof(clientaddr);
        connectfd = accept(listenfd, (struct sockaddr *) &clientaddr, &clientaddrlen);
        Readn(connectfd,&matrix,sizeof(matrix));
    //transpose the matrix that sent from client to server 
    int i,j;        
    for(i=0;i<5 br="" i="">      for(j=0;j<10 br="" j="">        matriceresult.resultmatrice[j][i]=matrix.matrice[i][j];
      }
    }
    //send resultMatrix to client side
    Writen(connectfd,&matriceresult,sizeof(matriceresult));
    }
    return 0;
}

matrix.h file is as follows:
#ifndef __matrix_h
#define __matrix_h
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

struct matrices{
int matrice[5][10];
};

struct matriceresult{
int resultmatrice[10][5];
};

ssize_t writen(int fd, const void *vptr, size_t n)
{
 size_t  nleft;
 ssize_t  nwritten;
 const char *ptr;

 ptr = vptr;
 nleft = n;
 while (nleft > 0) {
  if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
   if (errno == EINTR)
    nwritten = 0;  /* and call write() again */
   else
    return(-1);   /* error */
  }
  nleft -= nwritten;
  ptr   += nwritten;
 }
 return(n);
}
/* end writen */

void Writen(int fd, void *ptr, size_t nbytes)
{
 if (writen(fd, ptr, nbytes) != nbytes)
  printf("writen error");
}

ssize_t readn(int fd, void *vptr, size_t n)
{
 size_t nleft;
 ssize_t nread;
 char *ptr;

 ptr = vptr;
 nleft = n;
 while (nleft > 0) {
  if ( (nread = read(fd, ptr, nleft)) < 0) {
   if (errno == EINTR)
    nread = 0;  /* and call read() again */
   else
    return(-1);
  } else if (nread == 0)
   break;    /* EOF */

  nleft -= nread;
  ptr   += nread;
 }
 return(n - nleft);  /* return >= 0 */
}
/* end readn */

ssize_t Readn(int fd, void *ptr, size_t nbytes)
{
 ssize_t  n;

 if ( (n = readn(fd, ptr, nbytes)) < 0)
  printf("readn error");
 return(n);
}
#endif /* __matrix_h */


Sample run can be created as follows:

1-)Create server and client executables :

$ cc -o server server.c matrix.h
$ cc -o client client.c matrix.h

2-)Run server at the same tab

$ ./server -p 2000

3-)Open a new tab, run client

$ ./client -a 127.0.0.1 -p 2000

You can get client.c, server.c and matrix.h files from the links.Application tested on ubuntu9.04.

Friday, May 22, 2009

TCP Echo Client Server

When writing a TCP client server program in unix environment, elementary socket functions are used.As described at Stevens book these elementary functions are listed as:

-socket : To perform network I/O, the first thing a process must do is call the socket function.
-connect : used by a TCP client to establish a connection with a TCP server.
-bind : assigns a local protocol address to a socket.
-listen : called by only a TCP server and it converts an unconnected socket into a passive socket.
-accept :called by a TCP server to return the next completed connection from the front of the completed connection queue.
-fork :In Unix environment it is used to create a new process. By using fork() a process makes a copy of itself so that one copy can handle one operation while the other does another task.
-close : close a socket and terminate a TCP connection.

By using above elementary functions we can build our simple echo client and server programs. In this program, when a client connects to the server, the server will use fork() to create a new child process.

Newly created child process will serve the client. The child process terminates after the client sends its message and breaks the connection. The algorithm is as follows:

If this is the child process:
- Close listenfd since it is the responsibility of the parent to handle incoming connections.
- Display the message "Child process serving the client."
- Read the message from the client and display it.
- Close connectfd.
- Exit. The child process was created only to serve the client.

Since the client has transmitted its message and the connection is terminated, the child must terminate.

If this is the parent process:
- Close connectfd since it is the responsibility of the child process to serve the client.
- Go back to accept. Note that the server (parent) runs indefinitely.

client-source.c file is as follows:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc,char **argv)
{
    int clientfd;
    short int port_no;
    char msg[1000];
    struct sockaddr_in servaddr;
    char *server_ip_address;
    if(argc!=5){
       printf("Usage Format: ./client -a <IPAddress> -p <PortNumber>\n");
       printf("Sample Run: ./client -a 127.0.0.1 -p 2000\n");
       exit(1);
    }
    server_ip_address=(char *)argv[2];
    port_no = atoi(argv[4]);
    printf("Client will connect to the server at IP %s, port #%d\n", server_ip_address, port_no);
   
    // Create client socket.
    if((clientfd = socket(AF_INET, SOCK_STREAM, 0))<0 br="">       printf("Socket could not be created\n");
       printf("errno %i: %s\n",errno,strerror(errno));
       exit(1);
    }
    printf("Client socket created\n");
    errno=0;
    // Connect to the server client
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port_no);
    if((inet_pton(AF_INET, server_ip_address, &servaddr.sin_addr))<=0){
      printf("inet_pton error for %s\n",server_ip_address);
      printf("errno %d: %s\n",errno,strerror(errno));
      exit(1);
    }
    errno=0;
    if((connect(clientfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))<0 br="">      printf("Connect error\n");
      printf("errno %d: %s\n",errno,strerror(errno));
      exit(1);
    }
    printf("Client socket connected\n");
    // Read one line of message from the input and send it to the server.
    printf("Enter the message to be sent to the server: ");
    scanf("%s", msg);
    send(clientfd, msg, strlen(msg)+1, 0);
    close(clientfd);
    printf("Client sent the message and disconnected. \n");
    return 0;
}


server-source.c file is as follows:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
extern int errno;
int main(int argc,char **argv)
{
    int clientaddrlen, listenfd, connectfd, bytes_rcvd, listen_queue_size=1;
    short int port_no;
    char buffer[1000];
    struct sockaddr_in servaddr, clientaddr;
    pid_t  childpid;
    int status;
    if(argc!=3){
       printf("Usage Format: ./server -p <PortNumber>\n");
       printf("Sample Run: ./server -p 2000\n");
       exit(1);
    }
    port_no = atoi(argv[argc-1]);
    printf("Server running at port #%d\n", port_no);

    // Create server socket.
    if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        fprintf(stderr, "Cannot create server socket! errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server socket created\n");
    // Bind (attach) this process to the server socket.
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(port_no);
    errno = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
    if(errno < 0){
        printf("Server bind failure errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server socket is bound to port #%d\n", port_no);
    // Turn 'listenfd' to a listening socket. Listen queue size is 1.
    errno=listen(listenfd,listen_queue_size);
    if(errno < 0){
        printf("Server listen failure errno %i: %s\n",errno,strerror(errno));
        exit(1);
    }
    printf("Server listening with a queue of size %d. \n", listen_queue_size);
    // Wait for connection(s) from client(s).
    while (1){
        clientaddrlen = sizeof(clientaddr);
        connectfd = accept(listenfd, (struct sockaddr *) &clientaddr, &clientaddrlen);
        if(connectfd<0 br="">            printf("Server accept failure errno %d: %s\n",errno,strerror(errno));
            exit(1);
        }
        printf("A connection received from a client. Creating a child to serve the client.\n");
        if((childpid = fork()) == 0) { /* child process */
           close(listenfd); /* close listening socket */
           printf("Child process serving the client.\n");
           if (recv(connectfd, buffer, sizeof(buffer), 0 ) > 0){
               printf("Received message: %s\n", buffer);
           }
        close(connectfd);   /* parent closes connected socket */
        exit(1);
        }
        else if (childpid <0 br="" failed="" fork="" to="">             printf("Failed to fork\n");    
             printf("Fork error errno %d: %s\n",errno,strerror(errno));
        }
        else if(childpid != 0){  /* parent process */
             close(connectfd);   /* parent closes connected socket */  
             childpid = wait(&status);  
        }
    }
    return 0;
}

In order to avoid zombie processes created in the system, wait() function is used in the server main function.

Sample run can be created as follows:

1-)Create server and client executables :

$ cc -o server server_source.c
$ cc -o client client_source.c

2-)Run server at the same tab

$ ./server -p 2000

3-)Open a new tab, run client

$ ./client -a 127.0.0.1 -p 2000

You can get client_source.c and server_source.c files from the links.Application tested on ubuntu9.04.

Thursday, May 14, 2009

Ruby on Rails MySql Connection

After creating a new ROR application by typing

>rails applicationName

command from the console, Rails creates all the required files for the newly created application.

Rails creates many folders and database related files are placed under /config folder.

It is required to add some connection info into the database.yml file which is also located under /config folder of your new Rails project.

Rails keeps database-login related data out of the application code and places that login information into database.yml file.

database.yml file contains information about database connections. That file has 3 sections for development-test-production databases.

development:
  adapter: mysql
  encoding: utf8
  reconnect: false
  database: store_development
  pool: 5
  username: user
  password: userpass
  socket: /var/run/mysqld/mysqld.sock
test:
  adapter: mysql
  encoding: utf8
  reconnect: false
  database: store_test
  pool: 5
  username: user
  password: userpass
  socket: /var/run/mysqld/mysqld.sock
production:
  adapter: mysql
  encoding: utf8
  reconnect: false
  database: store_production
  pool: 5
  username: user
  password: userpass
  socket: /var/run/mysqld/mysqld.sock

adapter: section tells Rails what kind of database you are using.
database: name of the database that you want to connect to.
username&password: let's your application to login to the database.

You need to have that specified database created previously in your DBMS for connection.

For this example store_development database needs to be created previously in your mysql rdbms.

In order to create your database tables which are corresponding to models created use Rake.Rake helps to apply the migration to your database. You tell the rake to do some task and that task gets done.

>rake db:migrate

Rake looks for all the migrations not applied to the database and applies them. When it is required to add a new column to a database table, you can also use migration.

This helps you to remember what each migration does when you come back to your application at a later time.

You can create a migration explicitly by typing the command:

>ruby script/generate migration add_address

To be able to run migrations on Ubuntu 9.04 OS, also install required libmysql-ruby module.

Monday, May 4, 2009

Create Function PL/Sql

Function returns a value to the caller.

As a procedure, a function has two parts: the specification and the body.

Implementation is placed in the body part.

The following statement creates the function get_app_rec. This is the body of the function.
  FUNCTION get_app_rec
  (p_app_no  IN  appointment.app_no%TYPE)
  RETURN appointment%ROWTYPE
   IS
      v_rec                  appointment%ROWTYPE;
   BEGIN
      SELECT *
        INTO v_rec
        FROM appointment
       WHERE app_no = p_app_no
      ;
      RETURN v_rec;
   END;

Spec of the function is :
   FUNCTION get_app_rec
      (p_app_no  IN  appointment.app_no%TYPE)
   RETURN appointment%ROWTYPE;

Create Procedure PL/Sql

Procedure does not return a value to the caller.

Usually insert/update/delete operations are placed in a procedure.

A procedure has two parts: the specification and the body. Implementation is placed in the body part.

The following statement creates the procedure insert_visit_log. This is the body of the procedure.

  PROCEDURE insert_visit_log
      (p_visit_no  IN  visit_log.visit_no%TYPE,
       p_aim_code  IN  visit_log.aim_code%TYPE,
       p_op_name   IN  visit_log.op_name%TYPE,
       p_date      IN  visit_log.v_date%TYPE)
   IS
   BEGIN
      INSERT INTO visit_log
             (visit_no,aim_code,op_name,v_date)
      VALUES (p_visit_no, p_aim_code,p_op_name,p_date)
      ;
   END;

Spec of the procedure is :



  PROCEDURE insert_visit_log
      (p_visit_no  IN  visit_log.visit_no%TYPE,
       p_aim_code  IN  visit_log.aim_code%TYPE,
       p_op_name   IN  visit_log.op_name%TYPE,
       p_date      IN  visit_log.v_date%TYPE);

Create Sequence Pl/Sql

Sequence is usually used to generate unique primary key values for a relational database table.

Because a sequence is an independent db object, it is created and used independent of a database table.

Same sequence can be used for different tables.

The following statement creates the sequence visitor_seq.
CREATE SEQUENCE VISITOR_SEQ
  INCREMENT BY 1
  START WITH 1
  MINVALUE 1
  MAXVALUE 9999999999
  NOCYCLE
  NOORDER
  ; 

In order to drop previously created sequence issue following pl/sql statement.


DROP SEQUENCE VISITOR_SEQ;

Tuesday, April 28, 2009

Console Based Schedule Reminder in Ruby

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.

Schedule Reminder is a console based small application that reads the events from a yaml file and displays reports based on the user's choice.

Its written in Ruby.For the beginning, prepare your schedule.yml file by using a text editor.

Sample yaml file can contain following lines in it for this program.

## YAML Template.

app1:
 date_time : 2009-04-22 00:00
 subject : Deadline for HW

app2:
 date_time : 2009-04-23 14:00
 subject : Lecture Hour

app3:
 date_time : 2009-04-29 14:00
 subject : Research

app4:
 date_time : 2009-04-28 14:00
 subject : Meeting at Office

app5:
 date_time : 2009-04-28 14:00
 subject : Meeting with friends

app6:
 date_time : 2009-04-28 14:00
 subject : Library

app7:
 date_time : 2009-04-30 20:00
 subject : Watch game

You can also download schedule.yml file from the link.

Then prepare your generateScheduleReport.rb file and create a new GenerateReport class in it.

When the user runs the program, a console based menu is displayed to the client. Until the client enters a valid input from the console it is displayed.

To find events of today following method can be implemented.

Method searches for the entry with today's time from the hash and if found puts it in an array.

  def generate_report_for_the_events_of_the_day()
      t = Time.now
      t = t.strftime("%Y-%m-%d")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        str = str[0..9]
        if str.eql?(t.to_s)
          event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
          event_index = event_index + 1
        end
      end
      if event_array.size > 0
        puts "Report for the events of today is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for today\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for today\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for today\n"
      end
  end

To find events of the week following method can be implemented. 

Method searches for the entry with this week's date from the hash and if found puts it in an array. strftime("%W") used to find the number of week.



  def generate_report_for_the_events_of_the_week()
      t = Time.now
      searched_week_of_year =t.strftime("%W")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        time_from_yaml = Time.parse(str)
        week_of_year_from_yaml = time_from_yaml.strftime("%W")
        if searched_week_of_year.eql?(week_of_year_from_yaml)
           event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
           event_index = event_index + 1
        end
        week_of_year_from_yaml = 0
      end
      if event_array.size > 0
        puts "Report for the events of the week is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for this week\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for this week\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this week\n"
      end
  end

To find events of the month following method can be implemented.


Method searches for the entry with this month's date from the hash and if found puts it in an array. 

  def generate_report_for_the_events_of_the_month()
      t = Time.now
      t = t.strftime("%Y-%m-%d")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        str = str[5..6]
        if str.eql?(t.to_s[5..6])
          event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
          event_index = event_index + 1
        end
      end
      if event_array.size > 0
        puts "Report for the events of the month is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for this month\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for this month\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this month\n"
      end
  end
To find events in the upcoming n days following method can be implemented. 

  def generate_report_for_the_events_in_the_upcoming_n_days()
      while(1)
        puts "Please enter for the number of upcoming days to generate report"
        user_input = gets
        user_input = user_input.chomp
        if is_a_number?(user_input)
          t = Time.now
          day_of_year = t.yday
          searched_day_of_year = day_of_year + user_input.to_i
          t = t.strftime("%Y-%m-%d")
          event_array, event_index, hashelement = load_yaml_from_location
          for i in (0...hashelement.keys.size)
            x = hashelement[hashelement.keys[i]]
            str = x[x.keys[1]]
            time_from_yaml = Time.parse(str)
            day_of_year_from_yaml = time_from_yaml.yday
            if day_of_year_from_yaml >= day_of_year
               and day_of_year_from_yaml <= searched_day_of_year
              event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
              event_index = event_index + 1
            end
            day_of_year_from_yaml = 0
          end
          if event_array.size > 0
           puts "Report for the events of the upcoming "+user_input.to_s
                 +" days is:\n"
           if event_array.size==1
            puts "There is 1 event in your schedule for upcoming "
                  +user_input.to_s+" days\n"
           else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for upcoming "
                  +user_input.to_s+" days\n"
           end
           for j in (0 ... event_array.size)
             puts event_array[j]+"\n"
           end
           break
          else
            puts "There is no event in schedule for upcoming "
                  +user_input.to_s+" days"
            break
          end
        else
          puts "Enter a valid number of upcoming days!"
        end
      end
  end

To find events in the upcoming n work days following method can be implemented. 

yday method returns day of year. Exclude Sunday and Saturday in the if condition.

  def generate_report_for_the_events_in_the_upcoming_n_work_days()
      while(1)
        puts "Please enter for the number of"
              +" upcoming n working days to generate report"
        user_input = gets
        user_input = user_input.chomp
        if is_a_number?(user_input)
          t = Time.now
          day_of_year = t.yday
          searched_day_of_year = day_of_year + user_input.to_i
          t = t.strftime("%Y-%m-%d")
          event_array, event_index, hashelement = load_yaml_from_location
          for i in (0...hashelement.keys.size)
            x = hashelement[hashelement.keys[i]]
            str = x[x.keys[1]]
            time_from_yaml = Time.parse(str)
            day_from_yaml = time_from_yaml.strftime("%a")
            day_of_year_from_yaml = time_from_yaml.yday
            if day_of_year_from_yaml >= day_of_year
               and day_of_year_from_yaml <= searched_day_of_year
              if (day_from_yaml !="Sun" and day_from_yaml != "Sat")
                  event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
                  event_index = event_index + 1
              end
            end
            day_of_year_from_yaml = 0
          end
          if event_array.size > 0
           puts "Report for the events of the upcoming "
                 +user_input.to_s+" working days is:\n"
           if event_array.size==1
            puts "There is 1 event in your schedule for upcoming "
                  +user_input.to_s+" working days\n"
           else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for upcoming "
                  +user_input.to_s+" working days\n"
           end
           for j in (0 ... event_array.size)
             puts event_array[j]+"\n"
           end
           break
          else
            puts "There is no event in schedule for upcoming "
                  +user_input.to_s+" working days"
            break
          end
        else
          puts "Enter a valid number of upcoming days!"
        end
      end
  end


To find events in the weekend following method can be implemented. strftime("%W") returns week of year. 

  def generate_report_for_the_events_in_the_weekend()
      t = Time.now
      searched_week_of_year =t.strftime("%W")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        time_from_yaml = Time.parse(str)
        day_from_yaml = time_from_yaml.strftime("%a")
        week_of_year_from_yaml = time_from_yaml.strftime("%W")
        if searched_week_of_year.eql?(week_of_year_from_yaml)
           and (day_from_yaml.eql?("Sun") or day_from_yaml.eql?("Sat"))
           event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
           event_index = event_index + 1
        end
        week_of_year_from_yaml = 0
      end
      if event_array.size > 0
        puts "Report for the events of the weekend is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for weekend\n"
        else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for weekend\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this weekend\n"
      end
  end


To load yaml file and store its content in a hash, following method can be implemented: 

  def load_yaml_from_location
    hashelement = {}
    hashelement = YAML::load_file('/home/tufangorel/Desktop/schedule_reminder/schedule.yml')
    event_array = Array.new
    event_index = 0
    return event_array, event_index, hashelement
  end

Ruby comes with a rich date library operations.

You can download generateScheduleReport.rb file from the link. 

Put this generateScheduleReport.rb and schedule.yml files into the same folder and execute following command from the console to run the application.

user@machine:~/Desktop/reminder$ ruby generateScheduleReport.rb

A welcome menu is displayed and it loops until the user enters one of the options. 

Tested on ubuntu9.04

Passing multiple parameters with rpcgen

RPC handles arbitrary data structures and converts these structures to a standard transfer format called external data representation (XDR) before sending them over the transport.

The conversion from a machine representation to XDR is called serializing, and the reverse process is called deserializing.

For example, to send 2 string parameters, the routine is packaged in a structure containing these 2 different string parameters.

Client sends two different string parameters which are names of programs that are going to be executed at server side and the result is going to be returned back to the client.

Names of programs are set in client main() function. First program to be executed is "netstat -s" and the result of that program is going to be piped into another program "grep TCP".

Result of "grep TCP" is returned to the client program. At the same time this an example of using pipes in linux environment.

Define an extra struct in your prog.x file.
/* prog.x file                                                                
 * run_progs_1(program_names) returns the output to the client(struct param)
*/   

const MAXPARAMNAME = 255;
typedef string prog<MAXPARAMNAME>;
struct prognames
{
 prog program1;
 prog program2;
};
                                                            
program RPC_PROG {                                               
    version RPC_VERS {                                         
 string RUN_PROGS(prognames) = 1; /* procedure numer=1 */
    } = 1; /* version number = 1 */
                                                                  
} = 0x12345678; /* program number = 0x12345678 */


Running rpcgen on prog.x generates four output files:

1-)Header file (prog.h),
2-)Client stub (prog_clnt.c),
3-)Server skeleton (prog_svc.c),
4-)XDR routines in the file (prog_xdr.c).

Additionally, you need to implement that defined function (string RUN_PROGS(prognames)) in your prog.x file.

Create a new file "server_source.c" and add your implementation for
(string RUN_PROGS(prognames)) function into that file.

/* server_source.c file
 * run_progs_1(program_names) returns the output to the client(struct param)
*/   
#include <rpc/rpc.h> /* standard RPC include file */
#include "prog.h" /* this file is generated by rpcgen */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define READ_MAX_SIZE 512

/* Return the result of executed commands function1*/    
char** run_progs_1_svc(prognames *argparams, struct svc_req *arg2)
{
 FILE* fpipe;
 char* operator = " | ";
 char* program1AndProgram2;
 char* prog1 = argparams->program1;
 char* prog2 = argparams->program2;
 static char* readPipeInto;
 readPipeInto = (char*)malloc((READ_MAX_SIZE + 1)*sizeof(char));
 memset(readPipeInto, 0, READ_MAX_SIZE + 1);
 program1AndProgram2=(char*)malloc((strlen(prog1)+strlen(operator)+strlen(prog2)+1)*sizeof(char));
 strcpy(program1AndProgram2, argparams->program1);
 strcat(program1AndProgram2, operator);
 strcat(program1AndProgram2, argparams->program2);
 //execute commands
 if ( !(fpipe = (FILE*)popen(program1AndProgram2,"r")) )
 { 
   perror("Cant open pipe!");
   exit(1);
 }
 //store result in readPipeInto
 fread((char *)readPipeInto, READ_MAX_SIZE, 1, fpipe); 
 pclose(fpipe); 
 free(program1AndProgram2);
 //return output to the client
 return (char **)&readPipeInto;
}


Lastly, prepare your client and call the routine from server. Create a new file client_source.c .


/* client_source.c file */   
#include <stdio.h>
#include <stdlib.h>                                 
#include <rpc/rpc.h> /* standard RPC include file */     
#include "prog.h" /* this file is generated by rpcgen */ 

main(int argc, char *argv[])                               
{ 
   CLIENT *cl; /* RPC handle */

   char *server;

   char** resultStringFromServerExecutePrograms;
   if (argc != 2) {
       fprintf(stderr, "usage: %s hostname\n", argv[0]);
       exit(1);
   }

   server = argv[1];
   /* Create client handle */
   if ((cl = clnt_create(server, RPC_PROG, RPC_VERS, "udp")) == NULL) {
       /* can't establish connection with server */
       clnt_pcreateerror(server);
       exit(2);
   }
  
   prognames args;
   args.program1 = "netstat -s";
   args.program2 = "grep TCP";
   /*remote procedure run_progs */
   resultStringFromServerExecutePrograms = run_progs_1(&args, cl);
   if (resultStringFromServerExecutePrograms == NULL) {
      clnt_perror(cl, server);
      exit(3);
   }
   printf("Function1 Result of Run Programs is: \n\n");
   printf("%s",*resultStringFromServerExecutePrograms);
   printf("\n\n"); 
 
   clnt_destroy(cl); 
   exit(0);
}


In order to create server and client executables by using these 3 different files, issue the following commands from the terminal in the same order. 


Put your (prog.x, client_source.c, server_source.c) files into the same folder.

user@machine:~/Params$ rpcgen prog.x
user@machine:~/Params$ cc -o client client_source.c prog_clnt.c prog_xdr.c 
user@machine:~/Params$ cc -o server server_source.c prog_svc.c prog_xdr.c 
user@machine:~/Params$ ./server localhost

Open a new terminal tab and run the client.
user@machine:~/Params$ ./client localhost

Output of running client is as follows:
Function1 Result of Run Programs is: 

    35 TCP sockets finished time wait in fast timer
    15 other TCP timeouts

Run on ubuntu 9.04.

Friday, April 24, 2009

Distributed Systems Programming with rpcgen

rpcgen utility enables developers to write distributed applications.

It generates stubs for client and server side automatically. Programmer is required to write 3 additional programs to use rpcgen tool.

You need to have rpcgen utility installed on your machine to run the example. Ubuntu synaptic easily installs it for you.

1-) Write the prog.x file which contains definition for required routines. You can give any name for this *.x file ending with .x extension.You need to declare remote procedures in a remote program.

/*  prog.x
                                                                
 * Define your procedure here
 
 * function_1 dir_list_1(string) returns the output to the client 
 * (takes one string argument)

 * function_2 execute_uptime_1() returns the output to the client 
 * (no argument)
*/    
program RPC_PROG {                                               
    version RPC_VERS {                                         
    string DIR_LIST(string) = 1; /* procedure number = 1 */
    string EXECUTE_UPTIME(void) = 2; /* procedure number = 2 */
    } = 1; /* version number = 1 */
} = 0x12345678; /* program number = 0x12345678 */


2-) Write remote procedure implementation in a *.c file.

This file contains implementation of procedures declared in prog.x file.

/*  server_source.c   */  
#include <time.h>
#include <rpc/rpc.h> /* standard RPC include file */
#include "prog.h" /* this file is generated by rpcgen */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define READ_MAX_SIZE 512

/*Return the listing of all files in a directory function1*/
char** dir_list_1_svc(char** location, struct svc_req* arg2)
{
 FILE* fpipe;
 char* command="ls -l ";
 char* commandAndDirName;
 static char* readPipeInto;
 readPipeInto = (char*)malloc((READ_MAX_SIZE + 1)*sizeof(char));
 memset(readPipeInto, 0, READ_MAX_SIZE + 1);
 commandAndDirName=(char*)malloc((strlen(command)+strlen(*location)+1)*sizeof(char));
 strcpy(commandAndDirName, command);
 strcat(commandAndDirName, *location);
 //execute command ls -l
 if ( !(fpipe = (FILE*)popen(commandAndDirName,"r")) )
 {
    perror("Cant open pipe!");
    exit(1);
 }
 //store result in readPipeInto
 fread((char*)readPipeInto, READ_MAX_SIZE, 1, fpipe); 
 pclose(fpipe); 
 free(commandAndDirName);
 //return output to the client
   return (char**)&readPipeInto;
}
/* Return the result of command uptime function2*/
char** execute_uptime_1_svc(void* arg1,struct svc_req* arg2)
{
 FILE* fpipe;
 char* command="uptime";
 static char* readPipeInto;
 readPipeInto = (char*)malloc((READ_MAX_SIZE + 1)*sizeof(char));
 memset(readPipeInto, 0, READ_MAX_SIZE + 1);
 //execute command uptime
 if ( !(fpipe = (FILE*)popen(command,"r")) )
 { 
    perror("Cant open pipe!");
    exit(1);
 }
 //store result in readPipeInto
 fread((char*)readPipeInto, READ_MAX_SIZE, 1, fpipe); 
 pclose(fpipe);
 //return output to the client
 return (char**)&readPipeInto;
}

1st procedure at server program
" char** dir_list_1_svc(char** location, struct svc_req* arg2) " 


corresponds to " string DIR_LIST(string) " procedure declaration in prog.x file.

DIR_LIST procedure takes a string directory location such as "/home" from client program as an input parameter and appends this parameter to "ls -l" program at server procedure.


So, output of "ls -l /home" is returned back to the client from the server.

For return values of procedures, one more level of indirection is added to each procedure signature and parameters at server side.


For the 1st procedure at client program "string DIR_LIST(string) ", return value is changed from (char*) to (char**) .

2nd procedure at server program
" char** execute_uptime_1_svc(void* arg1,struct svc_req* arg2) "
corresponds to " string EXECUTE_UPTIME(void) " procedure declaration in prog.x file.

EXECUTE_UPTIME(void) procedure does not take any parameter from the client and executes the external program "uptime". 


Result of execution is sent back to the client.

At both of the above procedure implementations, it is common that programs (ls -l and uptime) are executed at server side and the result is written into a pipe. 


Then command output is read from that pipe and returned back to the client side.

3-) Write the main client program that calls the remote procedures from server.




/* client_source.c file */

#include <stdio.h>
#include <stdlib.h>                                       
#include <rpc/rpc.h> /* standard RPC include file */     
#include "prog.h" /* this file is generated by rpcgen */ 
                    
main(int argc, char *argv[])                               
{ 
   CLIENT *cl; /* RPC handle */

   char *server;
   /* return value from dir_list_1() function1*/
   char** resultStringFromServerDirList;
   /* return value from execute_uptime_1 function2*/ 
   char** resultStringFromServerUptime; 
   if (argc != 2) {
       fprintf(stderr, "usage: %s hostname\n", argv[0]);
       exit(1);
   }

   server = argv[1];
   /* Create client handle */
   if ((cl = clnt_create(server, RPC_PROG, RPC_VERS, "udp")) == NULL) {
       /* can't establish connection with server */
       clnt_pcreateerror(server);
       exit(2);
   }
   char* directory = "/home";

   /* call remote procedure dir_list */
   resultStringFromServerDirList = dir_list_1((char**)&directory, cl);
   if (resultStringFromServerDirList == NULL) {
      clnt_perror(cl, server);
      exit(3);
   }
   printf("\n\n");
   printf("Function1 Result of Directory Listing is: \n\n");
   printf("%s",*resultStringFromServerDirList);
   printf("\n\n");

   /* call remote procedure execute_uptime */
   resultStringFromServerUptime = execute_uptime_1(NULL, cl);
   if (resultStringFromServerUptime == NULL) {
      clnt_perror(cl, server);
      exit(4);
   }
   printf("Function2 Result of Command uptime is: \n\n");
   printf("%s",*resultStringFromServerUptime);
   printf("\n\n");
   
   clnt_destroy(cl); 
   exit(0);
}

After writing those 3 files, you can use rpcgen tool to generate related client and server programs.


Put "client_source.c" "prog.x" and "server_source.c" files into the same folder. 

Then by using cc -o from the command line create client and server executables separately.


Sample Run:
------------------------------------------------------------
Prepare server and run from the console: Open your console to run following commands.

user@machine:~/Desktop/user$ rpcgen prog.x
user@machine:~/Desktop/user$ cc -o client client_source.c prog_clnt.c 
user@machine:~/Desktop/user$ cc -o server server_source.c prog_svc.c 
user@machine:~/Desktop/user$ ./server 


"rpcgen prog.x" command creates prog_clnt.c(client stub) prog_svc.c(server stub) and prog.h header file. 


At the end of successful compilation client and server executables are located in the same directory. Then open a new terminal tab and Run client:

user@machine:~/Desktop/user$ ./client localhost


Server returns the output of executed programs to the client.

user@machine:~/Desktop/user$ ./client localhost


Function1 Result of Directory Listing is: 

total 4
drwxr-xr-x 52 user user 4096 2009-04-25 01:04 user


Function2 Result of Command uptime is: 

 01:05:49 up  4:08,  3 users,  load average: 0.17, 0.36, 0.25


user@machine:~/Desktop/user$ 

Monday, February 16, 2009

Apache Poi Turkish Character Support

Apache POI version 3.1 has got support for Turkish characters such as ('ş', 'ğ', 'İ', 'Ş', 'Ğ', 'ü', 'ç').

When I wanted to write a word into Excel file that is containing some of these characters, version 2.5.1 was not displaying it properly.

I updated the version of POI and the display problem resolved.


HSSFCell.ENCODING_UTF_16 includes required character support.
HSSFRow newRow = sheet.createRow((short)1);
newRow.createCell((short) 0).setCellValue("Başvuru Numarası");
HSSFCell cell0 = row.getCell((short) 0);
cell0.setCellType(HSSFCell.CELL_TYPE_STRING);
cell0.setEncoding(HSSFCell.ENCODING_UTF_16);

Required dependency for pom.xml file is :

 
   org.apache.poi
   poi
   3.1-FINAL
 

File Upload/Retrieve From Ftp With Jakarta Commons Net

Sometimes it is required to read and store files from Ftp file servers. For these operations Jakarta Commons Net library provides easy to implement functions.

In order to start working with Commons Net library add following lines into your Maven enabled project's pom.xml file.
 
   commons-net
   commons-net
   1.0.0
 

General procedure to start with ftp server is as follows:

1- connect to server
2- login with userName and Password
3- retrieve list of files from specified ftp folder
4- save the file from ftp to local
5- save the file from local to ftp
6- sometimes it is required to check for response codes from ftp
7- complete operations and disconnect

FtpConnect() method connects to remote ftp server, reads file content, save it to local director, then save a copy of it to another remote ftp location.


package apache.commons.net.ftpclient;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FtpClientService {
 
 public FtpClientService(){  
 }
 
 public static void FtpConnect(){
  String userName="ftpLoginUserName";
  String passWord = "ftppass";
  String ftpAddress = "ftp.somedomain.com";
  String retrieveFromFTPFolder = "RemoteFolderName/";
  String saveToLocalFolder = "/LocalFolder/";
  String saveToFtpFolder = "/ftpUploadFolder/";
  String strLine;
  DataInputStream inputStream = null;
  BufferedReader bufferedReader = null;
  FTPClient client = null;
  FTPFile[] ftpFiles = null;
  int reply;
 
  try{
   client = new FTPClient();
   client.connect(ftpAddress);
   client.login(userName, passWord);
   ftpFiles = client.listFiles(retrieveFromFTPFolder);  //retrieve list of files from ftp server
   if (ftpFiles != null && ftpFiles.length > 0) {
    for (FTPFile file : ftpFiles) {  // get specified file from folder
     if(file.isFile() && file.getName().equals("PrivateFile")){
      //read content of specific file from ftp
      inputStream = new DataInputStream(client.retrieveFileStream(retrieveFromFTPFolder+file.getName()));
      bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
      //save file from ftp to local directory
      File fileToWrite = new File(saveToLocalFolder+file.getName());
      DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fileToWrite)));
      while ((strLine = bufferedReader.readLine()) != null) {
       out.writeBytes(strLine);
          out.writeBytes("\n");
      }
      out.close();
      //check for reply code of ftp server if required then relogin
      reply = client.getReplyCode();
               if (!FTPReply.isPositiveCompletion(reply))
               {
                System.err.println("FTP server refused connection.");
                client.disconnect();
                client = new FTPClient();
                client.connect(ftpAddress);
                client.login(userName, passWord);                    
               }  
               //save file from local to remote ftp file server
      File fileToUpload = new File(saveToLocalFolder + file.getName());
      FileInputStream fileInputStream = new FileInputStream(fileToUpload);
      client.storeFile(saveToFtpFolder + file.getName(), fileInputStream); 
      break;
     }
    }
   }
  }
  catch (Exception e) {
   if (client.isConnected()) {
    try {
     client.logout();  
     client.disconnect();  
    } catch (IOException f) {
     // do nothing
    }
   }
  }
  finally{
   if (client.isConnected())
            {
                try
                {
                 client.logout();
                 client.disconnect();
                }
                catch (IOException f)
                {
                }
            }
  }  
 }
 
 public static void main(String[] args) {
  FtpConnect();
 }
}

Wednesday, February 11, 2009

Writing Test Cases with JUnit

JUnit is one of the most famous test case development frameworks for Java programmers.

It is also easy to integrate into Eclipse IDE.

If your projest is Maven enabled, then just by adding JUnit dependencies in your project's pom.xml file, you will be able to start generating test cases for your project. Add this dependency in your project's pom.xml file.
 
   junit
   junit
   3.8.2 
 

Save your pom.xml file and it will start downloading JUnit jar file into your Maven repository.

It is a good practice to place your test cases into the same project with your classes to be tested.

So create a folder named with "src/test/java" into your project and create a new package into it which is going to contain your JUnit test cases.

After adding Junit jar file and creating a folder which is going to contain your test cases, your directory structure is going to look like in Eclipse as follows.

eclipse project with junit dependency


Now add your class to be tested into org.junit.sample package.

Assume that, you are reading a flat file from your local disk containing mobilePhone number, id number and startDate of Employees separated by semicolon ";" .

Your simple Employee.java class contains:
package org.junit.sample;
import java.util.Date;
public class Employee {

 public Employee(){
 }
 String mobilePhone;
 String IdNumber;
 Date startDate;
 public String getMobilePhone() {
  return mobilePhone;
 }
 public void setMobilePhone(String mobilePhone) {
  this.mobilePhone = mobilePhone;
 }
 public String getIdNumber() {
  return IdNumber;
 }
 public void setIdNumber(String idNumber) {
  IdNumber = idNumber;
 }
 public Date getStartDate() {
  return startDate;
 }
 public void setStartDate(Date startDate) {
  this.startDate = startDate;
 } 
}


Sample file (Employee_Data) content is as follows, each line contains 3 significant parts separated by ";" :

3452701678;44522445566;12.09.2008 09:34:10
2133223914;56705003122;12.09.2008 10:36:31

and it is located at your home folder.

Java class that is required to be tested is a class that reads contents of the above text file and parses it to store each element of it's lines in an Employee object.

Simple FileService.java class which is located in the same package with Employee.java is as follows :
package org.junit.sample;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class FileService {

 public FileService(){
 }
 
 public Boolean parseTextFile(){
  String readFileFrom = "Employee_Data";
  String strLine,dateTime;
  String[] strArr= new String[3];
  
  File file = null;
  FileInputStream fstream = null;
  DataInputStream dataInputStream = null;
  BufferedReader br = null;
  
  Employee employee = null;
  List<Employee> list = null;
  DateFormat formatter = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
  Date date;
  try {
   file = new File(readFileFrom);   
   fstream = new FileInputStream(file);
   dataInputStream = new DataInputStream(fstream);
   br = new BufferedReader(new InputStreamReader(dataInputStream));
   list = new ArrayList<Employee>();
   while ((strLine = br.readLine()) != null) {
         System.out.println (strLine);
         strArr = strLine.split(";");
         employee = new Employee();
         employee.setMobilePhone(strArr[0]);
         employee.setIdNumber(strArr[1]);
         dateTime = strArr[2];
         date = (Date)formatter.parse(dateTime);
         employee.setStartDate(date);
         list.add(employee);
         employee = null;
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ParseException e) {
   e.printStackTrace();
  }
  if(list != null && list.size() > 0)
   return true;
  else
   return false;
 }
}

Related test case is located in the same Maven enabled project under "/src/test/java" folder. 


FileServiceTest.java class extends from junit framework's TestCase class. testparseTextFile() method in FileServiceTest.java class is used to test FileService.java class's parseTextFile() method.



package org.junit.sample.test;
import org.junit.sample.FileService;
import junit.framework.TestCase;

public class FileServiceTest extends TestCase {
 public FileServiceTest(){
 }
 public void testparseTextFile() throws Exception {
         Boolean readFileResult = false;
  FileService fileService = new FileService();
  readFileResult = fileService.parseTextFile();
  assertTrue(readFileResult);
 }
}



In order to start debugging your FileServiceTest.java class, right click on the name of the test method that you want to run from Outline view of Eclipse and then from the context menu choose :
Debug As -> JUnit Test.


eclipse run junit test case in debug mode



It is not taking long time to prepare Eclipse for JUnit test case development. 

Writing test cases efficiently decreases the amount of time spent for development and testing of your application.

Tuesday, February 10, 2009

Why to use Hibernate for persistence layer

Instead of working directly with JDBC, Hibernate can be selected for ORM tool for your application's persistence needs.

When your application becomes larger and your requirements are not met by using JDBC, Hibernate comes to play.

Although there are many other benefits of using Hibernate, main sophisticated properties that a JDBC programmer encounters when working for the first time with Hibernate can be stated as follows:

Lazy loading : Most of the objects contain another objects in itself.

Consider, you have got a CreditCardApplication object which contains ApplicationRequestOwnerData and AdditionalInfo objects.

Assume that, you are retrieving a CreditCardApplication object, but you are not interested in the details of the ApplicationRequestOwnerData and AdditionalInfo objects in itself.

If it is unnecessary to fetch the whole object with its related objects, then lazy-loading brings a great effectiveness for your application.

Lazy-loading enables you to retrieve data as it is required.

Eager fetching : In opposite to lazy-loading, sometimes it is required to retrieve the whole object at a time. This decreases the cost of round trips.

Cascading : Support for cascading is another main benefit that you can design in your related hbm.xml file or annotations.

Generally speaking, using an ORM tool for persistence layer helps you to write less code in a shorter time period, if you use it effectively in your application.


hibernate.org is a great resource for new starters.

Saturday, January 31, 2009

Generate Excel Files with Apache POI

Apache POI is a useful API to work with MS Excel files using Java.

It is capable of reading and writing Excel files with formatted cells.

You can extract a new Excel file by reading data from an existing Java entity to a specified location.

If you are using Apache Maven as your dependency management tool then add POI as a dependency into your project's pom.xml file.

Save your pom.xml file and then Eclipse will immediately update related Maven dependencies to your local Maven repository.

 poi
 poi
 2.5.1

After adding the above dependency in your project, under Maven dependencies you will see poi.jar file.

Also, create a Java entity class to use as a data holder which is named with Employee.java in the same package.

package org.sample.apachepoi;

public class Employee {

 private String name;
 private String surName;
 private String telNumber;
 private Long salary;
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getSurName() {
  return surName;
 }
 public void setSurName(String surName) {
  this.surName = surName;
 }
 public String getTelNumber() {
  return telNumber;
 }
 public void setTelNumber(String telNumber) {
  this.telNumber = telNumber;
 }
 public Long getSalary() {
  return salary;
 }
 public void setSalary(Long salary) {
  this.salary = salary;
 } 
}


Create a service class "ApachePoiSample.java" which contains operations to write an Excel file.


ApachePoiSample.java class methods









Outline of the ApachePoiSample class is represented at above. "generateExcelFiles" method is used to write Excel files to a specified location.


eclipse project with apache poi dependency

















After adding Apache Poi Maven dependency and creating a new Java Project, file structure is displayed in Eclipse IDE as in the image at above. 

You can change the location of the dependencies that are stored on your hard drive by modifying the settings.xml file for Maven.

To change the location of local Maven repository add these lines into your settings.xml file : 

Eclipse->Preferences->Maven->Installations->User Settings

clicking the Browse button will take you to the maven settings.xml file.

add your local repository in to the settings.xml file by adding "localrepository" node which contains the new repository location such as "/home/UserName/.m2/repository "
"generateExcelFiles" method is used to write new Excel files.

public void generateExcelFiles(List<Employee> employee){
  
  HSSFWorkbook wb;
  HSSFSheet sheet;
  OutputStream out;
  String fileName,fileExtension,fileLocation;

  if(employee != null && employee.size()>0){
  
   wb = new HSSFWorkbook();
   sheet = wb.createSheet("EmployeeData");
   prepareWorkBook(wb, sheet);
   fileLocation = "/home/tufangorel/";
   fileName = "Employee WorkSheet";
   fileExtension = ".csv";
   for (int j = 0; j < employee.size(); j++) {
    HSSFRow newRow = sheet.createRow((short) j + 1);
    createCell(employee,j,newRow);
   }
   try {
    out = new FileOutputStream(fileLocation+fileName+fileExtension);
    wb.write(out);
    out.close();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 } 


In order to create an Excel document add HSSFWorkBook and HSSFSheet objects into your method. 


HSSFRow object represents each row in the Excel file. "createCell" method takes a single employee record and copies that data into a new HSSFRow object.



private void createCell(List<Employee> list,int j, HSSFRow newRow) {
  if (list.get(j).getName() != null && !list.get(j).getName().equals("")) {
 newRow.createCell((short) 0).setCellValue(list.get(j).getName());
  }
  if (list.get(j).getSurName() != null && !list.get(j).getSurName().equals("")) {
 newRow.createCell((short) 1).setCellValue(list.get(j).getSurName());
  }
  if (list.get(j).getTelNumber() != null && !list.get(j).getTelNumber().equals("")) {
 newRow.createCell((short) 2).setCellValue(list.get(j).getTelNumber());
  }
  if (list.get(j).getSalary() != null) {
 newRow.createCell((short) 3).setCellValue(list.get(j).getSalary());
  }
}


"prepareWorkBook" method creates the first line, header line for the Excel file.


HSSFCellStyle and HSSFFont objects are required to make style modifications to Excel sheet.

private void prepareWorkBook(HSSFWorkbook wb, HSSFSheet sheet) {
  HSSFRow row = sheet.createRow((short) 0); 
  HSSFFont font = wb.createFont();    
  font.setColor(HSSFFont.BOLDWEIGHT_BOLD);
  font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  HSSFCellStyle cellStyle = wb.createCellStyle(); 
  cellStyle.setFont(font);
  createHeaderCellsFormatting(row, cellStyle); 
}


"createHeaderCellsFormatting" method writes the names of columns in your sheet and set cell style.

private void createHeaderCellsFormatting(HSSFRow row,HSSFCellStyle cellStyle) {
 row.createCell((short) 0).setCellValue("Name");
 HSSFCell cell0 = row.getCell((short) 0);
 cell0.setCellStyle(cellStyle);
 row.createCell((short) 1).setCellValue("SurName");
 HSSFCell cell1 = row.getCell((short) 1);
 cell1.setCellStyle(cellStyle);
 row.createCell((short) 2).setCellValue("Tel Number");
 HSSFCell cell2 = row.getCell((short) 2);
 cell2.setCellStyle(cellStyle);
 row.createCell((short) 3).setCellValue("Salary");
 HSSFCell cell3 = row.getCell((short) 3);
 cell3.setCellStyle(cellStyle);  
}


in order to test your ApachePoiSample class add a main method which creates Employee objects and calls "generateExcelFiles" method to see the extracted Excel at the specified location.


public static void main(String[] args) {
  
 List<Employee> employee = new ArrayList<Employee>();
 Employee e1 = new Employee();
 e1.setName("John");
 e1.setSalary(2000L);
 e1.setSurName("Blade");
 e1.setTelNumber("1233873");
 employee.add(e1);
 Employee e2 = new Employee();
 e2.setName("Mary");
 e2.setSalary(3000L);
 e2.setSurName("New");
 e2.setTelNumber("343222");
 employee.add(e2);  
 ApachePoiSample apachePoiSample = new ApachePoiSample();
 apachePoiSample.generateExcelFiles(employee);
}