Monday, August 22, 2011

Java Tips - Changing Data Using a ResultSet

If you have JDBC 2 and a conforming driver, you can request an updatable ResultSet when you create the statement object. When you're on the row you want to change, use the update( ) methods and end with updateRow( ).

You need to create the statement with the attribute ResultSet.CONCUR_UPDATABLE. Do an SQL SELECT with this statement. When you are on the row (only one row matches this particular query because it is selecting on the primary key), use the appropriate update method for the type of data in the column you want to change, passing in the column name or number and the new value. You can change more than one column in the current row this way. When you're done, call updateRow( ) on the ResultSet. Assuming that you didn't change the autocommit state, the data is committed to the database.

Example: ResultSetUpdate.java (partial listing)
try {

   con = DriverManager.getConnection(url, user, pass);

   stmt = con.createStatement(

       ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

   rs = stmt.executeQuery("SELECT * FROM Users where nick=\"ian\"");



   // Get the resultset ready, update the passwd field, commit

   rs.first( );

   rs.updateString("password", "unguessable");

   rs.updateRow( );



   rs.close( );

   stmt.close( );

   con.close( );

} catch(SQLException ex) {

   System.err.println("SQLException: " + ex.getMessage( ));

}

Java Tips - Connecting to a JDBC Database

The static method DriverManager.getConnection( ) lets you connect to the database using a URL-like syntax for the database name (for example, jdbc:dbmsnetproto://server:4567/mydatabase) and a login name and password. The "dbURL" that you give must begin with jdbc:. The rest of it can be in whatever form the driver vendor's documentation requires and is checked by the driver. The DriverManager asks each driver you have loaded (if you've loaded any) to see if it can handle a URL of the form you provided. The first one that responds in the affirmative gets to handle the connection, and its connect( ) method is called for you (by DriverManager.getConnection( )).

Four types of drivers are defined by Sun (not in the JDBC specification but in their less formal documentation)
  1. JDBC-ODBC bridge = Provide JDBC API Access.
  2. Java and Native Driver = Java code calls Native DB driver.
  3. Java and Middleware = Java contacts Middleware Server.
  4. Pure Java = java contacts (possibly remote) DB directly.
Example: Connect.java
import java.awt.*;

import java.sql.*;



/** Load a driver and connect to a database.

 */

public class Connect {



    public static void main(String[] av) {

        String dbURL = "jdbc:odbc:Companies";

        try {

            // Load the jdbc-odbc bridge driver

            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");



            // Enable logging

            DriverManager.setLogStream(System.err);



            System.out.println("Getting Connection");

            Connection conn = 

                DriverManager.getConnection(dbURL, "ian", "");    // user, passwd



            // If a SQLWarning object is available, print its

            // warning(s).  There may be multiple warnings chained.



            SQLWarning warn = conn.getWarnings( );

            while (warn != null) {

                System.out.println("SQLState: " + warn.getSQLState( ));

                System.out.println("Message:  " + warn.getMessage( ));

                System.out.println("Vendor:   " + warn.getErrorCode( ));

                System.out.println("");

                warn = warn.getNextWarning( );

            }



            // Process the connection here...



            conn.close( );    // All done with that DB connection



        } catch (ClassNotFoundException e) {

            System.out.println("Can't load driver " + e);

        } catch (SQLException e) {

            System.out.println("Database access failed " + e);

        }

    }

}

Java Tips - JDBC Setup and Connection

JDBC has two Levels, JDBC 1 and JDBC 2. Level 1 is included in all JDBC implementation and drivers; Level 2 is optional and requires a Level 2 driver.

To create a JDBC query:

  1. Load the appropriate Driver class, which has the side effect of registering with the DriverManager.
  2. Get a Connection object, using DriverManager.getConnection( ) :
    Connection con = DriverManager.getConnection (dbURL, name, pass);
  3. Get a Statement object, using the Connection object's createStatement( ) :
    Statement stmt = con.createStatement( );
  4. Get a ResultSet object, using the Statement object's executeQuery( ) :
    ResultSet rs = stmt.executeQuery("select * from MyTable");
  5. Iterate over the ResultSet:
    while (rs.next( )) {
    
        int x = rs.getInt("CustNO");
  6. Close the ResultSet.
  7. Close the Statement.
  8. Close the Connection.
     
The first step in using JDBC 1 is to load your database's driver. This is performed using some Java JVM magic. The class java.lang.Class has a method called forName( ) that takes a string containing the full Java name for a class and loads the class, returning a Class object describing it. This is part of the introspection or reflection API  but can be used anytime to ensure that a class has been correctly configured into your CLASSPATH. This is the use that we'll see here. And, in fact, part of the challenge of installing JDBC drivers is ensuring that they are in your CLASSPATH at deployment time. The advantage of my slightly convoluted approach is that the drivers do not have to be on your CLASSPATH at compile time. In some cases, this can allow customers to use your software with database drivers that didn't even exist when your software was written; how's that for flexibility?

In addition to checking your CLASSPATH, this method also registers the driver with another class called the DriverManager . How does it work? Each valid JDBC driver has a bit of method-like code called a static initializer . This is used whenever the class is loaded—just what the doctor ordered! So the static block registers the class with the DriverManager when you call Class.forName( ) on the driver class.

Example: LoadDriver.java
import java.awt.*;

import java.sql.*;



/** Load some drivers.  */

public class LoadDriver {

    public static void main(String[] av) {

        try {

            // Try to load the jdbc-odbc bridge driver

            // Should be present on Sun JDK implementations.

            Class c = Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

            System.out.println("Loaded " + c);
           
        } catch (ClassNotFoundException ex) {

            System.err.println(ex);

        }

    }

}

Java Tips - Formatting Numbers

The java.text package includes a Locale class, and, furthermore, the Java runtime automatically sets a default Locale object based on the user's environment; e.g., on the Macintosh and Windows, the user's preferences; on Unix, the user's environment variables. To provide formatters customized for numbers, currencies, and percentages, the NumberFormat class has static factory methods that normally return a DecimalFormat with the correct pattern already instantiated. A DecimalFormat object appropriate to the user's locale can be obtained from the factory method NumberFormat.getInstance( ) and manipulated using set methods. Surprisingly, the method setMinimumIntegerDigits( ) turns out to be the easy way to generate a number format with leading zeros. Here is an example:
import java.text.*;

import java.util.*;



/*

 * Format a number our way and the default way.

 */

public class NumFormat2 {

    /** A number to format */

    public static final double data[] = {

        0, 1, 22d/7, 100.2345678

    };



    /** The main (and only) method in this class. */

    public static void main(String av[]) { 

        // Get a format instance

        NumberFormat form = NumberFormat.getInstance( );



        // Set it to look like 999.99[99]

        form.setMinimumIntegerDigits(3);

        form.setMinimumFractionDigits(2);

        form.setMaximumFractionDigits(4);



        // Now print using it.

        for (int i=0; i<data.length; i++)

            System.out.println(data[i] + "\tformats as " +

                form.format(data[i]));

    }

}

This prints the contents of the array using the NumberFormat instance form:
$ java NumFormat2

0.0     formats as 000.00

1.0     formats as 001.00

3.142857142857143       formats as 003.1429

100.2345678     formats as 100.2346

$

You can also construct a DecimalFormat with a particular pattern or change the pattern dynamically using applyPattern( ). Some of the more common pattern characters are shown in the following.

# = Numeric digit (leading zeros suppressed)
0 = Numeric digit (leading zeros provided)
. = Locale-specific decimal separator (decimal point)
, = Locale-specific grouping separator (comma in English)
- = Locale-specific negative indicator (minus sign)
% = Shows the value as a percentage
; = Separates two formats: the first for positive and the second for negative values
, = Escapes one of the above characters so it appears

The NumFormatTest program uses one DecimalFormat to print a number with only two decimal places and a second to format the number according to the default locale:
// NumFormatTest.java 

/** A number to format */ 

public static final double intlNumber = 1024.25; 

/** Another number to format */ 

public static final double ourNumber = 100.2345678; 

NumberFormat defForm = NumberFormat.getInstance( ); 

NumberFormat ourForm = new DecimalFormat("##0.##"); 

// toPattern( ) shows the combination of #0., etc 

// that this particular local uses to format with 

System.out.println("defForm's pattern is " + 

    ((DecimalFormat)defForm).toPattern( )); 

System.out.println(intlNumber + " formats as " + 

    defForm.format(intlNumber)); 

System.out.println(ourNumber + " formats as " + 

    ourForm.format(ourNumber)); 

System.out.println(ourNumber + " formats as " + 

    defForm.format(ourNumber) + " using the default format");

This program prints the given pattern and then formats the same number using several formats:
defForm's pattern is #,##0.###

1024.25 formats as 1,024.25

100.2345678 formats as 100.23

100.2345678 formats as 100.235 using the default format   

Java Tips - Parsing Strings into Dates

The DateFormat class has some additional methods, notably parse( ) , which tries to parse a string according to the format stored in the given DateFormat object:
// DateParse1.java 

SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd"); 

String input = args.length == 0 ? "1818-11-11" : args[0]; 

System.out.print(input + " parses as "); 

Date t; 

try { 

    t = formatter.parse(input); 

    System.out.println(t); 

} catch (ParseException e) { 

    System.out.println("unparseable using " + formatter); 

}

This program parses any date back to Year Zero and well beyond Year 2000.
What if the date is embedded in an input string? You could, of course, use the string's substring( ) method to extract it, but there is an easier way. The ParsePosition object from java.text is designed to represent (and track) the position of an imaginary cursor in a string. Suppose we have genealogical data with input strings representing the times of a person's life:
BD: 1913-10-01 Vancouver, B.C. 

DD: 1983-06-06 Toronto, ON

This lists one person's birth date (BD) and place, and death date (DD) and place. We can parse these using String.indexOf(' ') to find the space after the : character, DateFormat parse( ) to parse the date, and String.substring( ) to get the city and other geographic information. Here's how:
// DateParse2.java 

SimpleDateFormat formatter = 

    new SimpleDateFormat ("yyyy-MM-dd"); 

String input[] = {  

    "BD: 1913-10-01 Vancouver, B.C.", 

    "MD: 1948-03-01 Ottawa, ON", 

    "DD: 1983-06-06 Toronto, ON" }; 

for (int i=0; i<input.length; i++) { 

    String aLine = input[i]; 

    String action; 

    switch(aLine.charAt(0)) { 

        case 'B': action = "Born"; break; 

        case 'M': action = "Married"; break; 

        case 'D': action = "Died"; break; 

        // others... 

        default: System.err.println("Invalid code in " + aLine); 

        continue; 

    } 

    int p = aLine.indexOf(' '); 

    ParsePosition pp = new ParsePosition(p); 

    Date d = formatter.parse(aLine, pp); 

    if (d == null) { 

        System.err.println("Invalid date in " + aLine); 

        continue; 

    } 

    String location = aLine.substring(pp.getIndex( )); 

    System.out.println( 

        action + " on " + d + " in " + location); 

}

This works like I said it would:
Born on Wed Oct 01 00:00:00 PDT 1913 in  Vancouver, B.C. 

Married on Mon Mar 01 00:00:00 PST 1948 in  Ottawa, ON 

Died on Mon Jun 06 00:00:00 PDT 1983 in  Toronto, ON

Introduction to XML

The Extensible Markup Language, or XML, is a portable, human-readable format for exchanging text or data between programs. XML is derived from the parent standard SGML, as is the HTML language used on web pages worldwide. XML, then, is HTML's younger but more capable sibling. And since most developers know at least a bit of HTML, parts of this discussion compare XML with HTML. XML's lesser-known grandparent is IBM's GML (General Markup Language), and one of its cousins is Adobe FrameMaker's Maker Interchange Format (MIF).  The following figure depicts the family tree.





XML's ancestry


One way of thinking about XML is that it's HTML cleaned up, consolidated, and with the ability for you to define your own tags. It's HTML with tags that can and should identify the informational content as opposed to the formatting. Another way of perceiving XML is as a general interchange format for such things as business-to-business communications over the Internet or as a human-editable description of things as diverse as word-processing files and Java documents. XML is all these things, depending on where you're coming from as a developer and where you want to go today—and tomorrow.
Because of the wide acceptance of XML, it is used as the basis for many other formats, including the Open Office (http://www.openoffice.org/) save file format, the SVG graphics file format, and many more.
From SGML, both HTML and XML inherit the syntax of using angle brackets (< and >) around tags, each pair of which delimits one part of an XML document, called an element . An element may contain content (like a <P> tag in HTML) or may not (like an <hr> in HTML). While HTML documents can begin with either an <html> tag or a <DOCTYPE...> tag (or, informally, with neither), an XML file may begin with an XML declaration. Indeed, it must begin with an XML processing instruction (<? ... ?> ) if the file's character encoding is other than UTF-8 or UTF-16:
<?xml version="1.0"  encoding="iso-8859-1"?>

The question mark is a special character used to identify the XML declaration (it's syntactically similar to the % used in ASP and JSP).
HTML has a number of elements that accept attributes, such as:
<BODY BGCOLOR=white> ... </body>

In XML, attribute values (such as the 1.0 for the version in the processing instruction or the white of BGCOLOR) must be quoted. In other words, quoting is optional in HTML, but required in XML.
The BODY example shown here, while allowed in traditional HTML, would draw complaints from any XML parser. XML is case-sensitive; in XML, BODY, Body, and body represent three different element names. Yes, each XML start tag must have a matching end tag. This is one of a small list of basic constraints detailed in the XML specification. Any XML file that satisfies all of these constraints is said to be well-formed and is accepted by an XML parser. A document that is not well-formed is rejected by an XML parser.
Speaking of XML parsing, a great variety of XML parsers are available. A parser is simply a program or class that reads an XML file, looks at it at least syntactically, and lets you access some or all of the elements. Most of these parsers conform to the Java bindings for one of the two well-known XML APIs, SAX and DOM. SAX, the Simple API for XML, reads the file and calls your code when it encounters certain events, such as start-of-element, end-of-element, start-of-document, and the like. DOM, the Document Object Model, reads the file and constructs an in-memory tree or graph corresponding to the elements and their attributes and contents in the file. This tree can be traversed, searched, modified (even constructed from scratch, using DOM), or written to a file.
But how does the parser know if an XML file contains the correct elements? Well, the simpler, "nonvalidating" parsers don't—their only concern is the well-formedness of the document. Validating parsers check that the XML file conforms to a given Document Type Definition (DTD) or an XML Schema. DTDs are inherited from SGML. Schemas are newer than DTDs and, while more complex, provide such object-based features as inheritance. DTDs are written in a special syntax derived from SGML while XML Schemas are expressed using ordinary XML elements and attributes.
In addition to parsing XML, you can use an XML processor to transform XML into some other format, such as HTML. This is a natural for use in a web servlet: if a given web browser client can support XML, just write the data as-is, but if not, transform the data into HTML. We'll look at two approaches to XML transformation: transformation using a generic XSLT processor and then later some parsing APIs suitable for customized operations on XML.
If you need to control how an XML document is formatted, for screen or print, you can use XSL ( Extensible Style Language). XSL is a more sophisticated variation on the HTML stylesheet concept that allows you to specify formatting for particular elements. XSL has two parts: tree transformation (for which XSLT was designed, though it can also be used independently, as we'll see) and formatting (the non-XSLT part is informally known as XSL-FO or XSL Formatting Objects).
XSL stylesheets can be complex; you are basically specifying a batch formatting language to describe how your textual data is formatted for the printed page. A comprehensive reference implementation is FOP (Formatting Objects Processor), which produces Acrobat PDF output and is available from http://xml.apache.org/.
Prior to JDK 1.4, writing portable XML-based Java programs was difficult because there was no single standard API. JDK 1.4 introduced JAXP, the Java API for XML Processing, which provides standard means for accessing the various components discussed in this chapter. If you are still using JDK 1.3, you may need to acquire additional JAR files and/or change the examples somewhat.

How to Install Adempiere version 3.6.0 on Windows 7 ?

You will need 3 files to install adempiere
  1. Java Development Kit (JDK6)
  2. Postgresql
  3. Adempiere installation file: you can download the Adempiere installation file from  http://sourceforge.net/projects/adempiere/
After you finish downloading All 3 files, do the following steps:
  1. Install Java Development Kit (JDK6)
  2. Install Postgresql
  3. Set Environment Variable of JAVA_HOME: For example in Windows 7: Control Panel > System > Advanced System Settings > Environment Variables > click new button under System varibles panel > Type JAVA_HOME in variable name text box. copy the java path that you just install and paste it in variable value text box. then press OK button
  4. Set PATH to Postgresql command: For example in Windows 7: Control Panel > System > Advanced System Settings > Environment Variables > Select PATH under System varibles panel. Click Edit button > Type semicolon at the end of variable value and then copy postgresql binary path that you just install and paste it at the end of variable value text box. then press OK button. Postgresql path is something like this "C:\Program Files\PostgreSQL\8.4\bin".
  5. Extract Adempiere3.6.zip
  6. Setup Server by running Run_setup.exe in Adempiere folder. The pop up window will appear. You need to set Adempiere Home path, JAVA_HOME path. for detail see http://www.adempiere.com/index.php/InstallServer
  7. Create Adempiere Database: Go to Adempiere > utils > RUN_ImportAdempiere.exe
  8. Start Adempiere Server: Go to Adempiere > utils > RUN_Server2.exe.  you must wait until Adempiere finish running and don't close this running windows otherwise it wil Stop Adempiere Server. For more detail see http://www.adempiere.com/index.php/InstallComplete
  9. Launch the Adempiere Application: Open Web browser and type your IP Address in address bar. Click Webstart button, Adempiere Application will be installed in your system. You can start testing Adempiere by using "GardenAdmin" as login name and password. For more detail see http://www.adempiere.com/Launching_the_ADempiere_Application
  10. To Stop Adempiere Server, RUN_Server2Stop.exe in "Adempiere\utils" folder.