Tuesday, December 8, 2009

Converting between different date formats in Java

It is often required to convert date from one format to another, for example from java.sql.Date('yyyy-MM-dd') to java.util.Date ('dd/MM/yyyy'). I wrote a generic function to do the job, which will convert from any given date format to another specified format. The method does not checks if the format provided is correct or not nor it checks if the date is a valid date or not.

I wrote this method to read dates from the database and to convert it to another format. It is assumed that the dates in the table are valid. Below is the code for the method.

public static String convertDate(String date, String sourceFormat, String destinationFormat) throws java.text.ParseException
{
    String returnDate="";
  
    SimpleDateFormat formatter = new SimpleDateFormat(sourceFormat);
    Date date1 = formatter.parse(date);

    formatter = new SimpleDateFormat(destinationFormat);
    returnDate = formatter.format(date1);
 
    return returnDate;
}

Usage: String newDate = convertDate("2009-12-08", "yyyy-MM-dd", "dd/MM/yyyy")
Output: date in dd/MM/yyyy format - 08/12/2009

Monday, November 30, 2009

Accepting input from List based Forms using Struts

At times you may be required to get input from a list based form. A list based form can be well explained by taking an example of an object which may contain variable number of a list of items. An example being an invoice, which may contain 1 item, 2 items, 5 items or more. The number of items in an invoice are never fixed. You may write a JSP page and allow the user to add any number of items into a list and then finally submit the page to save the invoice.
A similar is the case with the items in a Gate Pass. A Gate Pass is a document which is produced every time whenever item(s) move out of an office. As an example consider the screenshot below:
gatePass 
In the above page (ActionForm) the user has an option to add as many items to the list as desired. Now if we map this page onto an ActionForm we need something in the ActionForm which can accept a list of items. The other fields will be mapped to String objects. An item consists of a code, description and quantity, which means an item is an object in itself, with the previously mentioned instance variables. Since, a Gate Pass will have a list of items you will need to map them to a Java Collections object which may be an ArrayList or a LinkedList. For this example, let us map the list of items on to a LinkedList object.
For the above example let us consider the following two classes:
import java.util.LinkedList; 
import Utility;
/** 
* @author Harkiran Singh 
* 
*/ 
public class GatePass implements java.io.Serializable 
{ 
    /** 
     * 
     */ 
    private static final long serialVersionUID = 1L; 
    private String gatePassNumber;
    private String financialYear; 
    private java.sql.Date gpDate = 
Utility.getSQLDateFromString(Utility.getDateToday()); 
    private String issuedTo; 
    private String gpType; 
    private String authorizedSignature; 
    private int isCanceled = 0; 
    private String cancelUser; 
    private LinkedList<GatePassItems&gt lstItems; 
    public GatePass() 
    { 
        lstItems = new LinkedList<GatePassItems&gt(); 
    }
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
.
(getter and setter methods for the instance variables)
}

/** 
* @author Harkiran Singh 
* 
*/ 
public class GatePassItems implements java.io.Serializable 
{ 
    /** 
     * 
     */ 
    private static final long serialVersionUID = 1L; 
    private String itemCode; 
    private String description; 
    private int quantity; 
    private String gatePassNo; 
    private java.sql.Date returnDate; 
    public GatePassItems(){} 
    public GatePassItems(String itemCode, String description, 
int quantity, String gatePassNumber) 
    { 
        this.itemCode = itemCode; 
        this.description = description; 
        this.quantity = quantity; 
        this.gatePassNo = gatePassNumber; 
    }
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
(getter and setter methods for the instance variables) 
}



Below is the ActionForm:


import java.util.LinkedList; 
import javax.servlet.http.HttpServletRequest; 
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping; 
/**
* @author Harkiran Singh
*
*/
public class GatePassForm extends ActionForm 
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String gatePassNumber;
    private String financialYear;
    private String gpDate=Utility.getDateToday();
    private String issuedTo;
    private String gpType;
    private String authorizedSignature;
    private String isCanceled = "0";
    private String cancelUser;
    private LinkedList<GatePassItems&gt; lstItems;
    private String description;
    private String quantity;
    private String itemCode;
    private String button;
    private String noOfItems;
    public GatePassForm()
    {
        lstItems = new LinkedList<GatePassItems&gt;();
    }

public GatePassItems getItem(int index)
{
    return lstItems.get(index);
}
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
(getter and setter methods for the instance variables) 
}



The above method in the above ActionForm “getItem(int index)” is the key which will allow access to each item of the LinkedList.


Now, lets also look at the extract from the JSP file.


<c:set var="ctr" value="0"/>

    <table border="1" cellspacing="1" cellpadding="1" width="80%" align="center"&gt;


        <tr>


            <td width="5%" class="tablebgdark" align="right"&gt;<font class="fontwhite">S.No</font></td>

            <td width="20%" class="tablebgdark" align="center"&gt;<font class="fontwhite">Code</font></td>

            <td width="60%" class="tablebgdark" align="center"&gt;<font class="fontwhite">Description</font></td>

            <td width="10%" class="tablebgdark" align="center"&gt;<font class="fontwhite">Qty</font></td&gt;

            <td width="10%" class="tablebgdark">& </td>

        </tr>

        <logic:iterate id="item" name="GatePassForm" property="lstItems">

            <tr>

                <td align="right" class="tablebglight">

                    <c:set var="ctr" value="${ctr + 1}"/>

                    <font class="fontdark">${ctr }.</font>

                </td>

                <td>

                    <html:text name="item" property="itemCode" style="width:98%" indexed="true"&gt;</html:text>

                </td>

                <td>

                    <html:text name="item" property="description" style="width:98%" indexed="true"&gt;</html:text>

                    <html:hidden name="item" property="gatePassNo" value="${sessionScope.GatePassForm.gatePassNumber}" indexed="true"/>

                </td>

                <td>

                    <html:text name="item" property="quantity" style="text-align: right;width:98%" indexed="true"&gt;</html:text>

                </td>

                <td class="tablebglight">

                    <font class="fontdark">

                        <html:link page="/switch.action?prefix=/views/gatepass&&&page=/DeleteGatePassItem.action?index=${ctr-1}">Delete</html:link>

                    </font>

                </td>

            </tr>

        </logic:iterate>

        <tr>

            <td colspan="5" class="tablebgdark"><font class="fontwhite">New Item</font&gt;</td>

        </tr>

        <tr>

            <td class="tablebglight">&nbsp;</td>

            <td class="tablebglight">

                <html:text property="itemCode" style="width:98%" value="">&lt;/html:text>

            </td>

            <td class="tablebglight">

                <html:text property="description" style="width:98%" value="">&lt;/html:text>

            </td>

            <td class="tablebglight">

                <html:text property="quantity" style="text-align: right;width:98%" value="">&lt;/html:text>

                <html:hidden property="noOfItems" value="${ctr }"/>

            </td>

            <td class="tablebglight">&nbsp;</td>

        </tr>

        <tr>

            <td class="tablebglight">

                <html:submit property="button">Add Item</html:submit>

            </td>

            <td class="tablebglight">&nbsp;</td>

            <td class="tablebglight">&nbsp;</td>

            <td class="tablebglight">&nbsp;</td>

            <td class="tablebglight">&nbsp;</td>

        </tr>    
    </table>

The above JSP code in the iteration will be translated to HTML code which will access the LinkedList objects using the “getItem()” method.

The below line:

<html:text name="item" property="description" style="width:98%" indexed="true"&gt;</html:text> 

will get translated into following HTML:

<input type=”text” name=”item[0].description” >

and so on.

This will call the method “lstItems.getItems(0).getDescription()”,

“lstItems.getItem(0).setDescription(…)” and so on.

You will need to save the ActionForm in the session scope so that the previously entered objects are available until the form is submitted to save the Gate Pass in the database.

Also, you will need to add the code for adding the item into the LinkedList in the appropriate Action class which handles the form submission. Your Action class may look like:

public class AddGatePassItemAction extends Action 
{

 /* (non-Javadoc)
  * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
  */
 @Override
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception 
       {
    // TODO Auto-generated method stub
    
    GatePassForm gpForm = (GatePassForm) form;
  
    String description, quantity, gatePassNumber, itemCode;
    LinkedList lstItems = gpForm.getLstItems();
  
    description = gpForm.getDescription();
    quantity = gpForm.getQuantity();
    gatePassNumber = gpForm.getGatePassNumber();
    itemCode = gpForm.getItemCode();
  
    int qty = Integer.parseInt(quantity);
    GatePassItems item = new GatePassItems(itemCode, description, qty, gatePassNumber);
    
    lstItems.add(item);
    gpForm.setLstItems(lstItems);
   
    request.getSession().setAttribute("GatePassForm", gpForm);
  
    return mapping.findForward("success");
      }
}

With all the code and configuration entries in right place you will get a dynamically created LinkedList in your JSP page.

Tuesday, November 24, 2009

Modular application development using Struts - SwitchAction

Action classes are the important part of the Struts framework. Action classes are where your presentation logic resides. Struts 1.1 (and higher) provides some types of Action out-of-the-box, so you don't have to build them from the scratch. The Actions provided by Struts are ForwardAction, IncludeAction, DispatchAction, LookupDispatchAction and SwitchAction. All these classes are defined in org.apache.struts.actions package. These built-in actions are very helpful to address some problems faced in day to day programming. Understanding them is the key to using them effectively. All of these the Actions are frequently used, except for IncludeAction.

The SwitchAction class allows you to configure multiple application modules. In Struts1.0 (and earlier), a single config file was supported. This file, normally called struts-config.xml, was specified in web.xml as an initialization parameter for the ActionServlet as follows:
<servlet>

    <servlet-name>mybank</servlet-name>  
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

    <init-param>  
        <param-name>config</param-name>

        <param-value>/WEB-INF/struts-config.xml</param-value>  
    </init-param>

</servlet>


The single configuration file is bottleneck in large projects as all developers had to contend to modify this resource. In addition managing a monolithic file is painful and error prone. With Struts1.1 (and higher) this problem has been resolved by the addition of multiple sub application support better known as application modules. You can now have multiple configuration files, one for each module or logical group of forms. The configuration files are specified in web.xml file using multiple <init-param> - initialization parameters.

An example of the how to do this in a web.xml file is as below:




<servlet> 
    <servlet-name>action</servlet-name>

    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
    <init-param>

      <param-name>config</param-name>  
      <param-value>/WEB-INF/struts-config.xml</param-value>

    </init-param>  
    <init-param>

      <param-name>config/views/module1</param-name>  
      <param-value>/WEB-INF/struts-config-module1.xml</param-value>

    </init-param>  
    <init-param>

      <param-name>debug</param-name>  
      <param-value>3</param-value>

    </init-param>  
    <init-param>

      <param-name>detail</param-name>  
      <param-value>3</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>  
</servlet>
<servlet-mapping>  
    <servlet-name>action</servlet-name>

    <url-pattern>*.action</url-pattern>  
</servlet-mapping>

The above web.xml defines the servlet mapping for the action servlet to all URL patterns that ends with ‘.action’, and /WEB-INF/struts-config.xml to be the struts configuration file. You might be wondering what does the below configuration do:




<init-param> 

      <param-name>config/views/Module1</param-name>  
      <param-value>/WEB-INF/struts-config-module1.xml</param-value>  
</init-param>

The above initialization parameter name begins with ‘config/’. ‘config/’ is treated as a keyword for defining a new module. It is interpreted as a configuration for a separate module. Its corresponding value – /WEB-INF/struts-config-module1.xml is the struts configuration file containing Form bean definitions and ActionMappings for the module module1. If the URLs in the default struts-config.xml were accessed as http://localhost:8080/App1/start.action, and the corresponding ActionMapping were moved to struts-module1-config.xml then the URL would be accessed as http://localhost:8080/App1/module1/start.action where App1 is the web application context. Notice that the application URL contains the module name after the web application context as if it is a sub directory name.

The benefits of application modules are immediately obvious. You can now split your monolithic struts application into logical modules thus making maintenance easier. It will cause less contention during development time as developers working on different modules get to work on their own struts configuration files. Each Struts Configuration file and hence each application module can choose its own RequestProcessor, MessageResources and PlugIn. You can now choose to implement one or more modules with Tiles. If you find this convenient and useful then you can migrate your application to Tiles or JSF or plug in any other Struts extensions for one module at a time.

Now, lets look like how the struts-config.xml and struts-config-module1.xml files look like. Below is an extract from the struts-config.xml file:




<struts-config>

    <global-forwards>  

        <forward name="Module1" 

            path="/switch.action? page=/CreateCertificate.action&amp;prefix=/views/module1" /> 

    </global-forwards>

    <action-mappings>

        <action path="/switch"  
            type="org.apache.struts.actions.SwitchAction" />

    </action-mappings>    
    <controller processorClass="org.apache.struts.action.RequestProcessor" /> 
</struts-config>


struts-config-module1.xml file:



<struts-config>  
    <form-beans>

        <form-bean name="Form1"  
                    type="com.example.Form1"/>

        <form-bean name="Form2"

                    type="com.example.Form2"/>  
    </form-beans>


    <global-forwards>

        <forward name="mainpage" path="/"/>  
    </global-forwards>

    <action-mappings>

         <action path="/switch"

                type="org.apache.struts.actions.SwitchAction" />

         <action path="/start"  
                type="com.example.Module1Start"

                name="Form2"  
                scope="request"

                validate="true"  
                input="/input.jsp">

            <forward name="success" path="/switch.action?page=/success.jsp&amp;prefix=/views/module1"></forward>

            <forward name="failure" path="/switch.action?page=/error.jsp&amp;prefix=/views/module1"></forward>

        </action>

You might have noticed that




<action path="/switch"  
                type="org.apache.struts.actions.SwitchAction" /> 

has been defined in both the configuration files. This is important for the code to work properly.


Note: Source of most of the content- Struts Survival Guide, Author: Srikanth Shenoy.

Monday, November 23, 2009

Fixing your Windows Vista Sidebar

Since last two weeks the vista sidebar wasn't loading on my computer. Searching for a solution on google wasn't easy. However, I found a solution today so I thought to save it in my blog.

The problem was resolved after following these steps:

Click Start, All Programs, Accessories, right-click Command Prompt and select "Run as administrator".

Type these commands one by one:
Regsvr32 atl.dll
Regsvr32 "%ProgramFiles%\Windows Sidebar\sbdrop.dll"
Regsvr32 "%ProgramFiles%\Windows Sidebar\wlsrvc.dll"

Tuesday, November 3, 2009

Ubuntu - How to change the Display Manager

A Display Manager provides a graphical login screen. Ubuntu comes with default GUI - Gnome and 'gdm' as Display Manager. You may also choose to install K.D.E on Ubuntu to get an option to login into one out of two different GUI's. K.D.E comes with 'kdm' as the display manager. When you install K.D.E you are asked if you want to change the display manager to 'kdm'. If later you want to switch to the other available display manager then you can do so by using the following command in a terminal window:

$ sudo dpkg-reconfigure gdm

Monday, October 19, 2009

JDBC Connectivity

The JDBC ( Java Database Connectivity) API defines interfaces and classes for writing database applications in Java by making database connections. Using JDBC you can send SQL, PL/SQL statements to almost any relational database. JDBC is a Java API for executing SQL statements and supports basic SQL functionality. It provides RDBMS access by allowing you to embed SQL inside Java code. Because Java can run on a thin client, applets embedded in Web pages can contain downloadable JDBC code to enable remote database access.

Although JDBC was designed specifically to provide a Java interface to relational databases, you may find that you need to write Java code to access non-relational databases as well.
JDBC Architecture

Java application calls the JDBC library. JDBC loads a driver which talks to the database. We can change database engines without changing database code.

JDBC Basics - Java Database Connectivity Steps


Before you can create a java jdbc connection to the database, you must first import the

java.sql package.

import java.sql.*; The star ( * ) indicates that all of the classes in the package java.sql are to be imported.

Below is a list of classes and interfaces that are commonly used for writing JDBC code:

java.sql.Connection
java.sql.PreparedStatement
java.sql.ResultSet
java.sql.SQLException
java.sql.DriverManager
javax.sql.DataSource

Following are the classes / interfaces that will be used for doing a lookup for the DataSource in the servers context (JNDI Lookup).

javax.naming.Context
javax.naming.InitialContext
javax.naming.NamingException

Using Java there are two ways for connecting to a database. Either the DataManager class can be used or JNDI lookup can be done. JNDI lookup is mostly used in web based applications. Let us first look at how DataManager class can be used to connect to the database.



import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.DriverManager;

public class TestDBConnectivity
{
public static void main(String argv[])
{
Connection con = null;
Statement stmt = null;
ResultSet rs = null;

String url = "jdbc:oracle:thin:@server:1521:TESTDB"
String sql = "Select count(*) as total from Books";
int totalBooks=0;

try
{
Class.forName("oracle.jdbc.driver.OracleDriver"); //load the driver
con = DriverManager.getConnection(url, "dbuser", "dbpasswd");
stmt = con.CreateStatement();
rs = stmt.executeQuery(sql);

if(rs.next())
totalBooks = rs.getInt("total");

System.out.println("Total number of books : " + total);
}
catch(ClassNotFoundException ex)
{System.out.println("ClassNotFoundException:\n"+ex);}
catch(SQLException ex)
{System.out.println("SQLException:\n"+ex);}
finally
{
try
{
stmt.close();
rs.close();
con.close();
}
catch(SQLException ex)
{System.out.println("SQLException:\n"+ex);}
}
}
}







Now, let us look at how JNDI lookup works. For a small tutorial on JNDI please visit here.










For using a JNDI lookup first a resource has to be defined which can be done in the '\META-INF\context.xml' file. A sample of the 'context.xml' file is shown below:










import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DAGConnection
{
private DAGConnection(){}

public static java.sql.Connection getConnection()
{
Connection con=null;
Context ctx=null;
DataSource ds=null;
try
{
ctx = new InitialContext();
if(ctx == null)
{
System.out.println("Lookup failed!");
throw new RuntimeException("JNDI resource can not be found!");
}

ds = (DataSource) ctx.lookup("java:comp/env/jdbc/DBTEST");
if(ds==null)
{
System.out.println("DataSource could not be found!");
throw new RuntimeException("DataSource could not be found!");
}

con = ds.getConnection();
}
catch(NamingException ex)
{
System.out.println(ex);
return null;
}
catch(SQLException ex)
{
System.out.println(ex);
return null;
}

return con;
}
}





In the above example, the method getConnection() does a JNDI lookup and returns an object of type java.sql.Connection. Doing  JNDI lookup returns an object of type DataSource which in turn is used to create a connection to the database. You will need to place the JDBC drivers for the database in the classpath while using DriverManager and in the '\WEB-INF\lib' folder while doing a JNDI lookup.

Thursday, October 15, 2009

Aligning text in a HTML textbox

There is often a need to align text in a HTML textbox especially when the text to be entered are always numbers. In case of numbers the preferable alignment is ‘right’.

The ‘text-align’ property can be used to align text in a textbox or in fact in any element which supports the ‘style’ property.

An example to right align a text in a HTML textbox is as below:

The 'text-align' property describes how inline content of a block is aligned. Values have the following meanings:


left, right, center, justify, inherit


The 'inherit' value


Each property may also have a specified value of 'inherit', which means that, for a given element, the property takes the same computed value as the property for the element's parent. The 'inherit' value can be used to strengthen inherited values, and it can also be used on properties that are not normally inherited.


If the 'inherit' value is set on the root element, the property is assigned its initial value.


In the example below, the 'color' and 'background' properties are set on the BODY element. On all other elements, the 'color' value will be inherited and the background will be transparent. If these rules are part of the user's style sheet, black text on a white background will be enforced throughout the document.

body {
color: black !important; 
background: white !important;
}

* { 
color: inherit !important; 
background: transparent !important;
}

Tuesday, September 22, 2009

Formatting dates in Java

In this post I will write about formatting dates in Java in different formats (patterns).

The Java classes that I will be using in the examples are:

The class Date represents a specific instant in time, with millisecond precision.

Format is an abstract base class for formatting locale-sensitive information such as dates, messages, and numbers.

SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. It allows for formatting (date -> text), parsing (text -> date), and normalization. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting.

A pattern of special characters is used to specify the format of the date. This example demonstrates some of the characters. For a complete listing, see the javadoc documentation for the SimpleDateFormat class.

Note: default locale (which, in the author's case) is Locale.ENGLISH. If the example is run in a different locale, the text (e.g., month names) will not be there: This example formats dates using the  same.

   

    Format formatter; 
   
    // The year
    formatter = new SimpleDateFormat("yy");    // 02
    formatter = new SimpleDateFormat("yyyy");  // 2002
   
    // The month
    formatter = new SimpleDateFormat("M");     // 1
    formatter = new SimpleDateFormat("MM");    // 01
    formatter = new SimpleDateFormat("MMM");   // Jan
    formatter = new SimpleDateFormat("MMMM");  // January
   
    // The day
    formatter = new SimpleDateFormat("d");     // 9
    formatter = new SimpleDateFormat("dd");    // 09
   
    // The day in week
    formatter = new SimpleDateFormat("E");     // Wed
    formatter = new SimpleDateFormat("EEEE");  // Wednesday
   
    // Get today's date
    Date date = new Date();
   
    // Some examples
    formatter = new SimpleDateFormat("MM/dd/yy");
    String s = formatter.format(date);
    // 01/09/02
   
    formatter = new SimpleDateFormat("dd-MMM-yy");
    s = formatter.format(date);
    // 29-Jan-02

Thursday, September 17, 2009

How to change the HTTP port for Oracle 10g XE

Oracle XE uses the embedded http listener that comes with the XML DB (XDB) to serve http requests. The default port for HTTP access is 8080.

It also supports the WebDAV protocol just as well as FTP.

You can determine the current configuration using the following commands when you connect to XE as the oracle user SYSTEM (or any other DBA):

C:\WINDOWS\system32>sqlplus system@xe

SQL*Plus: Release 10.2.0.1.0 - Production on Wed Aug 26 00:19:35 2009

Copyright (c) 1982, 2004, Oracle. All rights reserved.

Enter password:

Connected to:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

SQL> -- get current status
SQL> select dbms_xdb.gethttpport as "HTTP-Port"
, dbms_xdb.getftpport as "FTP-Port" from dual;

HTTP-Port  FTP-Port
---------- ----------
8080
       0


You can change the http port and the ftp port to whatever you like (keep in mind that you need special privileges for ports < 1024 on Unix/Linux systems.)

SQL> -- set http port and ftp port
SQL> begin
2 dbms_xdb.sethttpport('80');
3 dbms_xdb.setftpport('2100');
4 end;
5 /

PL/SQL procedure successfully completed.

SQL> select dbms_xdb.gethttpport as "HTTP-Port"
, dbms_xdb.getftpport as "FTP-Port" from dual;

HTTP-Port  FTP-Port
---------- ----------
80
          2100


If you only want to use the database without allowing access via http or ftp then you can disable both:

SQL> -- disable http and ftp access
SQL> begin
2 dbms_xdb.sethttpport('0');
3 dbms_xdb.setftpport('0');
4 end;
5 /

PL/SQL procedure successfully completed.

SQL> -- get current status
SQL> select dbms_xdb.gethttpport as "HTTP-Port"
, dbms_xdb.getftpport as "FTP-Port" from dual;

HTTP-Port  FTP-Port
---------- ----------
0
           0


Alternatively, after logging in into sqlplus from command prompt, execute the following:

SQL> EXEC DBMS_XDB.SETHTTPPORT(8081);

the HTTP port will be changed to 8081 from the default port number 8080

Thursday, September 3, 2009

Import *.dmp file into Oracle 10g XE on Linux (Ubuntu)

Recently I installed Oracle 10g XE on my laptop on Windows Vista and was happy to see the same was available for Linux (Ubuntu). I downloaded the Linux version of Oracle 10g XE and installed it on Ubuntu. Installation is a straight forward process, just double click on the file and make sure you see the details before closing the installation window. You will need to run a command with "root" privileges to complete the Oracle installation. The command is as bellow:

sudo /etc/init.d/oracle-xe configure

You will be asked for Oracle configuration: port numbers and the password for the "system" and "sys" accounts.

After the installation you will want to import the data into Oracle from the .dmp file. Doing so on Windows is easy using Toad. The Linux equivalent for Toad, Tora for some reasons does not wants to connect to Oracle on Ubuntu and does not comes with an option to select the database as Oracle. You may try the other free softwares: SQL Developer from Oracle and Navicat 8 Lite for Oracle.

For importing the .dmp file into Oracle make sure the user with which you have logged in is a member of the "dba" group. Make the appropriate changes using the User and Groups from the Settings. Once this is done you can use the "imp" executable to import the .dmp file. The general syntax is as follows:

imp userid=system file=user_a.dmp log=imp.log fromuser=a touser=b
Click here for a detailed description on importing data into Oracle from a .dmp file.
Example for using the "imp" utility:

./imp userid=a file=/home/abc/dag.DMP log=/home/abc/exp_dag.log fromuser=b touser=a

abc = Linux user
a = Oracle schema (user) into which the data is to be imported
b = Oracle schema(user) from which the backup was taken.

Make sure to change your directory to

/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin

before you run the "imp" utility. If everything goes right then all the data will be imported into Oracle 10g XE.

Tuesday, September 1, 2009

Using CVSNT with Eclipse

My previous post was about using Version Control System in Eclipse and it also described CSV (Concurrent Version System). In this post I'll describe how CSVNT can be used with Eclipse for version control.
CVSNT is a version control system. Using it, you can record the history of your source files. With CVSNT, you can easily retrieve old versions to see exactly which change caused the bug. This can sometimes be a big help. You could of course save every version of every file you have ever created. This would however waste an enormous amount of disk space. CVSNT stores all the versions of a file in a single file in a clever way that only stores the differences between versions.

CVSNT started out as a bunch of shell scripts written by Dick Grune, posted to the newsgroup comp.sources.unix in the volume 6 release of December, 1986. While no actual code from these shell scripts is present in the current version of CVSNT much of the CVSNT conflict resolution algorithms come from them.

CVSNT can be downloaded from here and it is available as both free edition and paid CVS Suite.
Once you have downloaded CVSNT you can follow the steps below.

Setting up CVSNT
1. Download the latest version (2.0.58d) of CVSNT from www.cvsnt.org
2. Install it using the default options offered by the installer. You may have to reboot.
3. CVSNT should be installed in a folder of the same name under Start...Programs. Start the Service control panel application.
4. On the Service Status tab, make sure both services are running.
5. On the Compatibilty tab, turn on all three checkboxes for the "Generic non-cvsnt" client. (This instruction comes from the CVSNT Release Notes.)
6. From the Repositories tab click "Add" to create a new repository.
       a) You will need to select a directory for your repository. I suggest you create a new directory dedicated to this repository.
       b) After you select a directory location, CVSNT will automatically fill in the Name field. Do not change the name! Eclipse is expecting the repository location as a *NIX format directory, so CVSNT fakes it out using the name. Copy the name to a text editor so you can put it in Eclipse exactly as defined in CVSNT.
       c) Click OK to create the repository.

Setting up Eclipse

1. Open the CVS Repository Perspective (Window...Open Perspective...Other...CVS Repository Exploring).
2. With a right-click in the CVS Repositories pane, select New...Repository Location from the context menu. There's also a button at the top of the pane, but those button icons take some getting used to. They do have descriptive popups if you hover your mouse over them, though.
3. In the Add CVS Repository window that pops up, insert the following info, without the quotes. 
     a) Host: "127.0.0.1" (a standard TCP/IP self-reference)
     b) Repository path: Paste the repository name you copied from CVSNT.
     c) User/Password: Your Windows username and password (password optional.)
     d) Connection Type: "pserver"
     e) Use Default Port: Yes
     f) Validate connection on Finish: Yes
     g) Save Password: Up to you.
     h) Click Finish.

With the Validate connection on Finish option turned on, Eclipse will tell you whether or not it was able to connect to the repository. If not, it gives you the option of going back to the setup screen to change settings. If it can connect, the repository will will appear in the list of CVS Repositories.

If your Windows account requires a password, Eclipse will prompt you for it if you didn't provide it. If you don't save the password, Eclipse will prompt for it whenever it opens the repository.

Using Version Control System in Eclipse

Version Control System is an important component of Source Configuration Management (SCM). Using it, you can record the history of sources files, and documents. One such utility which Eclipse supports out of the box is CSV (Concurrent Versions System).
Most of today's applications are developed by a team of people. Even small projects that involve only a few developers require tight control over changes in source code. This is a task for source-code management software. Two core features must be supported by source-code version-control software:
  • A way to coordinate and integrate changes into the source code
  • A history of the work submitted by the team
As team members produce new work, they share this work by committing those changes to the repository. Similarly, when they wish to get the latest available work, they update their local workspaces to the changes on the repository. This means the project repository is constantly changing as team members submit new work. In the other words, the repository should represent the current state of the project. At any point, team members can update their workspaces from the repository and know they are up to date.

Maintaining history is also important so you can compare the current work against previous versions, and if needed, revert to the older work. Coordinating the team's work so that there is only one definition of the current project state, and containing the integrated work of the team are also essential to managing version control. This coordination is probably the hardest goal to achieve.

An optimal model is one where any member of the team can make changes to any resource he has access to. Because two team members can commit changes to the same resource, conflicts can occur and must be dealt with. This model assumes that conflicts are rather unique. Unfortunately, no source code exists in isolation; it typically contains implicit or explicit dependencies on other resources. Source code has references to artifacts described in other source code resources. And this is the point where source-code management software ends its work because it isn't a substitute for project management. Project managers must do their work: coordinating others' work, and looking after schedules, project phases, and release dates. Further, source-code management is not a substitute for developer communication.


How the Eclipse Platform supports code management

The Eclipse Platform offers the capability to share code and work as a team on a software project. Eclipse supports a wide range of code-management solutions, thanks to its plug-in architecture (however, CVS support comes out of box). The focal point of the Eclipse Platform architecture is the workspace. The workspace maintains everything necessary for building and testing a software project. It contains the objects (source code and resources). It also holds the configuration settings for the project, the IDE, and the plug-ins. The workspace is locally maintained on a developer's machine, and teams collaborate through external repositories that are meeting places for code parts from different developers. Repositories are accessible through the client-server architecture via the Internet.

The Eclipse Platform offers support for team development operations directly from the workspace. This support allows a developer to concurrently interact with several separate repositories and versions of code or projects. Resources within the workspace allow the team support component to deal with version and configuration management issues. Of course, single workspaces can access different types of repositories simultaneously. The Eclipse Platform does not provide its own code-management solution; it always depends on external systems. The Eclipse Platform has built-in support for only one (albeit the most popular) source-code management system: Concurrent Versions System (CVS).

What is CVS?

CVS started out as a collection of shell scripts in 1986, but it has evolved into the most popular source code version management solution for software developers. CVS is the open source client/server solution for code versioning and is available for variety of platforms, including Linux® and Windows® NT/2000/XP. See Resources for download links for CVS clients, servers, and source code.

In general, the primary function of CVS is to record the history of source files. When a group of developers work on the same project, CVS insulates them from each other. Every developer works separately, in his own directory and merges (from time to time) the results of the work with the CVS repository.

Eclipse has a built-in CVS client that is deeply integrated with the Eclipse Platform IDE, which is implemented as a separate perspective (CVS Repository Exploring Perspective) for interacting with CVS. General Eclipse settings for CVS are located under Window > Preferences window > Team. After switching to the CVS Repository Exploring Perspective, all CVS operations become available (go to Window > Open Perspective > Other > CVS Repository Exploring menu).

The first step is to set up a repository location that defines connection parameters for the selected CVS server/repository.

Source-code workflow with Eclipse/CVS

In the CVS team cooperation model, team members do all of their work on their own workbenches, isolated from others. Eventually, they will want to share their work. They do this via CVS repositories. CVS uses a branch model to support multiple courses of work that are isolated from each other, but still highly interdependent. Branches are where a development team shares and integrates ongoing work. A branch can be thought of as a shared workbench that is updated by team members as they make changes to the source code. This model allows individuals to work on a CVS team project, share their work with others as changes are made, and access the work of others as the project evolves.

A special branch, referred to as head, represents the main course of work in the repository (a head is often referred to as the trunk). As resources are committed to the branch, these dependencies can be affected. Ensuring the integrity of the dependencies is important because the branch represents the current project's state. Of course, at any point, a team member could make use of the branch contents as the basis for new work.

Those rules apply not only to the CVS: there are common steps for source-code management within team projects no matter what version-control software is in use. Below is an example workflow that uses Eclipse's built-in support for CVS:

1. Starting a new team project
Each new, empty Eclipse project can be shared through CVS (or any other supported source code management system). Developers can also share their existing code by migrating it to the repository. To do this, use the Team > Share Project option located in the context menu that displays when you click the project main folder.


Another option is to create a new workbench project by importing code from the selected branch of the CVS repository. Simply select the appropriate branch (or head), then select Checkout As Project from the context menu in the CVS Repository Exploring Perspective.

2. Working with code and making changes
Developers work with code locally via the Eclipse workbench, creating new resources, modifying existing ones, writing commentaries, and saving locally as they go.

3. Synchronizing local changes with the CVS repository
If a developer on a project is ready to commit his work, the first step is to perform the update operation. This will check the repository for incoming changes and add them to that developer's local workbench. This ensures that the developer knows the changes that might affect the integrity of what he is about to commit. Compare a local version against code stored in the repository using the Compare With option in the project context menu.
The next step is to resolve any conflict that eventually appears and try to compile the code again. If everything works, then perform the commit operation using the Team > Commit option from the project context menu, as shown below. This will integrate all changes into the repository.

4. Managing repositories
CVS allows developers to isolate changes into separate lines of development, known as branches. When one developer changes files on a branch, those changes do not appear on the main trunk or on other branches. Those branches are named subversions or code forks. Later, moving changes from one branch to another branch (or the main trunk) is performed by the merging operation. Then revisions are committed. This effectively copies the changes onto another branch. Eclipse makes it easy to move between development branches using the Team > Branch option from the project context menu.

Of course, when a development team maintains a large repository, it is necessary to have a control over commit and merge operations within projects. Eclipse/CVS integration offers a special view: the CVS Repository History. It gives a quick preview on changes in the repository performed by team members.

The Eclipse Platform comes with a few utilities that support code management. The most useful is the patch function. It compares code from two sources, such as a local workbench and the repository, then creates a UNIX®-like patch file containing code differences. This file can be sent to developers to upgrade source code to the newest version.
5. Disconnecting a project from CVS
When the project development has ended and the team wants to freeze source code, the final version of the project can be removed from the head repository. Disconnecting a project from CVS disables the repository operations that can be performed on the project and its resources, and optionally removes the CVS information associated with the project.

Disconnecting operations can be performed from the Team > Disconnect option in the project context menu. By choosing this option, the Confirm Disconnect from CVS dialog opens. When the project is disconnected from the repository, the team must then decide what to do with the CVS information. The first option is "Delete the CVS meta information," which disables the CVS team menu operations and removes the CVS folders and their contents from the file system. The second option is to use the "Do not delete the CVS meta information," which disables the CVS team menu operations, but leaves the CVS meta information.


Source of the above post: http://www.ibm.com/developerworks/library/os-ecshare/

Saturday, August 29, 2009

Map an external directory into your application directory in Tomcat

This article will explain how to map an external directory into your application directory (i.e. how to create a virtual directory) using Tomcat.
Let me first describe why you may need to create a virtual directory in your application. Suppose your application allows a user to upload images and there is no restriction on the total number of images that can be uploaded in your application. The folder in which the images are loaded will keep on growing in size from KBs to MBs to GBs, eventually the size of the application will also grow which will hamper the speed of your application.

Creating a virtual directory inside your context in Glassfish v3 Preview is straight forward as discussed in my previous post. While setting up the same in tomcat you need to make sure if you are using Tomcat 6 then it is version 6.0.18 or higher. The method that I had followed from the Tomcat manual does not works in version 6.0.16.

You might know that you can create a virtual host in tomcat and run your application by placing it anywhere outside of the "webapps" folder. Basically you are creating a new context which is outside the "webapps" folder. What I will be talking about is having something like "/yourContext/images", where the "images" folder is anywhere outside the "yourContext" folder which is inside "webapps" i.e. "images" can be anywhere other than "/webapps/yourContext/images".

Let us begin with what the Tomcat documentation says here,

The Context element represents a web application, which is run within a particular virtual host. Each web application is based on a Web Application Archive (WAR) file, or a corresponding directory containing the corresponding unpacked contents, as described in the Servlet Specification (version 2.2 or later).
You may define as many Context elements as you wish. Each such Context MUST have a unique context path. In addition, a Context must be present with a context path equal to a zero-length string. This Context becomes the default web application for this virtual host, and is used to process all requests that do not match any other Context's context path.

For Tomcat 6, unlike Tomcat 4.x, it is NOT recommended to place elements directly in the server.xml file. This is because it makes modifing the Context configuration more invasive since the main conf/server.xml file cannot be reloaded without restarting Tomcat.

Context elements may be explicitly defined:
  • In the $CATALINA_BASE/conf/context.xml file: the Context element information will be loaded by all webapps.
  • In the $CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default file: the Context element information will be loaded by all webapps of that host.
  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
  • Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files. If the web application is packaged as a WAR then /META-INF/context.xml will be copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to match the application's context path. Once this file exists, it will not be replaced if a new WAR with a newer /META-INF/context.xml is placed in the host's appBase.
  • Inside a Host element in the main conf/server.xml.
With the exception of server.xml, files that define Context elements may only define a single Context element.

Let us concentrate on the bullet point:
  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
It tells you how to create a multilevel context path, in other words how to create a virtual directory inside your context.

The method is simple, which involves the following steps:

1. Open the CATALINA_HOME location which is where you have installed tomcat.
2. Locate and change directory to "conf"
3. Now create a directory called "Catalina".
4. Now create another directory "localhost" inside the newly created directory "Catalina".
5. Inside "localhost" create a file called "yourContext#images.xml", replacing "yourContext" with your context name.
6. Now inside the above xml file put the following line:
<context docbase="d:/images"></context>
7. Now restart Tomcat server.

Now, when you load the Tomcat Manager you will find a new entry for the context "yourContext/images". Now this will point to the "images" directory in D drive as in the above example.

All the request made to "/yourContext/images" will be mapped to your directory "d:\images".

Now, you have an external directory mapped into your context which can be used to upload files or images.

Tuesday, August 11, 2009

Retrieving Automatically Generated Keys

Retrieving Automatically Generated Keys

Many DBMSs automatically generate a unique key field when a new row is inserted into a table. Methods and constants added in the JDBC 3.0 API make it possible to retrieve these keys, which is a two-step process. First the driver is alerted that it should make the keys available for retrieval. The second step is to access the generated keys by calling the Statement method getGeneratedKeys. The rest of this section explains these two steps more fully.
  1. Step One - Tell the driver that it should make automatically generated keys available for retrieval. This is done when an SQL statement is sent to the DBMS, which for Statement objects, is when the statement is executed. Three new versions of the method executeUpdate and three new versions of the method execute signal the driver about making automatically generated keys available. These six new methods take two parameters, the first being in all cases an SQL INSERT statement. The second parameter is either a constant indicating whether to make all generated keys retrievable (Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS) or an array indicating which specific key columns should be made retrievable. The array elements are either the indexes of the columns to be returned or the names of the columns to be returned.

    Note that although it is possible to use the method execute for executing a DML (Data Manipulation Language) statement, this method is generally reserved for executing CallableStatement objects that produce multiple return values.
    • For a PreparedStatement object, the SQL statement is sent to the DBMS to be precompiled when the PreparedStatement object is created with one of the Connection.prepareStatement methods. Thus, the driver is notified about making automatically generated keys retrievable via these methods.


  2. Step Two - After the driver has been notified about making automatically generated keys available for retrieval, the keys can be retrieved by calling the Statement method getGeneratedKeys. This method returns a ResultSet object, with each row being a generated key. If there are no automaticallty generated keys, the ResultSet object will be empty.
    The following code fragment creates a Statement object and signals the driver that it should be able to return any keys that are automatically generated as a result of executing the statement. The example then retrieves the keys that were generated and prints them out. If there are no generated keys, the printout says that there are none.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";

int rows = stmt.executeUpdate(sql,
Statement.RETURN_GENERATED_KEYS);

ResultSet rs = stmt.getGeneratedKeys();


int rows = stmt.executeUpdate(sql,
Statement.RETURN_GENERATED_KEYS);

ResultSet rs = stmt.getGeneratedKeys();
if (rs.next())
{
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
do {
for (int i = 1; i <= colCount; i++)   
{   
String key = rs.getString(i);     
System.out.println("key " + i + "is " + key); 
} 
} 
while (rs.next();)   }
else  
{ System.out.println("There are no generated keys."); }
Instead of telling the driver to make all automatically-generated keys available, it is possible to tell the driver to make particular columns retrievable. The following code fragment uses an array of column indexes (in this case, an array with one element) to indicate which columns with an automatically-generated key should be made available for retrieval.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";
int [] indexes = {4};
int rows = stmt.executeUpdate(sql, indexes);
The following code fragment shows a third alternative-supplying an array of column names to indicate which ResultSet columns to make available. In this case, the driver is told to make the automatically-generated key in the column AUTHOR_ID retrievable.
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
"'PARKER', 'DOROTHY', 'USA', keyColumn";
String [] keyColumn = {"AUTHOR_ID"};
int rows = stmt.executeUpdate(sql, keyColumn);
The above has been taken from http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/statement.html#1000569

Sunday, August 9, 2009

How to setup Java under Linux

For Fedora please visit the below link and check the post by "dinob" (#6)

http://forums.fedoraforum.org/showthread.php?t=85446

For Ubuntu please visit the link below and check the post by "hod139" (#1)

http://ubuntuforums.org/showthread.php?t=201378

Friday, August 7, 2009

Compiling and installing a Linux Kernel

Compiling custom kernel has its own advantages and disadvantages. However, new Linux user / admin find it difficult to compile Linux kernel. Compiling kernel needs to understand few things and then just type couple of commands. This step by step howto covers compiling Linux kernel.

Step # 1 Get Latest Linux kernel code


Visit http://kernel.org/ and download the latest source code. File name would be linux-x.y.z.tar.bz2, where x.y.z is actual version number. For example file inux-2.6.25.tar.bz2 represents 2.6.25 kernel version.

Step # 2 Extract tar (.tar.bz3) file

Type the following command:

# tar -xjvf linux-2.6.25.tar.bz2 -C /usr/src
# cd /usr/src

Step # 3 Configure kernel

Before you configure kernel make sure you have development tools (gcc compilers and related tools) are installed on your system.
Now you can start kernel configuration by typing any one of the command:
  • $ make menuconfig - Text based color menus, radiolists & dialogs. This option also useful on remote server if you wanna compile kernel remotely.
  • $ make xconfig - X windows (Qt) based configuration tool, works best under KDE desktop
  • $ make gconfig - X windows (Gtk) based configuration tool, works best under Gnome Dekstop.
For example make menuconfig command launches following screen:

$ make menuconfig

You have to select different options as per your need. Each configuration option has HELP button associated with it so select help button to get help.

Step # 4 Compile kernel

Start compiling to create a compressed kernel image, enter:

$ make


Start compiling to kernel modules:

$ make modules

Install kernel modules (become a root user, use su command):

$ su -
# make modules_install

Step # 5 Install kernel

So far we have compiled kernel and installed kernel modules. It is time to install kernel itself.

# make install

It will install three files into /boot directory as well as modification to your kernel grub configuration file:
  • System.map-2.6.25
  • config-2.6.25
  • vmlinuz-2.6.25

Step # 6: Create an initrd image

Type the following command at a shell prompt:

# cd /boot
# mkinitrd -o initrd.img-2.6.25 2.6.25


initrd images contains device driver which needed to load rest of the operating system later on. Not all computer requires initrd, but it is safe to create one.

Step # 7 Modify Grub configuration file - /boot/grub/menu.lst

Open file using vi:

# vi /boot/grub/menu.lst
title           Debian GNU/Linux, kernel 2.6.25 Default
root            (hd0,0)
kernel          /boot/vmlinuz root=/dev/hdb1 ro
initrd          /boot/initrd.img-2.6.25
savedefault
boot

Remember to setup correct root=/dev/hdXX device. Save and close the file. If you think editing and writing all lines by hand is too much for you, try out update-grub command to update the lines for each kernel in /boot/grub/menu.lst file. Just type the command:
# update-grub

Step # 8 : Reboot computer and boot into your new kernel

Just issue reboot command:

# reboot

For more information see:
  • Our Exploring Linux kernel article and Compiling Linux Kernel module only.
  • Official README file has more information on kernel and software requirement to compile it. This file is kernel source directory tree.
  • Documentation/ directory has interesting kernel documentation for you in kernel source tree.

Map an external directory into Glassfish

In this article I'll try to explain how to map an external directory into the Glassfish application server. Until you have experienced the need for mapping an external directory into Glassfish, the first thing that will come to your mind what is the need to do so.

The reason to map an external directory into the server may be different for different kind of applications. One of the situations may be when an application has to upload lots of files on the server which may be images, text documents, PDFs, Word Documents or other format of files. The files uploaded on a daily basis will eat up disk space and make the context of the application grow in size may be on a daily basis or even hourly basis. A best example of such an application may be an application which allows users to upload images. An inventory management system may also allow the user to upload images of the inventory items. And in cases where all the inventory items has at least one image attached to it the size of the folder storing the images may easily go beyond 2GB. Imagine a growing inventory of more than 24,000 items with an option to add two images for an item. If the server is running on Windows with FAT32 file system then there will be another problem when the folder size grows to 2GB. FAT32 does not supports folder size of more than 2GB. So, while uploading files on the server you should be careful and have to manage the files by segregating them into different folders, which may be by date and time.

Now getting back to the main topic of creating virtual directories. This can be easily done using the Glassfish application server. GlassFish v2 Build 40 adds support for alternate docroots to web applications. Previously, support for alternate docroots was limited to virtual servers.

Alternate docroots allow web applications to serve requests for certain resources from outside their own docroot, based on whether those requests match one (or more) of the URI patterns of the web application's alternate docroots.

This means that web applications no longer need to bundle all their resources. Instead, part of their resources may be outsourced into server directories outside the web application's docroot, so-called alternate docroots, where they may be shared with other web applications.
If a request matches an alternate docroot's URI pattern, it will be mapped to the alternate docroot by appending the request URI (minus the web application's context root!) to the alternate docroot's physical location (directory).

The URI patterns of alternate docroots of web applications support exact, path prefix, and extension matches, just like their counterparts for virtual servers. If a request matches multiple URI patterns, the alternate docroot is determined according to the following precedence order:
  • Exact match
  • Longest path match
  • Extension match
Alternate docroots of web applications are configured as sun-web.xml properties, using the same syntax as alternate docroots for virtual servers.

Example: The following sun-web.xml specifies 3 alternate docroots:

<sun-web-app>
     <property name="alternatedocroot_1" value="from=/my.jpg dir=/srv/images/jpg"/>
     <property name="alternatedocroot_2" value="from=*.jpg dir=/srv/images/jpg"/>
     <property name="alternatedocroot_3" value="from=/jpg/* dir=/src/images"/>
</sun-web-app>


The value of each alternate docroot has two name-value components: The first component (with name from) specifies the alternate docroot's URI pattern as its value, and the second component (with name dir) specifies the alternate docroot's physical location (directory) as its value.

In this example, the URI pattern of the first alternate docroot uses an exact match, whereas the URI patterns of the 2nd and 3rd alternate docroots use extension and path prefix matches, respectively.

Assume the above sun-web.xml belongs to a web application deployed at http://{hostName}:{portNumber}/myapp.

The first alternate docroot will cause any requests with this URL:

http://{hostName}:{portNumber}/myapp/my.jpg
to be mapped to this resource:

/svr/images/jpg/my.jpg

while the 2nd alternate docroot will cause any requests with a *.jpg suffix, as in:

http://{hostName}:{portNumber}/myapp/*.jpg

to be served from this physical location:

/svr/images/jpg

whereas the 3rd alternate docroot will cause any requests whose URI starts with /myapp/jpg/, as in:

http://{hostName}:{portNumber}/myapp/jpg/*

to be served from the same directory as the 2nd alternate docroot.

For example, the 2nd alternate docroot maps this request:

http://{hostName}:{portNumber}/myapp/abc/def/my.jpg

to:

/srv/images/jpg/abc/def/my.jpg

and the 3rd alternate docroot maps:

http://{hostName}:{portNumber}/myapp/jpg/abc/resource

to:

/srv/images/jpg/abc/resource

If a request does not match any of the target web application's alternate docroots, or if the target web application does not specify any alternate docroots, the request will be served from the web application's standard docroot, as usual.

One point to note is that the physical path and the one in the 'sun-web.xml' should match. For example in
<property name="alternatedocroot_3" value="from=/jpg/* dir=/src/images"/>

The above will map to /src/images/jpg. So, you need to make sure that whatever is after "from=" matches to a path inside the "images" folder. In the above examples the path is from Unix/Linux systems. To use on a Windows machine use something like "d:/src/images".

Wednesday, August 5, 2009

Install KDE on Ubuntu

KDE is a powerful graphical desktop environment for Unix workstations. It combines ease of use, contemporary functionality and outstanding graphical design with the technological superiority of the Unix operating system. KDE is a completely new desktop, incorporating a large suite of applications for Unix workstations. While KDE includes a window manager, file manager, panel, control center and many other components that one would expect to be part of a contemporary desktop environment, the true strength of this exceptional environment lies in the interoperability of its components.
If you have used Fedora in the past then you must be aware of the fact that it gives you an option to install both Gnome and KDE. This option had been available since the earlier days when Fedora used to be RedHat Linux.
If anyone of you misses KDE while working on Ubuntu you can install KDE on Ubuntu using the simple steps described below.
By default Ubuntu desktop installation will install gnome desktop enviroment and if you want to install KDE desktop enviroment you have three options. Those options are
kubuntu-desktop -This is the recommended metapackage to install; the full Kubuntu installation, with all the Kubuntu recommended packages. This includes OpenOffice, Kontact, Konversation, amaroK, K3B, and others.
kde -This will install the following KDE packages: kde-amusements, kdeaccessibility, kdeaddons, kdeadmin, kdeartwork, kdegraphics, kdemultimedia, kdenetwork, kdepim, kdesdk, kdeutils, kdewebdev, kdevelop3 and the kde-core metapackage
kde-core -This will install the core — the bare-minimum required– of KDE. That is, kdebase, kdelibs, arts and fontconfig.
If you choose to not install kubuntu-desktop, then you can still get all the Kubuntu-specific tweaks by installing the kubuntu-default-settings package.
First thing you need to make sure you have universe source list under
/etc/apt/sources.list file
If you want to install kubuntu-desktop use the following command
sudo apt-get install kubuntu-desktop
This will starts installing all the required packages you can see in the following screen.
During this installation process, you will be asked whether you want to use KDM or GDM as your default display manager. If you think you’ll use KDE , make KDM your default. If you think you’ll use Gnome , keep GDM as your default.Select which one is best for you.
This will complete the installation now you need to logout from ubuntu gnome session and now you are on ubuntu login screen in this you need to select options—> selectsession.
Uninstall KDE in ubuntu
If for any reasons you want to uninstall KDE session use the following command
sudo apt-get remove kubuntu-desktop